Beispiel #1
0
    def validate_response_id(self):
        """Validate the response id from the request.

        Return -1 if for example the response id does not exist.
        Return the response id otherwise.

        Side effect: an informative status message is set.
        """
        status = IStatusMessage(self.request)
        response_id = self.request.form.get('response_id', None)
        ts = getGlobalTranslationService()
        if response_id is None:
            msg = _(u"No response selected.")
            msg = ts.translate('Poi', msg, context=self.context)
            status.addStatusMessage(msg, type='error')
            return -1
        else:
            try:
                response_id = int(response_id)
            except ValueError:
                msg = _(u"Response id ${response_id} is no integer.",
                        mapping=dict(response_id=response_id))
                msg = ts.translate('Poi', msg, context=self.context)
                status.addStatusMessage(msg, type='error')
                return -1
            if response_id >= len(self.folder):
                msg = _(u"Response id ${response_id} does not exist.",
                        mapping=dict(response_id=response_id))
                msg = ts.translate('Poi', msg, context=self.context)
                status.addStatusMessage(msg, type='error')
                return -1
            else:
                return response_id
        # fallback
        return -1
Beispiel #2
0
    def __call__(self):
        context = aq_inner(self.context)
        request = self.request
        response_id = self.validate_response_id()
        file = None
        if response_id != -1:
            response = self.folder[response_id]
            file = response.attachment
            if file is None:
                status = IStatusMessage(request)
                ts = getGlobalTranslationService()
                msg = _(u"Response id ${response_id} has no attachment.",
                        mapping=dict(response_id=response_id))
                msg = ts.translate('Poi', msg, context=context)
                status.addStatusMessage(msg, type='error')
        if file is None:
            request.response.redirect(context.absolute_url())

        # From now on file exists.
        # Code mostly taken from Archetypes/Field.py:FileField.download
        filename = getattr(file, 'filename', file.getId())
        if filename is not None:
            if FILE_NORMALIZER:
                filename = IUserPreferredFileNameNormalizer(request).normalize(
                    safe_unicode(filename, context.getCharset()))
            else:
                filename = safe_unicode(filename, context.getCharset())
            header_value = contentDispositionHeader(
                disposition='attachment',
                filename=filename)
            request.response.setHeader("Content-disposition", header_value)
        return file.index_html(request, request.response)
Beispiel #3
0
 def translate(self, msgid, domain=None, mapping=None, default=None):
     context = self.contexts.get('context')
     return getGlobalTranslationService().translate(domain,
                                                    msgid,
                                                    mapping=mapping,
                                                    context=context,
                                                    default=default)
Beispiel #4
0
def translate(message, context):
    """ Translate i18n message.
    """
    GTS = getGlobalTranslationService()
    if isinstance(message, Exception):
        try:
            message = message[0]
        except (TypeError, IndexError):
            pass
    return GTS.translate('cmf_default', message, context=context)
Beispiel #5
0
    def __call__(self):
        context = aq_inner(self.context)
        status = IStatusMessage(self.request)
        ts = getGlobalTranslationService()

        if not self.can_delete_response:
            msg = _(u"You are not allowed to delete responses.")
            msg = ts.translate('Poi', msg, context=context)
            status.addStatusMessage(msg, type='error')
        else:
            response_id = self.request.form.get('response_id', None)
            if response_id is None:
                msg = _(u"No response selected for removal.")
                msg = ts.translate('Poi', msg, context=context)
                status.addStatusMessage(msg, type='error')
            else:
                try:
                    response_id = int(response_id)
                except ValueError:
                    msg = _(u"Response id ${response_id} is no integer so it "
                            "cannot be removed.",
                            mapping=dict(response_id=response_id))
                    msg = ts.translate('Poi', msg, context=context)
                    status.addStatusMessage(msg, type='error')
                    self.request.response.redirect(context.absolute_url())
                    return
                if response_id >= len(self.folder):
                    msg = _(u"Response id ${response_id} does not exist so it "
                            "cannot be removed.",
                            mapping=dict(response_id=response_id))
                    msg = ts.translate('Poi', msg, context=context)
                    status.addStatusMessage(msg, type='error')
                else:
                    self.folder.delete(response_id)
                    msg = _(u"Removed response id ${response_id}.",
                            mapping=dict(response_id=response_id))
                    msg = ts.translate('Poi', msg, context=context)
                    status.addStatusMessage(msg, type='info')
        self.request.response.redirect(context.absolute_url())
Beispiel #6
0
 def __call__(self):
     form = self.request.form
     context = aq_inner(self.context)
     status = IStatusMessage(self.request)
     ts = getGlobalTranslationService()
     if not self.can_edit_response:
         msg = _(u"You are not allowed to edit responses.")
         msg = ts.translate('Poi', msg, context=context)
         status.addStatusMessage(msg, type='error')
     else:
         response_id = form.get('response_id', None)
         if response_id is None:
             msg = _(u"No response selected for saving.")
             msg = ts.translate('Poi', msg, context=context)
             status.addStatusMessage(msg, type='error')
         elif self.folder[response_id] is None:
             msg = _(u"Response does not exist anymore; perhaps it was "
                     "removed by another user.")
             msg = translate(msg, 'Poi', context=self.request)
             status.addStatusMessage(msg, type='error')
         else:
             response = self.folder[response_id]
             response_text = form.get('response', u'')
             response.text = response_text
             # Remove cached rendered response.
             response.rendered_text = None
             msg = _(u"Changes saved to response id ${response_id}.",
                   mapping=dict(response_id=response_id))
             msg = ts.translate('Poi', msg, context=context)
             status.addStatusMessage(msg, type='info')
             # Fire event.  We put the context in the descriptions
             # so event handlers can use this fully acquisition
             # wrapped object to do their thing.  Feels like
             # cheating, but it gets the job done.  Arguably we
             # could turn the two arguments around and signal that
             # the issue has changed, with the response in the
             # event descriptions.
             modified(response, context)
     self.request.response.redirect(context.absolute_url())
