diff options
Diffstat (limited to 'slime-0.11/slime_mh.py')
-rw-r--r-- | slime-0.11/slime_mh.py | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/slime-0.11/slime_mh.py b/slime-0.11/slime_mh.py new file mode 100644 index 0000000..a4571d6 --- /dev/null +++ b/slime-0.11/slime_mh.py @@ -0,0 +1,245 @@ +"""Implement interface to MH folders.""" + +from slime_abstract import * +import os + +import mhlib2 +mhlib = mhlib2 # kludge until Python accepts my modified mhlib.py +import StringIO2 +StringIO = StringIO2 + +default_mh = None + +def mh_top_folder(): + """Return SlimeFolder with top level MH folders.""" + global default_mh + if not default_mh: + default_mh = mhlib.MH() + mhroot = SlimeFolder_MHroot(default_mh) + mhroot.open() + mhroot.rescan_subfolders() + if mhroot.list_all_subfolders(): + mhroot.close() + return mhroot + mhroot.close() + return None + +class SlimeFolder_MHroot(SlimeFolder): + """Root of all MH folders.""" + + def __init__(self, mh): + SlimeFolder.__init__(self) + self._mh = mh + self._name = mh.getpath() + self._subfolders = [] + + def open(self): + self._is_open = 1 + self.rescan_subfolders() + + def close(self): + self._is_open = 0 + + def commit_changes(self): + self._assert_open() + + def rescan_messages(self): + pass + + def rescan_subfolders(self): + self._assert_open() + list = [] + for name in self._mh.listfolders(): + if not os.path.isabs(name): + name = os.path.join(self._mh.getpath(), name) + new = None + for subfolder in self._subfolders: + if name == repr(subfolder): + new = subfolder + break + if new is None: + new = SlimeFolder_MH(name, self._mh) + list.append(new) + self._subfolders = list + +class SlimeFolder_MH(SlimeFolder): + """Abstract interface to an MH mail folder.""" + + def __init__(self, name, mh): + SlimeFolder.__init__(self) + self.mh = mh + self._subfolders = [] + self._name = os.path.join(mh.getpath(), name) + self.mh_folder = self.mh.openfolder(self._name) + self._last_message_scan = 0 + + def open(self): + self._is_open = 1 + self._old_numbers = [] + + def close(self): + """Close the folder.""" + for msg in self._messages: + msg.uncache_headers() + self._is_open = 0 + + def rescan_messages(self): + self._assert_open() + + dirname = self.mh_folder.getfullname() + dirmtime = os.stat(dirname)[8] + if dirmtime == self._last_message_scan: + return + self._last_message_scan = dirmtime + + seq = self.mh_folder.getsequences() + if seq.has_key("unseen"): + unseen = seq["unseen"] + else: + unseen = [] + + numbers = self.mh_folder.listmessages() + list = [] + for n in numbers: + if n in self._old_numbers: + for msg in self._messages: + if msg._id == n: + list.append(msg) + break + else: + msg = SlimeMessage_MH(self, n) + if n in unseen: + msg.set_status("N") + list.append(msg) + self._messages = list + self._old_numbers = numbers + self._threads = [] + + def rescan_subfolders(self): + oldlist = [] + for old in self._subfolders: + oldlist.append(repr(old)) + list = [] + for name in self.mh_folder.listsubfolders(): + fullname = os.path.join(self.mh.getpath(), name) + try: + i = oldlist.index(fullname) + new = self._subfolders[i] + except ValueError: + new = SlimeFolder_MH(name, self.mh) + list.append(new) + self._subfolders = list + + def add_message(self, file): + self._assert_open() + f = self.mh_folder + n = f.getlast() + 1 + f.createmessage(n, file) + msg = SlimeMessage_MH(self, n) + self._messages.append(msg) + self._old_numbers.append(n) + return msg + + def commit_changes(self): + if self._dirty: + self._assert_open() + unseen = [] + list = [] + for msg in self._messages: + if msg.has_status("D"): + list.append(msg._id) + elif msg.has_status("N"): + unseen.append(msg._id) + self.mh_folder.removemessages(list) + + seq = self.mh_folder.getsequences() + if seq.has_key("unseen"): + unseen.sort() + seq["unseen"] = unseen + self.mh_folder.putsequences(seq) + + self._dirty = 0 + + self.rescan_messages() + +class SlimeMessage_MH(SlimeMessage): + """A SlimeMessage interface to mhlib.Message.""" + + def __init__(self, folder, id): + SlimeMessage.__init__(self, folder) + self._msg = None + self._id = id + + def _open(self): + self._folder._assert_open() + self._open_count = self._open_count + 1 + if not self._msg: + self._msg = mhlib.Message(self._folder.mh_folder, + self._id) + # 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 + + def change_text(self, file): + self._folder._assert_open() + if self._open_count != 0: + raise Error, "change_text needs closed message" + filename = self._folder.mh_folder.getmessagefilename(self._id) + newname = filename + '.new' + f = open(newname, "w") + while 1: + buf = file.read(16*1024) + if not buf: + break + f.write(buf) + f.close() + os.rename(newname, filename) + self.uncache_headers() + +def main(): + root = mh_top_folder() + if not root: + print "no MH root" + else: +# root.open() +# root.rescan_subfolders() +# print root.list_all_subfolders() +# root.close() + foo(root) + +def foo(folder): + folder.open() + folder.rescan_subfolders() + folder.close() + folder.open() + folder.rescan_subfolders() + print folder + for sub in folder.list_all_subfolders(): + foo(sub) + folder.close() + +def profile_main(): + import time + f = mh_top_folder() + f.open() + f.rescan_subfolders() + for sub in f.list_all_subfolders(): + if sub.get_nice_name() == "cola-incoming": + 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() |