def _get_attachment_data(self, pos): """Return a tuple: file-data, content-type and filename extracted from the attachment at position `pos`. """ # get attachment at position pos attachment = None for i, part in enumerate(self.msg.walk()): if i == pos: attachment = part continue if not attachment: return None, '', '' # decode when it's necessary filename = get_filename(attachment) if not isinstance(filename, unicode): filename = filename.decode('utf-8') # remove line breaks from the filename filename = re.sub('\s{1,}', ' ', filename) content_type = attachment.get_content_type() if content_type == 'message/rfc822': nested_messages = attachment.get_payload() assert len(nested_messages) == 1, ( 'we expect that attachments with messages only contain one ' 'message per attachment.') data = nested_messages[0].as_string() else: data = attachment.get_payload(decode=1) return data, content_type, filename
def get_attachment_as_namedfile(self, pos): """Return a namedfile extracted from the attachment in position `pos`. """ # get attachment at position pos attachment = None for i, part in enumerate(self.context.msg.walk()): if i == pos: attachment = part continue if not attachment: return None # decode when it's necessary filename = get_filename(attachment) if not isinstance(filename, unicode): filename = filename.decode('utf-8') # remove line breaks from the filename filename = re.sub('\s{1,}', ' ', filename) return NamedFile(data=attachment.get_payload(decode=1), contentType=attachment.get_content_type(), filename=filename)
def render(self): """ Copied from ftw.mail.attachment: Just add the contenttype-check (see l.51) """ if self.message is None: raise NotFound message = email.message_from_string(self.message.data) # we need an int value for the position pos = 0 try: pos = int(self.position) except ValueError: raise NotFound # get attachment at position pos attachment = None for i, part in enumerate(message.walk()): if i == pos: attachment = part continue if attachment is not None: content_type = attachment.get_content_type() filename = utils.get_filename(attachment) if filename is None: raise NotFound # the the konsul migrated mails, often has a wrong # content-type for word documents, therefore we check the # content-type, in this case we guess it over the filename if content_type == 'application/octet-stream': mtr = getToolByName(self.context, 'mimetypes_registry') content_type = mtr.globFilename(filename) # make sure we have a unicode string if not isinstance(filename, unicode): filename = filename.decode('utf-8', 'ignore') # internet explorer and safari don't like rfc encoding of filenames # and they don't like utf encoding too. # therefore we first try to encode the filename in iso-8859-1 try: filename = filename.encode('iso-8859-1') except ConflictError: raise except Exception: filename = filename.encode('utf-8', 'ignore') self.request.response.setHeader('Content-Type', content_type) set_attachment_content_disposition(self.request, filename) if content_type == 'message/rfc822': return attachment.as_string() return attachment.get_payload(decode=1) raise NotFound
def test_get_filename(self): msg_txt = \ """Content-Type: application/octet-stream; name="=?iso-8859-1?Q?Aperovorschl=E4ge_2010=2Epdf?=" Content-Transfer-Encoding: base64 Content-Description: =?iso-8859-1?Q?Aperovorschl=E4ge_2010=2Epdf?= Content-Disposition: attachment; filename="=?iso-8859-1?Q?Aperovorschl=E4ge_2010=2Epdf?=" """ msg = email.message_from_string(msg_txt) # !!! seems to be a bug in email package self.assertEquals('Aperovorschläge 2010.pdf', utils.get_filename(msg)) msg_txt = \ """Content-Disposition: attachment; filename*=iso-8859-1''f%F6rmularz%FCgriffsber%E4chtigungen.doc Content-Type: application/msword; name*=iso-8859-1''f%F6rmularz%FCgriffsber%E4chtigungen.doc Content-Transfer-Encoding: base64 """ msg = email.message_from_string(msg_txt) self.assertEquals('f\xc3\xb6rmularz\xc3\xbcgriffsber\xc3\xa4chtigungen.doc', utils.get_filename(msg))
def render(self): if self.message is None: raise NotFound message = email.message_from_string(self.message.data) # we need an int value for the position pos = 0 try: pos = int(self.position) except ValueError: raise NotFound # get attachment at position pos attachment = None for i, part in enumerate(message.walk()): if i == pos: attachment = part continue if attachment is not None: content_type = attachment.get_content_type() filename = utils.get_filename(attachment) if filename is None: raise NotFound # make sure we have a unicode string if not isinstance(filename, unicode): filename = filename.decode('utf-8', 'ignore') # internet explorer and safari don't like rfc encoding of filenames # and they don't like utf encoding too. # therefore we first try to encode the filename in iso-8859-1 try: filename = filename.encode('iso-8859-1') except: filename = filename.encode('utf-8', 'ignore') self.request.response.setHeader('Content-Type', content_type) self.request.response.setHeader('Content-Disposition', 'inline; filename=%s' % filename) if content_type == 'message/rfc822': return attachment.as_string() return attachment.get_payload(decode=1) raise NotFound