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