provide CSV download view for reports; use for work and qualification listings
This commit is contained in:
parent
1716990d26
commit
e16f3e5ccf
7 changed files with 134 additions and 2 deletions
77
expert/browser/export.py
Normal file
77
expert/browser/export.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
#
|
||||
# Copyright (c) 2015 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
|
||||
#
|
||||
|
||||
"""
|
||||
View classes for export of report results.
|
||||
"""
|
||||
|
||||
import csv
|
||||
from cStringIO import StringIO
|
||||
from zope.i18n import translate
|
||||
|
||||
from loops.expert.browser.report import ReportConceptView
|
||||
from loops.interfaces import ILoopsObject
|
||||
from loops.util import _
|
||||
|
||||
|
||||
class ReportConceptCSVExport(ReportConceptView):
|
||||
|
||||
isToplevel = True
|
||||
reportMode = 'export'
|
||||
|
||||
delimiter = ';'
|
||||
encoding = 'UTF-8'
|
||||
|
||||
def getFileName(self):
|
||||
return 'output'
|
||||
|
||||
def getColumnTitle(self, field):
|
||||
lang = self.languageInfo.language
|
||||
return translate(_(field.title), target_language=lang)
|
||||
|
||||
def __call__(self):
|
||||
fields = self.displayedColumns
|
||||
fieldNames = [f.name for f in fields]
|
||||
output = StringIO()
|
||||
writer = csv.DictWriter(output, fieldNames, delimiter=self.delimiter)
|
||||
output.write(self.delimiter.join(
|
||||
[self.getColumnTitle(f) for f in fields]) + '\n')
|
||||
results = self.reportInstance.getResults()
|
||||
for row in results:
|
||||
data = {}
|
||||
for f in fields:
|
||||
value = f.getValue(row)
|
||||
if ILoopsObject.providedBy(value):
|
||||
value = value.title
|
||||
if isinstance(value, unicode):
|
||||
value = value.encode(self.encoding)
|
||||
data[f.name] = value
|
||||
writer.writerow(data)
|
||||
text = output.getvalue()
|
||||
self.setDownloadHeader(text)
|
||||
return text
|
||||
|
||||
def setDownloadHeader(self, text):
|
||||
response = self.request.response
|
||||
response.setHeader('Content-Disposition',
|
||||
'attachment; filename=%s.csv' %
|
||||
self.getFileName())
|
||||
response.setHeader('Cache-Control', '')
|
||||
response.setHeader('Pragma', '')
|
||||
response.setHeader('Content-Type', 'text/csv')
|
||||
response.setHeader('Content-Length', len(text))
|
|
@ -22,6 +22,7 @@ Field definitions for reports.
|
|||
|
||||
from zope.app.form.browser.interfaces import ITerms
|
||||
from zope import component
|
||||
from zope.i18n import translate
|
||||
from zope.i18n.locales import locales
|
||||
from zope.schema.interfaces import IVocabularyFactory, IContextSourceBinder
|
||||
|
||||
|
@ -92,6 +93,11 @@ class DateField(Field):
|
|||
format = ('date', 'short')
|
||||
cssClass = 'center'
|
||||
|
||||
def getValue(self, row):
|
||||
if getattr(row.parent.context.view, 'reportMode', None) == 'export':
|
||||
return self.getDisplayValue(row)
|
||||
super(DateField, self).getValue(row)
|
||||
|
||||
def getDisplayValue(self, row):
|
||||
value = self.getRawValue(row)
|
||||
if not value:
|
||||
|
@ -132,6 +138,15 @@ class WorkItemStateField(Field):
|
|||
statesDefinition = 'workItemStates'
|
||||
renderer = 'workitem_state'
|
||||
|
||||
def getValue(self, row):
|
||||
view = row.parent.context.view
|
||||
if getattr(view, 'reportMode', None) == 'export':
|
||||
stateObject = row.context.getStateObject()
|
||||
lang = view.languageInfo.language
|
||||
return translate(util._(stateObject.title), target_language=lang)
|
||||
return super(WorkItemStateField, self).getValue(row)
|
||||
|
||||
|
||||
def getDisplayValue(self, row):
|
||||
if row.context is None:
|
||||
return None
|
||||
|
@ -241,14 +256,18 @@ class TrackDateField(Field):
|
|||
cssClass = 'right'
|
||||
|
||||
def getValue(self, row):
|
||||
reportMode = getattr(row.parent.context.view, 'reportMode', None)
|
||||
if reportMode == 'export':
|
||||
return self.getDisplayValue(row)
|
||||
value = self.getRawValue(row)
|
||||
if not value:
|
||||
return None
|
||||
return timeStamp2Date(value)
|
||||
|
||||
def getDisplayValue(self, row):
|
||||
value = self.getValue(row)
|
||||
value = self.getRawValue(row)
|
||||
if value:
|
||||
value = timeStamp2Date(value)
|
||||
view = row.parent.context.view
|
||||
return formatDate(value, self.part, self.format,
|
||||
view.languageInfo.language)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2014 Helmut Merz helmutm@cy55.de
|
||||
# Copyright (c) 2015 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
|
||||
|
@ -26,6 +26,7 @@ from zope.app.pagetemplate import ViewPageTemplateFile
|
|||
from zope.cachedescriptors.property import Lazy
|
||||
|
||||
from loops.browser.concept import ConceptView
|
||||
from loops.expert.browser.export import ReportConceptCSVExport
|
||||
from loops.expert.browser.report import ResultsConceptView
|
||||
from loops.organize.party import getPersonForUser
|
||||
from loops.util import _
|
||||
|
@ -35,3 +36,8 @@ class Qualifications(ResultsConceptView):
|
|||
|
||||
reportName = 'qualification_overview'
|
||||
|
||||
|
||||
class QualificationsCSVExport(ReportConceptCSVExport):
|
||||
|
||||
reportName = 'qualification_overview'
|
||||
|
||||
|
|
|
@ -23,6 +23,12 @@
|
|||
factory="loops.knowledge.qualification.browser.Qualifications"
|
||||
permission="zope.View" />
|
||||
|
||||
<browser:page
|
||||
name="qualifications.csv"
|
||||
for="loops.organize.interfaces.IConceptSchema"
|
||||
class="loops.knowledge.qualification.browser.QualificationsCSVExport"
|
||||
permission="zope.View" />
|
||||
|
||||
<!-- reports -->
|
||||
|
||||
<zope:adapter
|
||||
|
|
|
@ -234,6 +234,18 @@ The user interface is a ReportConceptView subclass that is directly associated w
|
|||
>>> results.totals.data
|
||||
{'effort': 900}
|
||||
|
||||
Export of work data
|
||||
-------------------
|
||||
|
||||
>>> from loops.organize.work.report import WorkStatementCSVExport
|
||||
>>> reportView = WorkStatementCSVExport(task01, TestRequest())
|
||||
>>> reportView.nodeView = nodeView
|
||||
|
||||
>>> output = reportView()
|
||||
>>> print output
|
||||
Day;Start;End;Task;Party;Title;Duration;Effort;State
|
||||
08/12/28;19:00;20:15;loops Development;john;;1.25;0.25;finished
|
||||
|
||||
|
||||
Meeting Minutes
|
||||
===============
|
||||
|
|
|
@ -101,6 +101,12 @@
|
|||
class="loops.organize.work.report.WorkStatementView"
|
||||
permission="zope.View" />
|
||||
|
||||
<browser:page
|
||||
name="work.csv"
|
||||
for="loops.organize.interfaces.IConceptSchema"
|
||||
class="loops.organize.work.report.WorkStatementCSVExport"
|
||||
permission="zope.View" />
|
||||
|
||||
<zope:adapter
|
||||
name="meeting_minutes"
|
||||
factory="loops.organize.work.report.MeetingMinutes"
|
||||
|
|
|
@ -32,6 +32,7 @@ from cybertools.organize.interfaces import IWorkItems
|
|||
from cybertools.util.date import timeStamp2Date, timeStamp2ISO
|
||||
from cybertools.util.jeep import Jeep
|
||||
from loops.common import adapted, baseObject
|
||||
from loops.expert.browser.export import ReportConceptCSVExport
|
||||
from loops.expert.browser.report import ReportConceptView
|
||||
from loops.expert.field import Field, TargetField, DateField, StateField, \
|
||||
TextField, HtmlTextField, UrlField
|
||||
|
@ -49,6 +50,11 @@ class WorkStatementView(ReportConceptView):
|
|||
reportName = 'work_statement'
|
||||
|
||||
|
||||
class WorkStatementCSVExport(ReportConceptCSVExport):
|
||||
|
||||
reportName = 'work_statement'
|
||||
|
||||
|
||||
# fields
|
||||
|
||||
class DurationField(Field):
|
||||
|
|
Loading…
Add table
Reference in a new issue