def test_nested_remove_attachments(self): """A forwarded mail with attachments results in nested multipart payloads - this should also be handled by remove_attachments. """ msg = deepcopy(self.msg_nested_attachments) self.assertNotEquals(msg, self.msg_nested_attachments) # we have two attachments (which are nested) self.assertEquals([{'position': 4, 'size': 137588, 'content-type': 'image/jpg', 'filename': '1703693_0412c29a4f.jpg'}, {'position': 5, 'size': 223504, 'content-type': 'image/jpg', 'filename': '3512536451_e1310bf568.jpg'}], utils.get_attachments(msg)) # lets remove one attachment new_msg = utils.remove_attachments(msg, (5,)) # we get the same message back.. self.assertEquals(msg, new_msg) # .. but without the removed attachment self.assertEquals([{'position': 4, 'size': 137588, 'content-type': 'image/jpg', 'filename': '1703693_0412c29a4f.jpg'}], utils.get_attachments(new_msg))
def test_remove_attachments(self): # we dont want to change the message itselve, so lets copy it msg = deepcopy(self.msg_attachment) self.assertNotEquals(msg, self.msg_attachment) # our message has one attachment self.assertEquals([{'position': 1, 'size': 7, 'content-type': 'text/plain', 'filename': 'Bücher.txt'}], utils.get_attachments(msg)) # lets remove the attachment new_msg = utils.remove_attachments(msg, (1,)) # we get the same message back self.assertEquals(msg, new_msg) self.assertEquals([], utils.get_attachments(new_msg))
def _delete_attachments(self, attachments): if not attachments: return attachment_names = [ attachment.get('filename', '[no filename]').decode('utf-8') for attachment in attachments] positions = [attachment['position'] for attachment in attachments] # Flag the `message` attribute as having changed desc = Attributes(IAttachmentsDeletedEvent, "message") notify(AttachmentsDeleted(self, attachment_names, desc)) # set the new message file msg = remove_attachments(self.msg, positions) self.message = NamedFile( data=msg.as_string(), contentType=self.message.contentType, filename=self.message.filename)
def extract_attachments(self, positions, delete_action): dossier = self.find_parent_dossier() attachments_to_extract = filter( lambda att: att.get('position') in positions, get_attachments(self.context.msg)) # create documents from the selected attachments for att in attachments_to_extract: pos = att.get('position') filename = att.get('filename') # remove line breaks from the filename filename = re.sub('\s{1,}', ' ', filename) kwargs = {'title': filename[:filename.rfind('.')].decode('utf-8'), 'file': self.get_attachment_as_namedfile(pos), 'keywords': (), 'digitally_available': True} doc = createContentInContainer(dossier, 'opengever.document.document', **kwargs) for schemata in iterSchemata(doc): for name, field in getFieldsInOrder(schemata): if name not in kwargs.keys(): default = queryMultiAdapter(( doc, doc.REQUEST, # request None, # form field, None, # Widget ), IValue, name='default') if default is not None: default = default.get() if default is None: default = getattr(field, 'default', None) if default is None: try: default = field.missing_value except: pass field.set(field.interface(doc), default) # add a reference from the attachment to the mail intids = getUtility(IIntIds) iid = intids.getId(self.context) # prevent circular dependencies from opengever.document.behaviors import IRelatedDocuments IRelatedDocuments(doc).relatedItems = [RelationValue(iid)] msg = _(u'info_extracted_document', default=u'Created document ${title}', mapping={'title': doc.Title().decode('utf-8')}) IStatusMessage(self.request).addStatusMessage(msg, type='info') # reindex the new document to index also all the default values doc.reindexObject() # delete the attachments from the email message, if needed if delete_action in ('all', 'selected'): if delete_action == 'selected': pos_to_delete = positions else: # all pos_to_delete = [int(att['position']) for att in get_attachments(self.context.msg)] # set the new message file msg = remove_attachments(self.context.msg, pos_to_delete) self.context.message = NamedFile( data=msg.as_string(), contentType=self.context.message.contentType, filename=self.context.message.filename)
def extract_attachments(self, positions, delete_action): dossier = self.find_parent_dossier() attachments_to_extract = filter( lambda att: att.get('position') in positions, get_attachments(self.context.msg)) # create documents from the selected attachments for att in attachments_to_extract: pos = att.get('position') filename = att.get('filename') # remove line breaks from the filename filename = re.sub('\s{1,}', ' ', filename) kwargs = { 'title': filename[:filename.rfind('.')].decode('utf-8'), 'file': self.get_attachment_as_namedfile(pos), 'keywords': (), 'digitally_available': True } doc = createContentInContainer(dossier, 'opengever.document.document', **kwargs) for schemata in iterSchemata(doc): for name, field in getFieldsInOrder(schemata): if name not in kwargs.keys(): default = queryMultiAdapter( ( doc, doc.REQUEST, # request None, # form field, None, # Widget ), IValue, name='default') if default is not None: default = default.get() if default is None: default = getattr(field, 'default', None) if default is None: try: default = field.missing_value except: pass field.set(field.interface(doc), default) # add a reference from the attachment to the mail intids = getUtility(IIntIds) iid = intids.getId(self.context) # prevent circular dependencies from opengever.document.behaviors import IRelatedDocuments IRelatedDocuments(doc).relatedItems = [RelationValue(iid)] msg = _(u'info_extracted_document', default=u'Created document ${title}', mapping={'title': doc.Title().decode('utf-8')}) IStatusMessage(self.request).addStatusMessage(msg, type='info') # reindex the new document to index also all the default values doc.reindexObject() # delete the attachments from the email message, if needed if delete_action in ('all', 'selected'): if delete_action == 'selected': pos_to_delete = positions else: # all pos_to_delete = [ int(att['position']) for att in get_attachments(self.context.msg) ] # set the new message file msg = remove_attachments(self.context.msg, pos_to_delete) self.context.message = NamedFile( data=msg.as_string(), contentType=self.context.message.contentType, filename=self.context.message.filename)