Changeset 6849
- Timestamp:
- 3 Oct 2011, 08:11:11 (13 years ago)
- Location:
- main/waeup.sirp/trunk/src/waeup/sirp/students
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.sirp/trunk/src/waeup/sirp/students/batching.py
r6846 r6849 8 8 """ 9 9 import grok 10 import csv 11 import copy 10 12 from zope.interface import Interface 11 13 from zope.schema import getFields 12 14 from zope.component import queryUtility 13 15 from zope.catalog.interfaces import ICatalog 14 from waeup.sirp.interfaces import IBatchProcessor, FatalCSVError 16 from waeup.sirp.interfaces import ( 17 IBatchProcessor, FatalCSVError, IObjectConverter) 15 18 from waeup.sirp.students.interfaces import ( 16 IStudent, IStudentStudyCourse, IStudentStudyCourseImport) 19 IStudent, IStudentStudyCourse, IStudentStudyCourseImport, 20 IStudentUpdateByRegNo, IStudentUpdateByMatricNo) 17 21 from waeup.sirp.utils.batching import BatchProcessor 18 22 … … 29 33 iface = IStudent 30 34 31 location_fields = [ 'student_id',]35 location_fields = [] 32 36 factory_name = 'waeup.Student' 33 37 … … 35 39 36 40 @property 37 def req(self): 38 result = dict( 39 create = self.required_fields, 40 update = self.location_fields, 41 remove = self.location_fields, 42 ) 43 return result 41 def available_fields(self): 42 result = [] 43 return sorted(list(set( 44 ['student_id','reg_number','matric_number'] + getFields( 45 self.iface).keys()))) 46 47 def checkHeaders(self, headerfields, mode='create'): 48 if not 'reg_number' in headerfields and not 'student_id' in headerfields and not 'matric_number' in headerfields: 49 raise FatalCSVError( 50 "Need at least columns student_id or reg_number or matric_number for import!") 51 if mode == 'create': 52 for field in self.required_fields: 53 if not field in headerfields: 54 raise FatalCSVError( 55 "Need at least columns %s for import!" % 56 ', '.join(["'%s'" % x for x in self.required_fields])) 57 # Check for fields to be ignored... 58 not_ignored_fields = [x for x in headerfields 59 if not x.startswith('--')] 60 if len(set(not_ignored_fields)) < len(not_ignored_fields): 61 raise FatalCSVError( 62 "Double headers: each column name may only appear once.") 63 return True 44 64 45 65 def parentsExist(self, row, site): 46 66 return 'students' in site.keys() 67 68 def getLocator(self, row): 69 if 'student_id' in row.keys() and row['student_id']: 70 return 'student_id' 71 elif 'reg_number' in row.keys() and row['reg_number']: 72 return 'reg_number' 73 elif 'matric_number' in row.keys() and row['matric_number']: 74 return 'matric_number' 75 else: 76 return None 47 77 48 78 # The entry never exists in create mode. 49 79 def entryExists(self, row, site): 50 80 if not 'students' in site.keys(): 51 return False52 if 'student_id' in row.keys() and row['student_id']:81 return None 82 if self.getLocator(row) == 'student_id': 53 83 if row['student_id'] in site['students']: 54 84 student = site['students'][row['student_id']] 55 85 return student 56 elif 'reg_number' in row.keys() and row['reg_number']:86 elif self.getLocator(row) == 'reg_number': 57 87 reg_number = row['reg_number'] 58 88 cat = queryUtility(ICatalog, name='students_catalog') … … 61 91 if results: 62 92 return results[0] 63 elif 'matric_number' in row.keys() and row['matric_number']: 64 #import pdb; pdb.set_trace() 93 elif self.getLocator(row) == 'matric_number': 65 94 matric_number = row['matric_number'] 66 95 cat = queryUtility(ICatalog, name='students_catalog') … … 69 98 if results: 70 99 return results[0] 71 return False100 return None 72 101 73 102 def getParent(self, row, site): … … 88 117 del parent[student.student_id] 89 118 pass 119 120 def getMapping(self, path, headerfields, mode): 121 """Get a mapping from CSV file headerfields to actually used fieldnames. 122 """ 123 result = dict() 124 reader = csv.reader(open(path, 'rb')) 125 raw_header = reader.next() 126 for num, field in enumerate(headerfields): 127 if field not in ['student_id', 'reg_number', 'matric_number'] and mode == 'remove': 128 continue 129 if field == u'--IGNORE--': 130 # Skip ignored columns in failed and finished data files. 131 continue 132 result[raw_header[num]] = field 133 return result 134 135 def checkConversion(self, row, mode='create'): 136 """Validates all values in row. 137 """ 138 if mode in ['update', 'remove']: 139 if self.getLocator(row) == 'reg_number': 140 iface = IStudentUpdateByRegNo 141 elif self.getLocator(row) == 'matric_number': 142 iface = IStudentUpdateByMatricNo 143 else: 144 iface = self.iface 145 converter = IObjectConverter(iface) 146 errs, inv_errs, conv_dict = converter.fromStringDict( 147 row, self.factory_name) 148 return errs, inv_errs, conv_dict 90 149 91 150 class StudentStudyCourseProcessor(BatchProcessor): … … 102 161 factory_name = 'waeup.StudentStudyCourse' 103 162 163 location_fields = [] 164 104 165 mode = None 105 166 … … 125 186 def parentsExist(self, row, site): 126 187 if not 'students' in site.keys(): 127 return False188 return None 128 189 if 'student_id' in row.keys() and row['student_id']: 129 190 if row['student_id'] in site['students']: … … 132 193 elif 'reg_number' in row.keys() and row['reg_number']: 133 194 reg_number = row['reg_number'] 195 #import pdb; pdb.set_trace() 134 196 cat = queryUtility(ICatalog, name='students_catalog') 135 197 results = list( … … 144 206 if results: 145 207 return results[0] 146 return False208 return None 147 209 148 210 def entryExists(self, row, site): 149 211 student = self.parentsExist(row, site) 150 212 if not student: 151 return False213 return None 152 214 if 'studycourse' in student: 153 215 return student 154 return False216 return None 155 217 156 218 def getEntry(self, row, site): -
main/waeup.sirp/trunk/src/waeup/sirp/students/interfaces.py
r6825 r6849 100 100 student_id = schema.TextLine( 101 101 title = u'Student ID', 102 required = True,102 required = False, 103 103 ) 104 104 … … 165 165 """Representation of a student. 166 166 """ 167 168 class IStudentUpdateByRegNo(IStudent): 169 """Representation of a student. Skip regular reg_number validation. 170 """ 171 172 reg_number = schema.TextLine( 173 title = u'Registration Number', 174 default = None, 175 required = False, 176 ) 177 178 class IStudentUpdateByMatricNo(IStudent): 179 """Representation of a student. Skip regular matric_number validation. 180 """ 181 182 matric_number = schema.TextLine( 183 title = u'Matriculation Number', 184 default = None, 185 required = False, 186 ) 167 187 168 188 class IStudentStudyCourse(IWAeUPObject):
Note: See TracChangeset for help on using the changeset viewer.