source: products/quintagroup.analytics/trunk/quintagroup/analytics/browser/views.py @ 2908

Last change on this file since 2908 was 2908, checked in by fenix, 14 years ago

removed unnecessary import

  • Property svn:eol-style set to native
File size: 17.4 KB
Line 
1from Acquisition import aq_base
2from zope.component import getUtility, getMultiAdapter, queryMultiAdapter
3
4from OFS.interfaces import IPropertyManager
5from Products.Five.browser import BrowserView
6from Products.CMFCore.utils import getToolByName
7from Products.CMFCore.interfaces import IFolderish
8from Products.Archetypes.interfaces import IBaseFolder
9from plone.portlets.interfaces import IPortletManager
10from plone.portlets.interfaces import IPortletAssignmentMapping
11from plone.portlets.interfaces import ILocalPortletAssignmentManager
12try:
13    from plone.portlets.interfaces import IPortletAssignmentSettings
14except ImportError:
15    "Before plon4 we don't have an annotation storage for settings."
16    IPortletAssignmentSettings = lambda assignment:{}
17
18from GChartWrapper import VerticalBarStack
19
20class OwnershipByType(BrowserView):
21    MAX = 10
22    def __init__(self, context, request):
23        self.context = context
24        self.request = request
25        self.cat = getToolByName(self.context, 'portal_catalog')
26        self.users = None
27        self.total = None
28        self.types = None
29        self.data = {}
30
31    def getUsers(self):
32        if self.users is None:
33            index = self.cat._catalog.getIndex('Creator')
34            data = {}
35            for k in index._index.keys():
36                haslen = hasattr(index._index[k], '__len__')
37                if haslen:
38                    data[k] = len(index._index[k])
39                else:
40                    data[k] = 1
41            data = data.items()
42            data.sort(lambda a, b: a[1] - b[1])
43            data.reverse()
44            data = data[:self.MAX]
45            self.users = [i[0] for i in data]
46            self.total = [i[1] for i in data]
47        return self.users
48
49    def getTypes(self):
50        if self.types is None:
51            index = self.cat._catalog.getIndex('portal_type')
52            data = {}
53            for k in index._index.keys():
54                if not k:
55                    continue
56                haslen = hasattr(index._index[k], '__len__')
57                if haslen:
58                    data[k] = len(index._index[k])
59                else:
60                    data[k] = 1
61            data = data.items()
62            data.sort(lambda a, b: a[1] - b[1])
63            data.reverse()
64            self.types = [i[0] for i in data[:self.MAX]]
65        return self.types
66
67    def getContent(self, type_):
68        if type_ not in self.data:
69            data = self.data[type_] = []
70            for user in self.getUsers():
71                res = self.cat(portal_type=type_, Creator=user)
72                l = len(res)
73                if l == 0:
74                    data.append(0)
75                else:
76                    data.append(l)
77        return self.data[type_]
78
79    def getTotal(self):
80        return self.total
81
82    def getChart(self):
83        data = []
84        for type_ in self.getTypes():
85            data.append(self.getContent(type_))
86        max_value = max(self.getTotal())
87        chart = VerticalBarStack(data, encoding='text')
88        chart.title('Content ownership by type').legend(*self.types)
89        chart.bar('a', 10, 0).legend_pos("b")
90        chart.color('669933', 'CC9966', '993300', 'FF6633', 'E8E4E3', 'A9A486',
91                    'DCB57E', 'FFCC99', '996633', '333300')
92        chart.size(800, 375).scale(0,max_value).axes('xy').label(*self.users)
93        chart.axes.type("y")
94        chart.axes.range(0,0,max_value)
95        return chart.img()
96
97
98class OwnershipByState(BrowserView):
99    MAX = 10
100    def __init__(self, context, request):
101        self.context = context
102        self.request = request
103        self.cat = getToolByName(self.context, 'portal_catalog')
104        self.users = None
105        self.states = None
106        self.total = None
107        self.data = {}
108
109    def getUsers(self):
110        if self.users is None:
111            index = self.cat._catalog.getIndex('Creator')
112            data = {}
113            for k in index._index.keys():
114                haslen = hasattr(index._index[k], '__len__')
115                if haslen:
116                    data[k] = len(index._index[k])
117                else:
118                    data[k] = 1
119            data = data.items()
120            data.sort(lambda a, b: a[1] - b[1])
121            data.reverse()
122            data = data[:self.MAX]
123            self.users = [i[0] for i in data]
124            self.total = [i[1] for i in data]
125        return self.users
126
127    def getStates(self):
128        if self.states is None:
129            index = self.cat._catalog.getIndex('review_state')
130            data = {}
131            for k in index._index.keys():
132                haslen = hasattr(index._index[k], '__len__')
133                if haslen:
134                    data[k] = len(index._index[k])
135                else:
136                    data[k] = 1
137            data = data.items()
138            data.sort(lambda a, b: a[1] - b[1])
139            data.reverse()
140            self.states = [i[0] for i in data]
141        return self.states
142
143    def getContent(self, type_):
144        if type_ not in self.data:
145            data = self.data[type_] = []
146            for user in self.getUsers():
147                res = self.cat(review_state=type_, Creator=user)
148                l = len(res)
149                if l == 0:
150                    data.append(0)
151                else:
152                    data.append(l)
153        return self.data[type_]
154
155    def getTotal(self):
156        if self.total is None:
157            self.getUsers()
158        return self.total
159
160    def getChart(self):
161        data = []
162        for state in self.getStates():
163            data.append(self.getContent(state))
164        max_value = max(self.getTotal())
165        chart = VerticalBarStack(data, encoding='text')
166        chart.title('Content ownership by state').legend(*self.states)
167        chart.bar('a', 10, 0).legend_pos("b")
168        chart.color('669933', 'CC9966', '993300', 'FF6633', 'E8E4E3', 'A9A486',
169                    'DCB57E', 'FFCC99', '996633', '333300')
170        chart.size(800, 375).scale(0,max_value).axes('xy').label(*self.users)
171        chart.axes.type("y")
172        chart.axes.range(0,0,max_value)
173        return chart.img()
174
175
176class TypeByState(BrowserView):
177    MAX = 10
178    def __init__(self, context, request):
179        self.context = context
180        self.request = request
181        self.cat = getToolByName(self.context, 'portal_catalog')
182        self.types = None
183        self.states = None
184        self.total = None
185        self.data = {}
186
187    def getTypes(self):
188        if self.types is None:
189            index = self.cat._catalog.getIndex('portal_type')
190            data = {}
191            for k in index._index.keys():
192                if not k:
193                    continue
194                haslen = hasattr(index._index[k], '__len__')
195                if haslen:
196                    data[k] = len(index._index[k])
197                else:
198                    data[k] = 1
199            data = data.items()
200            data.sort(lambda a, b: a[1] - b[1])
201            data.reverse()
202            self.types = [i[0] for i in data[:self.MAX]]
203            self.total = [i[1] for i in data[:self.MAX]]
204        return self.types
205
206    def getStates(self):
207        if self.states is None:
208            index = self.cat._catalog.getIndex('review_state')
209            data = {}
210            for k in index._index.keys():
211                haslen = hasattr(index._index[k], '__len__')
212                if haslen:
213                    data[k] = len(index._index[k])
214                else:
215                    data[k] = 1
216            data = data.items()
217            data.sort(lambda a, b: a[1] - b[1])
218            data.reverse()
219            self.states = [i[0] for i in data]
220        return self.states
221
222    def getContent(self, state):
223        if state not in self.data:
224            data = self.data[state] = []
225            for type_ in self.getTypes():
226                res = self.cat(portal_type=type_, review_state=state)
227                l = len(res)
228                if l == 0:
229                    data.append(0)
230                else:
231                    data.append(l)
232        return self.data[state]
233
234    def getTotal(self):
235        if self.total is None:
236            self.getTypes()
237        return self.total
238
239    def getChart(self):
240        data = []
241        for state in self.getStates():
242            data.append(self.getContent(state))
243        max_value = max(self.getTotal())
244        chart = VerticalBarStack(data, encoding='text')
245        chart.title('Content type by state').legend(*self.states)
246        chart.bar('a', 10, 0).legend_pos("b")
247        chart.color('669933', 'CC9966', '993300', 'FF6633', 'E8E4E3', 'A9A486',
248                    'DCB57E', 'FFCC99', '996633', '333300')
249        chart.size(800, 375).scale(0,max_value).axes('xy').label(*self.types)
250        chart.axes.type("y")
251        chart.axes.range(0,0,max_value)
252        return chart.img()
253
254
255class LegacyPortlets(BrowserView):
256    def __init__(self, context, request):
257        self.context = context
258        self.request = request
259        self.total = None
260        self.DEBUG = False
261        self.expressions = set()
262
263    def _getInfo(self, obj):
264        href = obj.absolute_url()
265        path = '/'.join(obj.getPhysicalPath())
266        info = {
267            'path': path,
268            'href': href,
269            'left_slots': None,
270            'right_slots': None,
271        }
272        if IPropertyManager.providedBy(obj):
273            obj = aq_base(obj)
274            if obj.hasProperty('left_slots'):
275                info['left_slots'] = obj.getProperty('left_slots')
276                self.expressions = self.expressions.union(set(info['left_slots']))
277            if obj.hasProperty('right_slots'):
278                info['right_slots'] = obj.getProperty('right_slots')
279                self.expressions = self.expressions.union(set(info['right_slots']))
280        return info
281
282    def _walk(self, obj, level=-1):
283        yield self._getInfo(obj)
284        if level != 0 and (IFolderish.providedBy(obj) or IBaseFolder.providedBy(obj)):
285            for v in obj.contentValues():
286                for i in self._walk(v, level-1):
287                    yield i
288
289    def getPortlets(self):
290        level = self.request.form.get('level', 1)
291        level = int(level)
292        infos = []
293        for i in self._walk(self.context, level):
294            if self.DEBUG or i['left_slots'] is not None or i['right_slots'] is not None:
295                infos.append(i)
296        self.total = len(infos)
297        return infos
298
299    def getTotal(self):
300        return self.total
301
302    def getAllPortletExpressions(self):
303        exprs = []
304        for name in self.expressions:
305            name = name.split('|')[0]
306            if not '/macros/' in name:
307                name = name.split('/')[-1]
308            name = name.strip()
309            if name not in exprs:
310                exprs.append(name)
311        exprs.sort()
312        return exprs
313
314class PropertiesStats(BrowserView):
315    def __init__(self, context, request):
316        self.context = context
317        self.request = request
318        self.total = None
319        self.DEBUG = False
320        self.expressions = set()
321        self.proplist = []
322        self.propname = self.request.form.get('propname') or ""
323
324    def _getInfo(self, obj):
325
326        href = obj.absolute_url()
327        path = '/'.join(obj.getPhysicalPath())
328        info = {
329            'path': path,
330            'href': href,
331            'slots': None,
332        }
333        if IPropertyManager.providedBy(obj):
334            obj = aq_base(obj)
335            self.proplist.extend([i for i in obj.propertyIds() if i not in self.proplist])
336            if obj.hasProperty(self.propname):
337                info['slots'] = obj.getProperty(self.propname)
338                if isinstance(info['slots'], int):
339                    info['slots'] = str(info['slots'])
340                if not isinstance(info['slots'], basestring):
341                    self.expressions = self.expressions.union(set(info['slots']))
342                else:
343                    self.expressions = self.expressions.union(set([info['slots']]))
344        return info
345
346    def _walk(self, obj, level=-1):
347        yield self._getInfo(obj)
348        if level != 0 and (IFolderish.providedBy(obj) or IBaseFolder.providedBy(obj)):
349            for v in obj.contentValues():
350                for i in self._walk(v, level-1):
351                    yield i
352
353    def getPropsList(self):
354        level = self.request.form.get('level', 1)
355        level = int(level)
356        infos = []
357        for i in self._walk(self.context, level):
358            if self.DEBUG or i['slots'] is not None:
359                infos.append(i)
360        self.total = len(infos)
361        return infos
362
363    def getTotal(self):
364        return self.total
365
366    def getAllPortletExpressions(self):
367        exprs = []
368        for name in self.expressions:
369            name = name.strip()
370            if name not in exprs:
371                exprs.append(name)
372        #exprs.sort()
373        return exprs
374
375class PortletsStats(BrowserView):
376    def __init__(self, context, request):
377        self.context = context
378        self.request = request
379        self.total = None
380        self.DEBUG = False
381        self.expressions = set()
382        self.proplist = []
383        self.propname = self.request.form.get('propname') or ""
384
385    def getAssignmentMappingUrl(self, context, manager):
386        baseUrl = str(getMultiAdapter((context, self.request), name='absolute_url'))
387        return '%s/++contextportlets++%s' % (baseUrl, manager.__name__)
388
389    def getAssignmentsForManager(self, context, manager):
390        assignments = getMultiAdapter((context, manager), IPortletAssignmentMapping)
391        return assignments.values()
392
393    def getPortletsMapping(self, context):
394        leftcolumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=context)
395        rightcolumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=context)
396        leftmapping = getMultiAdapter((context, leftcolumn,), IPortletAssignmentMapping)
397        rightmapping = getMultiAdapter((context, rightcolumn,), IPortletAssignmentMapping)
398        return (leftmapping, rightmapping)
399
400    def getLocalPortletsManager(self, context):
401        leftcolumn = getUtility(IPortletManager, name='plone.leftcolumn', context=context)
402        rightcolumn = getUtility(IPortletManager, name='plone.rightcolumn', context=context)
403        leftmanager = getMultiAdapter((context, leftcolumn,), ILocalPortletAssignmentManager)
404        rightmanager = getMultiAdapter((context, rightcolumn,), ILocalPortletAssignmentManager)
405        return (leftmanager, rightmanager)
406
407    def getPortletsManager(self, context):
408        left = getUtility(IPortletManager, name='plone.leftcolumn', context=context)
409        right = getUtility(IPortletManager, name='plone.rightcolumn', context=context)
410        return (left, right)
411
412    def portlets_for_assignments(self, assignments, manager, base_url):
413        data = []
414        for idx in range(len(assignments)):
415            name = assignments[idx].__name__
416
417            editview = queryMultiAdapter(
418                (assignments[idx], self.request), name='edit', default=None)
419
420            if editview is None:
421                editviewName = ''
422            else:
423                editviewName = '%s/%s/edit' % (base_url, name)
424
425            settings = IPortletAssignmentSettings(assignments[idx])
426
427            data.append({
428                'title'      : assignments[idx].title,
429                'editview'   : editviewName,
430                'visible'    : settings.get('visible', True),
431                })
432        return data
433
434    def getPortlets(self, context, mapping, manager):
435        #import pdb; pdb.set_trace()
436        return mapping.keys()
437
438    def _getInfo(self, obj):
439        href = obj.absolute_url()
440        path = '/'.join(obj.getPhysicalPath())
441        info = {
442            'path': path,
443            'href': href,
444            'left_slots': None,
445            'right_slots': None,
446        }
447        left, right = self.getPortletsManager(obj)
448        #leftmapping, rightmapping = self.getPortletsMapping(obj)
449        #leftmanager, rightmanager = self.getLocalPortletsManager(obj)
450        #info['left_slots'] = self.getPortlets(obj, leftmapping, leftmanager)
451        #info['right_slots'] = self.getPortlets(obj, rightmapping, rightmanager)
452        lass = self.getAssignmentsForManager(obj, left)
453        rass = self.getAssignmentsForManager(obj, right)
454        lurl = self.getAssignmentMappingUrl(obj, left)
455        rurl = self.getAssignmentMappingUrl(obj, right)
456        plass = self.portlets_for_assignments(lass, left, lurl)
457        prass = self.portlets_for_assignments(rass, right, rurl)
458        #print obj, plass, prass
459        info['left_slots'] = plass #[i['title'] for i in plass]
460        info['right_slots'] = prass #[i['title'] for i in prass]
461        return info
462
463    def _walk(self, obj, level=-1):
464        try:
465            yield self._getInfo(obj)
466        except:
467            pass
468        if level != 0 and (IFolderish.providedBy(obj) or IBaseFolder.providedBy(obj)):
469            for v in obj.contentValues():
470                for i in self._walk(v, level-1):
471                    yield i
472
473    def getPropsList(self):
474        level = self.request.form.get('level', 1)
475        level = int(level)
476        infos = []
477        for i in self._walk(self.context, level):
478            if self.DEBUG or i['left_slots'] is not None or i['right_slots'] is not None:
479                infos.append(i)
480        self.total = len(infos)
481        return infos
482
483    def getTotal(self):
484        return self.total
485
486    def getAllPortletExpressions(self):
487        exprs = []
488        for name in self.expressions:
489            name = name.strip()
490            if name not in exprs:
491                exprs.append(name)
492        #exprs.sort()
493        return exprs
Note: See TracBrowser for help on using the repository browser.