provide a comments overview listing, e.g. for moderation of comments

This commit is contained in:
Helmut Merz 2014-04-19 10:48:45 +02:00
parent f34dc4a59c
commit 2d2240244e
8 changed files with 175 additions and 38 deletions

View file

@ -16,6 +16,7 @@
<div metal:use-macro="item/report_macros/params" />
<div metal:define-macro="buttons">
<input type="submit" name="report_execute" value="Execute Report"
tal:condition="item/queryFields"
i18n:attributes="value" />
</div>
</form>

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2013 Helmut Merz helmutm@cy55.de
# Copyright (c) 2014 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
@ -29,6 +29,7 @@ from cybertools.composer.report.field import Field as BaseField
from cybertools.composer.report.result import ResultSet
from cybertools.stateful.interfaces import IStateful, IStatesDefinition
from cybertools.util.date import timeStamp2Date
from cybertools.util.format import formatDate
from loops.common import baseObject
from loops.expert.report import ReportInstance
from loops import util
@ -209,6 +210,41 @@ class TargetField(RelationField):
return util.getObjectForUid(value)
# track fields
class TrackDateField(Field):
fieldType = 'date'
part = 'date'
format = 'short'
cssClass = 'right'
def getValue(self, row):
value = self.getRawValue(row)
if not value:
return None
return timeStamp2Date(value)
def getDisplayValue(self, row):
value = self.getValue(row)
if value:
view = row.parent.context.view
return formatDate(value, self.part, self.format,
view.languageInfo.language)
return u''
def getSelectValue(self, row):
value = self.getRawValue(row)
if not value:
return ''
return timeStamp2ISO(value)[:10]
class TrackTimeField(TrackDateField):
part = 'time'
# sub-report stuff
class SubReport(ReportInstance):

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2012 Helmut Merz helmutm@cy55.de
# Copyright (c) 2014 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
@ -25,9 +25,11 @@ 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.base import LeafQueryCriteria
from cybertools.composer.report.base import 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
@ -53,6 +55,8 @@ class IReport(ILoopsAdapter, IReportParams):
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
@ -68,6 +72,10 @@ class Report(AdapterBase):
_contextAttributes = list(IReport)
@Lazy
def name(self):
return getName(self.context)
TypeInterfaceSourceList.typeInterfaces += (IReport,)
@ -79,9 +87,11 @@ class ReportInstance(BaseReport):
rowFactory = Row
view = None # set upon creation
#headerRowFactory = Row
def __init__(self, context):
self.context = context
self.name = self.type
def getResultsRenderer(self, name, macros):
return macros[name]
@ -105,6 +115,8 @@ class ReportInstance(BaseReport):
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,
@ -161,3 +173,15 @@ class DefaultConceptReportInstance(ReportInstance):
label = u'Default Concept Report'
# specialized rows
class TrackRow(Row):
@staticmethod
def getContextAttr(obj, attr):
if attr in obj.context.metadata_attributes:
return getattr(obj.context, attr)
return obj.context.data.get(attr)

View file

@ -78,6 +78,12 @@ Viewing comments
('My comment', u'... ...', u'john')
Reporting
=========
>>> from loops.organize.comment.report import CommentsOverview
Fin de partie
=============

View file

@ -37,4 +37,26 @@
factory="loops.organize.comment.browser.CreateComment"
permission="zope.View" />
<!-- reporting -->
<zope:adapter
name="list_comments.html"
for="loops.interfaces.IConcept
zope.publisher.interfaces.browser.IBrowserRequest"
provides="zope.interface.Interface"
factory="loops.organize.comment.report.CommentsOverview"
permission="zope.View" />
<zope:adapter
name="comments_overview"
factory="loops.organize.comment.report.CommentsReportInstance"
provides="loops.expert.report.IReportInstance"
trusted="True" />
<zope:class class="loops.organize.comment.report.CommentsReportInstance">
<require permission="zope.View"
interface="loops.expert.report.IReportInstance" />
<require permission="zope.ManageContent"
set_schema="loops.expert.report.IReportInstance" />
</zope:class>
</configure>

View file

@ -0,0 +1,6 @@
type(u'report', u'Report', options=u'',
typeInterface='loops.expert.report.IReport', viewName=u'')
concept(u'comments_overview', u'\xdcbersicht Kommentare', u'report',
reportType=u'comments_overview')
concept(u'comments', u'Kommentare', u'query', options=u'',
viewName=u'list_comments.html')

View file

@ -0,0 +1,75 @@
#
# Copyright (c) 2014 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 views and definitions for comments listings and similar stuff.
"""
from cybertools.util.jeep import Jeep
from loops.expert.browser.report import ReportConceptView
from loops.expert.field import Field, StateField, TargetField
from loops.expert.field import TrackDateField
from loops.expert.report import ReportInstance, TrackRow
class CommentsOverview(ReportConceptView):
reportName = 'comments_overview'
timeStamp = TrackDateField('timeStamp', u'Timestamp',
description=u'The date and time the comment was posted.',
part='dateTime',
executionSteps=['sort', 'output'])
target = TargetField('taskId', u'Target',
description=u'The resource or concept the comment was posted at.',
executionSteps=['output'])
name = Field('name', u'Name',
description=u'The name addres of the poster.',
executionSteps=['output'])
email = Field('email', u'E-Mail Address',
description=u'The email addres of the poster.',
executionSteps=['output'])
subject = Field('subject', u'Subject',
description=u'The subject of the comment.',
executionSteps=['output'])
state = StateField('state', u'State',
description=u'The state of the comment.',
cssClass='center',
statesDefinition='organize.commentStates',
executionSteps=['query', 'sort', 'output'])
class CommentsRow(TrackRow):
pass
class CommentsReportInstance(ReportInstance):
type = "comments_overview"
label = u'Comments Overview'
rowFactory = CommentsRow
fields = Jeep((timeStamp, target, name, email, subject, state))
defaultOutputFields = fields
defaultSortCriteria = (state, timeStamp)
def selectObjects(self, parts):
return self.recordManager['comments'].values()

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2013 Helmut Merz helmutm@cy55.de
# Copyright (c) 2014 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
@ -30,13 +30,13 @@ from cybertools.composer.report.field import CalculatedField
from cybertools.composer.report.result import ResultSet, Row as BaseRow
from cybertools.organize.interfaces import IWorkItems
from cybertools.util.date import timeStamp2Date, timeStamp2ISO
from cybertools.util.format import formatDate
from cybertools.util.jeep import Jeep
from loops.common import adapted, baseObject
from loops.expert.browser.report import ReportConceptView
from loops.expert.field import Field, TargetField, DateField, StateField, \
TextField, HtmlTextField, UrlField
from loops.expert.field import SubReport, SubReportField
from loops.expert.field import TrackDateField, TrackTimeField
from loops.expert.report import ReportInstance
from loops import util
@ -50,39 +50,6 @@ class WorkStatementView(ReportConceptView):
# fields
class TrackDateField(Field):
fieldType = 'date'
part = 'date'
format = 'short'
cssClass = 'right'
def getValue(self, row):
value = self.getRawValue(row)
if not value:
return None
return timeStamp2Date(value)
def getDisplayValue(self, row):
value = self.getValue(row)
if value:
view = row.parent.context.view
return formatDate(value, self.part, self.format,
view.languageInfo.language)
return u''
def getSelectValue(self, row):
value = self.getRawValue(row)
if not value:
return ''
return timeStamp2ISO(value)[:10]
class TrackTimeField(TrackDateField):
part = 'time'
class DurationField(Field):
cssClass = 'right'