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

Last change on this file since 7733 was 7732, checked in by uli, 13 years ago
  • Add exporter for department.
  • Reflect changes in ICSVExporter interface.
  • Use utility names that could also be used in export filenames.
File size: 4.1 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)
Note: See TracBrowser for help on using the repository browser.