Last active
August 29, 2015 14:19
-
-
Save boris-arzur/431a47a162de77228f1f to your computer and use it in GitHub Desktop.
read maildir from interactive ipython notebook
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%%file /ipy/mailcheck.py | |
import mailbox | |
import email.utils | |
import email.header | |
import email.iterators | |
from IPython.html.widgets import interact, interactive, fixed | |
from IPython.html import widgets | |
from IPython.display import display | |
def decode_(packed_stff): | |
bits, charset = email.header.decode_header(packed_stff)[0] | |
if charset is None: | |
return str(packed_stff) | |
return str(bits, charset) | |
def get_charset(message, default="ascii"): | |
gcc = message.get_content_charset() | |
if gcc: return gcc | |
gc = message.get_charset() | |
if gc: return gc | |
return default | |
def unicode_me(part, charset): | |
return str(part.get_payload(decode=True), charset) | |
def get_parts_for_type(message, message_charset, type_): | |
prefered_parts = tuple(email.iterators.typed_subpart_iterator(message, 'text', type_)) | |
charsets = [get_charset(part, message_charset) for part in prefered_parts] | |
unicoded = [unicode_me(part, charset) for part, charset in zip(prefered_parts, charsets)] | |
return u"\n".join(unicoded).strip() | |
def get_body(message): | |
message_charset = get_charset(message) | |
if message.is_multipart(): | |
text_plain = get_parts_for_type(message, message_charset, 'plain') | |
if len(text_plain) > 0: return text_plain | |
return get_parts_for_type(message, message_charset, 'html') | |
else: | |
return unicode_me(message, message_charset).strip() | |
def get_date_as_timestamp(message): | |
return email.utils.parsedate(message['date']) | |
def list_mail(maildir, size): | |
md = mailbox.Maildir(maildir) | |
from_message_id_to_timestamp = lambda mid: get_date_as_timestamp(md.get_message(mid)) | |
sorted_by_date = sorted(md.keys(), key=from_message_id_to_timestamp) | |
mails = [] | |
descr_to_mid = {} | |
for mid in sorted_by_date[-size:]: | |
_mail = md.get_message(mid) | |
# Here I want to columnize the output, but {:10s} formatter dont work, | |
# spaces are collapsed, and keys lost in 'options' {text: lid} | |
descr_line = "{} from:{} subject:{}".format( | |
_mail['date'], | |
email.utils.parseaddr(_mail['from'])[-1], | |
decode_(_mail['subject']) | |
) | |
mails.append(descr_line) | |
descr_to_mid[descr_line] = mid | |
return md, mails, descr_to_mid | |
class tleilaxu_select: | |
def __init__(self, maildir, max_size): | |
self.size = 5 | |
self.max_size = max_size | |
self.maildir = maildir | |
self.select = widgets.Select(options=[], width=900) | |
self.refresh() | |
self.interactive = interactive(self.show, mail=self.select) | |
def resize(self, size): | |
if self.max_size == size: | |
# biggest size setting shows all | |
size = -1 | |
self.size = size | |
self.refresh() | |
def refresh(self, *args): | |
md, mails, descr_to_mid = list_mail(self.maildir, self.size) | |
self.md = md | |
self.select.options = [] # flush | |
self.select.options = mails # and show | |
self.descr_to_mid = descr_to_mid | |
def show(self, mail): | |
mid = self.descr_to_mid[mail] | |
_mail = self.md.get_message(mid) | |
print(_mail['date'], email.utils.parseaddr(_mail['from'])) | |
email.iterators._structure(_mail) | |
print(decode_(_mail['subject'])) | |
print(get_body(_mail)) | |
def make_button(self): | |
button = widgets.ButtonWidget(description="Refresh !") | |
button.on_click(self.refresh) | |
return button | |
def make_slider(self): | |
slider = interactive(self.resize, size=(0, self.max_size)); | |
return slider | |
def make_control_panel(self): | |
button = self.make_button() | |
slider = self.make_slider() | |
main_container = widgets.HBox(children=[button, slider]) | |
return main_container | |
def run(**kwargs): | |
select = tleilaxu_select(**kwargs) | |
control_panel = select.make_control_panel() | |
display(control_panel) | |
display(select.interactive) | |
# use it in an ipython 3.1 notebook, the cell content in my case is 'import mailcheck; mailcheck.run(maildir='/home/boris/Maildir', max_size=20)' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment