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