diff options
Diffstat (limited to 'slime-0.11/slime_unix.py')
-rw-r--r-- | slime-0.11/slime_unix.py | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/slime-0.11/slime_unix.py b/slime-0.11/slime_unix.py new file mode 100644 index 0000000..0410aa0 --- /dev/null +++ b/slime-0.11/slime_unix.py @@ -0,0 +1,183 @@ +import mhlib, os, StringIO2 +StringIO = StringIO2 +from slime_abstract import * +from mailbox import UnixMailbox, _Subfile + +def unix_top_folder(dirname): + """Return SlimeFolder with top level Unix folders.""" + dirname = os.path.expanduser(dirname) + if os.path.isdir(dirname): + if not os.path.isfile(os.path.join(dirname, "context")): + return SlimeFolder_Unix(dirname) + return None + +class SlimeFolder_Unix(SlimeFolder): + """A SlimeFolder interface to ordinary Unix mailbox folders.""" + + def __init__(self, name): + SlimeFolder.__init__(self) + if not os.path.isabs(name): + name = os.path.join(os.getcwd(), name) + self._name = name + self._is_dir = 0 + + def open(self): + self._is_open = 1 + if os.path.isdir(self._name): + self._is_dir = 1 + else: + self._is_dir = 0 + self._fp = open(self._name, 'r+') + + def close(self): + for msg in self._messages: + msg.uncache_headers() + if not self._is_dir: + self._fp = None + self._is_open = 0 + + def rescan_messages(self): + self._assert_open() + if not self._is_dir: + new_messages = [] + mb = UnixMailbox(self._fp) + while 1: + m = mb.next() + if not m: + break + mm = SlimeMessage_Unix(self, m.fp) + for msg in self._messages: + if mm._checksum == msg._checksum: + mm = msg + break + mm.set_status(mm["status"]) + new_messages.append(mm) + self._messages = new_messages + self._threads = [] + + def rescan_subfolders(self): + self._assert_open() + if self._is_dir: + list = [] + for pathname in os.listdir(self._name): + p = os.path.join(self._name, pathname) + list.append(SlimeFolder_Unix(p)) + self._subfolders = list + + def add_message(self, file): + self._assert_open() + + dummy = mhlib.Message('NONE', 1, file) + self._fp.seek(0,2) + start = self._fp.tell() + self._fp.write(self._make_separator(dummy)) + del dummy + file.seek(0,0) + while 1: + buf = file.read(16*1024) + if not buf: + break + self._fp.write(buf) + end = self._fp.tell() + subfile = _Subfile(self._fp, start, end) + msg = SlimeMessage_Unix(self, subfile) + self._messages.append(msg) + return msg + + def commit_changes(self): + self._assert_open() + if not self._is_dir and self._dirty: + newname = self._name + ".new" + f = open(newname, "w") + for msg in self._messages: + if not msg.has_status("D"): + f.write(self._make_separator(msg)) + f.write(msg.getfulltext()) + f.close() + os.rename(newname, self._name) + + self._messages = [] + self._dirty = 0 + self.open() + self.rescan_messages() + self.rescan_subfolders() + + def _make_separator(self, msg): + date = msg.getdate("date") + if date is None: + date = (1970,1,1,0,0,0,3,1,0) + mon = ["", "Jan", "Feb", "Mar", "Apr", "May", + "Jun", "Jul", "Aug", "Sep", "Oct", + "Nov", "Dec"][date[1]] + dow = ["Mon", "Tue", "Wed", "Thu", "Fri", + "Sat", "Sun"][date[6]] + year = date[0] + if year < 1900: + year = year + 1900 + name, addr = msg.getaddr("from") + if not addr: + addr = "foo" + return "From %s %s %s %2d %2d:%02d:%02d %d\n" % \ + (addr, dow, mon, date[2], date[3], date[4], + date[5], year) + +class SlimeMessage_Unix(SlimeMessage): + """A SlimeMessage interface to messages in Unix mailbox folders.""" + + def __init__(self, folder, subfile): + SlimeMessage.__init__(self, folder) + self._start = subfile.start + self._stop = subfile.stop + self._checksum = self._start + + def _open(self): + self._folder._assert_open() + self._open_count = self._open_count + 1 + if not self._msg: + self._fp = _Subfile(self._folder._fp, + self._start, self._stop) + self._msg = mhlib.Message('NONE', 1, self._fp) + + # make sure stuff is cached + if not self._cached_date: + self._cache_headers() + + def _close(self): + self._folder._assert_open() + self._open_count = self._open_count - 1 + if self._open_count == 0: + self._msg = None + self._fp.close() + +def main(): + f = SlimeFolder_Unix(os.path.expanduser("~/mail")) + f.open() + f.rescan_subfolders() + for sub in f.list_all_subfolders(): + sub.open() + sub.rescan_messages() + for msg in sub.list_all_messages()[:2]: + print sub._name, msg["subject"] + sub.close() + print + f.close() + +def profile_main(): + import time + f = unix_top_folder("~/mail") + f.open() + f.rescan_subfolders() + for sub in f.list_all_subfolders(): + if repr(sub) == "/home/liw/mail/yow3": + sub.open() + print "computing threads" + start = time.time() + sub.rescan_messages() + sub.list_all_threads() + end = time.time() + print "threads computed", end - start + sub.close() + f.close() + +if __name__ == "__main__": + main() |