def render_attachment_table(self):
        """Renders a ftw-table of attachments.
        """

        columns = (
            {'column': 'position',
             'column_title': _(u'column_attachment_checkbox',
                               default=u''),
             'transform': attachment_checkbox_helper},

            {'column': 'content-type',
             'column_title': _(u'column_attachment_type',
                               default=u'Type'),
             'transform': content_type_helper},

            {'column': 'filename',
             'column_title': _(u'column_attachment_filename',
                               default=u'Filename'),
             'transform': downloadable_filename_helper(self.context)},

            {'column': 'size',
             'column_title': _(u'column_attachment_size',
                               default=u'Size'),
             'transform': human_readable_filesize_helper(self.context)},
            )

        items = get_attachments(self.context.msg)

        generator = getUtility(ITableGenerator, 'ftw.tablegenerator')
        return generator.generate(items, columns, sortable=False)
Example #2
0
class IOGMail(form.Schema):
    """Opengever specific behavior,
    which add a title Field to the form.
    """

    form.fieldset(
        u'common',
        label=base_mf(u'fieldset_common', u'Common'),
        fields=[u'title', 'original_message', 'message_source'])

    form.order_before(title='message')
    dexteritytextindexer.searchable('title')
    title = schema.TextLine(
        title=dossier_mf(u'label_title', default=u'Title'),
        required=False,
    )

    form.mode(original_message=DISPLAY_MODE)
    form.read_permission(original_message='cmf.ManagePortal')
    form.write_permission(original_message='cmf.ManagePortal')
    original_message = field.NamedBlobFile(
        title=_(u'label_original_message',
                default=u'Raw *.msg message before conversion'),
        required=False,
    )

    form.mode(message_source=DISPLAY_MODE)
    form.read_permission(message_source='cmf.ManagePortal')
    form.write_permission(message_source='cmf.ManagePortal')
    message_source = schema.Choice(
        title=_('label_message_source',
                default='Message source'),
        vocabulary=get_message_source_vocabulary(),
        required=False,
    )
    def __call__(self):
        items = get_attachments(self.context.msg)
        if not len(items):
            msg = _(u'error_no_attachments_to_extract',
                    default=u'This mail has no attachments to extract.')
            IStatusMessage(self.request).addStatusMessage(msg, type='warning')
            return self.request.RESPONSE.redirect(self.context.absolute_url())

        elif self.request.get('form.cancelled'):
            return self.request.RESPONSE.redirect(self.context.absolute_url())

        elif self.request.get('form.submitted'):
            attachments = self.request.get('attachments')
            if not attachments:
                msg = _(u'error_no_attachments_selected',
                        default=u'You have not selected any attachments.')
                IStatusMessage(self.request).addStatusMessage(msg,
                                                              type='error')
            else:
                attachments = [int(pos) for pos in attachments]
                delete_action = self.request.get('delete_action', 'nothing')
                if delete_action not in self.allowed_delete_actions:
                    raise ValueError('Expected delete action to be one of ' +
                                     str(self.allowed_delete_actions))

                self.extract_attachments(attachments, delete_action)

                dossier = self.find_parent_dossier()
                return self.request.RESPONSE.redirect(
                    os.path.join(dossier.absolute_url(), '#documents'))

        return grok.View.__call__(self)
Example #4
0
    def get_metadata_config(self):
        rows = [
            FieldRow('title'),
            FieldRow('IDocumentMetadata.document_date'),
            FieldRow('IDocumentMetadata.document_type'),
            FieldRow('IDocumentMetadata.document_author'),
            CustomRow(self.render_creator_link,
                      label=ogdmf('label_creator', default='creator')),
            WebIntelligentFieldRow('IDocumentMetadata.description'),
            FieldRow('IDocumentMetadata.foreign_reference'),
            TemplateRow(self.file_template,
                        label=_('label_org_message', default='Message')),
            TemplateRow(self.attachments_template,
                        label=_('label_documents',
                                default='Attachments')),
            FieldRow('IDocumentMetadata.digitally_available'),
            FieldRow('IDocumentMetadata.preserved_as_paper'),
            FieldRow('IDocumentMetadata.receipt_date'),
            FieldRow('IDocumentMetadata.delivery_date'),
            FieldRow('IRelatedDocuments.relatedItems'),
            FieldRow('IClassification.classification'),
            FieldRow('IClassification.privacy_layer'),
            TemplateRow(self.public_trial_template,
                        label=ogbmf('label_public_trial',
                                    default='Public Trial')),
            FieldRow('IClassification.public_trial_statement'),
        ]

        if api.user.has_permission('cmf.ManagePortal'):
            rows.append(FieldRow('IOGMail.original_message'))
            rows.append(FieldRow('IOGMail.message_source'))

        return rows
    def __call__(self):
        disable_edit_bar()

        if not self.context.has_attachments():
            msg = _(u'error_no_attachments_to_extract',
                    default=u'This mail has no attachments to extract.')
            api.portal.show_message(msg, request=self.request, type='warning')
            return self.request.RESPONSE.redirect(self.context.absolute_url())

        if self.request.get('form.cancelled'):
            return self.request.RESPONSE.redirect(self.context.absolute_url())

        if self.request.get('form.submitted'):
            attachments = self.request.get('attachments')
            if not attachments:
                msg = _(u'error_no_attachments_selected',
                        default=u'You have not selected any attachments.')
                api.portal.show_message(msg,
                                        request=self.request,
                                        type='error')
            else:
                attachments = [int(pos) for pos in attachments]
                delete_action = self.request.get('delete_action', 'nothing')
                if delete_action not in self.allowed_delete_actions:
                    raise ValueError('Expected delete action to be one of ' +
                                     str(self.allowed_delete_actions))

                self.extract_attachments(attachments, delete_action)
                return self.request.RESPONSE.redirect("{}/#documents".format(
                    self.context.get_extraction_parent().absolute_url()))

        return super(ExtractAttachments, self).__call__()
