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

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

Add course exporter.

File size: 5.5 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', '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':
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', 'department', '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':
136            try:
137                value = context.__parent__.__parent__.__parent__.code
138            except AttributeError:
139                value = None
140        elif name == 'department':
141            value = getattr(
142                getattr(context, '__parent__', None),
143                'code', None)
144        return super(CourseExporter, self).mangle_value(
145            value, name, context)
146
147    def export_all(self, site, filepath=None):
148        """Export faculties in facultycontainer into filepath as CSV data.
149
150        If `filepath` is ``None``, a raw string with CSV data is returned.
151        """
152        writer, outfile = self.get_csv_writer(filepath)
153        faculties = site.get('faculties', {})
154        for faculty in faculties.values():
155            for department in faculty.values():
156                for course in department.courses.values():
157                    self.write_item(course, writer)
158        return self.close_outfile(filepath, outfile)
Note: See TracBrowser for help on using the repository browser.