Beispiel #7
0
def translate(message, context):
    """ Translate i18n message.
    """
    GTS = getGlobalTranslationService()
    return GTS.translate('cmf_default', message, context=context)
Beispiel #8
0
    def __call__(self):
        form = self.request.form
        context = aq_inner(self.context)
        if not self.memship.checkPermission('Poi: Add Response', context):
            raise Unauthorized
        ts = getGlobalTranslationService()

        response_text = form.get('response', u'')
        new_response = Response(response_text)
        new_response.mimetype = self.mimetype
        new_response.type = self.determine_response_type(new_response)

        issue_has_changed = False
        transition = form.get('transition', u'')
        if transition and transition in self.available_transitions:
            wftool = getToolByName(context, 'portal_workflow')
            before = wftool.getInfoFor(context, 'review_state')
            before = wftool.getTitleForStateOnType(before, 'PoiIssue')
            wftool.doActionFor(context, transition)
            after = wftool.getInfoFor(context, 'review_state')
            after = wftool.getTitleForStateOnType(after, 'PoiIssue')
            new_response.add_change('review_state', _(u'Issue state'),
                                    before, after)
            issue_has_changed = True

        options = [
            ('severity', _(u'Severity'), 'available_severities'),
            ('responsibleManager', _(u'Responsible manager'),
             'available_managers'),
            ]
        # Changes that need to be applied to the issue (apart from
        # workflow changes that need to be handled separately).
        changes = {}
        for option, title, vocab in options:
            new = form.get(option, u'')
            if new and new in self.__getattribute__(vocab):
                current = self.__getattribute__(option)
                if current != new:
                    changes[option] = new
                    new_response.add_change(option, title,
                                            current, new)
                    issue_has_changed = True


        #('targetRelease', 'Target release', 'available_releases'),
        new = form.get('targetRelease', u'')
        if new and new in self.available_releases:
            current = self.targetRelease
            if current != new:
                # from value (uid) to key (id)
                new_label = self.available_releases.getValue(new)
                current_label = self.available_releases.getValue(current)
                changes['targetRelease'] = new
                new_response.add_change(option, _(u'Target release'),
                                        current_label, new_label)
                issue_has_changed = True

        attachment = form.get('attachment')
        if attachment:
            # File(id, title, file)
            data = File(attachment.filename, attachment.filename, attachment)
            new_response.attachment = data
            issue_has_changed = True

        if len(response_text) == 0 and not issue_has_changed:
            status = IStatusMessage(self.request)
            ts = getGlobalTranslationService()
            msg = _(u"No response text added and no issue changes made.")
            msg = ts.translate('Poi', msg, context=context)
            status.addStatusMessage(msg, type='error')
        else:
            # Apply changes to issue
            context.update(**changes)
            # Add response
            self.folder.add(new_response)
        self.request.response.redirect(context.absolute_url())
Beispiel #9
0
    def sendNotificationEmail(self, addresses, subject, rstText):
        """
        Send a notification email to the list of addresses

        XXX Note to self [maurits]: look at this blog post from Marius
        Gedminas, titled "Sending Unicode emails in Python":
        http://mg.pov.lt/blog/unicode-emails-in-python.html
        """

        if not self.getSendNotificationEmailsTo() or not addresses:
            return

        portal_url = getToolByName(self, 'portal_url')
        plone_utils = getToolByName(self, 'plone_utils')

        portal = portal_url.getPortalObject()
        mailHost = plone_utils.getMailHost()
        charset = portal.getProperty('email_charset', '')
        if not charset:
            charset = plone_utils.getSiteEncoding()
        from_address = portal.getProperty('email_from_address', '')

        if not from_address:
            log('Cannot send notification email: email sender address not set')
            return
        from_name = portal.getProperty('email_from_name', '')
        mfrom = formataddr((from_name, from_address))
        if parseaddr(mfrom)[1] != from_address:
            # formataddr probably got confused by special characters.
            mfrom = from_address

        email_msg = MIMEMultipart('alternative')
        email_msg.epilogue = ''

        # Translate the body text
        ts = getGlobalTranslationService()
        rstText = ts.translate('Poi', rstText, context=self)
        # We must choose the body charset manually
        for body_charset in 'US-ASCII', charset, 'UTF-8':
            try:
                rstText = rstText.encode(body_charset)
            except UnicodeError:
                pass
            else:
                break

        textPart = MIMEText(rstText, 'plain', body_charset)
        email_msg.attach(textPart)
        htmlPart = MIMEText(renderHTML(rstText, charset=body_charset), 'html',
                            body_charset)
        email_msg.attach(htmlPart)

        # Make the subject unicode and translate it too.
        subject = safe_unicode(subject, charset)
        subject = ts.translate('Poi', subject, context=self)
        for address in addresses:
            address = safe_unicode(address, charset)
            if not address:
                # E-mail address may not be known, for example in case
                # of LDAP users.  See:
                # http://plone.org/products/poi/issues/213
                continue
            try:
                # Note that charset is only used for the headers, not
                # for the body text as that is a Message/MIMEText already.
                mailHost.secureSend(message=email_msg,
                                    mto=address,
                                    mfrom=mfrom,
                                    subject=subject,
                                    charset=charset)
            except (socket.error, SMTPException), exc:
                log_exc(('Could not send email from %s to %s regarding issue '
                         'in tracker %s\ntext is:\n%s\n') %
                        (mfrom, address, self.absolute_url(), email_msg))
                log_exc("Reason: %s: %r" % (exc.__class__.__name__, str(exc)))
            except: