Пример #1
0
class IBasicData(Interface):
    short_name = schema.TextLine(title=_(u'Short Name'), )
    title = schema.TextLine(title=_(u'Title'), )
    description = schema.TextLine(
        title=_(u'Description'),
        required=False,
    )
Пример #2
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)
        if response_id is None:
            msg = _(u"No response selected.")
            msg = translate(msg, 'Poi', context=self.request)
            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 = translate(msg, 'Poi', context=self.request)
                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 = translate(msg, 'Poi', context=self.request)
                status.addStatusMessage(msg, type='error')
                return -1
            else:
                return response_id
        # fallback
        return -1
Пример #3
0
 def getManagersVocab(self):
     """
     Get the managers available as a DisplayList. The first item is 'None',
     with a key of '(UNASSIGNED)'.
     """
     tracker = self.getTracker()
     items = tracker.getManagers()
     vocab = DisplayList()
     vocab.add('(UNASSIGNED)', _(u'None'), 'poi_vocab_none')
     vocab.add('(AREAMANAGER)', _(u'Area Manager'), 'poi_vocab_area_manager')
     for item in items:
         vocab.add(item, item)
     return vocab
Пример #4
0
 def getManagersVocab(self):
     """
     Get the managers available as a DisplayList. The first item is 'None',
     with a key of '(UNASSIGNED)'.
     """
     tracker = self.getTracker()
     items = tracker.getManagers()
     vocab = DisplayList()
     vocab.add("(UNASSIGNED)", _(u"None"), "poi_vocab_none")
     vocab.add("(AREAMANAGER)", _(u"Area Manager"), "poi_vocab_area_manager")
     for item in items:
         vocab.add(item, item)
     return vocab
Пример #5
0
    def default(self):
        self.errors = {}
        form = self.request.form
        self.authorized = True

        if not self.getTracker():
            self.authorized = False
            obj = self.tool.getNoFeaturePage()
            self.page_nofeature = obj

        campos = ['title','details','area','issueType',
                  'severity','contactEmail'] #'responsibleManager',

        if 'form.submited' in form.keys():
            for item in campos:
                if not form.get(item):
                    self.errors[item] = 'Este Campo não pode ficar em branco.'

            if not self.errors:
                obj = self.createIssue(form)

                url = obj.portal_url()+'/vindula_poi_issue?key='+form.get('key','')
#                self.request.set('ajax_load',True)
#                self.request.set('ajax_include_head',True)

                IStatusMessage(self.request).addStatusMessage(_(u"Obrigado, o seu ticket foi criado com sucesso."), "info")
                self.request.response.redirect(url, lock=True)

        return ''
Пример #6
0
    def getManagersVocab(self, strict=False):
        """
        Get the managers available as a DisplayList. The first item is 'None',
        with a key of '(UNASSIGNED)'.

        Note, we now also allow Technicians here, unless we are called
        with 'strict' is True.
        """
        vocab = DisplayList()
        vocab.add(
            '(UNASSIGNED)', _(
                u"not_assigned", default=u'(Not assigned)'))
        mtool = getToolByName(self, 'portal_membership')
        for item in self.getManagers():
            user = mtool.getMemberById(item)
            if user:
                fullname = user.getProperty('fullname', item) or item
            else:
                fullname = item

            vocab.add(item, fullname)
        if not strict:
            for item in self.getTechnicians():
                user = mtool.getMemberById(item)
                if user:
                    fullname = user.getProperty('fullname', item) or item
                else:
                    fullname = item

                vocab.add(item, fullname)
            return vocab
Пример #7
0
    def getManagersVocab(self, strict=False):
        """
        Get the managers available as a DisplayList. The first item is 'None',
        with a key of '(UNASSIGNED)'.

        Note, we now also allow Technicians here, unless we are called
        with 'strict' is True.
        """
        tracker = self.getTracker()
        vocab = DisplayList()
        vocab.add('(UNASSIGNED)', _(u'None'))
        mtool = getToolByName(self, 'portal_membership')
        for item in tracker.getManagers():
            user = mtool.getMemberById(item)
            if user:
                fullname = user.getProperty('fullname', item) or item
            else:
                fullname = item

            vocab.add(item, fullname)
        if not strict:
            for item in tracker.getTechnicians():
                user = mtool.getMemberById(item)
                if user:
                    fullname = user.getProperty('fullname', item) or item
                else:
                    fullname = item

                vocab.add(item, fullname)
            return vocab
Пример #8
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)
                msg = _(u"Response id ${response_id} has no attachment.",
                        mapping=dict(response_id=response_id))
                msg = translate(msg, 'Poi', 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)
Пример #9
0
 def __call__(self):
     form = self.request.form
     context = aq_inner(self.context)
     status = IStatusMessage(self.request)
     authenticator = getMultiAdapter((context, context.REQUEST),
                                     name=u"authenticator")
     if not self.can_edit_response:
         msg = _(u"You are not allowed to edit responses.")
         msg = translate(msg, 'Poi', context=self.request)
         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 = translate(msg, 'Poi', context=self.request)
             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 = translate(msg, 'Poi', context=self.request)
             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)
     redirect_url = "{0}?_authenticator={1}".format(context.absolute_url(),
                                                    authenticator.token())
     self.request.response.redirect(redirect_url)
