Exemple #1
0
    def validate(self, value):
        """The document must either have a digital file or be preserved
        in paper form.

        XXX: This validator is a hack, since it validates field values across
        schemata using request.form instead of `value`.
        """
        # Bail if not called during a regular add form
        if self.request.form == {}:
            return

        # Mails are always available in digital form
        if IMail.providedBy(self.context):
            return

        form = self.view.parentForm
        if getattr(form, 'skip_validate_file_field', False):
            return

        if not any([
                self.has_file(),
                self.is_preserved_as_paper(),
                self.has_referenced_document()
        ]):
            raise Invalid(
                _(u'error_file_and_preserved_as_paper',
                  default=u"You don't select a file and document is also not "
                  u"preserved in paper_form, please correct it."))
Exemple #2
0
    def cancel(self, obj):
        """Cancels a single document checkout.
        """
        if IMail.providedBy(obj):
            msg = _(u'msg_cancel_checkout_on_mail_not_possible',
                    default=u'Could not cancel checkout on document ${title}, '
                    'mails does not support the checkin checkout process.',
                    mapping={'title': obj.Title().decode('utf-8')})
            api.portal.show_message(
                message=msg, request=self.request, type='error')
            return

        # check out the document
        manager = getMultiAdapter((obj, self.request),
                                  ICheckinCheckoutManager)

        # is cancel allowed for this document?
        if not manager.is_cancel_allowed():
            msg = _(u'Could not cancel checkout on document ${title}',
                    mapping=dict(title=obj.Title().decode('utf-8')))
            api.portal.show_message(
                message=msg, request=self.request, type='error')

        else:
            manager.cancel()
            # notify the user
            msg = _(u'Cancel checkout: ${title}',
                    mapping={'title': obj.Title().decode('utf-8')})
            api.portal.show_message(
                message=msg, request=self.request, type='info')
Exemple #3
0
    def validate(self, value):
        """The document must either have a digital file or be preserved
        in paper form.

        XXX: This validator is a hack, since it validates field values across
        schemata using request.form instead of `value`.
        """
        # Bail if not called during a regular add form
        if self.request.form == {}:
            return

        # Mails are always available in digital form
        if IMail.providedBy(self.context):
            return

        form = self.view.parentForm
        if getattr(form, 'skip_validate_file_field', False):
            return

        if not any([self.has_file(),
                    self.is_preserved_as_paper(),
                    self.has_referenced_document()]):
            raise Invalid(
                _(u'error_file_and_preserved_as_paper',
                  default=u"You don't select a file and document is also not "
                          u"preserved in paper_form, please correct it."))
    def cancel(self, obj):
        """Cancels a single document checkout.
        """
        if IMail.providedBy(obj):
            msg = _(u'msg_cancel_checkout_on_mail_not_possible',
                    default=u'Could not cancel checkout on document ${title}, '
                    'mails does not support the checkin checkout process.',
                    mapping={'title': obj.Title().decode('utf-8')})
            api.portal.show_message(message=msg,
                                    request=self.request,
                                    type='error')
            return

        # check out the document
        manager = getMultiAdapter((obj, self.request), ICheckinCheckoutManager)

        # is cancel allowed for this document?
        if not manager.is_cancel_allowed():
            msg = _(u'Could not cancel checkout on document ${title}.',
                    mapping=dict(title=obj.Title().decode('utf-8')))
            api.portal.show_message(message=msg,
                                    request=self.request,
                                    type='error')

        else:
            manager.cancel()
            # notify the user
            msg = _(u'Cancel checkout: ${title}',
                    mapping={'title': obj.Title().decode('utf-8')})
            api.portal.show_message(message=msg,
                                    request=self.request,
                                    type='info')
    def test_returns_none_if_document_has_no_file(self):
        self.login(self.regular_user)
        IMail(self.mail_eml).message = None
        adapter = getMultiAdapter((self.mail_eml, self.request),
                                  IBumblebeeOverlay)

        self.assertIsNone(adapter.get_file())
