source: main/waeup.kofa/trunk/src/waeup/kofa/students/export.py @ 8431

Last change on this file since 8431 was 8414, checked in by uli, 13 years ago

Reduce redundance a bit.

  • Property svn:keywords set to Id
File size: 9.2 KB
RevLine 
[8057]1## $Id: export.py 8414 2012-05-10 22:06:17Z uli $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
[7944]18"""Exporters for student related stuff.
19"""
20import grok
21from zope.catalog.interfaces import ICatalog
22from zope.component import queryUtility
23from waeup.kofa.interfaces import MessageFactory as _
[8015]24from waeup.kofa.students.interfaces import (
[8371]25    IStudent, IStudentStudyCourse, IStudentStudyLevel, ICourseTicket,
[8411]26    IStudentOnlinePayment, ICSVStudentExporter)
[7944]27from waeup.kofa.utils.batching import ExporterBase
28from waeup.kofa.utils.helpers import iface_names
29
[8400]30#: A tuple containing all exporter names referring to students or
31#: subobjects thereof.
32EXPORTER_NAMES = ('students', 'studentstudycourses', 'studentstudylevels',
33                  'coursetickets', 'studentpayments')
34
[8414]35def get_students(site):
36    """Get all students registered in catalog in `site`.
[7944]37    """
[8414]38    catalog = queryUtility(
39        ICatalog, context=site, name='students_catalog', default=None)
40    if catalog is None:
41        return []
42    students = catalog.searchResults(student_id=(None, None))
43    return students
44
45def get_studycourses(students):
46    """Get studycourses of `students`.
47    """
48    return [x.get('studycourse', None) for x in students
49            if x is not None]
50
51def get_levels(students):
52    """Get all studylevels of `students`.
53    """
54    levels = []
55    for course in get_studycourses(students):
56        for level in course.values():
57            levels.append(level)
58    return levels
59
60def get_tickets(students):
61    """Get all course tickets of `students`.
62    """
63    tickets = []
64    for level in get_levels(students):
65        for ticket in level.values():
66            tickets.append(ticket)
67    return tickets
68
69def get_payments(students):
70    """Get all payments of `students`.
71    """
72    payments = []
73    for student in students:
74        for payment in student.get('payments', {}).values():
75            payments.append(payment)
76    return payments
77
78
79class StudentExporterBase(ExporterBase):
80    """Exporter for students or related objects.
81
82    This is a baseclass.
83    """
84    grok.baseclass()
[8411]85    grok.implements(ICSVStudentExporter)
86    grok.provides(ICSVStudentExporter)
[8414]87
88    def export(self, values, filepath=None):
89        """Export `values`, an iterable, as CSV file.
90
91        If `filepath` is ``None``, a raw string with CSV data is returned.
92        """
93        writer, outfile = self.get_csv_writer(filepath)
94        for value in values:
95            self.write_item(value, writer)
96        return self.close_outfile(filepath, outfile)
97
98
99class StudentsExporter(grok.GlobalUtility, StudentExporterBase):
100    """Exporter for Students.
101    """
[7944]102    grok.name('students')
103
104    #: Fieldnames considered by this exporter
105    fields = tuple(sorted(iface_names(IStudent, omit=['loggerInfo'])))
106
107    #: The title under which this exporter will be displayed
108    title = _(u'Students')
109
110    def export_all(self, site, filepath=None):
111        """Export students into filepath as CSV data.
112
113        If `filepath` is ``None``, a raw string with CSV data is returned.
114        """
[8414]115        return self.export(get_students(site), filepath)
[7994]116
[8411]117    def export_student(self, student, filepath=None):
118        return self.export([student], filepath=filepath)
119
[8414]120
121class StudentStudyCourseExporter(grok.GlobalUtility, StudentExporterBase):
[7994]122    """Exporter for StudentStudyCourses.
123    """
124    grok.name('studentstudycourses')
125
126    #: Fieldnames considered by this exporter
127    fields = tuple(sorted(iface_names(IStudentStudyCourse)))
128
129    #: The title under which this exporter will be displayed
130    title = _(u'Student Study Courses')
131
132    def mangle_value(self, value, name, context=None):
133        """Add the hash symbol at the end of date_of_birth.
134
135        This is to avoid annoying automatic date transformation
136        by Excel or Calc.
137        """
138        if name == 'certificate' and value is not None:
139            # XXX: hopefully cert codes are unique site-wide
140            value = value.code
141        return super(
142            StudentStudyCourseExporter, self).mangle_value(
143            value, name, context=context)
144
145    def export_all(self, site, filepath=None):
146        """Export study courses into filepath as CSV data.
147
148        If `filepath` is ``None``, a raw string with CSV data is returned.
149        """
[8414]150        return self.export(get_studycourses(get_students(site)), filepath)
[8015]151
[8411]152    def export_student(self, student, filepath=None):
[8414]153        """Export studycourse of a single student object.
154        """
155        return self.export(get_studycourses([student]), filepath)
[8411]156
157
[8414]158class StudentStudyLevelExporter(grok.GlobalUtility, StudentExporterBase):
[8015]159    """Exporter for StudentStudyLevels.
160    """
161    grok.name('studentstudylevels')
162
163    #: Fieldnames considered by this exporter
164    fields = tuple(sorted(iface_names(IStudentStudyLevel) + [
165        'reg_number', 'matric_number', 'level']))
166
167    #: The title under which this exporter will be displayed
168    title = _(u'Student Study Levels')
169
170    def mangle_value(self, value, name, context=None):
171        """Add the hash symbol at the end of date_of_birth.
172
173        This is to avoid annoying automatic date transformation
174        by Excel or Calc.
175        """
176
177        if name == 'reg_number' and context is not None:
178            value = getattr(
179                getattr(getattr(context, '__parent__', None),
180                        '__parent__', None), 'reg_number', None)
181        if name == 'matric_number' and context is not None:
182            value = getattr(
183                getattr(getattr(context, '__parent__', None),
184                        '__parent__', None), 'matric_number', None)
185        return super(
186            StudentStudyLevelExporter, self).mangle_value(
187            value, name, context=context)
188
189    def export_all(self, site, filepath=None):
190        """Export study levels into filepath as CSV data.
191
192        If `filepath` is ``None``, a raw string with CSV data is returned.
193        """
[8414]194        return self.export(get_levels(get_students(site)), filepath)
[8342]195
[8411]196    def export_student(self, student, filepath=None):
[8414]197        return self.export(get_levels([student]), filepath)
[8411]198
[8414]199class CourseTicketExporter(grok.GlobalUtility, StudentExporterBase):
[8342]200    """Exporter for CourseTickets.
201    """
202    grok.name('coursetickets')
203
204    #: Fieldnames considered by this exporter
205    fields = tuple(sorted(iface_names(ICourseTicket) + [
206        'reg_number', 'matric_number', 'level', 'code', 'title', 'credits',
207        'passmark', 'semester', 'fcode', 'dcode']))
208
209    #: The title under which this exporter will be displayed
210    title = _(u'Course Tickets')
211
212    def mangle_value(self, value, name, context=None):
213        """Treat location values special.
214        """
215        if context is not None:
216            student = context.getStudent()
217            if name in ['reg_number', 'matric_number'] and student is not None:
218                value = getattr(student, name, None)
219            if name == 'level':
[8393]220                value = getattr(context, 'getLevel', lambda: None)()
[8342]221        return super(
222            CourseTicketExporter, self).mangle_value(
223            value, name, context=context)
224
225    def export_all(self, site, filepath=None):
226        """Export course tickets into filepath as CSV data.
227
228        If `filepath` is ``None``, a raw string with CSV data is returned.
229        """
[8414]230        return self.export(get_tickets(get_students(site)), filepath)
[8342]231
[8411]232    def export_student(self, student, filepath=None):
[8414]233        return self.export(get_tickets([student]), filepath)
[8411]234
[8414]235
236class PaymentsExporter(grok.GlobalUtility, StudentExporterBase):
[8371]237    """Exporter for OnlinePayment instances.
238    """
239    grok.name('studentpayments')
240
241    #: Fieldnames considered by this exporter
242    fields = tuple(
243        sorted(['reg_number', 'matric_number'] +
244               iface_names(IStudentOnlinePayment, exclude_attribs=False)))
245
246    #: The title under which this exporter will be displayed
247    title = _(u'Course Tickets')
248
249    def mangle_value(self, value, name, context=None):
250        """Treat location values special.
251        """
252        if context is not None:
253            student = context.getStudent()
254            if name in ['reg_number', 'matric_number'] and student is not None:
255                value = getattr(student, name, None)
256        return super(
257            PaymentsExporter, self).mangle_value(
258            value, name, context=context)
259
260    def export_all(self, site, filepath=None):
261        """Export payments into filepath as CSV data.
262
263        If `filepath` is ``None``, a raw string with CSV data is returned.
264        """
[8414]265        return self.export(get_payments(get_students(site)), filepath)
[8411]266
267    def export_student(self, student, filepath=None):
[8414]268        return self.export(get_payments([student]), filepath)
Note: See TracBrowser for help on using the repository browser.