Merge lp:~stefanor/ibid/releasenotes-0.1.1 into lp:~ibid-core/ibid/old-release-0.1-1.6

Proposed by Stefano Rivera
Status: Merged
Approved by: Stefano Rivera
Approved revision: 996
Merged at revision: 982
Proposed branch: lp:~stefanor/ibid/releasenotes-0.1.1
Merge into: lp:~ibid-core/ibid/old-release-0.1-1.6
Diff against target: 686 lines (+597/-6)
8 files modified
CHANGES (+435/-0)
docs/_extensions/extlinks.py (+67/-0)
docs/changes.rst (+8/-0)
docs/conf.py (+13/-2)
docs/configuration.rst (+2/-3)
docs/index.rst (+1/-0)
setup.py (+1/-1)
tools/format-changelog (+70/-0)
To merge this branch: bzr merge lp:~stefanor/ibid/releasenotes-0.1.1
Reviewer Review Type Date Requested Status
Keegan Carruthers-Smith Approve
Max Rabkin Approve
marcog (community) Approve
Jonathan Hitchcock Approve
Review via email: mp+47198@code.launchpad.net

Commit message

Added CHANGES and tool for generating changelog entries.
Set version to 0.1.1

To post a comment you must log in.
Revision history for this message
Jonathan Hitchcock (vhata) :
review: Approve
Revision history for this message
marcog (marco-gallotta) :
review: Approve
Revision history for this message
Ibid Branch Auto-Lander (ibid-tarmac) wrote :

Voting does not meet specified criteria. Required: Approve >= 2, Disapprove == 0. Got: 1 Approve.