Exemple #6
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
    def test_handles_non_ascii_characters_in_filename(self):
        self.login(self.regular_user)

        IMail(self.mail).message.filename = u'GEVER - \xdcbernahme.msg'

        adapter = getMultiAdapter((self.mail, self.request), IBumblebeeOverlay)
        self.assertEqual(
            u'http://nohost/plone/ordnungssystem/fuhrung/vertrage-und-vereinbarungen/dossier-1/document-11/bumblebee-open-pdf?filename=GEVER%20-%20%C3%9Cbernahme.pdf',
            adapter.get_open_as_pdf_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
Exemple #9
0
    def test_handles_non_ascii_characters_in_filename(self):
        self.login(self.regular_user)
        IMail(self.mail_eml).message.filename = u'GEVER - \xdcbernahme.msg'
        view = api.content.get_view('tabbedview_view-overview',
                                    self.mail_eml, self.request)

        expected_url = (
            u'http://nohost/plone/ordnungssystem/fuhrung'
            u'/vertrage-und-vereinbarungen/dossier-1/document-29'
            u'/bumblebee-open-pdf?filename=GEVER%20-%20%C3%9Cbernahme.pdf'
            )

        self.assertEqual(expected_url, view.get_open_as_pdf_url())
Exemple #10
0
 def validate(self, value):
     if value:
         if self.request.get(
             'form.widgets.documents_as_links') != ['selected']:
             registry = queryUtility(IRegistry)
             reg_proxy = registry.forInterface(ISendDocumentConf)
             total = 0
             for obj in value:
                 #check if its a mail
                 if IMail.providedBy(obj):
                     total += obj.message.getSize()
                 elif obj.file:
                     total += obj.file.getSize()
             if total > (reg_proxy.max_size * 1000000):
                 raise FilesTooLarge()
     else:
         raise schema.interfaces.RequiredMissing()
Exemple #11
0
    def _handle_store_batch(self, brains):
        """This function stores the documents and their versions in bumblebee.

        It decides if a document has to be updated  depending on its
        conversion timestamp and updates the timestamp after storing the
        document.

        Track the checksums locally by batch first and only add them to the
        global set once the transaction has been commited. Otherwise we would
        skip storing objects in case a conflict occurs.
        """
        batch_checksums = set()
        objs_to_store = []

        for brain in brains:
            obj = brain.getObject()

            if not self.needs_update(obj, self.timestamp):
                continue

            self._prepare_store_batch(obj, objs_to_store, batch_checksums)

            # don't attempt to store versions for mails, mails should not have
            # versions. in some cases they do nevertheless and then iterating
            # over versions may fail utterly. we don't like that thus we
            # avoid that it happens.
            # XXX should be fixed properly by making sure mails don't have
            # versions, ever.
            if IMail.providedBy(obj):
                continue

            for versiondata in self.prtool.getHistory(obj):
                self._prepare_store_batch(versiondata.object, objs_to_store,
                                          batch_checksums)

        self._store_batch(objs_to_store)
        for obj in objs_to_store:
            self.set_conversion_timestamp(obj, self.timestamp)

        return batch_checksums
Exemple #12
0
    def _handle_store_batch(self, brains):
        """This function stores the documents and their versions in bumblebee.

        It decides if a document has to be updated  depending on its
        conversion timestamp and updates the timestamp after storing the
        document.

        Track the checksums locally by batch first and only add them to the
        global set once the transaction has been commited. Otherwise we would
        skip storing objects in case a conflict occurs.
        """
        batch_checksums = set()
        objs_to_store = []

        for brain in brains:
            obj = brain.getObject()

            if not self.needs_update(obj, self.timestamp):
                continue

            self._prepare_store_batch(obj, objs_to_store, batch_checksums)

            # don't attempt to store versions for mails, mails should not have
            # versions. in some cases they do nevertheless and then iterating
            # over versions may fail utterly. we don't like that thus we
            # avoid that it happens.
            # XXX should be fixed properly by making sure mails don't have
            # versions, ever.
            if IMail.providedBy(obj):
                continue

            for versiondata in self.prtool.getHistory(obj):
                self._prepare_store_batch(
                    versiondata.object, objs_to_store, batch_checksums)

        self._store_batch(objs_to_store)
        for obj in objs_to_store:
            self.set_conversion_timestamp(obj, self.timestamp)

        return batch_checksums
def recursive_find_uncatalogued_mails(parent, catalog, max_depth=None, depth=0):
    """Recursively traverse content starting at parent and find
    uncatalogued mails.
    """

    if max_depth and depth > max_depth:
        return
    if not hasattr(parent, 'objectItems'):
        return

    try:
        items = parent.objectItems()
    except:
        return

    for ident, item in items:
        if IMail.providedBy(item):
            path = '/'.join(item.getPhysicalPath())
            nof_results = len(catalog.unrestrictedSearchResults({'path': path}))
            if nof_results != 1:
                print "{} result(s) for: {}".format(nof_results, path)
        recursive_find_uncatalogued_mails(item, catalog,
                                          max_depth=max_depth, depth=depth+1)
Exemple #14
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 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 test_returns_false_if_mail_has_no_file(self):
        self.login(self.regular_user)
        IMail(self.mail).message = None

        adapter = getMultiAdapter((self.mail, self.request), IBumblebeeOverlay)
        self.assertFalse(adapter.has_file())
Exemple #16
0
from zope.lifecycleevent.interfaces import IObjectCreatedEvent
from zope.lifecycleevent.interfaces import IObjectModifiedEvent
import os
import re


from plone.namedfile.interfaces import HAVE_BLOBS
if HAVE_BLOBS:
    from plone.namedfile import NamedBlobFile as NamedFile
else:
    from plone.namedfile import NamedFile


IMail.setTaggedValue(FIELDSETS_KEY, [
    Fieldset('common',
             label=base_mf(u'fieldset_common', u'Common'),
             fields=[u'message'])
])


class IOGMailMarker(Interface):
    """Marker Interface for opengever mails."""


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'),
Exemple #17
0
if HAVE_BLOBS:
    from plone.namedfile import NamedBlobFile as NamedFile
else:
    from plone.namedfile import NamedFile


MESSAGE_SOURCE_DRAG_DROP_UPLOAD = 'upload'
MESSAGE_SOURCE_MAILIN = 'mailin'
NO_SUBJECT_FALLBACK_ID = 'no_subject'
NO_SUBJECT_TITLE_FALLBACK = '[No Subject]'


IMail.setTaggedValue(FIELDSETS_KEY, [
    Fieldset('common',
             label=base_mf(u'fieldset_common', u'Common'),
             fields=[u'message'])
])


class IOGMailMarker(Interface):
    """Marker Interface for opengever mails."""


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',
Exemple #18
0
 def change_mail_data(self, mail, data):
     old_file = IMail(self.mail).message
     IMail(self.mail).message = NamedBlobFile(data=data,
                                              filename=old_file.filename)
Exemple #19
0
 def test_factory(self):
     fti = queryUtility(IDexterityFTI, name='ftw.mail.mail')
     factory = fti.factory
     new_object = createObject(factory)
     self.failUnless(IMail.providedBy(new_object))
     self.assertEquals(u'no_subject', new_object.title)
Exemple #20
0
    def test_adding(self):
        mail = create(Builder('mail'))
        self.failUnless(IMail.providedBy(mail))

        self.assertEquals(u'no_subject', mail.title)