def getPads(self):
        pads = []
        username, password, url = self.getUserData()
        if not (username and password and url):
            return ()

        # try to request etherpad for page with table of pads
        try:
            content = self._getPadsPage()

        except:
            logException(_(u"Error during fetching pads from %s" % url),
                context=self.context, logger=logger)
            return ()

        # try to parse html page into pads
        try:
            pads = self._parsePadsPage(content, self.trail_url(url),
                self.data.count)

        except:
            logException(_(u"Error during parsing pads page from %s" % url),
                context=self.context, logger=logger)
            return ()

        return tuple(pads)
示例#2
0
    def _get_zmails(self, since=None, till=None, uid=None):
        """Returns list of recent zimbra emails."""
        purl = self.purl()

        # get zimbra settings
        mtool = getToolByName(self.context, 'portal_membership')
        member = mtool.getAuthenticatedMember()
        username = member.getProperty('zimbra_username', '')
        password = member.getProperty('zimbra_password', '')
        if not (username and password):
            return []

        # make zimbra soap query to get list of recent emails
        try:
            zimbra = getUtility(IZimbraUtil).get_client(username=username,
                password=password)
            mails = zimbra.get_emails(folder='inbox', limit=DEFAULT_ITEMS_NUM,
                types='message')
        except Exception:
            logException(_(u"Error during fetching zimbra mails"),
                context=self.context, logger=logger)
            return []

        zurl = getZimbraUrl(self.context)
        result = []
        for mail in mails:
            # TODO: handle till argument
            datetime = DateTime(int(mail['date']) / 1000).toZone('GMT')
            if since and since >= datetime:
                # we've got too old entry, break from the loop
                break

            result.append({
                'uid': mail['id'],
                'type': 'zm',
                'image': {
                    'url': '%s/add_content_area/metabox_icon_email.png' %
                    purl, 'alt': _(u"MAIL")},
                'url': '%s/zimbra/h/search?st=conversation&id=%s' \
                    '&action=view&cid=%s' % (zurl, mail['id'],
                    mail['cid']),
                'title': _(u"MAIL"),
                'date': datetime.strftime('%b %d, %Y'),
                'time': datetime.strftime('%I:%M'),
                'datetime': datetime,
                'replies_num': 0,
                'can_reply': True,
                'body': mail['subject']
            })

        return result
示例#3
0
    def update(self):
        self.tickets = ()

        if IPloneSiteRoot in providedBy(self.context):
            return

        tickets = []
        # check if settings are configured
        # check user redmine credentials and redmine url/field id
        registry = getUtility(IRegistry)
        url = registry.get('vnccollab.theme.redmine.url')
        field_id = registry.get('vnccollab.theme.redmine.plone_uid_field_id')
        username, password = self.getAuthCredentials()
        if username and password and url and field_id:
            Issue = type("Issue", (ActiveResource,), {'_site': url, '_user':
                username, '_password': password})
            # do actual calls to redmine
            try:
                # fetch opened issues belonging to authenticated user
                uuid = self.context.UID()
                data = Issue.find(**{'cf_%d' % field_id: uuid,
                    'status_id': 'o', 'sort': 'updated_on:desc'})
            except Exception:
                logException(_(u"Error during fetching redmine tickets %s" %
                    url), context=self.context, logger=logger)
                return

            for item in data:
                info = item.to_dict()

                # skip invalid entries
                if not info.get('id') or not info.get('subject'):
                    continue

                tickets.append({
                    'id': info['id'],
                    'title': safe_unicode(info['subject']),
                    'body': safe_unicode(info.get('description', '')),
                    'url': '%s/issues/%s' % (url, info['id'])
                })

        self.tickets = tuple(tickets)
示例#4
0
    def __call__(self, context):
        # get authenticated user
        mtool = getToolByName(context, 'portal_membership')
        member = mtool.getAuthenticatedMember()
        if not member:
            return SimpleVocabulary([])

        username, password = member.getProperty('redmine_username', ''), \
            safe_unicode(member.getProperty('redmine_password',
            '')).encode('utf-8')
        registry = getUtility(IRegistry)
        url = registry.get('vnccollab.theme.redmine.url')
        field_id = registry.get(
            'vnccollab.theme.redmine.plone_uid_field_id')
        if not (username and password and url and field_id):
            return SimpleVocabulary([])

        try:
            data = getRedmineEnumerators(url, username, password)
        except Exception, e:
            logException(_(u"Error during fetching redmine enumerators"),
                context=context, logger=logger)
            return SimpleVocabulary([])
    def _tickets(self, url, username, password):
        """Requests redmine for list of opened issues for current user"""
        # create ActiveResource classes to fetch data from Redmine over REST API
        attrs = {'_site': url, '_user': username, '_password': password}
        if self.data.request_timeout:
            attrs['_timeout'] = self.data.request_timeout

        Issue = type("Issue", (ActiveResource,), attrs.copy())
        User = type("User", (ActiveResource,), attrs.copy())

        # do actual calls to redmine
        try:
            # fetch opened issues belonging to authenticated user
            data = Issue.find(assigned_to_id=User.find('current').id,
                              status_id='o',
                              sort='updated_on:desc')
        except:
            logException(_(u"Error during fetching redmine tickets %s" % url),
                         context=self.context, logger=logger)
            return ()

        plone_view = getMultiAdapter((self.context, self.request),
                                     name=u'plone')

        # process retrieved data
        tickets = []
        limit = self.data.count
        counter = 0
        for item in data:
            # we've got enough tickets
            if counter >= limit:
                break

            info = item.to_dict()

            # skip invalid entries
            if not info.get('id') or not info.get('subject'):
                continue

            # prepare date
            date = info.get('updated_on', '')
            if date:
                date = plone_view.toLocalizedTime(date, long_format=1)

            # prepare ticket body
            body = safe_unicode(info.get('description', ''))
            if body:
                # convert textile to html and do not cut down ticket
                # description anymore
                try:
                    body = textile.textile(body)
                except:
                    pass
                # crop length to 160 characters
                # body = plone_view.cropText(body, 160, ellipsis=u'...')

            tickets.append({
                'id': info['id'],
                'title': safe_unicode(info['subject']),
                'body': body,
                'date': date,
                'url': '%s/issues/%s' % (url, info['id'])
            })

            counter += 1

        return tuple(tickets)
