diff options
author | pazz <patricktotzke@gmail.com> | 2011-08-13 10:22:27 +0100 |
---|---|---|
committer | pazz <patricktotzke@gmail.com> | 2011-08-13 10:22:27 +0100 |
commit | 6cbb90b2c8b202c46290d32aa72027e195c66948 (patch) | |
tree | 5eec74963aae2f3c9e40e7c52d40262fc0d819d8 | |
parent | 2f54e0940ea4915f00100610743f9365ef314f3f (diff) |
attach command for envelope + display
issue #29
-rw-r--r-- | alot/buffer.py | 10 | ||||
-rw-r--r-- | alot/command.py | 67 | ||||
-rw-r--r-- | alot/settings.py | 5 | ||||
-rw-r--r-- | alot/widgets.py | 4 |
4 files changed, 81 insertions, 5 deletions
diff --git a/alot/buffer.py b/alot/buffer.py index 4b5e6264..1ee9aa7f 100644 --- a/alot/buffer.py +++ b/alot/buffer.py @@ -118,6 +118,16 @@ class EnvelopeBuffer(Buffer): self.header_wgt = widgets.MessageHeaderWidget(self.mail, displayed_headers=dh) displayed_widgets.append(self.header_wgt) + + #display attachments + lines = [] + for part in self.mail.walk(): + if not part.is_multipart(): + if part.get_content_maintype() != 'text': + lines.append(widgets.AttachmentWidget(part)) + self.attachment_wgt = urwid.Pile(lines) + displayed_widgets.append(self.attachment_wgt) + self.body_wgt = widgets.MessageBodyWidget(self.mail) displayed_widgets.append(self.body_wgt) self.body = urwid.ListBox(displayed_widgets) diff --git a/alot/command.py b/alot/command.py index 55ab9c51..3d10bb25 100644 --- a/alot/command.py +++ b/alot/command.py @@ -17,17 +17,24 @@ along with notmuch. If not, see <http://www.gnu.org/licenses/>. Copyright (C) 2011 Patrick Totzke <patricktotzke@gmail.com> """ import os +import glob import code import logging import threading import subprocess import email import tempfile +import mimetypes from email.parser import Parser -from email.mime.text import MIMEText -from email.mime.multipart import MIMEMultipart from email import Charset from email.header import Header +from email import encoders +from email.message import Message +from email.mime.audio import MIMEAudio +from email.mime.base import MIMEBase +from email.mime.image import MIMEImage +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart import buffer import settings @@ -839,6 +846,59 @@ class EnvelopeSendCommand(Command): priority='error') +class EnvelopeAttachCommand(Command): + def __init__(self, path=None, **kwargs): + Command.__init__(self, **kwargs) + self.files = [] + if path: + self.files = glob.glob(path) + + def apply(self, ui): + if not self.files: + path = ui.prompt(prefix='attach files matching:', text='~/', + completer=completion.PathCompleter()) + if path: + self.files = glob.glob(os.path.expanduser(path)) + if not self.files: + ui.notify('no matches, abort') + return + logging.info(self.files) + msg = ui.current_buffer.get_email() + for path in self.files: + ctype, encoding = mimetypes.guess_type(path) + if ctype is None or encoding is not None: + # No guess could be made, or the file is encoded (compressed), so + # use a generic bag-of-bits type. + ctype = 'application/octet-stream' + maintype, subtype = ctype.split('/', 1) + if maintype == 'text': + fp = open(path) + # Note: we should handle calculating the charset + part = MIMEText(fp.read(), _subtype=subtype) + fp.close() + elif maintype == 'image': + fp = open(path, 'rb') + part = MIMEImage(fp.read(), _subtype=subtype) + fp.close() + elif maintype == 'audio': + fp = open(path, 'rb') + part = MIMEAudio(fp.read(), _subtype=subtype) + fp.close() + else: + fp = open(path, 'rb') + part = MIMEBase(maintype, subtype) + part.set_payload(fp.read()) + fp.close() + # Encode the payload using Base64 + encoders.encode_base64(part) + # Set the filename parameter + part.add_header('Content-Disposition', 'attachment', + filename=os.path.basename(path)) + msg.attach(part) + + ui.current_buffer.set_email(msg) + + # TAGLIST class TaglistSelectCommand(Command): def apply(self, ui): @@ -857,6 +917,7 @@ COMMANDS = { 'retagprompt': (RetagPromptCommand, {}), }, 'envelope': { + 'attach': (EnvelopeAttachCommand, {}), 'send': (EnvelopeSendCommand, {}), 'reedit': (EnvelopeEditCommand, {}), 'subject': (EnvelopeSetCommand, {'key': 'Subject'}), @@ -952,6 +1013,8 @@ def interpret_commandline(cmdline, mode): if params: h = {'To': params} return commandfactory(cmd, mode=mode, headers=h) + elif cmd == 'attach': + return commandfactory(cmd, mode=mode, path=params) elif cmd == 'forward': return commandfactory(cmd, mode=mode, inline=(params == '--inline')) elif cmd == 'prompt': diff --git a/alot/settings.py b/alot/settings.py index cd716b78..a6e13d45 100644 --- a/alot/settings.py +++ b/alot/settings.py @@ -245,10 +245,11 @@ DEFAULTS = { 'enter': 'select', }, 'envelope-maps': { + 'a': 'attach', 'y': 'send', 'enter': 'reedit', - 't': 'prompt to', - 's': 'prompt subject', + 't': 'prompt to ', + 's': 'prompt subject ', }, 'bufferlist-maps': { 'x': 'closefocussed', diff --git a/alot/widgets.py b/alot/widgets.py index 9dd8ecb0..128b5ff1 100644 --- a/alot/widgets.py +++ b/alot/widgets.py @@ -446,7 +446,9 @@ class MessageBodyWidget(urwid.AttrMap): class AttachmentWidget(urwid.WidgetWrap): def __init__(self, attachment): self.attachment = attachment - widget = urwid.AttrMap(urwid.Text(unicode(attachment)), + if not isinstance(attachment, message.Attachment): + self.attachment = message.Attachment(self.attachment) + widget = urwid.AttrMap(urwid.Text(unicode(self.attachment)), 'message_attachment', 'message_attachment_focussed') urwid.WidgetWrap.__init__(self, widget) |