Example #6
0
    def get_metadata_config(self):
        rows = [
            FieldRow('title'),
            FieldRow('IDocumentMetadata.document_date'),
            FieldRow('IDocumentMetadata.document_type'),
            FieldRow('IDocumentMetadata.document_author'),
            CustomRow(self.render_creator_link,
                      label=ogdmf('label_creator', default='creator')),
            FieldRow('IDocumentMetadata.description'),
            FieldRow('IDocumentMetadata.foreign_reference'),
            TemplateRow(self.file_template,
                        label=_('label_org_message',
                                default='Original message')),
            TemplateRow(self.attachments_template,
                        label=_('label_documents',
                                default='Attachments')),
            FieldRow('IDocumentMetadata.digitally_available'),
            FieldRow('IDocumentMetadata.preserved_as_paper'),
            FieldRow('IDocumentMetadata.receipt_date'),
            FieldRow('IDocumentMetadata.delivery_date'),
            FieldRow('IRelatedDocuments.relatedItems'),
            FieldRow('IClassification.classification'),
            FieldRow('IClassification.privacy_layer'),
            TemplateRow(self.public_trial_template,
                        label=ogbmf('label_public_trial',
                                    default='Public Trial')),
            FieldRow('IClassification.public_trial_statement'),
        ]

        if api.user.has_permission('cmf.ManagePortal'):
            rows.append(FieldRow('IOGMail.original_message'))
            rows.append(FieldRow('IOGMail.message_source'))

        return rows
    def render_attachment_table(self):
        """Renders a ftw-table of attachments.
        """

        columns = (
            {
                'column': '',
                'transform': attachment_checkbox_helper,
                'width': 30
            },
            {
                'column': 'content-type',
                'column_title': _(u'column_attachment_type', default=u'Type'),
                'transform': content_type_helper
            },
            {
                'column':
                'filename',
                'column_title':
                _(u'column_attachment_filename', default=u'Filename'),
                'transform':
                downloadable_filename_helper(self.context)
            },
            {
                'column': 'size',
                'column_title': _(u'column_attachment_size', default=u'Size'),
                'transform': human_readable_filesize_helper(self.context)
            },
        )

        items = self.context.get_attachments()

        generator = getUtility(ITableGenerator, 'ftw.tablegenerator')
        return generator.generate(items, columns, sortable=False)
    def __call__(self):
        items = get_attachments(self.context.msg)
        if not len(items):
            msg = _(u'error_no_attachments_to_extract',
                    default=u'This mail has no attachments to extract.')
            IStatusMessage(self.request).addStatusMessage(msg, type='warning')
            return self.request.RESPONSE.redirect(
                self.context.absolute_url())

        elif self.request.get('form.cancelled'):
            return self.request.RESPONSE.redirect(
                self.context.absolute_url())

        elif self.request.get('form.submitted'):
            attachments = self.request.get('attachments')
            if not attachments:
                msg = _(u'error_no_attachments_selected',
                        default=u'You have not selected any attachments.')
                IStatusMessage(self.request).addStatusMessage(msg,
                                                              type='error')
            else:
                attachments = [int(pos) for pos in attachments]
                delete_action = self.request.get('delete_action', 'nothing')
                if delete_action not in self.allowed_delete_actions:
                    raise ValueError('Expected delete action to be one of ' +
                                         str(self.allowed_delete_actions))

                self.extract_attachments(attachments, delete_action)

                dossier = self.find_parent_dossier()
                return self.request.RESPONSE.redirect(
                    os.path.join(dossier.absolute_url(), '#documents'))

        return grok.View.__call__(self)
    def __call__(self):
        disable_edit_bar()

        if not self.context.has_attachments():
            msg = _(u'error_no_attachments_to_extract',
                    default=u'This mail has no attachments to extract.')
            api.portal.show_message(msg, request=self.request, type='warning')
            return self.request.RESPONSE.redirect(self.context.absolute_url())

        if self.request.get('form.cancelled'):
            return self.request.RESPONSE.redirect(self.context.absolute_url())

        if self.request.get('form.submitted'):
            attachments = self.request.get('attachments')
            if not attachments:
                msg = _(u'error_no_attachments_selected',
                        default=u'You have not selected any attachments.')
                api.portal.show_message(
                    msg, request=self.request, type='error')
            else:
                attachments = [int(pos) for pos in attachments]
                delete_action = self.request.get('delete_action', 'nothing')
                if delete_action not in self.allowed_delete_actions:
                    raise ValueError('Expected delete action to be one of ' +
                                     str(self.allowed_delete_actions))

                self.extract_attachments(attachments, delete_action)
                return self.request.RESPONSE.redirect(
                    "{}/#documents".format(
                        self.context.get_extraction_parent().absolute_url()))

        return super(ExtractAttachments, self).__call__()
Example #10
0
def get_message_source_vocabulary():
    terms = [
        SimpleTerm(MESSAGE_SOURCE_MAILIN,
                   title=_('label_message_source_mailin', default='Mail-in')),
        SimpleTerm(MESSAGE_SOURCE_DRAG_DROP_UPLOAD,
                   title=_('label_message_source_d_n_d_upload',
                           default='Drag and drop upload')),
    ]
    return SimpleVocabulary(terms)
Example #11
0
    def create_mail(self, text='', objs=[], only_links=''):
        """Create the mail and attach the the files. For object without a file
        it include a Link to the Object in to the message"""
        attachment_parts = []
        msg = MIMEMultipart()
        msg['Date'] = formatdate(localtime=True)

        # iterate over object list (which can include documents and mails),
        # create attachement parts for them and prepare docs_links
        docs_links = '%s:\r\n' % (translate(
            _('label_documents', default=u'Documents'), context=self.request))

        for obj in objs:

            if IMail.providedBy(obj):
                obj_file = obj.message
            else:
                obj_file = obj.file

            if only_links or not obj_file:

                # rewrite the url with clients public url
                url = '%s/%s' % (get_current_client().public_url, '/'.join(
                    obj.getPhysicalPath()[2:]))

                docs_links = '%s\r\n - %s (%s)' % (docs_links, obj.title, url)
                continue

            docs_links = '%s\r\n - %s (%s)' % (
                docs_links, obj.title,
                translate(_('label_see_attachment', default=u'see attachment'),
                          context=self.request))

            mimetype = obj_file.contentType
            if not mimetype:
                mimetype = 'application/octet-stream'
            maintype, subtype = obj_file.contentType.split('/', 1)
            part = MIMEBase(maintype, subtype)
            part.set_payload(obj_file.data)
            Encoders.encode_base64(part)
            part.add_header('Content-Disposition',
                            'attachment; filename="%s"' % obj_file.filename)
            attachment_parts.append(part)

        # First, create the text part and attach it to the message ...
        text = '%s\r\n\r\n%s\r\n' % (text.encode(
            CHARSET, 'ignore'), docs_links.encode(CHARSET))

        if not isinstance(text, unicode):
            text = text.decode('utf8')
        msg.attach(MIMEText(text, 'plain', CHARSET))

        # ... then attach all the attachment parts
        for part in attachment_parts:
            msg.attach(part)

        return msg
