"""CSV importers. """ import grok from waeup.sirp.csvfile import CSVFile, toBool from waeup.sirp.csvfile.interfaces import ICSVFile from waeup.sirp.interfaces import IFacultyContainer, IWAeUPCSVImporter from waeup.sirp.utils.importexport import CSVImporter from zope.app.catalog.interfaces import ICatalog from zope.component import createObject, getUtility # # CSV import stuff # class IFacultyCSVFile(ICSVFile): """A CSV file that contains faculty data. """ class FacultyCSVFile(CSVFile): """An abstraction of a CSV file containing faculties. """ grok.implements(IFacultyCSVFile) grok.provides(IFacultyCSVFile) required_fields = ['code', 'title', 'title_prefix'] class FacultyCSVImporter(CSVImporter): """Shuffle data from faculty CSV files into faculty containers. """ # Tell, what kinds of objects we connect... grok.adapts(IFacultyCSVFile, IFacultyContainer) # Tell the world, that we are an importer... grok.implements(IWAeUPCSVImporter) grok.provides(IWAeUPCSVImporter) datatype = u'Faculty Importer' def doImport(self, clear_old_data=True, overwrite=True): # CSVImporter instances have a `csvfile` and a `receiver` # object defined which refer to the CSV file and the container. for row in self.csvfile.getData(): new_item = createObject(u'waeup.Faculty') for key, val in row.items(): setattr(new_item, key, val) self.receiver.addFaculty(new_item) return class IDepartmentCSVFile(ICSVFile): """A CSV file that contains department data. """ class DepartmentCSVFile(CSVFile): """An abstraction of a CSV file containing departments. """ grok.implements(IDepartmentCSVFile) grok.provides(IDepartmentCSVFile) required_fields = ['code', 'title', 'title_prefix', 'faculty_code'] class DepartmentCSVImporter(CSVImporter): """Shuffle data from department CSV files into faculty containers. """ # Tell, what kinds of objects we connect... grok.adapts(IDepartmentCSVFile, IFacultyContainer) # Tell the world, that we are an importer... grok.implements(IWAeUPCSVImporter) grok.provides(IWAeUPCSVImporter) datatype = u'Department Importer' def doImport(self, clear_old_data=True, overwrite=True): # CSVImporter instances have a `csvfile` and a `receiver` # object defined which refer to the CSV file and the container. for row in self.csvfile.getData(): new_item = createObject(u'waeup.Department') faculty_code = row['faculty_code'] faculty = self.receiver[faculty_code] del row['faculty_code'] for key, val in row.items(): setattr(new_item, key, val) faculty.addDepartment(new_item) return class ICourseCSVFile(ICSVFile): """A CSV file that contains course data. """ class CourseCSVFile(CSVFile): """An abstraction of a CSV file containing courses. """ grok.implements(ICourseCSVFile) grok.provides(ICourseCSVFile) required_fields = ['code', 'title', 'level', 'passmark', 'credits', 'semester', 'faculty', 'department'] class CourseCSVImporter(CSVImporter): """Shuffle data from course CSV files into faculty containers. """ # Tell, what kinds of objects we connect... grok.adapts(ICourseCSVFile, IFacultyContainer) # Tell the world, that we are an importer... grok.implements(IWAeUPCSVImporter) grok.provides(IWAeUPCSVImporter) datatype = u'Course Importer' def doImport(self, clear_old_data=True, overwrite=True): # CSVImporter instances have a `csvfile` and a `receiver` # object defined which refer to the CSV file and the container. for row in self.csvfile.getData(): new_item = createObject(u'waeup.Course') faculty_code = row['faculty'] faculty = self.receiver[faculty_code] del row['faculty'] dept_code = row['department'] dept = faculty[dept_code] del row['department'] # Type casts... if row['semester'] == '' or row['semester'] == 'None': row['semester'] = 0 if row['semester'] == '1,2': row['semester'] = 3 for key in ['semester', 'credits', 'passmark']: if row[key] == '' or row[key] == 'None': row[key] = None continue row[key] = int(row[key]) for key, val in row.items(): setattr(new_item, key, val) dept.courses.addCourse(new_item) return class ICertificateCSVFile(ICSVFile): """A CSV file that contains certificate data. """ class CertificateCSVFile(CSVFile): """An abstraction of a CSV file containing certificates. """ grok.implements(ICertificateCSVFile) grok.provides(ICertificateCSVFile) required_fields = ['code', 'title', 'faculty_code', 'department_code', 'category', 'study_mode', 'start_level', 'end_level', 'm_prefix', 'max_pass', 'application_category'] class CertificateCSVImporter(CSVImporter): """Shuffle data from certificate CSV files into faculty containers. """ # Tell, what kinds of objects we connect... grok.adapts(ICertificateCSVFile, IFacultyContainer) # Tell the world, that we are an importer... grok.implements(IWAeUPCSVImporter) grok.provides(IWAeUPCSVImporter) datatype = u'Certificate Importer' def doImport(self, clear_old_data=True, overwrite=True): # CSVImporter instances have a `csvfile` and a `receiver` # object defined which refer to the CSV file and the container. for row in self.csvfile.getData(): new_item = createObject(u'waeup.Certificate') faculty_code = row['faculty_code'] faculty = self.receiver[faculty_code] del row['faculty_code'] dept_code = row['department_code'] dept = faculty[dept_code] del row['department_code'] for key, val in row.items(): setattr(new_item, key, val) dept.certificates.addCertificate(new_item) return class ICertificateCourseCSVFile(ICSVFile): """A CSV file that contains certificate-course data. """ class CertificateCourseCSVFile(CSVFile): """An abstraction of a CSV file containing certificate-courses. """ grok.implements(ICertificateCourseCSVFile) grok.provides(ICertificateCourseCSVFile) required_fields = ['code', 'faculty_code', 'department_code', 'certificate_code', 'level', 'core_or_elective'] class CertificateCourseCSVImporter(CSVImporter): """Shuffle data from certificate CSV files into faculty containers. """ # Tell, what kinds of objects we connect... grok.adapts(ICertificateCourseCSVFile, IFacultyContainer) # Tell the world, that we are an importer... grok.implements(IWAeUPCSVImporter) grok.provides(IWAeUPCSVImporter) datatype = u'Certificate Course Importer' def doImport(self, clear_old_data=True, overwrite=True): # CSVImporter instances have a `csvfile` and a `receiver` # object defined which refer to the CSV file and the container. for row in self.csvfile.getData(): new_item = createObject(u'waeup.CertificateCourse') code = row['code'] del row['code'] faculty_code = row['faculty_code'] faculty = self.receiver[faculty_code] del row['faculty_code'] dept_code = row['department_code'] dept = faculty[dept_code] del row['department_code'] cert_code = row['certificate_code'] cert = dept.certificates[cert_code] del row['certificate_code'] course = self.getCourse(code) # Type casts... row['core_or_elective'] = toBool(row['core_or_elective']) row['level'] = int(row['level']) cert.addCourseRef(course, **row) return def getCourse(self, code): """Get the course with code `code`. Courses can be anywhere in the site. Therefore we ask the catalog. """ cat = getUtility(ICatalog, name='courses_catalog') result = cat.searchResults(code=(code, code)) if len(result) < 1: raise KeyError('No such course found: %s' % code) # We might get more than one result, but this should not # happen, as course codes are supposed to be unique. return list(result)[0]