source: main/waeup.sirp/trunk/src/waeup/sirp/university/export.py @ 7753

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

Add cert-exporter. Fix department code export for certs and courses.

File size: 6.4 KB
Line 
1"""Exporters for faculties, departments, and other academics components.
2"""
3import csv
4import grok
5from cStringIO import StringIO
6from waeup.sirp.interfaces import ICSVExporter
7
8class FacultyExporter(grok.GlobalUtility):
9    """Exporter for faculties.
10    """
11    grok.implements(ICSVExporter)
12    grok.name('faculties')
13
14    #: Fieldnames considered by this exporter
15    fields = ('code', 'title', 'title_prefix')
16
17    def mangle_value(self, value, name, context=None):
18        """Hook for mangling values in derived classes
19        """
20        if isinstance(value, unicode):
21            # CSV writers like byte streams better than unicode
22            value = value.encode('utf-8')
23        if value is None:
24            # None is not really representable in CSV files
25            value = ''
26        return value
27
28    def get_csv_writer(self, filepath=None):
29        """Get a CSV dict writer instance open for writing.
30
31        Returns a tuple (<writer>, <outfile>) where ``<writer>`` is a
32        :class:`csv.DictWriter` instance and outfile is the real file
33        which is written to. The latter is important when writing to
34        StringIO and can normally be ignored otherwise.
35
36        The returned file will already be filled with the header row.
37        """
38        if filepath is None:
39            outfile = StringIO()
40        else:
41            outfile = open(filepath, 'wb')
42        writer = csv.DictWriter(outfile, self.fields)
43        writer.writerow(dict(zip(self.fields, self.fields))) # header
44        return writer, outfile
45
46    def write_item(self, faculty, writer):
47        """Write a row into using `writer`.
48        """
49        row = {}
50        for name in self.fields:
51            value = getattr(faculty, name, None)
52            value = self.mangle_value(value, name, faculty)
53            row[name] = value
54        writer.writerow(row)
55        return
56
57    def close_outfile(self, filepath, outfile):
58        """Close outfile.
59
60        If filepath is None, the contents of outfile is returned.
61        """
62        outfile.seek(0)
63        if filepath is None:
64            return outfile.read()
65        outfile.close()
66        return
67
68    def export(self, faculties, filepath=None):
69        """Export `faculties`, an iterable, as CSV file.
70
71        If `filepath` is ``None``, a raw string with CSV data is returned.
72        """
73        writer, outfile = self.get_csv_writer(filepath)
74        for faculty in faculties:
75            self.write_item(faculty, writer)
76        return self.close_outfile(filepath, outfile)
77
78    def export_all(self, site, filepath=None):
79        """Export faculties in facultycontainer into filepath as CSV data.
80
81        If `filepath` is ``None``, a raw string with CSV data is returned.
82        """
83        writer, outfile = self.get_csv_writer(filepath)
84        faculties = site.get('faculties', {})
85        return self.export(faculties.values(), filepath)
86        for faculty in faculties.values():
87            self.write_item(faculty, writer)
88        return self.close_outfile(filepath, outfile)
89
90class DepartmentExporter(FacultyExporter, grok.GlobalUtility):
91    """Exporter for departments.
92    """
93    grok.implements(ICSVExporter)
94    grok.name('departments')
95
96    #: Fieldnames considered by this exporter
97    fields = ('code', 'faculty_code', 'title', 'title_prefix')
98
99    def mangle_value(self, value, name, context=None):
100        """Hook for mangling values in derived classes
101        """
102        if name == 'faculty_code':
103            value = getattr(
104                getattr(context, '__parent__', None),
105                'code', None)
106        return super(DepartmentExporter, self).mangle_value(
107            value, name, context)
108
109    def export_all(self, site, filepath=None):
110        """Export faculties in facultycontainer into filepath as CSV data.
111
112        If `filepath` is ``None``, a raw string with CSV data is returned.
113        """
114        writer, outfile = self.get_csv_writer(filepath)
115        faculties = site.get('faculties', {})
116        for faculty in faculties.values():
117            for department in faculty.values():
118                self.write_item(department, writer)
119        return self.close_outfile(filepath, outfile)
120
121
122class CourseExporter(FacultyExporter, grok.GlobalUtility):
123    """Exporter for courses.
124    """
125    grok.implements(ICSVExporter)
126    grok.name('courses')
127
128    #: Fieldnames considered by this exporter
129    fields = ('code', 'faculty_code', 'department_code', 'title', 'credits',
130              'passmark', 'semester')
131
132    def mangle_value(self, value, name, context=None):
133        """Hook for mangling values in derived classes
134        """
135        if name == 'faculty_code':
136            try:
137                value = context.__parent__.__parent__.__parent__.code
138            except AttributeError:
139                value = None
140        elif name == 'department_code':
141            try:
142                value = context.__parent__.__parent__.code
143            except AttributeError:
144                value = None
145        return super(CourseExporter, self).mangle_value(
146            value, name, context)
147
148    def export_all(self, site, filepath=None):
149        """Export faculties in facultycontainer into filepath as CSV data.
150
151        If `filepath` is ``None``, a raw string with CSV data is returned.
152        """
153        writer, outfile = self.get_csv_writer(filepath)
154        faculties = site.get('faculties', {})
155        for faculty in faculties.values():
156            for department in faculty.values():
157                for course in department.courses.values():
158                    self.write_item(course, writer)
159        return self.close_outfile(filepath, outfile)
160
161class CertificateExporter(CourseExporter, grok.GlobalUtility):
162    """Exporter for courses.
163    """
164    grok.implements(ICSVExporter)
165    grok.name('certificates')
166
167    #: Fieldnames considered by this exporter
168    fields = ('code', 'faculty_code', 'department_code', 'title', 'study_mode',
169              'start_level', 'end_level', 'application_category')
170
171    def export_all(self, site, filepath=None):
172        """Export faculties in facultycontainer into filepath as CSV data.
173
174        If `filepath` is ``None``, a raw string with CSV data is returned.
175        """
176        writer, outfile = self.get_csv_writer(filepath)
177        faculties = site.get('faculties', {})
178        for faculty in faculties.values():
179            for department in faculty.values():
180                for cert in department.certificates.values():
181                    self.write_item(cert, writer)
182        return self.close_outfile(filepath, outfile)
Note: See TracBrowser for help on using the repository browser.