loops/expert/report.py
2013-11-22 10:54:32 +01:00

174 lines
4.9 KiB
Python

#
# Copyright (c) 2012 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Report type, report concept adapter, and other reporting stuff.
"""
from zope import schema, component
from zope.component import adapts
from zope.interface import Interface, Attribute, implements
from zope.cachedescriptors.property import Lazy
from zope.security.proxy import removeSecurityProxy
from zope.traversing.api import getName
from cybertools.composer.report.base import Report as BaseReport
from cybertools.composer.report.base import LeafQueryCriteria, CompoundQueryCriteria
from cybertools.composer.report.interfaces import IReport as IBaseReport
from cybertools.composer.report.interfaces import IReportParams
from cybertools.composer.report.result import ResultSet, Row
from cybertools.util.jeep import Jeep
from loops.common import AdapterBase
from loops.interfaces import ILoopsAdapter
from loops.type import TypeInterfaceSourceList
from loops import util
from loops.util import _
# interfaces
class IReport(ILoopsAdapter, IReportParams):
""" The report adapter for the persistent object (concept) that stores
the report in the concept map.
"""
reportType = schema.Choice(
title=_(u'Report Type'),
description=_(u'The type of the report.'),
default=None,
source='loops.expert.reportTypeSource',
required=True)
name = Attribute('The name of the report.')
class IReportInstance(IBaseReport):
""" The report-type-specific object (an adapter on the report) that
does the real report execution stuff.
"""
# report concept adapter and instances
class Report(AdapterBase):
implements(IReport)
_contextAttributes = list(IReport)
@Lazy
def name(self):
return getName(self.context)
TypeInterfaceSourceList.typeInterfaces += (IReport,)
class ReportInstance(BaseReport):
implements(IReportInstance)
adapts(IReport)
rowFactory = Row
#headerRowFactory = Row
view = None # set upon creation
def __init__(self, context):
self.context = context
self.name = self.type
def getResultsRenderer(self, name, macros):
return macros[name]
@property
def queryCriteria(self):
return self.context.queryCriteria
def getResults(self, dynaParams=None):
crit = self.queryCriteria
limits = self.limits
if crit is None:
parts = Jeep()
#return ResultSet(self, [])
else:
if dynaParams is not None:
for k, v in dynaParams.items():
if k == 'limits':
limits = v
break
if k in crit.parts.keys():
crit.parts[k].comparisonValue = v
parts = Jeep(crit.parts)
if getattr(self, 'limitsCount', ''):
limits = None
result = list(self.selectObjects(parts)) # may modify parts
qc = CompoundQueryCriteria(parts)
return ResultSet(self, result, rowFactory=self.rowFactory,
sortCriteria=self.getSortCriteria(), queryCriteria=qc,
limits=limits)
def selectObjects(self, parts):
# to be implemented by subclass
return []
@Lazy
def conceptManager(self):
return self.view.conceptManager
@Lazy
def recordManager(self):
return self.view.loopsRoot.getRecordManager()
@Lazy
def hasReportPredicate(self):
return self.conceptManager['hasreport']
class ReportTypeSourceList(object):
implements(schema.interfaces.IIterableSource)
def __init__(self, context):
self.context = context
def __iter__(self):
return iter(self.reportTypes)
def __contains__(self, value):
return value in [item[0] for item in self]
@Lazy
def reportTypes(self):
result = []
for item in component.getAdapters([self.context], IReportInstance):
name, adapter = item
adapter = removeSecurityProxy(adapter)
label = getattr(adapter, 'label', name)
result.append((name, label,))
return result
def __len__(self):
return len(self.reportTypes)
# default concept report
class DefaultConceptReportInstance(ReportInstance):
label = u'Default Concept Report'