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

Last change on this file since 9253 was 9253, checked in by Henrik Bettermann, 12 years ago

Export always certcode which is very helpful for offline data evaluation. Also add current_level, current_session and is_postgrad to StudentExporter?.

  • Property svn:keywords set to Id
File size: 9.4 KB
Line 
1## $Id: export.py 9253 2012-09-28 09:56:23Z henrik $
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##
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 _
24from waeup.kofa.students.interfaces import (
25    IStudent, IStudentStudyCourse, IStudentStudyLevel, ICourseTicket,
26    IStudentOnlinePayment, ICSVStudentExporter)
27from waeup.kofa.utils.batching import ExporterBase
28from waeup.kofa.utils.helpers import iface_names
29
30#: A tuple containing all exporter names referring to students or
31#: subobjects thereof.
32EXPORTER_NAMES = ('students', 'studentstudycourses', 'studentstudylevels',
33                  'coursetickets', 'studentpayments')
34
35def get_students(site):
36    """Get all students registered in catalog in `site`.
37    """
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()
85    grok.implements(ICSVStudentExporter)
86    grok.provides(ICSVStudentExporter)
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    """
102    grok.name('students')
103
104    #: Fieldnames considered by this exporter
105    fields = tuple(sorted(iface_names(
106        IStudent, omit=['loggerInfo']))) + (
107        'password', 'state', 'history', 'certcode', 'is_postgrad',
108        'current_level', 'current_session')
109
110    #: The title under which this exporter will be displayed
111    title = _(u'Students')
112
113    def mangle_value(self, value, name, context=None):
114        if name == 'history':
115            value = value.messages
116        if name == 'phone' and value is not None:
117            # Append hash '#' to phone numbers to circumvent
118            # unwanted excel automatic
119            value = str('%s#' % value)
120        return super(
121            StudentsExporter, self).mangle_value(
122            value, name, context=context)
123
124    def export_all(self, site, filepath=None):
125        """Export students into filepath as CSV data.
126
127        If `filepath` is ``None``, a raw string with CSV data is returned.
128        """
129        return self.export(get_students(site), filepath)
130
131    def export_student(self, student, filepath=None):
132        return self.export([student], filepath=filepath)
133
134
135class StudentStudyCourseExporter(grok.GlobalUtility, StudentExporterBase):
136    """Exporter for StudentStudyCourses.
137    """
138    grok.name('studentstudycourses')
139
140    #: Fieldnames considered by this exporter
141    fields = tuple(sorted(iface_names(IStudentStudyCourse))) + ('student_id',)
142
143    #: The title under which this exporter will be displayed
144    title = _(u'Student Study Courses')
145
146    def mangle_value(self, value, name, context=None):
147        """Treat location values special.
148        """
149        if name == 'certificate' and value is not None:
150            # XXX: hopefully cert codes are unique site-wide
151            value = value.code
152        if name == 'student_id' and context is not None:
153            student = context.student
154            value = getattr(student, name, None)
155        return super(
156            StudentStudyCourseExporter, self).mangle_value(
157            value, name, context=context)
158
159    def export_all(self, site, filepath=None):
160        """Export study courses into filepath as CSV data.
161
162        If `filepath` is ``None``, a raw string with CSV data is returned.
163        """
164        return self.export(get_studycourses(get_students(site)), filepath)
165
166    def export_student(self, student, filepath=None):
167        """Export studycourse of a single student object.
168        """
169        return self.export(get_studycourses([student]), filepath)
170
171
172class StudentStudyLevelExporter(grok.GlobalUtility, StudentExporterBase):
173    """Exporter for StudentStudyLevels.
174    """
175    grok.name('studentstudylevels')
176
177    #: Fieldnames considered by this exporter
178    fields = tuple(sorted(iface_names(
179        IStudentStudyLevel) + ['level'])) + (
180        'student_id', 'number_of_tickets','certcode')
181
182    #: The title under which this exporter will be displayed
183    title = _(u'Student Study Levels')
184
185    def mangle_value(self, value, name, context=None):
186        """Treat location values special.
187        """
188        if name == 'student_id' and context is not None:
189            student = context.student
190            value = getattr(student, name, None)
191        return super(
192            StudentStudyLevelExporter, self).mangle_value(
193            value, name, context=context)
194
195    def export_all(self, site, filepath=None):
196        """Export study levels into filepath as CSV data.
197
198        If `filepath` is ``None``, a raw string with CSV data is returned.
199        """
200        return self.export(get_levels(get_students(site)), filepath)
201
202    def export_student(self, student, filepath=None):
203        return self.export(get_levels([student]), filepath)
204
205class CourseTicketExporter(grok.GlobalUtility, StudentExporterBase):
206    """Exporter for CourseTickets.
207    """
208    grok.name('coursetickets')
209
210    #: Fieldnames considered by this exporter
211    fields = tuple(sorted(iface_names(ICourseTicket) +
212        ['level', 'code', 'title', 'credits',
213        'passmark', 'semester', 'fcode', 'dcode'])) + ('student_id', 'certcode')
214
215    #: The title under which this exporter will be displayed
216    title = _(u'Course Tickets')
217
218    def mangle_value(self, value, name, context=None):
219        """Treat location values special.
220        """
221        if context is not None:
222            student = context.student
223            if name == 'student_id' and student is not None:
224                value = getattr(student, name, None)
225            if name == 'level':
226                value = getattr(context, 'getLevel', lambda: None)()
227        return super(
228            CourseTicketExporter, self).mangle_value(
229            value, name, context=context)
230
231    def export_all(self, site, filepath=None):
232        """Export course tickets into filepath as CSV data.
233
234        If `filepath` is ``None``, a raw string with CSV data is returned.
235        """
236        return self.export(get_tickets(get_students(site)), filepath)
237
238    def export_student(self, student, filepath=None):
239        return self.export(get_tickets([student]), filepath)
240
241
242class PaymentsExporter(grok.GlobalUtility, StudentExporterBase):
243    """Exporter for OnlinePayment instances.
244    """
245    grok.name('studentpayments')
246
247    #: Fieldnames considered by this exporter
248    fields = tuple(
249        sorted(iface_names(
250            IStudentOnlinePayment, exclude_attribs=False))) + ('student_id',)
251
252    #: The title under which this exporter will be displayed
253    title = _(u'Student Payments')
254
255    def mangle_value(self, value, name, context=None):
256        """Treat location values special.
257        """
258        if context is not None:
259            student = context.student
260            if name in ['student_id'] and student is not None:
261                value = getattr(student, name, None)
262        return super(
263            PaymentsExporter, self).mangle_value(
264            value, name, context=context)
265
266    def export_all(self, site, filepath=None):
267        """Export payments into filepath as CSV data.
268
269        If `filepath` is ``None``, a raw string with CSV data is returned.
270        """
271        return self.export(get_payments(get_students(site)), filepath)
272
273    def export_student(self, student, filepath=None):
274        return self.export(get_payments([student]), filepath)
Note: See TracBrowser for help on using the repository browser.