Пример #10
0
 def __call__(self):
     form = self.request.form
     context = aq_inner(self.context)
     status = IStatusMessage(self.request)
     authenticator = getMultiAdapter((context, context.REQUEST),
                                     name=u"authenticator")
     if not self.can_edit_response:
         msg = _(u"You are not allowed to edit responses.")
         msg = translate(msg, 'Poi', context=self.request)
         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 = translate(msg, 'Poi', context=self.request)
             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 = translate(msg, 'Poi', context=self.request)
             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)
     redirect_url = "{0}?_authenticator={1}".format(context.absolute_url(),
                                                    authenticator.token())
     self.request.response.redirect(redirect_url)
Пример #11
0
 def subject(self):
     context = aq_inner(self.context)
     tracker = context.getTracker()
     subject = _('poi_email_new_response_subject_template',
                 u"[${tracker_title}] #${issue_id} - Re: ${issue_title}",
                 mapping=dict(tracker_title=su(tracker.Title()),
                              issue_id=su(context.getId()),
                              issue_title=su(context.Title())))
     # Ensure that the subject is unicode and translate it too.
     subject = su(subject)
     subject = translate(subject, 'Poi', context=self.request)
     return subject
Пример #12
0
 def getReleasesVocab(self):
     """
     Get the vocabulary of available releases, including the item
     (UNASSIGNED) to denote that a release is not yet assigned.
     """
     vocab = DisplayList()
     vocab.add('(UNASSIGNED)', _(u'None'))
     tracker = self.getTracker()
     trackerVocab = tracker.getReleasesVocab()
     for k in trackerVocab.keys():
         vocab.add(k, trackerVocab.getValue(k), trackerVocab.getValue(k))
     return vocab
Пример #13
0
 def getReleasesVocab(self):
     """
     Get the vocabulary of available releases, including the item
     (UNASSIGNED) to denote that a release is not yet assigned.
     """
     vocab = DisplayList()
     vocab.add("(UNASSIGNED)", _(u"None"))
     tracker = self.getTracker()
     trackerVocab = tracker.getReleasesVocab()
     for k in trackerVocab.keys():
         vocab.add(k, trackerVocab.getValue(k), trackerVocab.getValue(k))
     return vocab
Пример #14
0
    def __call__(self):
        context = aq_inner(self.context)
        status = IStatusMessage(self.request)

        if not self.can_delete_response:
            msg = _(u"You are not allowed to delete responses.")
            msg = translate(msg, 'Poi', context=self.request)
            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 = translate(msg, 'Poi', context=self.request)
                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 = translate(msg, 'Poi', context=self.request)
                    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 = translate(msg, 'Poi', context=self.request)
                    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 = translate(msg, 'Poi', context=self.request)
                    status.addStatusMessage(msg, type='info')
        self.request.response.redirect(context.absolute_url())
Пример #15
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())
Пример #16
0
 def subject(self):
     context = aq_inner(self.context)
     tracker = context.getTracker()
     subject = _(
         'poi_email_issue_resolved_subject_template',
         u"[${tracker_title}] Resolved #${issue_id} - ${issue_title}",
         mapping=dict(tracker_title=su(tracker.Title()),
                      issue_id=su(context.getId()),
                      issue_title=su(context.Title())))
     # Make the subject unicode and translate it too.
     subject = su(subject)
     subject = translate(subject, 'Poi', context=self.request)
     return subject
Пример #17
0
 def subject(self):
     context = aq_inner(self.context)
     tracker = context.getTracker()
     subject = _(
         'poi_email_issue_resolved_subject_template',
         u"[${tracker_title}] Resolved #${issue_id} - ${issue_title}",
         mapping=dict(
             tracker_title=su(tracker.getExternalTitle()),
             issue_id=su(context.getId()),
             issue_title=su(context.Title())))
     # Make the subject unicode and translate it too.
     subject = su(subject)
     subject = translate(subject, 'Poi', context=self.request)
     return subject
Пример #18
0
 def subject(self):
     context = aq_inner(self.context)
     tracker = context.getTracker()
     subject = _(
         'poi_email_new_response_subject_template',
         u"[${tracker_title}] #${issue_id} - Re: ${issue_title}",
         mapping=dict(
             tracker_title=su(tracker.Title()),
             issue_id=su(context.getId()),
             issue_title=su(context.Title())))
     # Ensure that the subject is unicode and translate it too.
     subject = su(subject)
     subject = translate(subject, 'Poi', context=self.request)
     return subject
Пример #19
0
    def getManagersVocab(self, strict=False):
        """
        Get the managers available as a DisplayList. The first item is 'None',
        with a key of '(UNASSIGNED)'.

        Note, we now also allow Technicians here, unless we are called
        with 'strict' is True.
        """
        tracker = self.getTracker()
        vocab = DisplayList()
        vocab.add("(UNASSIGNED)", _(u"None"))
        for item in tracker.getManagers():
            vocab.add(item, item)
        if not strict:
            for item in tracker.getTechnicians():
                vocab.add(item, item)
        return vocab
