From e4f2a4d05b81f840f9a48c7877132b0220b83276 Mon Sep 17 00:00:00 2001 From: moculus Date: Tue, 11 Nov 2008 05:10:26 +0000 Subject: [PATCH] more mbox fixes --HG-- branch : pmacs2 --- mode/mbox.py | 115 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 84 insertions(+), 31 deletions(-) diff --git a/mode/mbox.py b/mode/mbox.py index 5bafaa1..2b8451b 100644 --- a/mode/mbox.py +++ b/mode/mbox.py @@ -36,6 +36,16 @@ class MboxMsgBuffer(Buffer): def save(self, force=False): raise Exception, "can't save an mbox message" def save_as(self, path): raise Exception, "can't save an mbox message" def name(self): return 'mbox:%s:%s' % (self.base, self.lineno) + def _get_msg_lines(self, msg): + if msg.is_multipart(): + lines = [] + for msg2 in msg.get_payload(): + lines.extend(self._get_msg_lines(msg2)) + return lines + elif msg.get_content_type() == 'text/plain': + return msg.get_payload().split('\n') + else: + return [] def _get_lines(self): lines = [ 'Delivered-To: ' + self.msg.get('delivered-to'), @@ -45,7 +55,7 @@ class MboxMsgBuffer(Buffer): 'Date: ' + self.msg.get('date'), '', ] - lines.extend(self.msg.get_payload().split('\n')) + lines.extend(self._get_msg_lines(self.msg)) return lines def open(self): self.lines = self._get_lines() @@ -54,9 +64,16 @@ class MboxMsgBuffer(Buffer): self.set_lines(lines, force=True) class MboxListBuffer(Buffer): - btype = 'mboxlist' - format = '%(pos)4d %(flags)5.5s %(subject)s' - re1 = re.compile('[\n\t ]+') + btype = 'mboxlist' + reverse = True + format = '%(pos)4d %(replied)s %(dow)3.3s %(day)2.2s %(fromname)-15.15s %(size)6.6s %(subject)s' + + from_re1 = re.compile(r'^ *" *([^"]+) *" *< *(.+) *> *$') + from_re2 = re.compile(r'^ *([^" ].*?) *< *(.+) *> *$') + from_re3 = re.compile(r'^ *([^\'" ]+) *$') + from_re4 = re.compile(r'^ *([^\'" ]+) *\(([^\)]+)\) *$') + + date_re1 = re.compile(r'^(Sun|Mon|Tue|Wed|Thu|Fri|Sat), (\d{1,2}) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d{2}):(\d{2}):(\d{2}) ([-\+]\d{4})(?: .*)?$') def __init__(self, path): Buffer.__init__(self) self.path = os.path.realpath(path) @@ -69,42 +86,78 @@ class MboxListBuffer(Buffer): def save(self, force=False): raise Exception, "can't save an mbox" def save_as(self, path): raise Exception, "can't save an mbox" def name(self): return 'mbox:%s' % (self.base) - def _get_lines(self): - f = open(self.path, 'r') - self.size = len(f.read()) - f.close() - self.mbox = mailbox.mbox(self.path) - - # - lines = [] - pos = 1 - for msg in self.mbox: - subject = self.re1.sub(' ', msg['subject']) - msize = len(str(msg)) - d = { - 'pos': pos, - 'flags': ''.join(msg.get_flags()), - 'subject': subject, - } - s = self.format % d - lines.append(s) - pos += 1 - # - - return lines def open(self): self.lines = self._get_lines() def reload(self): lines = self._get_lines() self.set_lines(lines, force=True) + def _parse_msg_from(self, msg): + m = self.from_re1.match(msg['from']) + if m: return m.groups() + m = self.from_re2.match(msg['from']) + if m: return m.groups() + m = self.from_re3.match(msg['from']) + if m: return m.group(1), m.group(1) + m = self.from_re4.match(msg['from']) + if m: return m.group(2), m.group(1) + #return msg['from'], msg['from'] + return 'unknown', 'unknown' + def _parse_date(self, msg): + m = self.date_re1.match(msg['date']) + if m: return m.groups() + return ('', '', '', '', '', '', '', '') + + def _create_msg_dict(self, pos, msg): + d = {} + for key in msg.keys(): + d[key.lower()] = msg[key] + + d['fromname'], d['fromaddr'] = self._parse_msg_from(msg) + d['dow'], d['day'], d['month'], d['year'], \ + d['hour'], d['min'], d['sec'], d['tz'] = self._parse_date(msg) + + if 'A' in msg.get_flags(): + d['replied'] = 'r' + else: + d['replied'] = ' ' + + d['pos'] = pos + d['flags'] = ''.join(msg.get_flags()) + d['size'] = len(str(msg)) + for key in d: + if type(d[key]) == type(''): + d[key] = d[key].replace('\t', ' ') + return d + + def _get_lines(self): + f = open(self.path, 'r') + self.size = len(f.read()) + f.close() + self.mbox = mailbox.mbox(self.path) + lines = [] + pos = 1 + msgs = list(self.mbox) + if self.reverse: + msgs.reverse() + for msg in msgs: + d = self._create_msg_dict(pos, msg) + s = self.format % d + lines.append(s) + pos += 1 + return lines + class MboxRefresh(Method): def _execute(self, w, **vargs): w.buffer.reload() -class MboxOpenMsg(Method): +class MboxReadMsg(Method): def _execute(self, w, **vargs): b = w.buffer - b = MboxMsgBuffer(b.path, w.cursor.y, b.mbox[w.cursor.y]) + if w.buffer.reverse: + i = len(b.mbox) - 1 - w.cursor.y + else: + i = w.cursor.y + b = MboxMsgBuffer(b.path, i, b.mbox[i]) b.open() window.Window(b, w.application, height=0, width=0, mode_name='mboxmsg') w.application.add_buffer(b) @@ -142,11 +195,11 @@ class MboxMsg(mode.Fundamental): class Mbox(mode.Fundamental): modename = 'Mbox' - actions = [MboxRefresh, MboxOpenPath, MboxOpenMsg] + actions = [MboxRefresh, MboxOpenPath, MboxReadMsg] def __init__(self, w): mode.Fundamental.__init__(self, w) self.add_bindings('mbox-refresh', ('C-c r',)) - self.add_bindings('mbox-open-msg', ('RETURN',)) + self.add_bindings('mbox-read-msg', ('RETURN',)) def install(*args): Mbox.install(*args)