Example #12
0
def get_message_source_vocabulary():
    terms = [
        SimpleTerm(MESSAGE_SOURCE_MAILIN,
                   title=_('label_message_source_mailin',
                           default='Mail-in')),
        SimpleTerm(MESSAGE_SOURCE_DRAG_DROP_UPLOAD,
                   title=_('label_message_source_d_n_d_upload',
                           default='Drag and drop upload')),
    ]
    return SimpleVocabulary(terms)
Example #13
0
    def create_mail(self, text="", objs=[], only_links=""):
        """Create the mail and attach the the files. For object without a file
        it include a Link to the Object in to the message"""
        attachment_parts = []
        msg = MIMEMultipart()
        msg["Date"] = formatdate(localtime=True)

        # iterate over object list (which can include documents and mails),
        # create attachement parts for them and prepare docs_links
        docs_links = "%s:\r\n" % (translate(_("label_documents", default=u"Documents"), context=self.request))

        for obj in objs:

            if IMail.providedBy(obj):
                obj_file = obj.message
            else:
                obj_file = obj.file

            if only_links or not obj_file:

                # rewrite the url with clients public url
                url = "%s/%s" % (get_current_client().public_url, "/".join(obj.getPhysicalPath()[2:]))

                docs_links = "%s\r\n - %s (%s)" % (docs_links, obj.title, url)
                continue

            docs_links = "%s\r\n - %s (%s)" % (
                docs_links,
                obj.title,
                translate(_("label_see_attachment", default=u"see attachment"), context=self.request),
            )

            mimetype = obj_file.contentType
            if not mimetype:
                mimetype = "application/octet-stream"
            maintype, subtype = obj_file.contentType.split("/", 1)
            part = MIMEBase(maintype, subtype)
            part.set_payload(obj_file.data)
            Encoders.encode_base64(part)
            part.add_header("Content-Disposition", 'attachment; filename="%s"' % obj_file.filename)
            attachment_parts.append(part)

        # First, create the text part and attach it to the message ...
        text = "%s\r\n\r\n%s\r\n" % (text.encode(CHARSET, "ignore"), docs_links.encode(CHARSET))

        if not isinstance(text, unicode):
            text = text.decode("utf8")
        msg.attach(MIMEText(text, "plain", CHARSET))

        # ... then attach all the attachment parts
        for part in attachment_parts:
            msg.attach(part)

        return msg
Example #14
0
class MailTabbedView(GeverTabbedView):
    """Tabbedview for the ftw.mail.mail objects. Provides the following tabs:
    Overview, Preview (configurable), Journal, Sharing.
    """

    overview_tab = {
        'id': 'overview',
        'title': _(u'label_overview', default=u'Overview'),
    }

    journal_tab = {
        'id': 'journal',
        'title': _(u'label_journal', default=u'Journal'),
    }

    sharing_tab = {
        'id': 'sharing',
        'title': _(u'label_sharing', default=u'Sharing'),
    }

    def __init__(self, context, request):
        """Slap a warning onto the overview of a trashed mail.

        We're asserting on the request not having a form as the tabs themselves,
        which get requested by AJAX, rely on a form in the request data. If
        we'd also slap the portal warning onto those requests, the next 'full'
        page view would display them, as the tabs do not consume a portal
        warning.
        """
        super(MailTabbedView, self).__init__(context, request)
        if ITrashed.providedBy(self.context):
            if not self.request.form:
                msg = _(u'warning_trashed', default=u'This mail is trashed.')
                api.portal.show_message(msg, self.request, type='warning')

    @property
    def preview_tab(self):
        if api.portal.get_registry_record(name='preview_tab_visible',
                                          interface=IMailTabbedviewSettings):
            return {
                'id': 'preview',
                'title': _(u'label_preview', default=u'Preview'),
            }

        return None

    def _get_tabs(self):
        return filter(None, [
            self.overview_tab,
            self.preview_tab,
            self.journal_tab,
            self.sharing_tab,
        ])
Example #15
0
 def get_metadata_config(self):
     return [
         FieldRow('title'),
         FieldRow('IDocumentMetadata.document_date'),
         FieldRow('IDocumentMetadata.document_type'),
         FieldRow('IDocumentMetadata.document_author'),
         CustomRow(self.render_creator_link,
                   label=ogdmf('label_creator', default='creator')),
         FieldRow('IDocumentMetadata.description'),
         FieldRow('IDocumentMetadata.foreign_reference'),
         TemplateRow(self.file_template,
                     label=_('label_org_message',
                             default='Original message')),
         FieldRow('IDocumentMetadata.digitally_available'),
         FieldRow('IDocumentMetadata.preserved_as_paper'),
         FieldRow('IDocumentMetadata.receipt_date'),
         FieldRow('IDocumentMetadata.delivery_date'),
         FieldRow('IRelatedDocuments.relatedItems'),
         FieldRow('IClassification.classification'),
         FieldRow('IClassification.privacy_layer'),
         TemplateRow(self.public_trial_template,
                     label=ogbmf('label_public_trial',
                                 default='Public Trial')),
         FieldRow('IClassification.public_trial_statement'),
     ]
Example #16
0
 def file_sent_mail_in_dossier(self, msg):
     dossier = self.context
     mail = createMailInContainer(dossier, msg.as_string())
     mail.delivery_date = date.today()
     mail.reindexObject(idxs=['delivery_date'])
     status_msg = _(u"Sent mail filed as '${title}'.",
                    mapping={'title': mail.title_or_id()})
     IStatusMessage(self.request).addStatusMessage(status_msg, type='info')