def sendResolvedMail(self, state_change, **kw):
    """Send an email to the original submitter that the issue was marked
    as resolved, inviting him/her to confirm it.
    """
    issue = state_change.object
    tracker = issue.aq_parent

    if not tracker.getSendNotificationEmailsTo():
        return

    issueEmail = issue.getContactEmail()
    if not issueEmail:
        return

    portal_url = getToolByName(self, 'portal_url')
    portal = portal_url.getPortalObject()
    plone_utils = getToolByName(portal, 'plone_utils')
    charset = plone_utils.getSiteEncoding()

    def su(value):
        # We are going to use the same encoding everywhere, so we will
        # make that easy.
        return safe_unicode(value, encoding=charset)

    portal_membership = getToolByName(portal, 'portal_membership')
    member = portal_membership.getAuthenticatedMember()

    memberInfo = portal_membership.getMemberInfo(member.getUserName())
    stateChanger = member.getUserName()
    if memberInfo:
        stateChanger = memberInfo['fullname'] or stateChanger

    fromName = portal.getProperty('email_from_name', None)


    mailText = _(
        'poi_email_issue_resolved_template',
        u"""The issue **${issue_title}** in the **${tracker_title}**
tracker has been marked as resolved by **${response_author}**.
Please visit the issue and either confirm that it has been
satisfactorily resolved or re-open it.

Response Information
--------------------

Issue
  ${issue_title} (${issue_url})


* This is an automated email, please do not reply - ${from_name}""",
        mapping=dict(
            issue_title = su(issue.title_or_id()),
            tracker_title = su(tracker.title_or_id()),
            response_author = su(stateChanger),
            issue_url = su(issue.absolute_url()),
            from_name = su(fromName)))

    subject = _(
        'poi_email_issue_resolved_subject_template',
        u"[${tracker_title}] Resolved #${issue_id} - ${issue_title}",
        mapping=dict(
            tracker_title = su(tracker.getExternalTitle()),
            issue_id = su(issue.getId()),
            issue_title = su(issue.Title())))

    tracker.sendNotificationEmail([issueEmail], subject, mailText)
Пример #21
0
from Products.Poi import PoiMessageFactory as _
from Products.Poi import permissions
from Products.Poi.config import PROJECTNAME
from Products.Poi.config import ISSUE_RECOGNITION_PATTERNS
from Products.Poi.config import REVISION_RECOGNITION_PATTERNS
from Products.Poi.interfaces import ITracker
from Products.Poi.utils import linkBugs
from Products.Poi.utils import linkSvn

