]> code.delx.au - monosys/blob - mail/maildirstat.py
f7a151b1f04a8e5f1c643feba66293a4b616be36
[monosys] / mail / maildirstat.py
1 #!/usr/bin/env python
2
3 import os, os.path, sys
4 import kqueue
5 j = os.path.join
6 sep = os.path.sep
7
8 def watchDirectories(directories):
9 """ Given a list of directories to monitor, returns a function which when
10 called will sleep until a directory changes, and then return a list of
11 changed directories.
12 """
13 def doWatch():
14 while True:
15 changed = []
16 for event in kqueue.kevent(kq, events, 10, None):
17 changed.append(directories[dirfds.index(event.ident)])
18 return changed
19
20 # Open all the directories
21 dirfds = []
22 for directory in directories:
23 dirfds.append(os.open(directory, os.O_RDONLY))
24
25 # Set up the kqueue events
26 events = []
27 filter = kqueue.EV_ADD | kqueue.EV_CLEAR | kqueue.EV_ENABLE
28 fflags = kqueue.NOTE_WRITE | kqueue.NOTE_DELETE | kqueue.NOTE_EXTEND
29 for fd in dirfds:
30 e=kqueue.Event(fd, kqueue.EVFILT_VNODE, filter, fflags=fflags, data=fd)
31 events.append(e)
32
33 # Give back a function pointer
34 kq = kqueue.kqueue()
35 return doWatch
36
37 def clear():
38 """ Clears the screen """
39 os.system("clear")
40
41 def checkMailbox(mailbox):
42 """ Ensure that mailbox is a maildir directory """
43 if not (os.path.isdir(mailbox) and
44 os.path.isdir(j(mailbox, "cur")) and
45 os.path.isdir(j(mailbox, "new")) and
46 os.path.isdir(j(mailbox, "tmp"))):
47 print >> sys.stderr, "Error! Not a maildir mailbox."
48 sys.exit(1)
49
50 def extractFlags(messages):
51 """ Extract the flags from the messages """
52 return [m.rsplit(":", 1)[1].split(",")[1] for m in messages]
53
54 def maildirStat(mailbox):
55 """ Returns newCount, unreadCount for the given maildir mailbox """
56 checkMailbox(mailbox)
57
58 # Reuse the directory listing
59 curList = extractFlags(os.listdir(j(mailbox, "cur")))
60
61 # Get the new messages
62 newCount = len(os.listdir(j(mailbox, "new")))
63 newCount += len([m for m in curList if "N" in m])
64
65 # Get the unread messages
66 unreadCount = len([m for m in curList if "S" not in m])
67
68 return newCount, unreadCount
69
70 def multiStat(mailboxes, counts):
71 for mailbox in mailboxes:
72 counts[mailbox] = maildirStat(mailbox)
73
74 def printCounts(mailboxes, counts):
75 """ Prints the counts to the screen ordered """
76 clear()
77 for mailbox in mailboxes:
78 newCount, unreadCount = counts[mailbox]
79 mailbox = mailbox.rsplit("/", 1)[-1]
80 print "%s:\n\t%d\t%d\n" % (mailbox, newCount, unreadCount)
81
82 def main(mailboxes):
83 """ Stat all the mailboxes and then watch for changes """
84 counts = {}
85 multiStat(mailboxes, counts)
86 printCounts(mailboxes, counts)
87
88 watcher = watchDirectories([j(m, "cur") for m in mailboxes] +
89 [j(m, "new") for m in mailboxes])
90 while True:
91 changed = watcher()
92 changed = [sep.join(d.split(os.path.sep)[:-1]) for d in changed]
93 changed = list(set(changed))
94 multiStat(changed, counts)
95 printCounts(mailboxes, counts)
96
97
98 if __name__ == "__main__":
99 try:
100 mailboxes = sys.argv[1:]
101 except IndexError:
102 print >> sys.stderr, "Usage: %s mailbox [mailbox ...]" % sys.argv[0]
103 sys.exit(1)
104
105 try:
106 main(mailboxes)
107 except KeyboardInterrupt:
108 print
109