Example #17
0
    def preview_tab(self):
        if api.portal.get_registry_record(
                name='preview_tab_visible', interface=IMailTabbedviewSettings):
            return {
                'id': 'preview',
                'title': _(u'label_preview', default=u'Preview'),
            }

        return None
Example #18
0
    def preview_tab(self):
        if api.portal.get_registry_record(name='preview_tab_visible',
                                          interface=IMailTabbedviewSettings):
            return {
                'id': 'preview',
                'title': _(u'label_preview', default=u'Preview'),
            }

        return None
Example #19
0
 def validateHasEmail(self):
     """ check if minium one e-mail-address is given."""
     if len(self.intern_receiver) == 0 and not self.extern_receiver:
         raise NoMail(
             _(
                 u"You have to select a intern \
                         or enter a extern mail-addres"
             )
         )
Example #20
0
 def file_sent_mail_in_dossier(self, msg):
     dossier = self.context
     mail = createMailInContainer(dossier, msg.as_string())
     mail.delivery_date = date.today()
     mail.reindexObject(idxs=['delivery_date'])
     status_msg = _(
         u"Sent mail filed as '${title}'.",
         mapping={'title': mail.title_or_id()})
     IStatusMessage(self.request).addStatusMessage(status_msg, type='info')
Example #21
0
    def send_button_handler(self, action):
        """Create and Send the Email."""
        data, errors = self.extractData()

        if len(errors) == 0:
            mh = getToolByName(self.context, 'MailHost')
            userid = self.context.portal_membership.getAuthenticatedMember()
            userid = userid.getId()
            intern_receiver = []
            for receiver in data.get('intern_receiver', []):
                # cut away the username
                intern_receiver.append(receiver.split(':')[0])

            extern_receiver = data.get('extern_receiver') or []
            addresses = intern_receiver + extern_receiver

            # create the mail
            msg = self.create_mail(
                data.get('message'),
                data.get('documents'),
                only_links=data.get('documents_as_links'))

            msg['Subject'] = Header(data.get('subject'), CHARSET)

            user = ogds_service().fetch_user(userid)
            sender_address = user and user.email
            if not sender_address:
                portal = self.context.portal_url.getPortalObject()
                sender_address = portal.email_from_address

            msg['From'] = make_addr_header(
                user.label(), sender_address, CHARSET)

            header_to = Header(','.join(addresses), CHARSET)
            msg['To'] = header_to

            # send it
            mfrom = u'{} <{}>'.format(
                user.label(), sender_address).encode(CHARSET)
            mh.send(msg, mfrom=mfrom, mto=','.join(addresses))

            # Store a copy of the sent mail in dossier
            if (data.get('file_copy_in_dossier', False)
                    and self._allow_save_file_copy_in_context()):
                self.file_sent_mail_in_dossier(msg)

            # let the user know that the mail was sent
            info = _(u'info_mail_sent', 'E-mail has been sent.')
            notify(DocumentSent(
                    self.context, userid, header_to, data.get('subject'),
                    data.get('message'), data.get('documents')))

            IStatusMessage(self.request).addStatusMessage(info, type='info')
            # and redirect to default view / tab
            return self.request.RESPONSE.redirect(
                get_containing_document_tab_url(data.get('documents')[0]))
Example #22
0
    def send_button_handler(self, action):
        """Create and Send the Email."""
        data, errors = self.extractData()

        if len(errors) == 0:
            mh = getToolByName(self.context, 'MailHost')
            userid = self.context.portal_membership.getAuthenticatedMember()
            userid = userid.getId()
            intern_receiver = []
            for receiver in data.get('intern_receiver', []):
                # cut away the username
                intern_receiver.append(receiver.split(':')[0])

            extern_receiver = data.get('extern_receiver') or []
            addresses = intern_receiver + extern_receiver

            # create the mail
            msg = self.create_mail(
                data.get('message'),
                data.get('documents'),
                only_links=data.get('documents_as_links'))

            msg['Subject'] = Header(data.get('subject'), CHARSET)

            user = ogds_service().fetch_user(userid)
            sender_address = user and user.email
            if not sender_address:
                portal = self.context.portal_url.getPortalObject()
                sender_address = portal.email_from_address

            msg['From'] = make_addr_header(
                user.label(), sender_address, CHARSET)

            header_to = Header(','.join(addresses), CHARSET)
            msg['To'] = header_to

            # send it
            mfrom = u'{} <{}>'.format(
                user.label(), sender_address).encode(CHARSET)
            mh.send(msg, mfrom=mfrom, mto=','.join(addresses))

            # Store a copy of the sent mail in dossier
            if (data.get('file_copy_in_dossier', False)
                    and self._allow_save_file_copy_in_context()):
                self.file_sent_mail_in_dossier(msg)

            # let the user know that the mail was sent
            info = _(u'info_mail_sent', 'E-mail has been sent.')
            notify(DocumentSent(
                    self.context, userid, header_to, data.get('subject'),
                    data.get('message'), data.get('documents')))

            IStatusMessage(self.request).addStatusMessage(info, type='info')
            # and redirect to default view / tab
            return self.request.RESPONSE.redirect(
                get_containing_document_tab_url(data.get('documents')[0]))
Example #23
0
 def get_items(self):
     return [
         {
             "class": "created",
             "label": _("byline_created", default="Created"),
             "content": self.created(),
             "replace": False,
         },
         {
             "class": "sequenceNumber",
             "label": _("label_sequence_number", default="Sequence Number"),
             "content": self.sequence_number(),
             "replace": False,
         },
         {
             "class": "reference_number",
             "label": _("label_reference_number", default="Reference Number"),
             "content": self.reference_number(),
             "replace": False,
         },
     ]
    def extract_attachments(self, positions, delete_action):
        docs = self.context.extract_attachments_into_parent(positions)
        for document in docs:
            msg = _(u'info_extracted_document',
                    default=u'Created document ${title}',
                    mapping={'title': document.Title().decode('utf-8')})
            api.portal.show_message(msg, request=self.request, type='info')

        # delete the attachments from the email message, if needed
        if delete_action == 'selected':
            self.context.delete_attachments(positions)
        elif delete_action == 'all':
            self.context.delete_all_attachments()