schema = atapi.Schema((

    atapi.StringField(
        name='title',
        widget=atapi.StringWidget(
            label=_(u'Poi_label_tracker_title',
                    default=u"Tracker name"),
            description=_(
                u'Poi_help_tracker_title',
                default=u"Enter a descriptive name for this tracker"),
        ),
        required=True,
        accessor="Title",
        searchable=True
    ),

    atapi.TextField(
        name='description',
        widget=atapi.TextAreaWidget(
            label=_(u'Poi_label_tracker_description',
                    default=u"Tracker description"),
            description=_(
Пример #22
0
def sendResolvedMail(self, state_change, **kw):
    """Send an email to the original submitter that the issue was marked
    as resolved, inviting him/her to confirm it.
    """
    issue = state_change.object
    tracker = issue.aq_parent

    if not tracker.getSendNotificationEmailsTo():
        return

    issueEmail = issue.getContactEmail()
    if not issueEmail:
        return

    portal_url = getToolByName(self, 'portal_url')
    portal = portal_url.getPortalObject()
    plone_utils = getToolByName(portal, 'plone_utils')
    charset = plone_utils.getSiteEncoding()

    def su(value):
        # We are going to use the same encoding everywhere, so we will
        # make that easy.
        return safe_unicode(value, encoding=charset)

    portal_membership = getToolByName(portal, 'portal_membership')
    member = portal_membership.getAuthenticatedMember()

    memberInfo = portal_membership.getMemberInfo(member.getUserName())
    stateChanger = member.getUserName()
    if memberInfo:
        stateChanger = memberInfo['fullname'] or stateChanger

    fromName = portal.getProperty('email_from_name', None)

    mailText = _('poi_email_issue_resolved_template',
                 u"""The issue **${issue_title}** in the **${tracker_title}**
tracker has been marked as resolved by **${response_author}**.
Please visit the issue and either confirm that it has been
satisfactorily resolved or re-open it.

Response Information
--------------------

Issue
  ${issue_title} (${issue_url})


* This is an automated email, please do not reply - ${from_name}""",
                 mapping=dict(issue_title=su(issue.title_or_id()),
                              tracker_title=su(tracker.title_or_id()),
                              response_author=su(stateChanger),
                              issue_url=su(issue.absolute_url()),
                              from_name=su(fromName)))

    subject = _('poi_email_issue_resolved_subject_template',
                u"[${tracker_title}] Resolved #${issue_id} - ${issue_title}",
                mapping=dict(tracker_title=su(tracker.getExternalTitle()),
                             issue_id=su(issue.getId()),
                             issue_title=su(issue.Title())))

    tracker.sendNotificationEmail([issueEmail], subject, mailText)
Пример #23
0
    def __call__(self):
        form = self.request.form
        context = aq_inner(self.context)
        if not self.memship.checkPermission('Poi: Add Response', context):
            raise Unauthorized

        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('targetRelease', _(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)
            msg = _(u"No response text added and no issue changes made.")
            msg = translate(msg, 'Poi', context=self.request)
            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())
Пример #24
0
class IIssue(model.Schema):
    """Marker interface for Poi issue"""

    dexteritytextindexer.searchable('title')
    title = schema.TextLine(
        title=_(u'Poi_label_issue_title', default=u"Title"),
        description=_(u'Poi_help_issue_title',
                      default=u"Enter a short, descriptive title for "
                      u"the issue. A good title will make it easier "
                      u"for project managers to identify and respond "
                      u"to the issue."))

    release = schema.Choice(
        title=_(u'Poi_label_issue_release', default=u'Release'),
        description=_(u'Poi_help_issue_release',
                      default=u"Select the version the issue was found in."),
        required=False,
        source=possibleTargetReleases)

    dexteritytextindexer.searchable('details')
    details = RichText(title=_(u'Poi_label_issue_details', default=u'Details'),
                       description=_(
                           u'Poi_help_issue_details',
                           default=u"Please provide further details."))

    dexteritytextindexer.searchable('steps')
    steps = RichText(
        title=_(u'Poi_label_issue_steps', default=u'Steps To Reproduce'),
        description=_(u'Poi_help_issue_steps',
                      default=u"If applicable, please provide the steps to "
                      u"reproduce the error or identify the issue, one per "
                      u"line."),
        required=False,
    )

    area = schema.Choice(
        title=_(u'Poi_label_issue_area', default=u'Area'),
        description=_(u'Poi_help_issue_area',
                      default=u"Select the area this issue is relevant to."),
        source=possibleAreas)

    issue_type = schema.Choice(title=_(u'Poi_label_issue_type',
                                       default=u'Issue Type'),
                               description=_(
                                   u'Poi_help_issue_type',
                                   default=u"Select the type of issue."),
                               source=possibleIssueTypes)

    read_permission(severity='Poi.ModifyIssueSeverity')
    write_permission(severity='Poi.ModifyIssueSeverity')
    severity = schema.Choice(
        title=_(u'Poi_label_issue_severity', default=u'Severity'),
        description=_(u'Poi_help_issue_severity',
                      default=u"Select the severity of this issue."),
        defaultFactory=default_severity,
        source=possibleSeverities)

    read_permission(target_release='Poi.ModifyIssueTargetRelease')
    write_permission(target_release='Poi.ModifyIssueTargetRelease')
    target_release = schema.Choice(
        title=_(u'Poi_label_issue_target_release', default=u'Target Release'),
        description=_(u'Poi_help_issue_target_release',
                      default=u"Release this issue is targetted to be fixed "
                      u"in."),
        source=possibleTargetReleases,
        required=False,
    )

    read_permission(assignee='Poi.ModifyIssueAssignment')
    write_permission(assignee='Poi.ModifyIssueAssignment')
    assignee = schema.Choice(
        title=_(u'Poi_label_issue_assignee', default=u'Assignee'),
        description=_(u'Poi_help_issue_assignee',
                      default=u"Select which person, if any, is assigned to "
                      u"this issue."),
        source=possibleAssignees,
        required=False,
    )

    contact_email = email.Email(
        title=_(u'Poi_label_issue_contact_email', default=u'Contact Email'),
        description=_(u'Poi_help_issue_contact_email',
                      default=u"Please provide an email address where you can "
                      u"be contacted for further information or when a "
                      u"resolution is available. Note that your email "
                      u"address will not be displayed to others."),
        required=False,
    )

    read_permission(watchers='Poi.ModifyIssueWatchers')
    write_permission(watchers='Poi.ModifyIssueWatchers')
    widget('watchers',
           AjaxSelectFieldWidget,
           vocabulary='plone.app.vocabularies.Users')
    watchers = schema.List(
        title=_(u'Poi_label_issue_watchers', default=u'Watchers'),
        description=_(u'Poi_help_issue_watchers',
                      default=u"Enter the user ids of members who are watching"
                      u" this issue, one per line. E-mail addresses are "
                      u"allowed too. These persons will "
                      u"receive an email when a response is added to the "
                      u"issue. Members can also add themselves as "
                      u"watchers."),
        value_type=schema.TextLine(),
        required=False,
        defaultFactory=default_watchers,
    )

    write_permission(subject='Poi.ModifyIssueTags')
    read_permission(subject='Poi.ModifyIssueTags')
    widget('subject',
           AjaxSelectFieldWidget,
           vocabulary='plone.app.vocabularies.Keywords',
           pattern_options={'allowNewItems': 'true'})
    subject = schema.Tuple(
        title=_(u'Poi_label_issue_subject', default=u'Subject'),
        description=_(u'Poi_help_issue_subject',
                      default=u"Tags can be used to add arbitrary "
                      u"categorisation to issues. The list below shows "
                      u"existing tags which you can select, or you can add "
                      u"new ones."),
        value_type=schema.TextLine(),
        required=False,
        missing_value=[],
    )

    read_permission(related_issue='Poi.ModifyRelatedIssues')
    write_permission(related_issue='Poi.ModifyRelatedIssues')
    widget(
        'related_issue',
        RelatedItemsFieldWidget,
        pattern_options={
            'resultTemplate':
            '' +
            '<div class="pattern-relateditems-result<% if (oneLevelUp) { %> one-level-up<% } %>">'
            +
            '  <a class="pattern-relateditems-result-select<% if (selectable) { %> selectable<% } else if (browsing && is_folderish) { %> pattern-relateditems-result-browse<% } %><% if (oneLevelUp) { %> one-level-up<% } %>" data-path="<%- path %>">'
            +
            '    <% if (getURL && (getIcon || portal_type === "Image")) { %><img src="<%- getURL %>/@@images/image/icon "><br><% } %>'
            +
            '    <span class="pattern-relateditems-result-title" title="<%- portal_type %>"><%- Title %></span>'
            +
            '    <span class="pattern-relateditems-result-path"><%- path %></span>'
            + '  </a>' + '</div>'
        })
    related_issue = RelationList(title=_(u'Poi_label_issue_related',
                                         default=u'Related Issue(s)'),
                                 description=_(
                                     u'Poi_help_issue_related',
                                     default=u'Link related issues.'),
                                 value_type=RelationChoice(
                                     title=u"Related",
                                     source=tracker_issues,
                                 ),
                                 required=False)

    empty = schema.Bool(title=_(u'Poi_label_issue_empty',
                                default=u'Leave this field empty'),
                        required=False,
                        constraint=checkEmpty)
Пример #25
0
    def __call__(self):
        form = self.request.form
        context = aq_inner(self.context)
        request = context.REQUEST
        authenticator = getMultiAdapter((context, request),
                                        name=u"authenticator")
        # CSRF should be disabled during tests
        if (not IDisableCSRFProtection.providedBy(request) and
           not authenticator.verify()):
            raise Unauthorized
        if not self.memship.checkPermission('Poi: Add Response', context):
            raise Unauthorized

        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'),
            ('current_assignee', _(u'Assignee'),
             'available_assignees'),
            ('targetRelease', _(u'Target release'), 'available_releases'),
        ]
        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:
                    continue
                new_response.add_change(option, title, current, new)
                issue_has_changed = True
                if option == 'severity':
                    context.severity = new
                elif option == 'targetRelease':
                    context.target_release = new
                elif option == 'current_assignee':
                    context.assignee = new

        if len(response_text) == 0 and not issue_has_changed:
            status = IStatusMessage(self.request)
            msg = _(u"No response text added and no issue changes made.")
            msg = translate(msg, 'Poi', context=self.request)
            status.addStatusMessage(msg, type='error')
        else:
            # Add response
            self.folder.add(new_response)
        redirect_url = "{0}?_authenticator={1}".format(context.absolute_url(),
                                                       authenticator.token())
        self.request.response.redirect(redirect_url)
Пример #26
0
wrapper = textwrap.TextWrapper(initial_indent='    ', subsequent_indent='    ')
logger = logging.getLogger('Poi')

PLAIN_MIMETYPES = (
    'text/x-web-intelligent',
    'text/plain',
)

schema = Schema((

    StringField(
        name='id',
        widget=StringWidget(
            visible={'view': 'invisible', 'edit': 'visible'},
            modes=('view', ),
            label=_(u'Poi_label_issue_id',
                    default=u'Id'),
        ),
        mode="r"
    ),

    StringField(
        name='title',
        widget=StringWidget(
            label=_(u"Poi_label_issue_title",
                    default=u"Title"),
            description=_(
                u'Poi_help_issue_title',
                default=(
                    u"Enter a short, descriptive title for the issue. "
                    u"A good title will make it easier for project "
                    u"managers to identify and respond to the issue.")),
Пример #27
0
    def sendNotificationMail(self):
        """
        When this issue is created, send a notification email to all
        tracker managers, unless emailing is turned off.
        """
        portal_url = getToolByName(self, 'portal_url')
        portal = portal_url.getPortalObject()
        portal_membership = getToolByName(portal, 'portal_membership')
        plone_utils = getToolByName(portal, 'plone_utils')
        charset = plone_utils.getSiteEncoding()
        # We are going to use the same encoding everywhere, so we will
        # make that easy.
        def su(value):
            return safe_unicode(value, encoding=charset)

        fromName = portal.getProperty('email_from_name', None)
        if isinstance(fromName, unicode):
            fromName = fromName.encode(charset, 'replace')

        tracker = self.getTracker()

        issueCreator = self.Creator()
        issueCreatorInfo = portal_membership.getMemberInfo(issueCreator)
        issueAuthor = issueCreator
        if issueCreatorInfo:
            issueAuthor = issueCreatorInfo['fullname'] or issueCreator

        issueText = self.getDetails(mimetype="text/x-web-intelligent")
        paras = issueText.splitlines()
        issueDetails = '\n\n'.join([wrapper.fill(p) for p in paras])

        addresses = tracker.getNotificationEmailAddresses()

        mailText = _(
            'poi_email_new_issue_template',
            u"""A new issue has been submitted to the **${tracker_title}**
tracker by **${issue_author}** and awaits confirmation.

Issue Information
-----------------

Issue
  ${issue_title} (${issue_url})


**Issue Details**::

${issue_details}


* This is an automated email, please do not reply - ${from_name}""",
            mapping=dict(
                issue_title = su(self.title_or_id()),
                tracker_title = su(tracker.title_or_id()),
                issue_author = su(issueAuthor),
                issue_details = su(issueDetails),
                issue_url = su(self.absolute_url()),
                from_name = su(fromName)))

        subject = _(
            'poi_email_new_issue_subject_template',
            u"[${tracker_title}] #${issue_id} - New issue: ${issue_title}",
            mapping=dict(
                tracker_title = su(tracker.getExternalTitle()),
                issue_id = su(self.getId()),
                issue_title = su(self.Title())))

        tracker.sendNotificationEmail(addresses, subject, mailText)
Пример #28
0
from Products.Poi.config import PROJECTNAME
from Products.Poi.interfaces import IIssue
from Products.Poi.interfaces import ITracker

wrapper = textwrap.TextWrapper(initial_indent='    ', subsequent_indent='    ')
logger = logging.getLogger('Poi')

schema = Schema((
    StringField(name='id',
                widget=StringWidget(
                    visible={
                        'view': 'invisible',
                        'edit': 'visible'
                    },
                    modes=('view', ),
                    label=_(u'Poi_label_issue_id', default=u'Id'),
                ),
                mode="r"),
    StringField(
        name='title',
        widget=StringWidget(
            label=_(u"Poi_label_issue_title", default=u"Title"),
            description=_(
                u'Poi_help_issue_title',
                default=(u"Enter a short, descriptive title for the issue. "
                         u"A good title will make it easier for project "
                         u"managers to identify and respond to the issue.")),
        ),
        required=True,
        accessor="Title",
        searchable=True),
Пример #29
0
def sendResponseNotificationMail(issue, response):
    """When a response is created, send a notification email to all
    tracker managers, unless emailing is turned off.
    """

    tracker = aq_parent(issue)
    addresses = tracker.getNotificationEmailAddresses(issue)
    if not addresses:
        # This also catches the case where there may be addresses but
        # the tracker is not configured to send emails.
        return

    portal_url = getToolByName(issue, 'portal_url')
    portal = portal_url.getPortalObject()
    portal_membership = getToolByName(portal, 'portal_membership')
    plone_utils = getToolByName(portal, 'plone_utils')
    ts = getGlobalTranslationService()

    charset = plone_utils.getSiteEncoding()

    # We are going to use the same encoding everywhere, so we will
    # make that easy.

    def su(value):
        return safe_unicode(value, encoding=charset)

    fromName = su(portal.getProperty('email_from_name', ''))

    creator = response.creator
    creatorInfo = portal_membership.getMemberInfo(creator)
    if creatorInfo and creatorInfo['fullname']:
        responseAuthor = creatorInfo['fullname']
    else:
        responseAuthor = creator
    responseAuthor = su(responseAuthor)

    responseText = su(response.text)
    paras = responseText.splitlines()

    # Indent the response details so they are correctly interpreted as
    # a literal block after the double colon behind the 'Response
    # Details' header.
    wrapper = textwrap.TextWrapper(initial_indent=u'    ',
                                   subsequent_indent=u'    ')
    responseDetails = u'\n\n'.join([wrapper.fill(p) for p in paras])

    if responseDetails:
        header = _(
            'poi_heading_response_details',
            u"Response Details")
        header = ts.translate('Poi', header, context=issue)
        responseDetails = u"**%s**::\n\n\n%s" % (header, responseDetails)

    changes = u''
    for change in response.changes:
        before = su(change.get('before'))
        after = su(change.get('after'))
        # Some changes are workflow changes, which can be translated.
        # Note that workflow changes are in the plone domain.
        before = ts.translate('plone', before, context=issue)
        after = ts.translate('plone', after, context=issue)
        changes += u"%s -> %s\n" % (before, after)
        if response.attachment:
            extra = _(
                'poi_attachment_added',
                u"An attachment has been added with id ${attachment_id}",
                mapping=dict(
                    attachment_id=response.attachment.getId()))
            extra = ts.translate(extra, 'Poi', context=issue)
            changes += extra + "\n"

    mailText = _(
        'poi_email_new_response_template',
        u"""A new response has been given to the issue **${issue_title}**
in the tracker **${tracker_title}** by **${response_author}**.

Response Information
--------------------

Issue
  ${issue_title} (${issue_url})

${changes}

${response_details}

* This is an automated email, please do not reply - ${from_name}""",
        mapping=dict(
            issue_title = su(issue.title_or_id()),
            tracker_title = su(tracker.title_or_id()),
            response_author = responseAuthor,
            response_details = responseDetails,
            issue_url = su(issue.absolute_url()),
            changes = changes,
            from_name = fromName))

    subject = _(
        'poi_email_new_response_subject_template',
        u"[${tracker_title}] #${issue_id} - Re: ${issue_title}",
        mapping=dict(
            tracker_title = su(tracker.getExternalTitle()),
            issue_id = su(issue.getId()),
            issue_title = su(issue.Title())))

    tracker.sendNotificationEmail(addresses, subject, mailText)
Пример #30
0
    def sendNotificationMail(self):
        """
        When this issue is created, send a notification email to all
        tracker managers, unless emailing is turned off.
        """
        portal_url = getToolByName(self, "portal_url")
        portal = portal_url.getPortalObject()
        portal_membership = getToolByName(portal, "portal_membership")
        plone_utils = getToolByName(portal, "plone_utils")
        charset = plone_utils.getSiteEncoding()
        # We are going to use the same encoding everywhere, so we will
        # make that easy.
        def su(value):
            return safe_unicode(value, encoding=charset)

        fromName = portal.getProperty("email_from_name", None)
        if isinstance(fromName, unicode):
            fromName = fromName.encode(charset, "replace")

        tracker = self.getTracker()

        issueCreator = self.Creator()
        issueCreatorInfo = portal_membership.getMemberInfo(issueCreator)
        issueAuthor = issueCreator
        if issueCreatorInfo:
            issueAuthor = issueCreatorInfo["fullname"] or issueCreator

        issueText = self.getDetails(mimetype="text/x-web-intelligent")
        paras = issueText.splitlines()
        issueDetails = "\n\n".join([wrapper.fill(p) for p in paras])

        addresses = tracker.getNotificationEmailAddresses()

        mailText = _(
            "poi_email_new_issue_template",
            u"""A new issue has been submitted to the **${tracker_title}**
tracker by **${issue_author}** and awaits confirmation.

Issue Information
-----------------

Issue
  ${issue_title} (${issue_url})


**Issue Details**::

${issue_details}


* This is an automated email, please do not reply - ${from_name}""",
            mapping=dict(
                issue_title=su(self.title_or_id()),
                tracker_title=su(tracker.title_or_id()),
                issue_author=su(issueAuthor),
                issue_details=su(issueDetails),
                issue_url=su(self.absolute_url()),
                from_name=su(fromName),
            ),
        )

        subject = _(
            "poi_email_new_issue_subject_template",
            u"[${tracker_title}] #${issue_id} - New issue: ${issue_title}",
            mapping=dict(
                tracker_title=su(tracker.getExternalTitle()), issue_id=su(self.getId()), issue_title=su(self.Title())
            ),
        )

        tracker.sendNotificationEmail(addresses, subject, mailText)
Пример #31
0
    def __call__(self):
        form = self.request.form
        context = aq_inner(self.context)
        request = context.REQUEST
        authenticator = getMultiAdapter((context, request),
                                        name=u"authenticator")
        # CSRF should be disabled during tests
        if (not IDisableCSRFProtection.providedBy(request)
                and not authenticator.verify()):
            raise Unauthorized
        if not self.memship.checkPermission('Poi: Add Response', context):
            raise Unauthorized

        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'),
            ('current_assignee', _(u'Assignee'), 'available_assignees'),
            ('targetRelease', _(u'Target release'), 'available_releases'),
        ]
        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:
                    continue
                new_response.add_change(option, title, current, new)
                issue_has_changed = True
                if option == 'severity':
                    context.severity = new
                elif option == 'targetRelease':
                    context.target_release = new
                elif option == 'current_assignee':
                    context.assignee = new

        if len(response_text) == 0 and not issue_has_changed:
            status = IStatusMessage(self.request)
            msg = _(u"No response text added and no issue changes made.")
            msg = translate(msg, 'Poi', context=self.request)
            status.addStatusMessage(msg, type='error')
        else:
            # Add response
            self.folder.add(new_response)
            context.reindexObject()
        redirect_url = "{0}?_authenticator={1}".format(context.absolute_url(),
                                                       authenticator.token())
        self.request.response.redirect(redirect_url)
Пример #32
0
from Products.Poi.utils import link_bugs
from Products.Poi.utils import link_repo
from plone.app.textfield import RichText
from plone.app.z3cform.widget import AjaxSelectFieldWidget
from plone.autoform.directives import widget
from plone.autoform.directives import write_permission, read_permission
from plone.dexterity.content import Container
from plone.protect.utils import addTokenToUrl
from plone.supermodel import model
from plone.z3cform.textlines import TextLinesFieldWidget
from collective.z3cform.datagridfield import DataGridFieldFactory, DictRow
from z3c.form import validator


DEFAULT_SEVERITIES = [
    _(u'Critical'),
    _(u'Important'),
    _(u'Medium'),
    _(u'Low')
]


def possibleAreas(context):
    """
    Get the available areas as a Vocabulary.
    """
    if ITracker.providedBy(context):
        tracker = context
    elif hasattr(context, 'getTracker'):
        tracker = context.getTracker()
    else:
Пример #33
0
class ITracker(model.Schema):
    title = schema.TextLine(
        title=_(u'title', default=u'Title'),
        description=_(u'Poi_help_tracker_title',
                      default=u"Enter a descriptive name for this tracker"),
    )

    description = schema.Text(
        title=_(u'description', default=u'Description'),
        description=_(u'Poi_help_tracker_description',
                      default=u"Describe the purpose of this tracker"),
        required=False,
    )

    help_text = RichText(
        title=_(u'help_text', default=u'Help Text'),
        description=_(
            u'Poi_help_helpText',
            default=(u"Enter any introductory help text you'd like to "
                     u"display on the tracker front page.")),
        required=False,
    )

    widget(available_areas=DataGridFieldFactory)
    available_areas = schema.List(
        title=_(u'Poi_label_availableAreas', default=u"Areas"),
        description=_(
            u'Poi_help_availableAreas',
            default="Enter the issue topics/areas for this tracker."),
        default=[
            {
                'short_name': 'ui',
                'title': 'User interface',
                'description': 'User interface issues'
            },
            {
                'short_name': 'functionality',
                'title': 'Functionality',
                'description': 'Issues with the basic functionality'
            },
            {
                'short_name': 'process',
                'title': 'Process',
                'description':
                'Issues relating to the development process itself'
            },
        ],
        value_type=DictRow(title=_(u'Area'), schema=IBasicData),
    )

    widget(available_issue_types=DataGridFieldFactory)
    available_issue_types = schema.List(
        title=_(u'Poi_label_availableIssueTypes', default=u"Issue types"),
        description=_(u'Poi_help_availableIssueTypes',
                      default=u"Enter the issue types for this tracker."),
        default=[
            {
                'short_name': 'bug',
                'title': 'Bug',
                'description': 'Functionality bugs in the software'
            },
            {
                'short_name': 'feature',
                'title': 'Feature',
                'description': 'Suggested features'
            },
            {
                'short_name': 'patch',
                'title': 'Patch',
                'description': 'Patches to the software'
            },
        ],
        value_type=DictRow(title=_(u'Issue Type'), schema=IBasicData),
    )

    widget(available_severities=TextLinesFieldWidget)
    available_severities = schema.List(
        title=_(u'Poi_label_availableSeverities',
                default=u"Available severities"),
        default=DEFAULT_SEVERITIES,
        description=_(u'Poi_help_availableSeverities',
                      default=(u"Enter the different type of issue severities "
                               u"that should be available, one per line.")),
        value_type=schema.TextLine(),
    )

    default_severity = schema.Choice(
        title=_(
            u'Poi_label_defaultSeverity',
            default=u"Default severity",
        ),
        default=_(u'Medium'),
        description=_(u'Poi_help_defaultSeverity',
                      default=u"Select the default severity for new issues."),
        source=possibleSeverities,
    )

    widget(available_releases=TextLinesFieldWidget)
    available_releases = schema.List(
        title=_(u'Poi_label_availableReleases', default=u'Available releases'),
        description=_(
            u'Poi_help_availableReleases',
            default=(u"Enter the releases which issues can be assigned to, "
                     u"one per line. If no releases are entered, issues "
                     u"will not be organized by release.")),
        value_type=schema.TextLine(),
        required=False,
    )

    widget('assignees', AjaxSelectFieldWidget)
    assignees = schema.List(
        title=_(u'Poi_label_assignees', default=u'Assignees'),
        description=_(u"Enter users who will be responsible for solving "
                      u"the issues. Users also need to be added as "
                      u"Watchers to receive notifications."),
        value_type=schema.Choice(source='plone.app.vocabularies.Users'),
    )

    read_permission(watchers='Poi.ModifyIssueWatchers')
    write_permission(watchers='Poi.ModifyIssueWatchers')
    widget('watchers',
           AjaxSelectFieldWidget,
           vocabulary='plone.app.vocabularies.Users')
    watchers = schema.List(
        title=_(u'Poi_label_tracker_watchers', default=u'Watchers'),
        description=_(
            u'Poi_help_tracker_watchers',
            default=(u"Enter the user ids of members who are watching "
                     u"this tracker, one per line. E-mail addresses are "
                     u"allowed too. These persons will receive "
                     u"an email when an issue or response is added to the "
                     u"tracker. Members can also add themselves as "
                     u"watchers.")),
        value_type=schema.TextLine(),
        required=False,
    )

    notification_emails = schema.Bool(
        title=_(u'Poi_label_sendNotificationEmails',
                default=u"Send notification emails"),
        description=_(
            u'Poi_help_sendNotificationEmails',
            default=(u"If selected, all tracker assignees above will "
                     u"receive an email for new issues and all issue "
                     u"responses. Issue watchers will receive an email "
                     u"for all issue responses. Issue submitters will "
                     u"receive an email when the issue has been resolved.")),
    )

    mailing_list = schema.TextLine(
        title=_(u'Poi_label_mailingList', default=u"Mailing list"),
        description=_(
            u'Poi_help_mailingList',
            default=(u"If given, and if 'Send notification emails' is "
                     u"selected, an email will be sent to this address "
                     u"each time a new issue or response is posted.")),
        required=False,
        constraint=is_email,
    )

    repo_url = schema.TextLine(
        title=_(u'Poi_label_svnurl', default=u"URL to Repository"),
        description=_(
            u'Poi_help_svnurl',
            default=(
                u"Please enter the URL to the related repository, "
                u"e.g.: "
                u"https://github.com/collective/Products.Poi/commit/%(rev)s "
                u"for Products.Poi.")),
        required=False,
    )
Пример #34
0
    # No multilingual support
    from Products.Archetypes import atapi

from Products.Poi import PoiMessageFactory as _
from Products.Poi import permissions
from Products.Poi.config import PROJECTNAME
from Products.Poi.interfaces import ITracker
from Products.Poi.utils import linkBugs
from Products.Poi.utils import linkSvn

schema = atapi.Schema((

    atapi.StringField(
        name='title',
        widget=atapi.StringWidget(
            label=_(u'Poi_label_tracker_title',
                    default=u"Tracker name"),
            description=_(
                    u'Poi_help_tracker_title',
                    default=u"Enter a descriptive name for this tracker"),
            ),
        required=True,
        accessor="Title",
        searchable=True
        ),

    atapi.TextField(
        name='description',
        widget=atapi.TextAreaWidget(
            label=_(u'Poi_label_tracker_description',
                    default=u"Tracker description"),
            description=_(
Пример #35
0
from Products.Poi.utils import is_email
from Products.Poi.utils import link_bugs
from Products.Poi.utils import link_repo
from plone.app.textfield import RichText
from plone.app.z3cform.widget import AjaxSelectFieldWidget
from plone.autoform.directives import widget
from plone.autoform.directives import write_permission, read_permission
from plone.dexterity.content import Container
from plone.memoize import ram
from plone.protect.utils import addTokenToUrl
from plone.supermodel import model
from plone.z3cform.textlines import TextLinesFieldWidget
from collective.z3cform.datagridfield import DataGridFieldFactory, DictRow
from z3c.form import validator

DEFAULT_SEVERITIES = [_(u'Critical'), _(u'Important'), _(u'Medium'), _(u'Low')]


def possibleAreas(context):
    """
    Get the available areas as a Vocabulary.
    """
    if ITracker.providedBy(context):
        tracker = context
    elif hasattr(context, 'getTracker'):
        tracker = context.getTracker()
    else:
        return SimpleVocabulary.fromValues([])
    terms = [
        SimpleTerm(value=tt.get('short_name'), title=tt.get('title'))
        for tt in tracker.available_areas if tt.get('short_name') is not None
Пример #36
0
except ImportError:
    # No multilingual support
    from Products.Archetypes import atapi

from Products.Poi import PoiMessageFactory as _
from Products.Poi import permissions
from Products.Poi.config import PROJECTNAME
from Products.Poi.interfaces import ITracker
from Products.Poi.utils import linkBugs
from Products.Poi.utils import linkSvn

schema = atapi.Schema((
    atapi.StringField(
        name='title',
        widget=atapi.StringWidget(
            label=_(u'Poi_label_tracker_title', default=u"Tracker name"),
            description=_(
                u'Poi_help_tracker_title',
                default=u"Enter a descriptive name for this tracker"),
        ),
        required=True,
        accessor="Title",
        searchable=True),
    atapi.TextField(
        name='description',
        widget=atapi.TextAreaWidget(
            label=_(u'Poi_label_tracker_description',
                    default=u"Tracker description"),
            description=_(u'Poi_help_tracker_description',
                          default=u"Describe the purpose of this tracker"),
        ),