## $Id: export.py 7757 2012-03-03 06:02:36Z henrik $ ## ## Copyright (C) 2012 Uli Fouquet & Henrik Bettermann ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## """Exporters for faculties, departments, and other academics components. """ import csv import grok from cStringIO import StringIO from waeup.sirp.interfaces import ICSVExporter class FacultyExporter(grok.GlobalUtility): """Exporter for faculties. """ grok.implements(ICSVExporter) grok.name('faculties') #: Fieldnames considered by this exporter fields = ('code', 'title', 'title_prefix') def mangle_value(self, value, name, context=None): """Hook for mangling values in derived classes """ if isinstance(value, bool): value = value and '1' or '0' elif isinstance(value, unicode): # CSV writers like byte streams better than unicode value = value.encode('utf-8') elif value is None: # None is not really representable in CSV files value = '' return value def get_csv_writer(self, filepath=None): """Get a CSV dict writer instance open for writing. Returns a tuple (, ) where ```` is a :class:`csv.DictWriter` instance and outfile is the real file which is written to. The latter is important when writing to StringIO and can normally be ignored otherwise. The returned file will already be filled with the header row. """ if filepath is None: outfile = StringIO() else: outfile = open(filepath, 'wb') writer = csv.DictWriter(outfile, self.fields) writer.writerow(dict(zip(self.fields, self.fields))) # header return writer, outfile def write_item(self, faculty, writer): """Write a row into using `writer`. """ row = {} for name in self.fields: value = getattr(faculty, name, None) value = self.mangle_value(value, name, faculty) row[name] = value writer.writerow(row) return def close_outfile(self, filepath, outfile): """Close outfile. If filepath is None, the contents of outfile is returned. """ outfile.seek(0) if filepath is None: return outfile.read() outfile.close() return def export(self, faculties, filepath=None): """Export `faculties`, an iterable, as CSV file. If `filepath` is ``None``, a raw string with CSV data is returned. """ writer, outfile = self.get_csv_writer(filepath) for faculty in faculties: self.write_item(faculty, writer) return self.close_outfile(filepath, outfile) def export_all(self, site, filepath=None): """Export faculties in facultycontainer into filepath as CSV data. If `filepath` is ``None``, a raw string with CSV data is returned. """ writer, outfile = self.get_csv_writer(filepath) faculties = site.get('faculties', {}) return self.export(faculties.values(), filepath) for faculty in faculties.values(): self.write_item(faculty, writer) return self.close_outfile(filepath, outfile) class DepartmentExporter(FacultyExporter, grok.GlobalUtility): """Exporter for departments. """ grok.implements(ICSVExporter) grok.name('departments') #: Fieldnames considered by this exporter fields = ('code', 'faculty_code', 'title', 'title_prefix') def mangle_value(self, value, name, context=None): """Hook for mangling values in derived classes """ if name == 'faculty_code': value = getattr( getattr(context, '__parent__', None), 'code', None) return super(DepartmentExporter, self).mangle_value( value, name, context) def export_all(self, site, filepath=None): """Export faculties in facultycontainer into filepath as CSV data. If `filepath` is ``None``, a raw string with CSV data is returned. """ writer, outfile = self.get_csv_writer(filepath) faculties = site.get('faculties', {}) for faculty in faculties.values(): for department in faculty.values(): self.write_item(department, writer) return self.close_outfile(filepath, outfile) class CourseExporter(FacultyExporter, grok.GlobalUtility): """Exporter for courses. """ grok.implements(ICSVExporter) grok.name('courses') #: Fieldnames considered by this exporter fields = ('code', 'faculty_code', 'department_code', 'title', 'credits', 'passmark', 'semester') def mangle_value(self, value, name, context=None): """Hook for mangling values in derived classes """ if name == 'faculty_code': try: value = context.__parent__.__parent__.__parent__.code except AttributeError: value = None elif name == 'department_code': try: value = context.__parent__.__parent__.code except AttributeError: value = None return super(CourseExporter, self).mangle_value( value, name, context) def export_all(self, site, filepath=None): """Export faculties in facultycontainer into filepath as CSV data. If `filepath` is ``None``, a raw string with CSV data is returned. """ writer, outfile = self.get_csv_writer(filepath) faculties = site.get('faculties', {}) for faculty in faculties.values(): for department in faculty.values(): for course in department.courses.values(): self.write_item(course, writer) return self.close_outfile(filepath, outfile) class CertificateExporter(CourseExporter, grok.GlobalUtility): """Exporter for courses. """ grok.implements(ICSVExporter) grok.name('certificates') #: Fieldnames considered by this exporter fields = ('code', 'faculty_code', 'department_code', 'title', 'study_mode', 'start_level', 'end_level', 'application_category') def export_all(self, site, filepath=None): """Export faculties in facultycontainer into filepath as CSV data. If `filepath` is ``None``, a raw string with CSV data is returned. """ writer, outfile = self.get_csv_writer(filepath) faculties = site.get('faculties', {}) for faculty in faculties.values(): for department in faculty.values(): for cert in department.certificates.values(): self.write_item(cert, writer) return self.close_outfile(filepath, outfile) class CertificateCourseExporter(CourseExporter, grok.GlobalUtility): """Exporter for courses. """ grok.implements(ICSVExporter) grok.name('certificate_courses') #: Fieldnames considered by this exporter fields = ('course', 'faculty_code', 'department_code', 'certificate_code', 'level', 'mandatory') def mangle_value(self, value, name, context=None): """Hook for mangling values in derived classes """ if name == 'faculty_code': try: value = context.__parent__.__parent__.__parent__.__parent__.code except AttributeError: value = None elif name == 'department_code': try: value = context.__parent__.__parent__.__parent__.code except AttributeError: value = None elif name == 'certificate_code': value = getattr(context, '__parent__', None) value = getattr(value, 'code', None) if name == 'course': value = getattr(value, 'code', None) return super(CourseExporter, self).mangle_value( value, name, context) def export_all(self, site, filepath=None): """Export faculties in facultycontainer into filepath as CSV data. If `filepath` is ``None``, a raw string with CSV data is returned. """ writer, outfile = self.get_csv_writer(filepath) faculties = site.get('faculties', {}) for faculty in faculties.values(): for department in faculty.values(): for cert in department.certificates.values(): for certref in cert.values(): self.write_item(certref, writer) return self.close_outfile(filepath, outfile)