Merge lp:~stefanor/ibid/multiline-501410 into lp:~ibid-core/ibid/old-trunk-1.6

Proposed by Stefano Rivera
Status: Merged
Approved by: Michael Gorven
Approved revision: 819
Merged at revision: 814
Proposed branch: lp:~stefanor/ibid/multiline-501410
Merge into: lp:~ibid-core/ibid/old-trunk-1.6
Diff against target: 451 lines (+91/-71)
19 files modified
ibid/core.py (+2/-16)
ibid/event.py (+5/-2)
ibid/plugins/bzr.py (+3/-1)
ibid/plugins/core.py (+25/-0)
ibid/plugins/games.py (+16/-14)
ibid/plugins/google.py (+4/-1)
ibid/plugins/help.py (+11/-2)
ibid/plugins/info.py (+0/-1)
ibid/plugins/lookup.py (+7/-7)
ibid/plugins/network.py (+1/-2)
ibid/source/campfire.py (+3/-20)
ibid/source/dc.py (+2/-2)
ibid/source/irc.py (+1/-1)
ibid/source/jabber.py (+2/-0)
ibid/source/pb.py (+2/-0)
ibid/source/silc.py (+2/-1)
ibid/source/smtp.py (+2/-0)
ibid/source/telnet.py (+2/-0)
scripts/ibid-plugin (+1/-1)
To merge this branch: bzr merge lp:~stefanor/ibid/multiline-501410
Reviewer Review Type Date Requested Status
Michael Gorven Approve
Jonathan Hitchcock Approve
Review via email: mp+16674@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Jonathan Hitchcock (vhata) wrote :

There may be a few plugins whose responses need tweaking, but the functionality is solid.

review: Approve
lp:~stefanor/ibid/multiline-501410 updated
816. By Stefano Rivera

Clean up usage output

Revision history for this message
Michael Gorven (mgorven) wrote :

I think the conflation should happen in the dispatcher to avoid code
duplication in the sources.
 review needs_fixing

review: Needs Fixing
lp:~stefanor/ibid/multiline-501410 updated
817. By Stefano Rivera

Move response compatibility-formatting to a core plugin

Revision history for this message
Stefano Rivera (stefanor) wrote :

> I think the conflation should happen in the dispatcher to avoid code
> duplication in the sources.

How about r817?

Revision history for this message
Jonathan Hitchcock (vhata) wrote :

Still approve - don't like the <action> reply format though - I'd prefer just *action*

lp:~stefanor/ibid/multiline-501410 updated
818. By Stefano Rivera

Tab -> Space on IRC & SILC

819. By Stefano Rivera

Change action ASCIIfication to *action*

