Ignore:
Timestamp:
14 Oct 2012, 04:54:11 (12 years ago)
Author:
Henrik Bettermann
Message:

Reorganize course batch processing. Use courses_catalog for getting entry in update mode.

Location:
main/waeup.kofa/trunk/src/waeup/kofa/university
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/src/waeup/kofa/university/batching.py

    r9087 r9333  
    211211        return
    212212
    213 class CourseProcessor(FacultyProcessor):
    214     """A batch processor for ICourse objects.
    215     """
    216     grok.implements(IBatchProcessor)
    217     grok.provides(IBatchProcessor)
    218     grok.context(Interface)
    219     util_name = 'courseprocessor'
    220     grok.name(util_name)
    221 
    222     name = u'Course Processor'
    223     iface = ICourse
    224     allowed_roles = Course.local_roles
    225 
    226     location_fields = ['code', 'faculty_code', 'department_code']
    227     factory_name = 'waeup.Course'
    228 
    229     mode = None
    230 
    231     def parentsExist(self, row, site):
    232         if not 'faculties' in site.keys():
    233             return False
    234         if not row['faculty_code'] in site['faculties'].keys():
    235             return False
    236         faculty = site['faculties'][row['faculty_code']]
    237         return row['department_code'] in faculty.keys()
    238 
    239     def entryExists(self, row, site):
    240         if not self.parentsExist(row, site):
    241             return False
    242         parent = self.getParent(row, site)
    243         return row['code'] in parent.keys()
    244 
    245     def getParent(self, row, site):
    246         dept = site['faculties'][row['faculty_code']][row['department_code']]
    247         return dept.courses
    248 
    249     def getEntry(self, row, site):
    250         if not self.entryExists(row, site):
    251             return None
    252         parent = self.getParent(row, site)
    253         return parent.get(row['code'])
    254 
    255     def addEntry(self, obj, row, site):
    256         parent = self.getParent(row, site)
    257         parent.addCourse(obj)
    258         return
    259 
    260     def delEntry(self, row, site):
    261         parent = self.getParent(row, site)
    262         del parent[row['code']]
    263         return
    264 
    265213class CertificateProcessor(FacultyProcessor):
    266214    """A batch processor for ICertificate objects.
     
    289237
    290238    def checkHeaders(self, headerfields, mode='create'):
    291         req = self.req[mode]
    292         # Check for required fields...
    293         for field in req:
    294             if not field in headerfields:
    295                 raise FatalCSVError(
    296                     "Need at least columns %s for import!" %
    297                     ', '.join(["'%s'" % x for x in req]))
    298         # Check for double fields. Cannot happen because this error is
    299         # already catched in views
    300         not_ignored_fields = [x for x in headerfields
    301                               if not x.startswith('--')]
    302         if len(set(not_ignored_fields)) < len(not_ignored_fields):
    303             raise FatalCSVError(
    304                 "Double headers: each column name may only appear once.")
     239        super(CertificateProcessor, self).checkHeaders(headerfields, mode)
    305240        if mode == 'create':
    306241            if not 'faculty_code' in headerfields \
     
    359294        return
    360295
     296class CourseProcessor(CertificateProcessor):
     297    """A batch processor for ICourse objects.
     298    """
     299    grok.implements(IBatchProcessor)
     300    grok.provides(IBatchProcessor)
     301    grok.context(Interface)
     302    util_name = 'courseprocessor'
     303    grok.name(util_name)
     304
     305    name = u'Course Processor'
     306    iface = ICourse
     307    allowed_roles = Course.local_roles
     308
     309    location_fields = ['code']
     310    factory_name = 'waeup.Course'
     311
     312    mode = None
     313
     314    def getParent(self, row, site):
     315        if not 'faculties' in site.keys():
     316            return None
     317        # If both faculty and department codes are provided, use
     318        # these to get parent.
     319        if row.get('faculty_code',None) not in (None, IGNORE_MARKER) and \
     320            row.get('department_code',None) not in (None, IGNORE_MARKER):
     321            if not row['faculty_code'] in site['faculties'].keys():
     322                return None
     323            faculty = site['faculties'][row['faculty_code']]
     324            if not row['department_code'] in faculty.keys():
     325                return None
     326            dept = faculty[row['department_code']]
     327            return dept.courses
     328        # If department code or faculty code is missing,
     329        # use catalog to get parent. Makes only sense in update mode but
     330        # does also work in create mode.
     331        cat = queryUtility(ICatalog, name='courses_catalog')
     332        results = list(
     333            cat.searchResults(code=(row['code'], row['code'])))
     334        if results:
     335            return results[0].__parent__
     336        return None
     337
     338    def addEntry(self, obj, row, site):
     339        parent = self.getParent(row, site)
     340        parent.addCourse(obj)
     341        return
     342
    361343class CertificateCourseProcessor(FacultyProcessor):
    362344    """A batch processor for ICertificateCourse objects.
  • main/waeup.kofa/trunk/src/waeup/kofa/university/tests/test_batching.py

    r9293 r9333  
    7272
    7373COURSE_HEADER_FIELDS = COURSE_SAMPLE_DATA.split(
     74    '\n')[0].split(',')
     75
     76COURSE_SAMPLE_DATA_UPDATE = open(
     77    os.path.join(os.path.dirname(__file__), 'sample_course_data_update.csv'),
     78    'rb').read()
     79
     80COURSE_HEADER_FIELDS_UPDATE = COURSE_SAMPLE_DATA_UPDATE.split(
    7481    '\n')[0].split(',')
    7582
     
    441448        self.row4 = dict(department_code='DEP1', faculty_code='FAC1', code="CRS1")
    442449
    443         self.csv_file_course = os.path.join(self.workdir, 'sample_course_data.csv')
     450        self.csv_file_course = os.path.join(
     451            self.workdir, 'sample_course_data.csv')
    444452        open(self.csv_file_course, 'wb').write(COURSE_SAMPLE_DATA)
     453        self.csv_file_course_update = os.path.join(
     454            self.workdir, 'sample_course_data_update.csv')
     455        open(self.csv_file_course_update, 'wb').write(COURSE_SAMPLE_DATA_UPDATE)
    445456        return
    446457
     
    513524        self.assertEqual(user_name, 'anne')
    514525        self.assertEqual(local_role, 'waeup.local.Lecturer')
     526        shutil.rmtree(os.path.dirname(fin_file))
     527        return
     528
     529    def test_import_update(self):
     530        num, num_warns, fin_file, fail_file = self.proc.doImport(
     531            self.csv_file_course, COURSE_HEADER_FIELDS)
     532        shutil.rmtree(os.path.dirname(fin_file))
     533        num, num_warns, fin_file, fail_file = self.proc.doImport(
     534            self.csv_file_course_update, COURSE_HEADER_FIELDS_UPDATE, 'update')
     535        self.assertEqual(num_warns,0)
     536        self.assertEqual(
     537            self.app['faculties']['FAC1']['DEP1'].courses['CRS2'].title,
     538            'New Title')
    515539        shutil.rmtree(os.path.dirname(fin_file))
    516540        return
Note: See TracChangeset for help on using the changeset viewer.