source: products/quintagroup.contentstats/trunk/quintagroup/contentstats/browser.py @ 2870

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

initial import.

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