Example #25
0
 def get_items(self):
     return [
         {
             'class': 'created',
             'label': _('byline_created', default='Created'),
             'content': self.created(),
             'replace': False
         },
         {
             'class': 'sequenceNumber',
             'label': _('label_sequence_number', default='Sequence Number'),
             'content': self.sequence_number(),
             'replace': False
         },
         {
             'class': 'reference_number',
             'label': _('label_reference_number',
                        default='Reference Number'),
             'content': self.reference_number(),
             'replace': False
         },
     ]
    def extract_attachments(self, positions, delete_action):
        docs = self.context.extract_attachments_into_parent(positions)
        for document in docs:
            msg = _(u'info_extracted_document',
                    default=u'Created document ${title}',
                    mapping={'title': document.Title().decode('utf-8')})
            api.portal.show_message(msg, request=self.request, type='info')

        # delete the attachments from the email message, if needed
        if delete_action == 'selected':
            self.context.delete_attachments(positions)
        elif delete_action == 'all':
            self.context.delete_all_attachments()
Example #27
0
    def send_button_handler(self, action):
        """ create and Send the Email """
        data, errors = self.extractData()

        if len(errors) == 0:
            mh = getToolByName(self.context, 'MailHost')
            contact_info = getUtility(IContactInformation)
            userid = self.context.portal_membership.getAuthenticatedMember()
            userid = userid.getId()
            intern_receiver = []
            for receiver in data.get('intern_receiver', []):
                # cut away the username
                intern_receiver.append(receiver.split(':')[0])

            extern_receiver = data.get('extern_receiver') or []
            addresses = intern_receiver + extern_receiver

            # create the mail
            msg = self.create_mail(
                data.get('message'),
                data.get('documents'),
                only_links=data.get('documents_as_links'))

            msg['Subject'] = Header(data.get('subject'), CHARSET)
            sender_address = contact_info.get_email(userid)
            if not sender_address:
                portal = self.context.portal_url.getPortalObject()
                sender_address = portal.email_from_address

            mail_from = '%s <%s>' % (
                    contact_info.describe(userid).encode(CHARSET),
                    sender_address.encode(CHARSET))

            msg['From'] = Header(mail_from, CHARSET)

            header_to = Header(','.join(addresses), CHARSET)
            msg['To'] = header_to

            # send it
            mh.send(msg, mfrom=mail_from, mto=','.join(addresses))

            # let the user know that the mail was sent
            info = _(u'info_mails_sent', 'Mails sent')
            notify(DocumentSent(
                    self.context, userid, header_to, data.get('subject'),
                    data.get('message'), data.get('documents')))

            IStatusMessage(self.request).addStatusMessage(info, type='info')
            # and redirect to default view / tab
            return self.request.RESPONSE.redirect(
                get_containg_document_tab_url(data.get('documents')[0]))
Example #28
0
class MailTabbedView(GeverTabbedView):
    """Tabbedview for the ftw.mail.mail objects. Provides the following tabs:
    Overview, Preview (configurable), Journal, Sharing.
    """

    overview_tab = {
        'id': 'overview',
        'title': _(u'label_overview', default=u'Overview'),
    }

    journal_tab = {
        'id': 'journal',
        'title': _(u'label_journal', default=u'Journal'),
    }

    sharing_tab = {
        'id': 'sharing',
        'title': _(u'label_sharing', default=u'Sharing'),
    }

    @property
    def preview_tab(self):
        if api.portal.get_registry_record(name='preview_tab_visible',
                                          interface=IMailTabbedviewSettings):
            return {
                'id': 'preview',
                'title': _(u'label_preview', default=u'Preview'),
            }

        return None

    def _get_tabs(self):
        return filter(None, [
            self.overview_tab,
            self.preview_tab,
            self.journal_tab,
            self.sharing_tab,
        ])
Example #29
0
    def send_button_handler(self, action):
        """ create and Send the Email """
        data, errors = self.extractData()

        if len(errors) == 0:
            mh = getToolByName(self.context, 'MailHost')
            contact_info = getUtility(IContactInformation)
            userid = self.context.portal_membership.getAuthenticatedMember()
            userid = userid.getId()
            intern_receiver = []
            for receiver in data.get('intern_receiver', []):
                # cut away the username
                intern_receiver.append(receiver.split(':')[0])

            extern_receiver = data.get('extern_receiver') or []
            addresses = intern_receiver + extern_receiver

            # create the mail
            msg = self.create_mail(data.get('message'),
                                   data.get('documents'),
                                   only_links=data.get('documents_as_links'))

            msg['Subject'] = Header(data.get('subject'), CHARSET)
            sender_address = contact_info.get_user(userid).email
            if not sender_address:
                portal = self.context.portal_url.getPortalObject()
                sender_address = portal.email_from_address

            mail_from = '%s <%s>' % (contact_info.describe(userid).encode(
                CHARSET), sender_address.encode(CHARSET))

            msg['From'] = Header(mail_from, CHARSET)

            header_to = Header(','.join(addresses), CHARSET)
            msg['To'] = header_to

            # send it
            mh.send(msg, mfrom=mail_from, mto=','.join(addresses))

            # let the user know that the mail was sent
            info = _(u'info_mails_sent', 'Mails sent')
            notify(
                DocumentSent(self.context, userid, header_to,
                             data.get('subject'), data.get('message'),
                             data.get('documents')))

            IStatusMessage(self.request).addStatusMessage(info, type='info')
            # and redirect to default view / tab
            return self.request.RESPONSE.redirect(
                get_containg_document_tab_url(data.get('documents')[0]))
Example #30
0
    def __init__(self, context, request):
        """Slap a warning onto the overview of a trashed mail.

        We're asserting on the request not having a form as the tabs themselves,
        which get requested by AJAX, rely on a form in the request data. If
        we'd also slap the portal warning onto those requests, the next 'full'
        page view would display them, as the tabs do not consume a portal
        warning.
        """
        super(MailTabbedView, self).__init__(context, request)
        if ITrashed.providedBy(self.context):
            if not self.request.form:
                msg = _(u'warning_trashed', default=u'This mail is trashed.')
                api.portal.show_message(msg, self.request, type='warning')
