diff --git a/extensions/webmail/imaputils.py b/extensions/webmail/imaputils.py index 8c1f758ed..bbc284832 100644 --- a/extensions/webmail/imaputils.py +++ b/extensions/webmail/imaputils.py @@ -93,6 +93,7 @@ class BodyStructure(object): self.inlines[params["cid"].strip("<>")] = params return + params["Content-Type"] = ftype if len(definition) > 7: extensions = ["md5", "disposition", "language", "location"] if mtype == "text": @@ -124,6 +125,12 @@ class BodyStructure(object): def has_attachments(self): return len(self.attachments) + def find_attachment(self, pnum): + for att in self.attachments: + if pnum == att["pnum"]: + return att + return None + class IMAPconnector(object): __metaclass__ = ConnectionsManager @@ -551,9 +558,21 @@ class IMAPconnector(object): self.quota_actual = int(m.group(1)) def fetchpart(self, uid, mbox, partnum): + """Retrieve a specific message part + + Useful to fetch attachments from the server. Part headers and + the payload are returned separatly. + + :param uid: a message UID + :param mbox: the mailbox containing the message + :param partnum: the part number + :return: a 2uple (dict, string) + """ self.select_mailbox(mbox, False) - data = self._cmd("FETCH", uid, "(BODY[%s])" % partnum) - return data[int(uid)]["BODY[%s]" % partnum] + data = self._cmd("FETCH", uid, "(BODYSTRUCTURE BODY[%s])" % partnum) + bs = BodyStructure(data[int(uid)]["BODYSTRUCTURE"]) + attdef = bs.find_attachment(partnum) + return attdef, data[int(uid)]["BODY[%s]" % partnum] def fetch(self, start, stop=None, mbox=None, **kwargs): """Retrieve information about messages from the server @@ -604,7 +623,6 @@ class IMAPconnector(object): :param readonly: :param extraheaders: """ - print mbox self.select_mailbox(mbox, readonly) if headers is None: headers = ['DATE', 'FROM', 'TO', 'CC', 'SUBJECT'] diff --git a/extensions/webmail/lib.py b/extensions/webmail/lib.py index 6e734fd17..5e4956c1d 100644 --- a/extensions/webmail/lib.py +++ b/extensions/webmail/lib.py @@ -182,8 +182,8 @@ class ImapEmail(Email): pnum = self.bs.contents[mformat]['pnum'] data = self.imapc._cmd("FETCH", mailid, "(BODY.PEEK[%s])" % pnum) - content = self._decode_content(self.bs.contents[mformat]['encoding'], - data[int(mailid)]['BODY[%s]' % pnum]) + content = decode_payload(self.bs.contents[mformat]['encoding'], + data[int(mailid)]['BODY[%s]' % pnum]) charset = self._find_content_charset(mformat) if charset is not None: content = content.decode(charset) @@ -229,16 +229,6 @@ class ImapEmail(Email): return self.bs.contents[subtype]["params"][pos + 1] return None - def _decode_content(self, encoding, content): - encoding = encoding.lower() - if encoding == "base64": - import base64 - return base64.b64decode(content) - elif encoding == "quoted-printable": - import quopri - return quopri.decodestring(content) - return content - def _find_attachments(self): for att in self.bs.attachments: attname = "part_%s" % att["pnum"] @@ -270,9 +260,9 @@ class ImapEmail(Email): if os.path.exists(path): continue - content = self.imapc.fetchpart(self.mailid, self.mbox, params["pnum"]) + pdef, content = self.imapc.fetchpart(self.mailid, self.mbox, params["pnum"]) fp = open(path, "wb") - fp.write(self._decode_content(params["encoding"], content)) + fp.write(decode_payload(params["encoding"], content)) fp.close() @@ -428,6 +418,25 @@ class EmailSignature(object): def __repr__(self): return self._sig +def decode_payload(encoding, payload): + """Decode the payload according to the given encoding + + Supported encodings: base64, quoted-printable. + + :param encoding: the encoding's name + :param payload: the value to decode + :return: a string + """ + print payload + encoding = encoding.lower() + if encoding == "base64": + import base64 + return base64.b64decode(payload) + elif encoding == "quoted-printable": + import quopri + return quopri.decodestring(payload) + return payload + def find_images_in_body(body): """Looks for images inside a HTML body diff --git a/extensions/webmail/templates/webmail/headers.html b/extensions/webmail/templates/webmail/headers.html index 1b5616f6c..ea795ecdb 100644 --- a/extensions/webmail/templates/webmail/headers.html +++ b/extensions/webmail/templates/webmail/headers.html @@ -1,13 +1,11 @@ -{% extends "common/mailheaders.html" %} -{% load i18n %} +{% extends "common/mailheaders.html" %}{% load i18n %} {% block extraheaders %} {% if attachments %}