示例#6
0
    def handleCreate(self, action):
        """Create redmine ticket using REST API."""
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        # check user redmine credentials and redmine url/field id
        registry = getUtility(IRegistry)
        url = registry.get('vnccollab.theme.redmine.url')
        field_id = registry.get('vnccollab.theme.redmine.plone_uid_field_id')
        username, password = self.getAuthCredentials()
        if not username or not password or not url or not field_id:
            if not username or not password:
                msg = _(u"Please, set correct redmine username and password in "
                "your profile form in order to create redmine issue.")
            else:
                msg = _(u"Please, set Redmine URL and ID settings in Control "
                    " Panel (Configuration Registry).")

            # issue form level error
            self.status = msg
            error = getMultiAdapter((Invalid(u''), self.request, None,
                None, self, self.context), IErrorViewSnippet)
            error.update()
            self.widgets.errors += (error,)
            return

        # finally trying to post new issue
        Issue = type("Issue", (ActiveResource,), {'_site': url, '_user':
            username, '_password': password})
        try:
            start_date = data.get('start_date') or ''
            if start_date:
                start_date = start_date.strftime('%Y-%m-%d')
            due_date = data.get('due_date') or ''
            if due_date:
                due_date = due_date.strftime('%Y-%m-%d')

            issue = Issue({
                'project_id': data['project'],
                'subject': data['subject'].encode('utf-8'),
                'tracker_id': data['tracker'],
                'description': (data.get('description') or u'').encode('utf-8'),
                'priority_id': data['priority'],
                'assigned_to_id': data.get('asignee') or '',
                'start_date': start_date,
                'due_date': due_date,
                'estimated_hours': data.get('estimated_time') or '',
                'custom_fields': [{'value': self.context.UID(),
                    'id': '%d' % field_id}]
            })
            created = issue.save()
        except Exception, e:
            # issue form level error
            logException(_(u"Error during creating redmine issue at %s" %
                self.context.absolute_url()), context=self.context,
                logger=logger)
            plone_utils = getToolByName(self.context, 'plone_utils')
            exception = plone_utils.exceptionString()
            self.status = _(u"Unable create issue: ${exception}",
                mapping={u'exception' : exception})
            error = getMultiAdapter((Invalid(u''), self.request, None,
                None, self, self.context), IErrorViewSnippet)
            error.update()
            self.widgets.errors += (error,)
            return
示例#7
0
    def _get_rtickets(self, since=None, till=None, uid=None):
        """Returns list of Redmine tickets belonging to currently logged in
        user.

        If since or till are passed, then return tickets that suit given date
        range.
        """
        result = []
        purl = self.purl()

        # get redmine credentials
        mtool = getToolByName(self.context, 'portal_membership')
        member = mtool.getAuthenticatedMember()
        username, password = member.getProperty('redmine_username', ''), \
            member.getProperty('redmine_password', '')
        if not (username and password):
            return []
        else:
            password = safe_unicode(password).encode('utf-8')

        # get redmine url
        url = getUtility(IRegistry).get('vnccollab.theme.redmine.url')
        if not url:
            return []

        # create ActiveResource classes to fetch data from Redmine over REST API
        attrs = {'_site': url, '_user': username, '_password': password}

        Issue = type("Issue", (ActiveResource,), attrs.copy())
        User = type("User", (ActiveResource,), attrs.copy())

        # do actual calls to redmine
        try:
            # fetch opened issues belonging to authenticated user
            data = Issue.find(assigned_to_id=User.find('current').id,
             status_id='o', sort='updated_on:desc')
        except Exception:
            logException(_(u"Error during fetching redmine tickets %s" % url),
                context=self.context, logger=logger)
            return []

        # cut down number of tickets in case we don't have date range arguments
        if not since:
            data = data[:DEFAULT_ITEMS_NUM]

        for item in data:
            info = item.to_dict()

            # skip invalid entries
            if not info.get('id') or not info.get('subject'):
                continue

            # prepare date
            datetime = DateTime(info.get('updated_on', '')).toZone('GMT')
            # TODO: handle till argument
            if since and since >= datetime:
                # we've got too old entry, break from the loop
                break

            result.append({
                'uid': info['id'],
                'type': 'tickets',
                'image': {
                    'url': '%s/add_content_area/metabox_icon_task.png' % purl,
                    'alt': _(u"ISSUE")},
                'url': '%s/issues/%s' % (url, info['id']),
                'title': _(u"ISSUE"),
                'date': datetime.strftime('%b %d, %Y'),
                'time': datetime.strftime('%I:%M'),
                'datetime': datetime,
                'replies_num': 0,
                'can_reply': True,
                'body': _(safe_unicode(info['subject']))
            })

        return result