Example #31
0
    def __init__(self, context, request):
        """Slap a warning onto the overview of a trashed mail.

        We're asserting on the request not having a form as the tabs themselves,
        which get requested by AJAX, rely on a form in the request data. If
        we'd also slap the portal warning onto those requests, the next 'full'
        page view would display them, as the tabs do not consume a portal
        warning.
        """
        super(MailTabbedView, self).__init__(context, request)
        if ITrashed.providedBy(self.context):
            if not self.request.form:
                msg = _(u'warning_trashed', default=u'This mail is trashed.')
                api.portal.show_message(msg, self.request, type='warning')
Example #32
0
    def updateWidgets(self):
        super(SendDocumentForm, self).updateWidgets()

        if not self._allow_save_file_copy_in_context():
            file_copy_widget = self.widgets['file_copy_in_dossier']
            disabled_hint_text = translate(
                _(u'file_copy_widget_disabled_hint_text',
                  default='(only possible for open dossiers)'),
                context=self.request)

            file_copy_widget.value = []
            checkbox = file_copy_widget.items[0]
            checkbox['label'] = u'{} {}'.format(
                checkbox['label'], disabled_hint_text)
            file_copy_widget.disabled = 'disabled'
Example #33
0
    def updateWidgets(self):
        super(SendDocumentForm, self).updateWidgets()

        if not self._allow_save_file_copy_in_context():
            file_copy_widget = self.widgets['file_copy_in_dossier']
            disabled_hint_text = translate(
                _(u'file_copy_widget_disabled_hint_text',
                  default='(only possible for open dossiers)'),
                context=self.request)

            file_copy_widget.value = []
            checkbox = file_copy_widget.items[0]
            checkbox['label'] = u'{} {}'.format(
                checkbox['label'], disabled_hint_text)
            file_copy_widget.disabled = 'disabled'
Example #34
0
class SendDocumentForm(form.Form):
    """A form to send documents over mail with."""

    fields = field.Fields(ISendDocumentSchema)
    ignoreContext = True
    label = _('heading_send_as_email', default="Send as email")

    fields['extern_receiver'].widgetFactory[INPUT_MODE] \
        = TextLinesFieldWidget
    fields['intern_receiver'].widgetFactory[INPUT_MODE] = ParameterizedWidget(
        KeywordWidget,
        async=True)

    fields['documents_as_links'].widgetFactory[INPUT_MODE] \
        = SingleCheckBoxFieldWidget

    def update(self):
        """Put default value for documents field, into the request,
        because this view would call from the document tab in the dossier view
        """
        paths = self.request.get('paths', [])
        if paths:
            self.request.set('form.widgets.documents', paths)

        super(SendDocumentForm, self).update()

    def updateWidgets(self):
        super(SendDocumentForm, self).updateWidgets()

        if not self._allow_save_file_copy_in_context():
            file_copy_widget = self.widgets['file_copy_in_dossier']
            disabled_hint_text = translate(
                _(u'file_copy_widget_disabled_hint_text',
                  default='(only possible for open dossiers)'),
                context=self.request)

            file_copy_widget.value = []
            checkbox = file_copy_widget.items[0]
            checkbox['label'] = u'{} {}'.format(
                checkbox['label'], disabled_hint_text)
            file_copy_widget.disabled = 'disabled'

    @button.buttonAndHandler(_(u'button_send', default=u'Send'))
    def send_button_handler(self, action):
        """Create and Send the Email."""
        data, errors = self.extractData()

        if len(errors) == 0:
            mh = getToolByName(self.context, 'MailHost')
            userid = self.context.portal_membership.getAuthenticatedMember()
            userid = userid.getId()
            intern_receiver = []
            for receiver in data.get('intern_receiver', []):
                # cut away the username
                intern_receiver.append(receiver.split(':')[0])

            extern_receiver = data.get('extern_receiver') or []
            addresses = intern_receiver + extern_receiver

            # create the mail
            msg = self.create_mail(
                data.get('message'),
                data.get('documents'),
                only_links=data.get('documents_as_links'))

            msg['Subject'] = Header(data.get('subject'), CHARSET)

            user = ogds_service().fetch_user(userid)
            sender_address = user and user.email
            if not sender_address:
                portal = self.context.portal_url.getPortalObject()
                sender_address = portal.email_from_address

            msg['From'] = make_addr_header(
                user.label(), sender_address, CHARSET)

            header_to = Header(','.join(addresses), CHARSET)
            msg['To'] = header_to

            # send it
            mfrom = u'{} <{}>'.format(
                user.label(), sender_address).encode(CHARSET)
            mh.send(msg, mfrom=mfrom, mto=','.join(addresses))

            # Store a copy of the sent mail in dossier
            if (data.get('file_copy_in_dossier', False)
                    and self._allow_save_file_copy_in_context()):
                self.file_sent_mail_in_dossier(msg)

            # let the user know that the mail was sent
            info = _(u'info_mail_sent', 'E-mail has been sent.')
            notify(DocumentSent(
                    self.context, userid, header_to, data.get('subject'),
                    data.get('message'), data.get('documents')))

            IStatusMessage(self.request).addStatusMessage(info, type='info')
            # and redirect to default view / tab
            return self.request.RESPONSE.redirect(
                get_containing_document_tab_url(data.get('documents')[0]))

    @button.buttonAndHandler(_('cancel_back', default=u'Cancel'))
    def cancel_button_handler(self, action):
        data, errors = self.extractData()

        if data.get('documents'):
            url = get_containing_document_tab_url(data.get('documents')[0])
        else:
            url = get_containing_document_tab_url(self.context)

        return self.request.RESPONSE.redirect(url)

    def create_mail(self, text='', objs=[], only_links=''):
        """Create the mail and attach the the files.

        For object without a file it include a Link to the Object in to the
        message.
        """
        attachment_parts = []
        msg = MIMEMultipart()
        msg['Date'] = formatdate(localtime=True)

        # iterate over object list (which can include documents and mails),
        # create attachement parts for them and prepare docs_links
        docs_links = '%s:\r\n' % (translate(
                _('label_documents', default=u'Attachments'),
                context=self.request))

        for obj in objs:

            if IMail.providedBy(obj):
                obj_file = obj.message
            else:
                obj_file = obj.file

            if only_links or not obj_file:
                # rewrite the url with current adminunit's public url
                url = '%s/%s' % (
                    get_current_admin_unit().public_url,
                    '/'.join(obj.getPhysicalPath()[2:]))

                docs_links = '%s\r\n - %s (%s)' % (
                    docs_links, obj.title, url)
                continue

            docs_links = '%s\r\n - %s (%s)' % (
                docs_links,
                obj.title,
                translate(
                    _('label_see_attachment', default=u'see attachment'),
                    context=self.request))

            mimetype = obj_file.contentType
            if not mimetype:
                mimetype = 'application/octet-stream'
            maintype, subtype = obj_file.contentType.split('/', 1)
            part = MIMEBase(maintype, subtype)
            part.set_payload(obj_file.data)
            if mimetype != 'message/rfc822':
                Encoders.encode_base64(part)
            part.add_header('Content-Disposition', 'attachment; filename="%s"'
                            % obj_file.filename)
            attachment_parts.append(part)

        # First, create the text part and attach it to the message ...
        text = '%s\r\n\r\n%s\r\n' % (
            text.encode(CHARSET, 'ignore'),
            docs_links.encode(CHARSET))

        if not isinstance(text, unicode):
            text = text.decode('utf8')
        msg.attach(MIMEText(text, 'plain', CHARSET))

        # ... then attach all the attachment parts
        for part in attachment_parts:
            msg.attach(part)

        return msg

    def file_sent_mail_in_dossier(self, msg):
        dossier = self.context
        mail = createMailInContainer(dossier, msg.as_string())
        mail.delivery_date = date.today()
        mail.reindexObject(idxs=['delivery_date'])
        status_msg = _(
            u"Sent mail filed as '${title}'.",
            mapping={'title': mail.title_or_id()})
        IStatusMessage(self.request).addStatusMessage(status_msg, type='info')

    def _allow_save_file_copy_in_context(self):
        """The field file_copy_in_dossier should not be allowed for closed
        dossiers or on all other contenttypes (i.e. the Inbox).
        """
        if IDossierMarker.providedBy(self.context):
            return self.context.is_open()
        return False
