# HG changeset patch # User Dmitriy Morozov # Date 1208380900 14400 # Node ID 5b3579dc7abf0b4753f8624d0f74615ae851c3f5 # Parent 1630cf85c7f7fc5af15bf666760b7e005e7410ed Switched to maildir diff -r 1630cf85c7f7 -r 5b3579dc7abf artemis.py --- a/artemis.py Fri Jan 11 09:01:17 2008 -0500 +++ b/artemis.py Wed Apr 16 17:21:40 2008 -0400 @@ -43,18 +43,19 @@ properties += _get_properties(opts['property']) for issue in issues: - mbox = mailbox.mbox(issue) + mbox = mailbox.Maildir(issue, factory=mailbox.MaildirMessage) + root = _find_root_key(mbox) property_match = True for property,value in properties: - property_match = property_match and (mbox[0][property] == value) - if not show_all and (not properties or not property_match) and (properties or mbox[0]['State'].upper() == state['fixed'].upper()): continue + property_match = property_match and (mbox[root][property] == value) + if not show_all and (not properties or not property_match) and (properties or mbox[root]['State'].upper() == state['fixed'].upper()): continue - if match_date and not date_match(util.parsedate(mbox[0]['date'])[0]): continue + if match_date and not date_match(util.parsedate(mbox[root]['date'])[0]): continue ui.write("%s (%3d) [%s]: %s\n" % (issue[len(issues_path)+1:], # +1 for trailing / len(mbox)-1, # number of replies (-1 for self) - mbox[0]['State'], - mbox[0]['Subject'])) + mbox[root]['State'], + mbox[root]['Subject'])) def iadd(ui, repo, id = None, comment = 0): @@ -89,8 +90,8 @@ return # Create the message - msg = mailbox.mboxMessage(issue) - msg.set_from('artemis', True) + msg = mailbox.MaildirMessage(issue) + #msg.set_from('artemis', True) # Pick random filename if not id: @@ -101,21 +102,24 @@ # else: issue_fn already set # Add message to the mailbox - mbox = mailbox.mbox(issue_fn) - if id and comment not in mbox: + mbox = mailbox.Maildir(issue_fn) + keys = _order_keys_date(mbox) + mbox.lock() + if id and comment >= len(mbox): ui.warn('No such comment number in mailbox, commenting on the issue itself\n') + if not id: msg.add_header('Message-Id', "<%s-0-artemis@%s>" % (issue_id, socket.gethostname())) else: + root = keys[0] msg.add_header('Message-Id', "<%s-%s-artemis@%s>" % (issue_id, _random_id(), socket.gethostname())) - msg.add_header('References', mbox[(comment < len(mbox) and comment) or 0]['Message-Id']) - msg.add_header('In-Reply-To', mbox[(comment < len(mbox) and comment) or 0]['Message-Id']) - mbox.add(msg) + msg.add_header('References', mbox[(comment < len(mbox) and keys[comment]) or root]['Message-Id']) + msg.add_header('In-Reply-To', mbox[(comment < len(mbox) and keys[comment]) or root]['Message-Id']) + repo.add([issue_fn[(len(repo.root)+1):] + '/new/' + mbox.add(msg)]) # +1 for the trailing / mbox.close() # If adding issue, add the new mailbox to the repository if not id: - repo.add([issue_fn[(len(repo.root)+1):]]) # +1 for the trailing / ui.status('Added new issue %s\n' % issue_id) @@ -125,13 +129,16 @@ comment = int(comment) issue, id = _find_issue(ui, repo, id) if not issue: return - mbox = mailbox.mbox(issue) + mbox = mailbox.Maildir(issue, factory=mailbox.MaildirMessage) if opts['all']: ui.write('='*70 + '\n') - for i in xrange(len(mbox)): - _write_message(ui, mbox[i], i) + i = 0 + keys = _order_keys_date(mbox) + for k in keys: + _write_message(ui, mbox[k], i) ui.write('-'*70 + '\n') + i += 1 return _show_mbox(ui, mbox, comment) @@ -146,8 +153,9 @@ properties = _get_properties(opts['property']) # Read the issue - mbox = mailbox.mbox(issue) - msg = mbox[0] + mbox = mailbox.Maildir(issue, factory=mailbox.MaildirMessage) + root = _find_root_key(mbox) + msg = mbox[root] # Fix the properties properties_text = '' @@ -157,7 +165,8 @@ else: msg.add_header(property, value) properties_text += '%s=%s\n' % (property, value) - mbox[0] = msg + mbox.lock() + mbox[root] = msg # Write down a comment about updated properties if properties and not opts['no_property_comment']: @@ -170,9 +179,9 @@ msg.add_header('Message-Id', "<%s-%s-artemis@%s>" % (id, _random_id(), socket.gethostname())) msg.add_header('References', mbox[0]['Message-Id']) msg.add_header('In-Reply-To', mbox[0]['Message-Id']) - msg.set_from('artemis', True) - mbox.add(msg) - mbox.flush() + #msg.set_from('artemis', True) + repo.add([issue_fn[(len(repo.root)+1):] + '/new/' + mbox.add(msg)]) # +1 for the trailing / + mbox.close() # Show updated message _show_mbox(ui, mbox, 0) @@ -212,11 +221,13 @@ if comment >= len(mbox): comment = 0 ui.warn('Comment out of range, showing the issue itself\n') - msg = mbox[comment] + keys = _order_keys_date(mbox) + root = keys[0] + msg = mbox[keys[comment]] ui.write('='*70 + '\n') if comment: - ui.write('Subject: %s\n' % mbox[0]['Subject']) - ui.write('State: %s\n' % mbox[0]['State']) + ui.write('Subject: %s\n' % mbox[root]['Subject']) + ui.write('State: %s\n' % mbox[root]['State']) ui.write('-'*70 + '\n') _write_message(ui, msg, comment) ui.write('-'*70 + '\n') @@ -224,10 +235,12 @@ # Read the mailbox into the messages and children dictionaries messages = {} children = {} - for i in xrange(len(mbox)): - m = mbox[i] + i = 0 + for k in keys: + m = mbox[k] messages[m['Message-Id']] = (i,m) children.setdefault(m['In-Reply-To'], []).append(m['Message-Id']) + i += 1 children[None] = [] # Safeguard against infinte loop on empty Message-Id # Iterate over children @@ -242,6 +255,17 @@ ui.write(' '*offset + ('%d: ' % index) + msg['Subject'] + '\n') ui.write('-'*70 + '\n') +def _find_root_key(maildir): + for k,m in maildir.iteritems(): + if 'in-reply-to' not in m: + return k + +def _order_keys_date(mbox): + keys = mbox.keys() + root = _find_root_key(mbox) + keys.sort(lambda k1,k2: -(k1 == root) or cmp(util.parsedate(mbox[k1]['date']), util.parsedate(mbox[k2]['date']))) + return keys + def _pretty_list(lst): s = '' for i in lst: diff -r 1630cf85c7f7 -r 5b3579dc7abf convert-mbox-maildir.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/convert-mbox-maildir.py Wed Apr 16 17:21:40 2008 -0400 @@ -0,0 +1,18 @@ +import mailbox, glob, os.path, os +import artemis +from mercurial import ui, hg + +repo = hg.repository(ui.ui()) + +issue_filenames = glob.glob(os.path.join(artemis.issues_dir, '*')) +for fn in issue_filenames: + mb = mailbox.mbox(fn) + messages = [m for m in mb] + mb.close() + os.unlink(fn) + repo.remove([fn]) + md = mailbox.Maildir(fn) + md.lock() + keys = [md.add(m) for m in messages] + md.close() + for k in keys: repo.add([fn + '/new/' + k])