Revision history for this message
Max Rabkin (max-rabkin) :
review: Approve
Revision history for this message
Keegan Carruthers-Smith (keegan-csmith) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'CHANGES'
2--- CHANGES 1970-01-01 00:00:00 +0000
3+++ CHANGES 2011-02-20 21:52:17 +0000
4@@ -0,0 +1,435 @@
5+Release 0.1.1 (2011-02-24)
6+==============================
7+
8+Bug fix release, including a couple of security issues.
9+
10+Several plugins that consume Web services or scrape Web sites have been
11+updated to cope with changes since the last release.
12+
13+There were no DB schema changes between 0.1.0 and 0.1.1.
14+
15+Resolved Security Issues
16+------------------------
17+
18+Remote Execution
19+^^^^^^^^^^^^^^^^
20+
21+:bug:`705860`:
22+ Permissions were ignored for handlers not using :func:`@match
23+ <ibid.plugins.match>`.
24+ This allowed users to perform actions they were not authorised to.
25+
26+ However, no included plugins were exposed by this, all
27+ access-restricted handlers had match patterns.
28+
29+Information Disclosure
30+^^^^^^^^^^^^^^^^^^^^^^
31+
32+:bug:`567576`:
33+ Occasionally insecure permissions on log files.
34+ When the bot spoke first (creating a new log file), the log file
35+ would be publicly readable, even if the message was sent in private.
36+
37+ Example:
38+ If the bot delivered a *privmsg* memo to a user at the beginning of
39+ the month, it would create the logfile with public readable
40+ permissions.
41+ If the logfile directory was published by a web server, this would
42+ make this private conversation log accessible to the public.
43+
44+ Resolution: Now channels must be explicitly configured to have
45+ publicly readable logs.
46+
47+:bug:`649383`:
48+ If someone received a private message from the bot
49+ during a public meeting, the message could appear in the meeting
50+ minutes.
51+
52+ Example: a *privmsg* memo received during a meeting would appear in
53+ the minutes.
54+
55+Major User Visible Changes
56+--------------------------
57+
58+* New configuration option ``plugins.log.public_logs``, a list of
59+ ``source:channel`` globs of channels to log in files with publically
60+ readable permissions.
61+
62+* New configuration option ``plugins.ascii.preferred_fonts``, a list of
63+ figlet fonts, the first one found is the default.
64+
65+* Currency exchange now uses Yahoo instead of XE.com.
66+
67+API Changes
68+-----------
69+
70+* New Function: :func:`ibid.utils.parse_timestamp` for parsing
71+ well-formatted timestamps.
72+
73+* New Function: :func:`ibid.utils.generic_webservice` for retrieving
74+ arbitrary data from a web-service.
75+
76+* New Function: :func:`ibid.db.get_regexp_op` which returns a REGEXP
77+ SqlAlchemy operator for the DBMS in use.
78+
79+All Changes
80+-----------
81+
82+2011-02-20 Stefano Rivera <stefano@rivera.za.net>
83+
84+ Filter out empty definitions in gdefine.
85+
86+ Fixes: :bug:`719851`.
87+
88+2011-02-20 Stefano Rivera <stefano@rivera.za.net>
89+
90+ We don't support SQLAlchemy 0.6 yet.
91+
92+ Fixes: :bug:`651992`.
93+
94+2011-02-20 Marco Gallotta <marco@gallotta.co.za>
95+
96+ Only append .com for url's like "example".
97+
98+ Fixes: :bug:`702062`.
99+
100+2011-02-20 Stefano Rivera <stefano@rivera.za.net>
101+
102+ Use escape=# for LIKEs.
103+ Perform literal queries on all non-get Factoid operations. Return
104+ useful error if start index is too high.
105+ Substitute $arg for _% in search.
106+
107+ Fixes: :bug:`544493`.
108+
109+2011-02-20 Stefano Rivera <stefano@rivera.za.net>
110+
111+ HTTPErrors should result in using url as title, not abandoning the
112+ grab.
113+
114+ Fixes: :bug:`702798`.
115+
116+2011-02-20 Stefano Rivera <stefano@rivera.za.net>
117+
118+ Catch ImportErrors for packages we don't require in setup.py.
119+
120+ Fixes: :bug:`651990`.
121+
122+2011-02-20 Stefano Rivera <stefano@rivera.za.net>
123+
124+ pysqlite is only necessary on ancient Pythons.
125+
126+ Fixes: :bug:`708302`.
127+
128+2011-01-25 Stefano Rivera <stefano@rivera.za.net>
129+
130+ Add function get_regexp_op to ibid.db that returns a REGEXP op that
131+ works on Postgres too.
132+
133+ Fixes: :bug:`595423`.
134+
135+2011-01-22 Keegan Carruthers-Smith <keegan.csmith@gmail.com>
136+
137+ Use correct plurality in pending memos message.
138+
139+ Fixes :bug:`634257`.
140+
141+2011-01-22 Stefano Rivera <stefano@rivera.za.net>
142+
143+ Add parse_timestamp function to ibid.utils, use for parsing
144+ timestamps from Twitter.
145+
146+ Fixes :bug:`702815`.
147+
148+2011-01-22 Stefano Rivera <stefano@rivera.za.net>
149+
150+ URLErrors have reasons, but there are other HTTPErrors
151+
152+ Fixes :bug:`670855`.
153+
154+2011-01-21 Max Rabkin <max.rabkin@gmail.com>
155+
156+ Enforce permissions on non-@match handlers.
157+
158+ Fixes :bug:`705860`.
159+
160+2011-01-19 Stefano Rivera <stefano@rivera.za.net>
161+
162+ Handle non-500 error codes from twitter.
163+
164+ Fixes :bug:`670855`.
165+
166+2011-01-19 Stefano Rivera <stefano@rivera.za.net>
167+
168+ Strip tags from gcalc response.
169+
170+ Fixes :bug:`702371`.
171+
172+2011-01-19 Max Rabkin <max.rabkin@gmail.com>
173+
174+ Check content_type is set before checking its value.
175+
176+ Fixes :bug:`701900`.
177+
178+2011-01-19 Max Rabkin <max.rabkin@gmail.com>
179+
180+ Catch exceptions when polling feeds so that one broken feed doesn't
181+ stop all feeds.
182+
183+ Fixes :bug:`578396`.
184+
185+2011-01-19 Max Rabkin <max.rabkin@gmail.com>
186+
187+ Use new OEIS API at oeis.org
188+
189+ Fixes :bug:`700475`.
190+
191+2010-12-25 Stefano Rivera <stefano@rivera.za.net>
192+
193+ Fix for the logging open file cache: Logs in logs might not be in
194+ recent_logs.
195+
196+ Fixes :bug:`655645`.
197+
198+2010-12-25 Stefano Rivera <stefano@rivera.za.net>
199+
200+ Support toilet fonts, correctly decode utf-8 figlet output, handle
201+ font choice edge cases.
202+
203+ Fixes :bug:`607743`.
204+
205+2010-12-24 Stefano Rivera <stefano@rivera.za.net>
206+
207+ Follow redirects in "is it up"
208+
209+ Fixes :bug:`599410`.
210+
211+2010-12-24 Stefano Rivera <stefano@rivera.za.net>
212+
213+ Rework nickserv auth to allow simultaneous authentications for the
214+ same nick (although Nickserv will only be bothered once).
215+
216+ Fixes :bug:`655647`.
217+
218+2010-12-24 Stefano Rivera <stefano@rivera.za.net>
219+
220+ Use absolute imports to import SILC correctly
221+
222+ Fixes :bug:`654202`.
223+
224+2010-12-20 Stefano Rivera <stefano@rivera.za.net>
225+
226+ Country Code list parsing: Check for ; in a line before splitting by
227+ semi-colons.
228+
229+ Fixes :bug:`692347`.
230+
231+2010-12-20 Max Rabkin <max.rabkin@gmail.com>
232+
233+ Don't treat feeds with no messages as errors.
234+
235+ Fixes :bug:`661187`.
236+
237+2010-11-08 Stefano Rivera <stefano@rivera.za.net>
238+
239+ Correctly handle state events that have no channel.
240+
241+ Fixes :bug:`656349`.
242+
243+2010-11-07 Stefano Rivera <stefano@rivera.za.net>
244+
245+ Port google scrape search to get_html_parse_tree + etree. Handle
246+ superscript in gcalc.
247+
248+ Fixes :bug:`580696`.
249+
250+2010-11-07 Stefano Rivera <stefano@rivera.za.net>
251+
252+ Put periodic lock-using code in a try...finally block.
253+
254+2010-10-15 Stefano Rivera <stefano@rivera.za.net>
255+
256+ Support twitter's new AJAX URLs.
257+
258+ Fixes :bug:`654535`.
259+
260+2010-10-15 Stefano Rivera <stefano@rivera.za.net>
261+
262+ Always respond to memo sending with confirmation of recipient. Allow
263+ memos to begin with "on ..." when not naming a known source.
264+
265+ Fixes :bug:`634253`.
266+
267+2010-10-04 Stefano Rivera <stefano@rivera.za.net>
268+
269+ Disallow empty factoid names.
270+
271+ Fixes :bug:`606065`.
272+
273+2010-10-05 Guy Halse
274+
275+ Allow bot to identify with zanet.net's NickServ.
276+
277+ Fixes :bug:`652000`.
278+
279+2010-10-03 Stefano Rivera <stefano@rivera.za.net>
280+
281+ [SECURITY] Add a configuration glob-list of channels which should
282+ have public logs, rather than attempting to guess.
283+
284+ Fixes :bug:`567576`.
285+
286+2010-09-30 Stefano Rivera <stefano@rivera.za.net>
287+
288+ Docs: Be clear that ibid is in Debian & Ubuntu.
289+
290+2010-09-30 Stefano Rivera <stefano@rivera.za.net>
291+
292+ Handle 0 tweets in Twitter Atom feed parsing, correctly handle it
293+ elsewhere instead of treating it as no such twit.
294+
295+ Fixes :bug:`646989`.
296+
297+2010-09-29 Max Rabkin <max.rabkin@gmail.com>
298+
299+ [SECURITY] Don't leak private messages to meeting logs.
300+
301+ Fixes :bug:`649383`.
302+
303+2010-08-14 Stefano Rivera <stefano@rivera.za.net>
304+
305+ Don't try to process() events without a message in meeting.
306+
307+ Fixes :bug:`598094`.
308+
309+2010-07-10 Stefano Rivera <stefano@rivera.za.net>
310+
311+ Correct abbreviated cross-ref format, shown up by Sphinx 1.0b1.
312+
313+2010-07-04 Stefano Rivera <stefano@rivera.za.net>
314+
315+ Display latest tweets from retweeting-twits instead of thinking they
316+ don't exist.
317+
318+ Fixes :bug:`554906`.
319+
320+2010-06-13 Michael Gorven <michael@gorven.za.net>
321+
322+ Fix real JID detection when more than one 'x' element is received.
323+
324+2010-06-07 Stefano Rivera <stefano@rivera.za.net>
325+
326+ NickServ support for rizon.
327+
328+2010-06-04 Stefano Rivera <stefano@rivera.za.net>
329+
330+ Switch from XE.com to Yahoo for currency conversions.
331+
332+2010-06-04 Stefano Rivera <stefano@rivera.za.net>
333+
334+ Limit the size of the file-descriptor pool in log.
335+
336+ Fixes :bug:`567571`.
337+
338+2010-05-12 Stefano Rivera <stefano@rivera.za.net>
339+
340+ Google is also a calculator.
341+
342+ Fixes :bug:`574300`.
343+
344+2010-05-12 Stefano Rivera <stefano@rivera.za.net>
345+
346+ Use explicit lower() on each side of LIKE so factoids with arguments
347+ can be case-insensitive on Postgres.
348+
349+ Fixes :bug:`574427`.
350+
351+2010-05-05 Max Rabkin <max.rabkin@gmail.com>
352+
353+ Escape query url in google scrape.
354+
355+ Fixes :bug:`572308`.
356+
357+2010-05-05 Stefano Rivera <stefano@rivera.za.net>
358+
359+ Incorrect substitution in SQLite indexing warning.
360+
361+2010-05-05 Stefano Rivera <stefano@rivera.za.net>
362+
363+ Change administrative user & identity linking syntax to be less
364+ problematically broad.
365+
366+ Fixes :bug:`567510`.
367+
368+2010-04-26 Stefano Rivera <stefano@rivera.za.net>
369+
370+ Increase default HTTP GET size from 500 bytes to 2kiB.
371+
372+ Fixes :bug:`563928`.
373+
374+2010-04-13 Stefano Rivera <stefano@rivera.za.net>
375+
376+ Update youtube plugin to cope with site redesign.
377+
378+ Fixes :bug:`561684`.
379+
380+2010-04-13 Max Rabkin <max.rabkin@gmail.com>
381+
382+ Allow digits in Unicode character names.
383+
384+2010-04-13 Stefano Rivera <stefano@rivera.za.net>
385+
386+ HTTP GET: Don't assume everything is utf-8, decode according to
387+ provided charset, fall back to utf-8 for text, and guess with chardet
388+ if either of those was wrong.
389+
390+ Fixes :bug:`560973`.
391+
392+2010-04-09 Max Rabkin <max.rabkin@gmail.com>
393+
394+ Use unicode case-insensitive matching in factoid.
395+
396+ Fixes :bug:`542707`.
397+
398+2010-03-27 Michael Gorven <michael@gorven.za.net>
399+
400+ Treat the Processor's first feature as the primary feature in RPC.
401+
402+ Fixes :bug:`545168`.
403+
404+2010-03-27 Max Rabkin <max.rabkin@gmail.com>
405+
406+ Respond with unicode in bible error handlers.
407+
408+ Fixes :bug:`544260`.
409+
410+2010-03-26 Marco Gallotta <marco@gallotta.co.za>
411+
412+ Allow trailing punctuation in tea-style addressing.
413+
414+ Fixes :bug:`545186`.
415+
416+2010-03-23 Marco Gallotta <marco@gallotta.co.za>
417+
418+ Add username=ibid parameter to geonames API calls. Some calls now
419+ require it.
420+
421+ Fixes :bug:`543989`.
422+
423+2010-03-23 Max Rabkin <max.rabkin@gmail.com>
424+
425+ Python 2.5 compatibility update for unicode lookup. Exception for
426+ unknown character changed in 2.6.
427+
428+ Fixes :bug:`542593`.
429+
430+2010-03-10 Stefano Rivera <stefano@rivera.za.net>
431+
432+ Add placeholder to force ibid/static to be distributed.
433+
434+Release 0.1.0 (2010-03-10)
435+==========================
436+
437+* First public release.
438+
439+.. vi: set ft=rst et sta sw=3 ts=3:
440
441=== added directory 'docs/_extensions'
442=== added file 'docs/_extensions/extlinks.py'
443--- docs/_extensions/extlinks.py 1970-01-01 00:00:00 +0000
444+++ docs/_extensions/extlinks.py 2011-02-20 21:52:17 +0000
445@@ -0,0 +1,67 @@
446+# -*- coding: utf-8 -*-
447+# Backport of sphinx.ext.extlinks to Sphinx 0.6
448+"""
449+ sphinx.ext.extlinks
450+ ~~~~~~~~~~~~~~~~~~~
451+
452+ Extension to save typing and prevent hard-coding of base URLs in the reST
453+ files.
454+
455+ This adds a new config value called ``extlinks`` that is created like this::
456+
457+ extlinks = {'exmpl': ('http://example.com/%s.html', prefix), ...}
458+
459+ Now you can use e.g. :exmpl:`foo` in your documents. This will create a
460+ link to ``http://example.com/foo.html``. The link caption depends on the
461+ *prefix* value given:
462+
463+ - If it is ``None``, the caption will be the full URL.
464+ - If it is a string (empty or not), the caption will be the prefix prepended
465+ to the role content.
466+
467+ You can also give an explicit caption, e.g. :exmpl:`Foo <foo>`.
468+
469+ :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
470+ :license: BSD, see LICENSE for details.
471+"""
472+
473+import re
474+
475+from docutils import nodes, utils
476+
477+explicit_title_re = re.compile(r'^(.+?)\s*(?<!\x00)<(.*?)>$', re.DOTALL)
478+def split_explicit_title(text):
479+ """Split role content into title and target, if given."""
480+ match = explicit_title_re.match(text)
481+ if match:
482+ return True, match.group(1), match.group(2)
483+ return False, text, text
484+
485+def make_link_role(base_url, prefix):
486+ def role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
487+ text = utils.unescape(text)
488+ has_explicit_title, title, part = split_explicit_title(text)
489+ try:
490+ full_url = base_url % part
491+ except (TypeError, ValueError):
492+ env = inliner.document.settings.env
493+ env.warn(env.docname, 'unable to expand %s extlink with base '
494+ 'URL %r, please make sure the base contains \'%%s\' '
495+ 'exactly once' % (typ, base_url))
496+ full_url = base_url + part
497+ if not has_explicit_title:
498+ if prefix is None:
499+ title = full_url
500+ else:
501+ title = prefix + part
502+ pnode = nodes.reference(title, title, refuri=full_url)
503+ return [pnode], []
504+ return role
505+
506+def setup_link_roles(app):
507+ for name, (base_url, prefix) in app.config.extlinks.iteritems():
508+ app.add_role(name, make_link_role(base_url, prefix))
509+
510+def setup(app):
511+ app.add_config_value('extlinks', {}, 'env')
512+ app.connect('builder-inited', setup_link_roles)
513
514=== added file 'docs/changes.rst'
515--- docs/changes.rst 1970-01-01 00:00:00 +0000
516+++ docs/changes.rst 2011-02-20 21:52:17 +0000
517@@ -0,0 +1,8 @@
518+:tocdepth: 2
519+
520+Changes in Ibid
521+***************
522+
523+.. include:: ../CHANGES
524+
525+.. vi: set et sta sw=3 ts=3:
526
527=== modified file 'docs/conf.py'
528--- docs/conf.py 2011-01-15 08:51:05 +0000
529+++ docs/conf.py 2011-02-20 21:52:17 +0000
530@@ -13,6 +13,8 @@
531
532 import sys, os
533
534+import sphinx
535+
536 # If extensions (or modules to document with autodoc) are in another directory,
537 # add these directories to sys.path here. If the directory is relative to the
538 # documentation root, use os.path.abspath to make it absolute, like shown here.
539@@ -22,7 +24,11 @@
540
541 # Add any Sphinx extension module names here, as strings. They can be extensions
542 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
543-extensions = []
544+sys.path.append(os.path.abspath('_extensions'))
545+if sphinx.__version__ > '1.0':
546+ extensions = ['sphinx.ext.extlinks']
547+else:
548+ extensions = ['extlinks']
549
550 # Add any paths that contain templates here, relative to this directory.
551 templates_path = ['_templates']
552@@ -47,7 +53,7 @@
553 # The short X.Y version.
554 version = '0.1'
555 # The full version, including alpha/beta/rc tags.
556-release = '0.1.0'
557+release = '0.1.1'
558
559 # The language for content autogenerated by Sphinx. Refer to documentation
560 # for a list of supported languages.
561@@ -192,3 +198,8 @@
562
563 # If false, no module index is generated.
564 #latex_use_modindex = True
565+
566+# -- Options for extensions ----------------------------------------------------
567+
568+# pre-1.0 mode intersphinx:
569+extlinks = {'bug': ('https://bugs.launchpad.net/bugs/%s', 'LP: #')}
570
571=== modified file 'docs/configuration.rst'
572--- docs/configuration.rst 2010-02-26 08:29:31 +0000
573+++ docs/configuration.rst 2011-02-20 21:52:17 +0000
574@@ -170,9 +170,8 @@
575 **Reqired**
576 String: The hostname of the IRC server to connect to.
577
578- Ibid `does not currently support
579- <https://bugs.launchpad.net/bugs/363466>`_ falling back to alternate
580- servers, so you may want to use a round-robin hostname.
581+ Ibid :bug:`does not currently support <363466>` falling back to
582+ alternate servers, so you may want to use a round-robin hostname.
583
584 .. describe:: port:
585
586
587=== modified file 'docs/index.rst'
588--- docs/index.rst 2010-01-12 16:29:15 +0000
589+++ docs/index.rst 2011-02-20 21:52:17 +0000
590@@ -11,6 +11,7 @@
591 tutorial
592 contributing
593 api/index
594+ changes
595
596
597 Indices and tables
598
599=== modified file 'setup.py'
600--- setup.py 2011-02-20 20:34:20 +0000
601+++ setup.py 2011-02-20 21:52:17 +0000
602@@ -35,7 +35,7 @@
603
604 setup(
605 name='Ibid',
606- version='0.1.0',
607+ version='0.1.1',
608 description='Multi-protocol general purpose chat bot',
609 url='http://ibid.omnia.za.net/',
610 keywords='chat bot irc jabber twisted messaging',
611
612=== added directory 'tools'
613=== added file 'tools/format-changelog'
614--- tools/format-changelog 1970-01-01 00:00:00 +0000
615+++ tools/format-changelog 2011-02-20 21:52:17 +0000
616@@ -0,0 +1,70 @@
617+#!/usr/bin/env python
618+
619+import optparse
620+import re
621+import subprocess
622+import textwrap
623+
624+def process_block(block):
625+ "Reformat a block into nice rst"
626+ block = ''.join(block).decode('utf-8').strip()
627+
628+ template_re = re.compile(r'^\tAuthor: .*\n'
629+ r'(?:\tMerge Request: .*\n)?'
630+ r'\tApproved by: .*\n'
631+ r'\tFixes LP: #(.*)$',
632+ re.MULTILINE | re.UNICODE)
633+ def repl(m):
634+ bugs = [int(bug) for bug in m.group(1).split(',')]
635+ if bugs:
636+ bugs = [u':bug:`%i`' % bug for bug in bugs]
637+ return u'\n\tFixes: %s.' % u', '.join(bugs)
638+ return u''
639+ block = template_re.sub(repl, block)
640+
641+ block = block.splitlines()
642+
643+ wrapper = textwrap.TextWrapper(subsequent_indent=u' ')
644+ for i, line in enumerate(block):
645+ if not line.strip():
646+ line = u''
647+
648+ if line.startswith(u'\t'):
649+ line = u' ' + line[1:]
650+ if i + 1 == len(block) or not block[i+1].strip():
651+ if not line.endswith(u'.'):
652+ line += u'.'
653+
654+ line = u'\n'.join(wrapper.wrap(line))
655+
656+ block[i] = line
657+
658+ block.append(u'')
659+ block = u'\n'.join(block)
660+ print block.encode('utf-8')
661+
662+def main():
663+ parser = optparse.OptionParser()
664+ parser.add_option('-r', '--revision', metavar='REVSPEC',
665+ help='Passed to bzr')
666+ opts, args = parser.parse_args()
667+
668+ cmd = ['bzr', 'log', '--gnu', '-n1']
669+ if opts.revision:
670+ cmd.append('-r' + opts.revision)
671+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
672+
673+ head_re = re.compile(r'^\d{4}-\d{2}-\d{2} .+ <.+>$')
674+ block = []
675+ for line in p.stdout:
676+ if head_re.match(line):
677+ process_block(block)
678+ block = []
679+ block.append(line)
680+
681+ process_block(block)
682+
683+ assert p.wait() == 0
684+
685+if __name__ == '__main__':
686+ main()

Subscribers

People subscribed via source and target branches