Mailbox summary script
September 13, 2008 at 11:51 PM by Dr. Drang
I keep my email organized by project, and sometimes I need a list of all the messages in a project’s mailbox. I don’t necessarily need to print all the messages in the mailbox, just a summary of each: date, to, from, and subject. This is basically what I have showing in the top right pane of Apple Mail, but since there doesn’t seem to be a builtin way of printing that pane, I wrote a script to do it.
I decided to make the output of my script an HTML file with a tabular summary of the messages, like this:
(This is a Safari screenshot, but without a toolbar.)
HTML is portable, easy to write, easy to print from a browser, and—on a Mac—easy to convert to PDF. Detailed formatting is somewhat limited, even with CSS, but I didn’t need elaborate styling. Writing HTML means slinging text, so I decided to write the script in Python using Appscript because it’s better at handling text than AppleScript is. Here it is:
1: #!/usr/bin/python
2:
3: from appscript import *
4: import datetime
5:
6: # The name of the mailbox of interest. If the mailbox is in a folder,
7: # the format is "Folder name/Mailbox name"
8: mailboxname = "Active projects/Project X"
9:
10: # The template for the HTML file is a table with the message date,
11: # the first recipient, the sender, and the subject of each message.
12: tmpl = """<html>
13: <head>
14: <meta http-equiv="Content-type" content="text/html; charset=utf-8">
15: <title>Email Summary</title>
16: <style type="text/css">
17: table {
18: border-collapse: collapse;
19: }
20:
21: table th {
22: padding: .5em 1em .25em 1em;
23: background-color: #ddd;
24: border: 1px solid black;
25: border-bottom: 2px solid black;
26: }
27:
28: table td {
29: padding: .25em 1em .25em 1em;
30: border: 1px solid black;
31: }
32: </style>
33: </head>
34: <body>
35: <table>
36: <tr><th>Date</th><th>To</th><th>From</th><th>Subject</td></tr>
37: %s
38: </table>
39: </body>
40: </html>
41: """
42:
43: # Get the mail box of interest and sort the messages in ascending order by date sent.
44: box = app('Mail.app').mailboxes[mailboxname].messages.get()
45: box.sort( lambda x,y: cmp( x.date_sent.get(), y.date_sent.get() ) )
46:
47: # Collect the summary information from each message in the box.
48: summaries = []
49: for msg in box:
50: info = []
51: info.append(msg.date_sent.get().strftime("%Y-%m-%d"))
52: # Use the recipient's name if possible, otherwise the address.
53: if msg.to_recipients.get()[0].name.get():
54: info.append(msg.to_recipients.get()[0].name.get().encode('utf-8'))
55: else:
56: info.append(msg.to_recipients.get()[0].address.get().encode('utf-8'))
57: info.append(msg.sender.get().encode('utf-8'))
58: info.append(msg.subject.get().encode('utf-8'))
59: row = " <tr><td>" + "</td><td>".join(info) + "</td></tr>"
60: summaries.append(row)
61:
62: # Print out the resulting HTML file.
63: print tmpl % "\n".join(summaries)
I call it “email-summary,” and I’ve made it executable and put it in my $PATH so I can run it directly from the command line.
email-summary > project-x-summary.html
The comments in the source tell most of the story, but a little extra explanation may help.
- Apple Mail uses a Unix-style naming convention for mailboxes within folders. Even if the name of a mailbox is unique, you still have to include the enclosing folder(s) in the name, separating each level of folder with a slash, like this: “Outer folder/Inner folder/Mailbox.”
- The HTML template is simple and includes some CSS in the header (Lines 16-32) to style the table in a way that I like. If you know a little CSS, you can change the style to suit you.
- By default, the messages in a mailbox are not sorted in chronological order, so Line 45 takes the list of messages collected in Line 44 and sorts them by date. (Actually, it’s been my experience that the messages in
box
are in reverse chronological order—i.e., earliest at the end, latest at the beginning—after Line 44. If I knew that were always true, I wouldn’t have tosort
them; a simplereverse
would suffice.) - The sender, recipients, and summary may have Unicode characters, hence the
encode('utf-8')
invocations on Lines 54 and 55-57. The<meta>
line in the header on Line 14 ensures that the browser will treat the exotic characters as UTF-8 rather than Latin-1 or Mac OS Roman or some Windows encoding. - I decided for the sake of space to print only the first recipient, regardless of the number of people the email was sent to.
- Although I prefer to print the name of the first recipient, sometimes there is no name associated with the address and trying to print it would lead to an error. Lines 53-56 perform a test, printing the name if there is one and printing the address if there isn’t. Oddly, there’s no need to do this test for the sender.
Having a list like this printed out on several pages often gives me a good sense of the development of a project.