Revision history for this message
Michael Gorven (mgorven) wrote :

 review approve
 status approved

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ibid/core.py'
2--- ibid/core.py 2009-12-21 12:43:58 +0000
3+++ ibid/core.py 2009-12-30 18:39:15 +0000
4@@ -60,14 +60,7 @@
5
6 filtered = []
7 for response in event['responses']:
8- source = response['source'].lower()
9- if source == event.source.lower():
10- if (response.get('action', False)
11- and 'action' not in ibid.sources[source].supports):
12- response['reply'] = '* %s %s' % (
13- ibid.config['botname'],
14- response['reply'],
15- )
16+ if response['source'].lower() == event.source.lower():
17 filtered.append(response)
18 else:
19 self.send(response)
20@@ -80,14 +73,7 @@
21 def send(self, response):
22 source = response['source']
23 if source in ibid.sources:
24- source = ibid.sources[source]
25- if (response.get('action', False)
26- and 'action' not in source.supports):
27- response['reply'] = '* %s %s' % (
28- ibid.config['botname'],
29- response['reply'],
30- )
31- reactor.callFromThread(source.send, response)
32+ reactor.callFromThread(ibid.sources[source].send, response)
33 self.log.debug(u"Sent response to non-origin source %s: %s", response['source'], response['reply'])
34 else:
35 self.log.warning(u'Received response for invalid source %s: %s', response['source'], response['reply'])
36
37=== modified file 'ibid/event.py'
38--- ibid/event.py 2009-12-14 13:51:54 +0000
39+++ ibid/event.py 2009-12-30 18:39:15 +0000
40@@ -30,6 +30,8 @@
41 action: True for actions
42 notice: True for IRC Notices
43 address: False to suppress user addressing, in public
44+ conflate: False to suppress conflation and truncation of lines in
45+ sources like IRC and SILC that don't support newlines
46 """
47 if response is None:
48 # We want to detect this now, so we know which plugin is to blame
49@@ -42,8 +44,9 @@
50 response = {'reply': response}
51
52 for k, val in (('target', self.get('channel', None)),
53- ('source', self.source),
54- ('address', True)):
55+ ('source', self.source),
56+ ('address', True),
57+ ('conflate', True)):
58 if k not in response:
59 response[k] = val
60
61
62=== modified file 'ibid/plugins/bzr.py'
63--- ibid/plugins/bzr.py 2009-11-30 15:10:40 +0000
64+++ ibid/plugins/bzr.py 2009-12-30 18:39:15 +0000
65@@ -108,9 +108,11 @@
66 revno = revno and int(revno) or None
67 commits = self.get_commits(repository, revno, full=full)
68
69+ output = u''
70 for commit in commits:
71 if commit:
72- event.addresponse(commit.strip())
73+ output += commit.strip()
74+ event.addresponse(output, conflate=False)
75
76 def get_commits(self, repository, start, end=None, full=None):
77 branch = None
78
79=== modified file 'ibid/plugins/core.py'
80--- ibid/plugins/core.py 2009-12-05 18:26:45 +0000
81+++ ibid/plugins/core.py 2009-12-30 18:39:15 +0000
82@@ -169,6 +169,31 @@
83 else:
84 event.processed = True
85
86+class Format(Processor):
87+ priority = 2000
88+
89+ def process(self, event):
90+ filtered = []
91+ for response in event.responses:
92+ source = response['source'].lower()
93+ supports = ibid.sources[source].supports
94+
95+ if response.get('action', False) and 'action' not in supports:
96+ response['reply'] = u'*%s*' % response['reply']
97+
98+ if (not response.get('conflate', True)
99+ and 'multiline' not in supports):
100+ for line in response['reply'].split('\n'):
101+ r = {'reply': line}
102+ for k in response.iterkeys():
103+ if k not in ('reply', 'conflate'):
104+ r[k] = response[k]
105+ filtered.append(r)
106+ else:
107+ filtered.append(response)
108+
109+ event.responses = filtered
110+
111 class UnicodeWarning(Processor):
112 priority = 1950
113
114
115=== modified file 'ibid/plugins/games.py'
116--- ibid/plugins/games.py 2009-11-30 15:12:13 +0000
117+++ ibid/plugins/games.py 2009-12-30 18:39:15 +0000
118@@ -581,14 +581,16 @@
119 This state lasts for the whole night. The next state is dawn.
120 """
121 self.state = self.night
122- event.addresponse(u'Night falls... most villagers are sleeping, '
123- 'but outside, something stirs.')
124- event.addresponse(plural(len(self.wolves),
125- u'Werewolf, you may kill somebody.',
126- u'Werewolves, you may kill somebody.'))
127- event.addresponse(plural(len(self.seers),
128- u"Seer, you may discover somebody's true form.",
129- u"Seers, you may discover somebody's true form."))
130+ event.addresponse(
131+ u'Night falls... most villagers are sleeping, '
132+ u'but outside, something stirs.\n'
133+ + plural(len(self.wolves),
134+ u'Werewolf, you may kill somebody.',
135+ u'Werewolves, you may kill somebody.') + '\n'
136+ + plural(len(self.seers),
137+ u"Seer, you may discover somebody's true form.",
138+ u"Seers, you may discover somebody's true form."),
139+ conflate=False)
140 self.say_survivors(event)
141
142 self.wolf_targets = {}
143@@ -773,15 +775,15 @@
144 if 2 * len(self.wolves) >= len(self.roles):
145 # werewolves win
146 event.addresponse(u'The werewolves devour the remaining '
147- u'villagers and win. OM NOM NOM.')
148- event.addresponse(u'The winning werewolves were: %s',
149- human_join(self.wolves))
150+ u'villagers and win. OM NOM NOM.\n'
151+ u'The winning werewolves were: %s',
152+ human_join(self.wolves), conflate=False)
153 elif not self.wolves:
154 # villagers win
155 event.addresponse(u'The villagers have defeated the werewolves. '
156- 'Vigilantism FTW.')
157- event.addresponse(u'The surviving villagers were: %s',
158- human_join(self.roles))
159+ u'Vigilantism FTW.\n'
160+ u'The surviving villagers were: %s',
161+ human_join(self.roles), conflate=False)
162 else:
163 return False
164
165
166=== modified file 'ibid/plugins/google.py'
167--- ibid/plugins/google.py 2009-12-29 15:52:42 +0000
168+++ ibid/plugins/google.py 2009-12-30 18:39:15 +0000
169@@ -154,15 +154,18 @@
170 try:
171 phrase, src_lang, dest_lang = self._parse_request(data)
172 chain = set([phrase])
173+ output = []
174 for i in range(self.chain_length):
175 phrase, src_lang = self._translate(event, phrase,
176 src_lang, dest_lang)
177 src_lang, dest_lang = dest_lang, src_lang
178- event.addresponse(phrase)
179+ output.append(phrase)
180 if phrase in chain:
181 break
182 chain.add(phrase)
183
184+ event.addresponse(u'\n'.join(output), conflate=False)
185+
186 except TranslationException, e:
187 event.addresponse(u"I couldn't translate that: %s.", unicode(e))
188
189
190=== modified file 'ibid/plugins/help.py'
191--- ibid/plugins/help.py 2009-07-27 14:00:45 +0000
192+++ ibid/plugins/help.py 2009-12-30 18:39:15 +0000
193@@ -46,13 +46,22 @@
194 def usage(self, event, feature):
195 feature = feature.lower()
196
197+ output = []
198 for processor in ibid.processors:
199 for name, klass in inspect.getmembers(processor, inspect.isclass):
200 if hasattr(klass, 'feature') and klass.feature == feature and klass.__doc__:
201 for line in klass.__doc__.strip().splitlines():
202- event.addresponse(u'Usage: %s', line.strip())
203+ output.append(line.strip())
204
205- if not event.responses:
206+ if len(output) == 1:
207+ event.addresponse(u'Usage: %s', output[0])
208+ elif len(output) > 1:
209+ event.addresponse(
210+ u"You can use %(feature)s in the following ways:\n%(usage)s", {
211+ 'feature': feature,
212+ 'usage': u'\n'.join(output)
213+ }, conflate=False)
214+ else:
215 event.addresponse(u"I don't know how to use %s either", feature)
216
217 # vi: set et sta sw=4 ts=4:
218
219=== modified file 'ibid/plugins/info.py'
220--- ibid/plugins/info.py 2009-10-16 16:31:34 +0000
221+++ ibid/plugins/info.py 2009-12-30 18:39:15 +0000
222@@ -39,7 +39,6 @@
223 code = fortune.wait()
224
225 output = unicode_output(output.strip(), 'replace')
226- output = output.replace(u'\t', u' ').replace(u'\n', u' ')
227
228 if code == 0:
229 return output
230
231=== modified file 'ibid/plugins/lookup.py'
232--- ibid/plugins/lookup.py 2009-12-29 15:43:31 +0000
233+++ ibid/plugins/lookup.py 2009-12-30 18:39:15 +0000
234@@ -62,9 +62,8 @@
235
236 soup = get_html_parse_tree('http://bash.org/?%s' % id)
237
238- if id == "random":
239- number = u"".join(soup.find('p', 'quote').find('b').contents)
240- event.addresponse(u'%s:', number)
241+ number = u"".join(soup.find('p', 'quote').find('b').contents)
242+ output = [u'%s:' % number]
243
244 body = soup.find('p', 'qt')
245 if not body:
246@@ -73,7 +72,8 @@
247 for line in body.contents:
248 line = unicode(line).strip()
249 if line != u'<br />':
250- event.addresponse(line)
251+ output.append(line)
252+ event.addresponse(u'\n'.join(output), conflate=False)
253
254 help['lastfm'] = u'Lists the tracks last listened to by the specified user.'
255 class LastFm(Processor):
256@@ -179,7 +179,7 @@
257 item.get('id'),
258 )
259 text = item.find('text').text
260- return u'%s - %s' % (text, url)
261+ return u'%s\n- %s' % (text, url)
262
263 @match(r'^(?:fml\s+|http://www\.fmylife\.com/\S+/)(\d+|random|flop|top|last|love|money|kids|work|health|sex|miscellaneous)$')
264 def fml(self, event, id):
265@@ -264,7 +264,7 @@
266 event.addresponse(line)
267 event.addresponse(u'- http://textsfromlastnight.com/view/%i', id)
268 else:
269- event.addresponse(u'%(body)s - http://textsfromlastnight.com/view/%(id)i', {
270+ event.addresponse(u'%(body)s\n- http://textsfromlastnight.com/view/%(id)i', {
271 'id': id,
272 'body': body[0],
273 })
274@@ -375,7 +375,7 @@
275 url += 's/%i' % id
276 else:
277 url += 'story.php?id=%i' % id
278- event.addresponse(u'%(body)s - %(url)s', {
279+ event.addresponse(u'%(body)s\n- %(url)s', {
280 'url': url,
281 'body': body,
282 })
283
284=== modified file 'ibid/plugins/network.py'
285--- ibid/plugins/network.py 2009-07-27 14:00:45 +0000
286+++ ibid/plugins/network.py 2009-12-30 18:39:15 +0000
287@@ -99,8 +99,7 @@
288
289 if code == 0:
290 output = unicode_output(output)
291- for line in output.splitlines():
292- event.addresponse(line)
293+ event.addresponse(output, conflate=False)
294 else:
295 error = unicode_output(error.strip())
296 event.addresponse(u'Error: %s', error.replace(u'\n', u' '))
297
298=== modified file 'ibid/source/campfire.py'
299--- ibid/source/campfire.py 2009-12-28 14:09:20 +0000
300+++ ibid/source/campfire.py 2009-12-30 18:39:15 +0000
301@@ -78,25 +78,8 @@
302 self.say(response['target'], message)
303
304 def respond(self, event):
305- if len(event.responses) == 1:
306- self.send(event.responses[0])
307- elif len(event.responses) > 1:
308- # Attempt to merge contiguous responses into a PasteMessage
309- buffer = event.responses[0]
310- buffer['reply'] = buffer['reply'].replace(u'\n', u' ')
311- for r in event.responses[1:]:
312- keys = set(r.keys()).union(set(buffer.keys())) \
313- .difference(set(('reply',)))
314- for k in keys:
315- if k not in buffer or k not in r or buffer[k] != r[k]:
316- break
317- else:
318- buffer['reply'] += u'\n' + r['reply'].replace(u'\n', u' ')
319- continue
320- self.send(buffer)
321- buffer = r
322-
323- self.send(buffer)
324+ for response in event.responses:
325+ self.send(response)
326
327 def join(self, room_name):
328 return self.join_room(self._locate_room(room_name))
329@@ -107,7 +90,7 @@
330 class SourceFactory(IbidSourceFactory):
331
332 auth = ('implicit',)
333- supports = ('action', 'topic')
334+ supports = ('action', 'multiline', 'topic')
335
336 subdomain = Option('subdomain', 'Campfire subdomain')
337 secure = BoolOption('secure', 'Use https (paid accounts only)', False)
338
339=== modified file 'ibid/source/dc.py'
340--- ibid/source/dc.py 2009-12-20 20:02:55 +0000
341+++ ibid/source/dc.py 2009-12-30 18:39:15 +0000
342@@ -97,7 +97,7 @@
343 self.send(response)
344
345 def send(self, response):
346- message = response['reply'].replace('\n', ' ')[:490]
347+ message = response['reply']
348
349 if message:
350 for prefix in self.factory.banned_prefixes:
351@@ -142,7 +142,7 @@
352 class SourceFactory(protocol.ReconnectingClientFactory, IbidSourceFactory):
353 protocol = DCBot
354
355- supports = ('action', 'topic')
356+ supports = ('action', 'multiline', 'topic')
357 auth = ('op',)
358
359 port = IntOption('port', 'Server port number', 411)
360
361=== modified file 'ibid/source/irc.py'
362--- ibid/source/irc.py 2009-10-31 14:28:20 +0000
363+++ ibid/source/irc.py 2009-12-30 18:39:15 +0000
364@@ -137,7 +137,7 @@
365 self.send(response)
366
367 def send(self, response):
368- message = response['reply'].replace('\n', ' ')[:490]
369+ message = response['reply'].expandtabs(1).replace('\n', ' ')[:490]
370 raw_message = message.encode('utf-8')
371
372 # Target may be a connection or a plain nick
373
374=== modified file 'ibid/source/jabber.py'
375--- ibid/source/jabber.py 2009-12-24 09:14:32 +0000
376+++ ibid/source/jabber.py 2009-12-30 18:39:15 +0000
377@@ -137,6 +137,8 @@
378 class SourceFactory(client.DeferredClientFactory, IbidSourceFactory):
379
380 auth = ('implicit',)
381+ supports = ('multiline',)
382+
383 port = IntOption('port', 'Server port number')
384 ssl = BoolOption('ssl', 'Usel SSL', False)
385 server = Option('server', 'Server hostname')
386
387=== modified file 'ibid/source/pb.py'
388--- ibid/source/pb.py 2009-02-23 20:29:44 +0000
389+++ ibid/source/pb.py 2009-12-30 18:39:15 +0000
390@@ -33,6 +33,8 @@
391
392 class SourceFactory(IbidSourceFactory):
393
394+ supports = ('multiline',)
395+
396 port = IntOption('port', 'Port number to listen on', 8789)
397
398 def setServiceParent(self, service):
399
400=== modified file 'ibid/source/silc.py'
401--- ibid/source/silc.py 2009-10-31 14:28:20 +0000
402+++ ibid/source/silc.py 2009-12-30 18:39:15 +0000
403@@ -70,7 +70,8 @@
404 self.send(response)
405
406 def send(self, response):
407- message = response['reply'].replace('\n', ' ').encode('utf-8')
408+ message = response['reply'].expandtabs(1).replace('\n', ' ') \
409+ .encode('utf-8')
410 flags=0
411 if response.get('action', False):
412 flags=4
413
414=== modified file 'ibid/source/smtp.py'
415--- ibid/source/smtp.py 2009-10-19 15:07:40 +0000
416+++ ibid/source/smtp.py 2009-12-30 18:39:15 +0000
417@@ -76,6 +76,8 @@
418
419 class SourceFactory(IbidSourceFactory, smtp.SMTPFactory):
420
421+ supports = ('multiline',)
422+
423 port = IntOption('port', 'Port number to listen on', 10025)
424 address = Option('address', 'Email address to accept messages for and send from', 'ibid@localhost')
425 accept = ListOption('accept', 'Email addresses to accept messages for', [])
426
427=== modified file 'ibid/source/telnet.py'
428--- ibid/source/telnet.py 2009-07-10 13:34:44 +0000
429+++ ibid/source/telnet.py 2009-12-30 18:39:15 +0000
430@@ -52,6 +52,8 @@
431 class SourceFactory(protocol.ServerFactory, IbidSourceFactory):
432 protocol = TelnetProtocol
433
434+ supports = ('multiline',)
435+
436 port = IntOption('port', 'Port to listen on', 3000)
437
438 def __init__(self, name, *args, **kwargs):
439
440=== modified file 'scripts/ibid-plugin'
441--- scripts/ibid-plugin 2009-12-21 12:43:58 +0000
442+++ scripts/ibid-plugin 2009-12-30 18:39:15 +0000
443@@ -58,7 +58,7 @@
444 class TestSource(dict):
445 type = 'test'
446 permissions = []
447- supports = ('action', 'notice')
448+ supports = ('action', 'multiline', 'notice')
449 logging_name = lambda self, name: name
450
451 ibid.sources[u'test_source'] = TestSource()

Subscribers

People subscribed via source and target branches