summaryrefslogtreecommitdiff
path: root/slime-0.11/slime_mh.py
diff options
context:
space:
mode:
Diffstat (limited to 'slime-0.11/slime_mh.py')
-rw-r--r--slime-0.11/slime_mh.py245
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()