Example #35
0
 def validateHasEmail(self):
     """Check if minium one e-mail-address is given."""
     if len(self.intern_receiver) == 0 and not self.extern_receiver:
         raise NoMail(_(u'You have to select a intern \
                         or enter a extern mail-addres'))
Example #36
0
def create_initial_journal_entry(mail):
    title = _(
        u'label_journal_initialized',
        default=u'Journal initialized')
    journal_entry_factory(mail, 'Journal initialized', title)
Example #37
0
class ISendDocumentSchema(Interface):
    """The Send Document Form Schema."""

    intern_receiver = schema.Tuple(
        title=_('intern_receiver', default="Intern receiver"),
        description=_('help_intern_receiver',
                      default="Live Search: search for users and contacts"),

        value_type=schema.Choice(
            title=_(u"mails"),
            source=AllEmailContactsAndUsersSourceBinder()),
        required=False,
        missing_value=(),  # important!
        default=(),
        )

    extern_receiver = schema.List(
        title=_('extern_receiver', default="Extern receiver"),
        description=_('help_extern_receiver',
                      default="email addresses of the receivers. "
                      "Enter manually the addresses, one per each line."),
        value_type=schema.TextLine(title=_('receiver'), ),
        required=False,
        )

    subject = schema.TextLine(
        title=_(u'label_subject', default=u'Subject'),
        required=True,
        )

    message = schema.Text(
        title=_(u'label_message', default=u'Message'),
        required=True,
        )

    documents = RelationList(
        title=_(u'label_documents', default=u'Attachments'),
        default=[],
        missing_value=[],
        value_type=RelationChoice(
            title=u"Documents",
            source=DossierPathSourceBinder(
                portal_type=("opengever.document.document", "ftw.mail.mail"),
                navigation_tree_query={
                    'object_provides':
                        ['opengever.dossier.behaviors.dossier.IDossierMarker',
                         'opengever.task.task.ITask',
                         'opengever.document.document.IDocumentSchema',
                         'ftw.mail.mail.IMail',
                         ]}),
            ),
        required=False,
        )

    documents_as_links = schema.Bool(
        title=_(u'label_documents_as_link',
                default=u'Send documents only als links'),
        required=True,
        )

    file_copy_in_dossier = schema.Bool(
        title=_(u'label_file_copy_in_dossier',
                default=u'File a copy of the sent mail in dossier'),
        required=True,
        default=True,
        )

    @invariant
    def validateHasEmail(self):
        """Check if minium one e-mail-address is given."""
        if len(self.intern_receiver) == 0 and not self.extern_receiver:
            raise NoMail(_(u'You have to select a intern \
                            or enter a extern mail-addres'))
