1: """Miscellaneous utility functions"""
1: from math import ceil
1: from pyzimbra.auth import AuthException
1: from plone.memoize.instance import memoize
1: from plone.app.layout.navigation.interfaces import INavtreeStrategy
1: from plone.app.layout.navigation.interfaces import INavigationQueryBuilder
1: from plone.app.layout.navigation.navtree import buildFolderTree
1: from zope.component import getUtility, getMultiAdapter
1: from zope.annotation.interfaces import IAnnotations
1: from Products.CMFPlone.utils import safe_unicode
1: from Products.CMFCore.utils import getToolByName
1: from Acquisition import aq_inner
1: from vnccollab.theme.zimbrautil import IZimbraUtil
1: def getAllActiveResources(klass, limit=100, page=1):
"""Returns all items from ActiveResource class.
@klass: ActiveResource inherited class
@limit: amount of items in one page query
@page: page number to get items from
Mosty used for Redmine REST API calls to get all items
using pagination.
"""
# yiled given page items
>>>>>> res = klass.find(limit=limit, page=page)
>>>>>> for item in res:
>>>>>> yield item
# check if we got any more pages left
>>>>>> if len(res) >= limit:
>>>>>> for item in getAllActiveResources(klass, limit=limit, page=page + 1):
>>>>>> yield item
1: def getZimbraUrl(context):
#TODO: get zimbra url from registry
>>>>>> return 'https://zcs.vnc.biz'
1: def getZimbraEmail(context):
>>>>>> mtool = getToolByName(context, 'portal_membership')
>>>>>> member = mtool.getAuthenticatedMember()
>>>>>> email = member.getProperty('email')
>>>>>> return email
1: def getZimbraClient(context):
>>>>>> username, password = getZimbraCredentials(context)
>>>>>> try:
>>>>>> client = getUtility(IZimbraUtil).get_client(username=username,
>>>>>> password=password)
>>>>>> except AuthException:
>>>>>> client = None
>>>>>> return client
1: def getZimbraCredentials(context):
11: mtool = getToolByName(context, 'portal_membership')
11: member = mtool.getAuthenticatedMember()
11: username = member.getProperty('zimbra_username', '')
11: password = member.getProperty('zimbra_password', '')
# password could contain non-ascii chars, ensure it's properly encoded
11: return username, safe_unicode(password).encode('utf-8')
1: def _zimbraAnnotatedTaskKey(username):
'''Returns the key for zimbra tasks annotations associated with a username.'''
>>>>>> return 'vnccollab.theme.related_zimbra_task.{0}'.format(username)
1: def getZimbraAnnotatedTasks(context, username):
''' Returns the zimbra tasks annotated associated with the give username
or [] if anonymous.'''
11: if not username:
11: return []
>>>>>> annotation = IAnnotations(context)
>>>>>> key = _zimbraAnnotatedTaskKey(username)
>>>>>> annotatedTasks = annotation.get(key, [])
>>>>>> return annotatedTasks
1: def setZimbraAnnotatedTasks(context, username, tasks):
'''Sets the zimbra tasks annotated associated with the given username.'''
>>>>>> if not username:
>>>>>> return
>>>>>> annotation = IAnnotations(context)
>>>>>> key = _zimbraAnnotatedTaskKey(username)
>>>>>> annotation[key] = tasks
1: def getZimbraLiveAnnotatedTasks(context):
''' Returns the zimbra tasks annotated associated with the authenticated
user or [] if anonymous.
If some of the annotated tasks don't exists in the zimbra server, the
annotation is updated.
'''
11: username, password = getZimbraCredentials(context)
11: annotated_tasks = getZimbraAnnotatedTasks(context, username)
11: if not annotated_tasks:
11: return []
>>>>>> try:
# Clean the orphan tasks, the ones are annotated,
# but don't exist anymore.
>>>>>> zimbra_util = getUtility(IZimbraUtil)
>>>>>> zimbra_client = zimbra_util.get_client(username=username,
>>>>>> password=password)
>>>>>> all_tasks = zimbra_client.get_all_tasks()
>>>>>> tasks = [x for x in all_tasks if x in annotated_tasks]
>>>>>> if tasks != annotated_tasks:
>>>>>> setZimbraAnnotatedTasks(context, username, tasks)
>>>>>> except:
# If we can't get all the task, we won't clean the orphans.
>>>>>> tasks = annotated_tasks
>>>>>> return tasks
1: def addZimbraAnnotatedTasks(context, task):
'''Adds a task to the zimbra annotated tasks of the context.'''
>>>>>> username, _ = getZimbraCredentials(context)
>>>>>> annotatedTasks = getZimbraAnnotatedTasks(context, username)
>>>>>> annotatedTasks.append(task)
>>>>>> setZimbraAnnotatedTasks(context, username, annotatedTasks)
1: def groupList(value, batch_size=None, groups_number=None):
"""Divide give list into groups"""
>>>>>> if not value:
>>>>>> return ()
>>>>>> value = value[:]
# we can group by group size or by groups number
>>>>>> if groups_number is not None:
>>>>>> size = int(ceil(len(value) / float(groups_number)))
else:
>>>>>> size = batch_size
>>>>>> assert size is not None
# add zeros to get even number of elems for size
# to preform further grouping
>>>>>> if len(value) % size != 0:
>>>>>> value.extend([0 for i in range(size - len(value) % size)])
# group elements into batches
>>>>>> value = zip(*[value[i::size] for i in range(size)])
# finally filter out any zeros we added before grouping
>>>>>> value[-1] = tuple([k for k in value[-1] if k != 0])
>>>>>> return value
1: def sortNavTree(tree):
12: result = sorted(tree, key=lambda e: e['Title'])
12: for element in result:
>>>>>> if 'children' in element:
>>>>>> element['children'] = sortNavTree(element['children'])
12: return result
1: @memoize
1: def getNavTree(self, _marker=[]):
u""" Pathed method from plone.app.portlets.portlets.navigation.Renderer
Sorting result alphabetically.
"""
12: context = aq_inner(self.context)
12: queryBuilder = getMultiAdapter(
12: (context, self.data), INavigationQueryBuilder)
12: strategy = getMultiAdapter((context, self.data), INavtreeStrategy)
12: result = buildFolderTree(
12: context, obj=context, query=queryBuilder(), strategy=strategy)
12: if 'children' in result:
12: result['children'] = sortNavTree(result['children'])
12: return result
def sendto(self, send_to_address, send_from_address, comment,
1: subject='Plone', **kwargs):
"""Pathed method from Products.CMFPlone.PloneTool.PloneTool.
Sends a link of a page to someone."""
>>>>>> host = self.getMailHost()
>>>>>> template = getattr(self, 'sendto_template')
>>>>>> portal = getToolByName(self, 'portal_url').getPortalObject()
>>>>>> encoding = portal.getProperty('email_charset')
>>>>>> if 'envelope_from' in kwargs:
>>>>>> envelope_from = kwargs['envelope_from']
else:
>>>>>> envelope_from = send_from_address
# Cook from template
>>>>>> message = template(self, send_to_address=send_to_address,
>>>>>> send_from_address=send_from_address,
>>>>>> comment=comment, subject=subject, **kwargs)
>>>>>> message = message.encode(encoding)
>>>>>> host.send(message, mto=send_to_address,
>>>>>> mfrom=envelope_from, subject=subject,
>>>>>> charset=self.getSiteEncoding(), msg_type='text/html')