Example #38
0
class SendDocumentForm(form.Form):
    """ The Send Documents per Mail Formular """

    fields = field.Fields(ISendDocumentSchema)
    ignoreContext = True
    label = _('heading_send_as_email', default="Send as email")

    fields['extern_receiver'].widgetFactory[INPUT_MODE] \
        = TextLinesFieldWidget
    fields['intern_receiver'].widgetFactory[INPUT_MODE] \
        = AutocompleteMultiFieldWidget
    fields['documents_as_links'].widgetFactory[INPUT_MODE] \
        = SingleCheckBoxFieldWidget

    def update(self):
        """ put default value for documents field, into the request,

        because this view would call from the document tab in the dossier view

        """
        paths = self.request.get('paths', [])
        if paths:
            self.request.set('form.widgets.documents', paths)
        super(SendDocumentForm, self).update()

    @button.buttonAndHandler(_(u'button_send', default=u'Send'))
    def send_button_handler(self, action):
        """ create and Send the Email """
        data, errors = self.extractData()

        if len(errors) == 0:
            mh = getToolByName(self.context, 'MailHost')
            contact_info = getUtility(IContactInformation)
            userid = self.context.portal_membership.getAuthenticatedMember()
            userid = userid.getId()
            intern_receiver = []
            for receiver in data.get('intern_receiver', []):
                # cut away the username
                intern_receiver.append(receiver.split(':')[0])

            extern_receiver = data.get('extern_receiver') or []
            addresses = intern_receiver + extern_receiver

            # create the mail
            msg = self.create_mail(data.get('message'),
                                   data.get('documents'),
                                   only_links=data.get('documents_as_links'))

            msg['Subject'] = Header(data.get('subject'), CHARSET)
            sender_address = contact_info.get_user(userid).email
            if not sender_address:
                portal = self.context.portal_url.getPortalObject()
                sender_address = portal.email_from_address

            mail_from = '%s <%s>' % (contact_info.describe(userid).encode(
                CHARSET), sender_address.encode(CHARSET))

            msg['From'] = Header(mail_from, CHARSET)

            header_to = Header(','.join(addresses), CHARSET)
            msg['To'] = header_to

            # send it
            mh.send(msg, mfrom=mail_from, mto=','.join(addresses))

            # let the user know that the mail was sent
            info = _(u'info_mails_sent', 'Mails sent')
            notify(
                DocumentSent(self.context, userid, header_to,
                             data.get('subject'), data.get('message'),
                             data.get('documents')))

            IStatusMessage(self.request).addStatusMessage(info, type='info')
            # and redirect to default view / tab
            return self.request.RESPONSE.redirect(
                get_containg_document_tab_url(data.get('documents')[0]))

    @button.buttonAndHandler(_('cancel_back', default=u'Cancel'))
    def cancel_button_handler(self, action):
        data, errors = self.extractData()

        if data.get('documents'):
            url = get_containg_document_tab_url(data.get('documents')[0])
        else:
            url = get_containg_document_tab_url(self.context)

        return self.request.RESPONSE.redirect(url)

    def create_mail(self, text='', objs=[], only_links=''):
        """Create the mail and attach the the files. For object without a file
        it include a Link to the Object in to the message"""
        attachment_parts = []
        msg = MIMEMultipart()
        msg['Date'] = formatdate(localtime=True)

        # iterate over object list (which can include documents and mails),
        # create attachement parts for them and prepare docs_links
        docs_links = '%s:\r\n' % (translate(
            _('label_documents', default=u'Documents'), context=self.request))

        for obj in objs:

            if IMail.providedBy(obj):
                obj_file = obj.message
            else:
                obj_file = obj.file

            if only_links or not obj_file:

                # rewrite the url with clients public url
                url = '%s/%s' % (get_current_client().public_url, '/'.join(
                    obj.getPhysicalPath()[2:]))

                docs_links = '%s\r\n - %s (%s)' % (docs_links, obj.title, url)
                continue

            docs_links = '%s\r\n - %s (%s)' % (
                docs_links, obj.title,
                translate(_('label_see_attachment', default=u'see attachment'),
                          context=self.request))

            mimetype = obj_file.contentType
            if not mimetype:
                mimetype = 'application/octet-stream'
            maintype, subtype = obj_file.contentType.split('/', 1)
            part = MIMEBase(maintype, subtype)
            part.set_payload(obj_file.data)
            Encoders.encode_base64(part)
            part.add_header('Content-Disposition',
                            'attachment; filename="%s"' % obj_file.filename)
            attachment_parts.append(part)

        # First, create the text part and attach it to the message ...
        text = '%s\r\n\r\n%s\r\n' % (text.encode(
            CHARSET, 'ignore'), docs_links.encode(CHARSET))

        if not isinstance(text, unicode):
            text = text.decode('utf8')
        msg.attach(MIMEText(text, 'plain', CHARSET))

        # ... then attach all the attachment parts
        for part in attachment_parts:
            msg.attach(part)

        return msg
Example #39
0
class NoMail(Invalid):
    """ The No Mail was defined Exception."""
    __doc__ = _(u"No Mail Address")
    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)
Example #41
0
class NoMail(Invalid):
    """This is a dummy class to raise an exception in the lack of a mail
    address.
    """

    __doc__ = _(u"No Mail Address")
Example #42
0
class FilesTooLarge(schema.interfaces.ValidationError):
    """ Total size of selected files is too large. """

    __doc__ = _(u"The files you selected are larger than the maximum size")
Example #43
0
    def create_mail(self, text='', objs=[], only_links=''):
        """Create the mail and attach the the files.

        For object without a file it include a Link to the Object in to the
        message.
        """
        attachment_parts = []
        msg = MIMEMultipart()
        msg['Date'] = formatdate(localtime=True)

        # iterate over object list (which can include documents and mails),
        # create attachement parts for them and prepare docs_links
        docs_links = '%s:\r\n' % (translate(
                _('label_documents', default=u'Attachments'),
                context=self.request))

        for obj in objs:
            obj_file = obj.get_file()

            if only_links or not obj_file:
                # rewrite the url with current adminunit's public url
                url = '%s/%s' % (
                    get_current_admin_unit().public_url,
                    '/'.join(obj.getPhysicalPath()[2:]))

                docs_links = '%s\r\n - %s (%s)' % (
                    docs_links, obj.title, url)
                continue

            docs_links = '%s\r\n - %s (%s)' % (
                docs_links,
                obj.title,
                translate(
                    _('label_see_attachment', default=u'see attachment'),
                    context=self.request))

            mimetype = obj_file.contentType
            if not mimetype:
                mimetype = 'application/octet-stream'
            maintype, subtype = obj_file.contentType.split('/', 1)
            part = MIMEBase(maintype, subtype)
            part.set_payload(obj_file.data)
            if mimetype != 'message/rfc822':
                Encoders.encode_base64(part)
            part.add_header('Content-Disposition', 'attachment; filename="%s"'
                            % obj_file.filename)
            attachment_parts.append(part)

        # First, create the text part and attach it to the message ...
        text = '%s\r\n\r\n%s\r\n' % (
            text.encode(CHARSET, 'ignore'),
            docs_links.encode(CHARSET))

        if not isinstance(text, unicode):
            text = text.decode('utf8')
        msg.attach(MIMEText(text, 'plain', CHARSET))

        # ... then attach all the attachment parts
        for part in attachment_parts:
            msg.attach(part)

        return msg
    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)