Changeset 12869 for main/waeup.kofa/trunk
- Timestamp:
- 22 Apr 2015, 19:14:14 (10 years ago)
- Location:
- main/waeup.kofa/trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.kofa/trunk/docs/source/userdocs/datacenter/import.rst
r12868 r12869 53 53 ================ 54 54 55 All batch processors inherit their methods from the :py:class:`waeup.kofa.utils.batching.BatchProcessor` base class. The core ``doImport`` method always remains unchanged. 55 All batch processors inherit from the :py:class:`waeup.kofa.utils.batching.BatchProcessor` base class. The `doImport` method, described above, always remains unchanged. All processors have a property `available_fields` which defines the set of importable data. They correspond with the column titles of the import file. Available fields are usually composed of location fields, interface fields and additional fields. Overlaps are possible. Location fields define the minumum set of fields which are necessary to locate an existing object in order to update or remove it. Interface fields (schema fields) are the fields defined in the interface of the data entity. Additional fields are additionally needed for data processing. We further distinguish between required and optional fields or between schema and non-schema fields. 56 57 In the following we list all available processors of the Kofa base package including some important methods which describe them best. We do not list available fields of each processor here. Available fields are shown in the browser user interface on the upload page of the portal. 58 59 User Processor 60 -------------- 61 62 .. autoclass:: waeup.kofa.authentication.UserProcessor() 63 :noindex: 64 65 Faculty Processor 66 ----------------- 67 68 .. autoclass:: waeup.kofa.university.batching.FacultyProcessor() 69 :noindex: 70 71 Department Processor 72 -------------------- 73 74 .. autoclass:: waeup.kofa.university.batching.DepartmentProcessor() 75 :noindex: 76 77 Certificate Processor 78 --------------------- 79 80 .. autoclass:: waeup.kofa.university.batching.CertificateProcessor() 81 :noindex: 82 83 Course Processor 84 ---------------- 85 86 .. autoclass:: waeup.kofa.university.batching.CourseProcessor() 87 :noindex: 88 89 90 Certificate Course Processor 91 ---------------------------- 92 93 .. autoclass:: waeup.kofa.university.batching.CertificateCourseProcessor() 94 :noindex: 95 96 Applicants Container Processor 97 ------------------------------ 98 99 .. autoclass:: waeup.kofa.applicants.batching.ApplicantsContainerProcessor() 100 :noindex: 101 102 Applicant Processor 103 ------------------- 104 105 .. autoclass:: waeup.kofa.applicants.batching.ApplicantProcessor() 106 :noindex: -
main/waeup.kofa/trunk/src/waeup/kofa/applicants/batching.py
r11891 r12869 35 35 36 36 class ApplicantsContainerProcessor(BatchProcessor): 37 """A processor for applicants containers. 37 """The Applicants Container Processor imports containers for applicants. 38 It does not import their content. There is nothing special about this 39 processor. 38 40 """ 39 41 grok.implements(IBatchProcessor) … … 76 78 77 79 class ApplicantProcessor(BatchProcessor): 78 """A batch processor for IApplicant objects. 79 80 In create mode container_code is required. If application_number is given 81 an applicant with this number is created in the designated container. 82 If application_number is not given a random application_number is assigned. 83 applicant_id is being determined by the system and can't be imported. 84 85 In update or remove mode container_code and application_number columns 86 must not exist. The applicant object is solely searched by its applicant_id 87 or reg_number. 80 """The Applicant Processor imports application records (applicants). 81 82 In create mode `container_code` is required. If `application_number` is 83 given, an applicant with this number is created in the designated container. 84 If `application_number` is not given, a random `application_number` is 85 assigned. `applicant_id` is being determined by the system and can't be 86 imported. 87 88 In update or remove mode `container_code` and `application_number` columns 89 must not exist. The applicant object is solely localized by 90 `applicant_id` or `reg_number`. 88 91 """ 89 92 grok.implements(IBatchProcessor) … … 95 98 iface = IApplicant 96 99 iface_byregnumber = IApplicantUpdateByRegNo 97 location_fields = ['']98 100 factory_name = 'waeup.Applicant' 99 101 … … 303 305 if cert is not None and (mode in ('create', 'update')): 304 306 # course1 application category must match container's. 305 parent = self.getParent(row, self.site) 307 site = grok.getSite() 308 parent = self.getParent(row, site) 306 309 if parent is None: 307 310 errs.append(('container', 'not found')) … … 332 335 return 'Applicant is blocked.' 333 336 return None 334 335 def doImport(self, *args, **kw):336 # XXX: Not thread-safe. Parallel applicant imports into337 # different sites could mean a mess. Luckily this is not a338 # typical use-case. On the other hand it spares thousands of339 # site lookups during large imports.340 # XXX: Maybe this should go into Importer base.341 self.site = grok.getSite() # needed by checkConversion()342 return super(ApplicantProcessor, self).doImport(*args, **kw) -
main/waeup.kofa/trunk/src/waeup/kofa/authentication.py
r12190 r12869 449 449 450 450 class UserProcessor(BatchProcessor): 451 """A batch processor for IUserAccount objects. 451 """The User Processor processes user accounts, i.e. `Account` objects in the 452 ``users`` container. 453 454 The `roles` columns must contain Python list 455 expressions like ``['waeup.PortalManager', 'waeup.ImportManager']``. 456 457 The processor does not import local roles. These can be imported 458 by means of batch processors in the academic section. 452 459 """ 453 460 grok.implements(IBatchProcessor) -
main/waeup.kofa/trunk/src/waeup/kofa/students/batching.py
r12623 r12869 64 64 iface_bymatricnumber = IStudentUpdateByMatricNo 65 65 66 location_fields = []67 66 factory_name = 'waeup.Student' 68 67 … … 312 311 additional_fields = [] 313 312 314 # : header fields additionally required315 additional_ headers= []313 # additional required fields (subset of additional_fields) 314 additional_fields_required = [] 316 315 317 316 @property … … 328 327 "Need at least columns student_id " + 329 328 "or reg_number or matric_number for import!") 330 for name in self.additional_ headers:329 for name in self.additional_fields_required: 331 330 if not name in headerfields: 332 331 raise FatalCSVError( … … 410 409 iface_transfer = IStudentStudyCourseTransfer 411 410 factory_name = 'waeup.StudentStudyCourse' 412 413 location_fields = []414 additional_fields = []415 411 416 412 def getParent(self, row, site): … … 510 506 factory_name = 'waeup.StudentStudyLevel' 511 507 512 location_fields = []513 514 508 additional_fields = ['level'] 515 additional_ headers = ['level']509 additional_fields_required = additional_fields 516 510 517 511 @property … … 591 585 factory_name = 'waeup.CourseTicket' 592 586 593 location_fields = []594 587 additional_fields = ['level', 'code'] 595 additional_ headers = ['level', 'code']588 additional_fields_required = additional_fields 596 589 597 590 @property … … 695 688 factory_name = 'waeup.StudentOnlinePayment' 696 689 697 location_fields = []698 690 additional_fields = ['p_id'] 699 additional_headers = []700 691 701 692 def checkHeaders(self, headerfields, mode='ignore'): -
main/waeup.kofa/trunk/src/waeup/kofa/university/batching.py
r11891 r12869 44 44 45 45 class FacultyProcessor(BatchProcessor): 46 """A batch processor for IFaculty objects. 46 """The Faculty Processor processes faculties in the `faculties` container. 47 The `FacultyProcessor` class also serves as a baseclass for all other 48 batch processors in the academic section. 49 50 The processor makes some efforts to set local roles. 51 If new roles are provided, the `updateEntry` method first removes 52 all existing roles and then sets the new roles as given in the import 53 file. That means the entire set of local roles is replaced. 47 54 """ 48 55 grok.implements(IBatchProcessor) … … 103 110 role_map = IPrincipalRoleMap(obj) 104 111 # Remove all existing local roles. 105 for local_role, user_name, setting in role_map.getPrincipalsAndRoles(): 112 for local_role, user_name, setting in \ 113 role_map.getPrincipalsAndRoles(): 106 114 role_manager.unsetRoleForPrincipal(local_role, user_name) 107 115 notify(LocalRoleSetEvent( … … 114 122 local_role = rolemap['local_role'] 115 123 role_manager.assignRoleToPrincipal(local_role, user) 116 notify(LocalRoleSetEvent(obj, local_role, user, granted=True)) 117 items_changed += ( 118 '%s=%s, ' % ('local_roles', '%s|%s' % (user,local_role))) 124 notify(LocalRoleSetEvent( 125 obj, local_role, user, granted=True)) 126 items_changed += ('%s=%s, ' 127 % ('local_roles', '%s|%s' % (user,local_role))) 119 128 row.pop('local_roles') 120 129 … … 151 160 if not 'user_name' in rolemap.keys() or not \ 152 161 'local_role' in rolemap.keys(): 153 errs.append(('local_roles','user_name or local_role missing')) 162 errs.append(( 163 'local_roles','user_name or local_role missing')) 154 164 return errs, inv_errs, conv_dict 155 165 local_role = rolemap['local_role'] … … 165 175 166 176 class DepartmentProcessor(FacultyProcessor): 167 """A batch processor for IDepartment objects. 177 """The Department Processor works in the same way as the Faculty 178 Processor. Since department codes are not necessarily unique, it needs the 179 `faculty_code` to create and update objects. 168 180 """ 169 181 grok.implements(IBatchProcessor) … … 213 225 214 226 class CertificateProcessor(FacultyProcessor): 215 """A batch processor for ICertificate objects. 227 """The Certificate Processor gets the parent object (the 228 `certificates` attribute of the department container) in two ways. 229 If both faculty and department codes are provided, `getPartents` uses 230 these to locate the certificate. If department code or 231 faculty code are missing, it use the certificates catalog to find the 232 certificate. 216 233 """ 217 234 grok.implements(IBatchProcessor) … … 270 287 return dept.certificates 271 288 # If department code or faculty code is missing, 272 # use catalog to get parent. Makes only sense in update mode but 273 # does also work in create mode. 289 # use catalog to get parent. 274 290 cat = queryUtility(ICatalog, name='certificates_catalog') 275 291 results = list( … … 296 312 297 313 class CourseProcessor(CertificateProcessor): 298 """A batch processor for ICourse objects. 314 """The Course Processor works exactly in the same way as the 315 Certificate Processor. It uses the courses catalog instead of the 316 certificates catalog. 299 317 """ 300 318 grok.implements(IBatchProcessor) … … 343 361 344 362 class CertificateCourseProcessor(FacultyProcessor): 345 """A batch processor for ICertificateCourse objects. 363 """The Certificate Course Processor needs more location fields. 364 Certificate courses are stored inside the certificate container. 365 Thus, `faculty_code`, `department_code` and the 366 `certificate_code` are necessary to find the parent container. 367 It furthermore needs the `course` and the `level` field to locate 368 existing objects as they are part of the object id (code). 346 369 """ 347 370 grok.implements(IBatchProcessor) -
main/waeup.kofa/trunk/src/waeup/kofa/university/export.py
r12858 r12869 26 26 27 27 class FacultyExporter(grok.GlobalUtility, ExporterBase): 28 """The Faculty Exporter exports all faculties in the 'faculties'28 """The Faculty Exporter exports all faculties in the `faculties` 29 29 container. This is the only place where faculties are stored. 30 30 """ -
main/waeup.kofa/trunk/src/waeup/kofa/utils/batching.py
r12868 r12869 56 56 57 57 # Internal name... 58 util_name = ' baseprocessor'58 util_name = '' 59 59 60 60 # Items for this processor need an interface with zope.schema fields. … … 66 66 67 67 # Headers needed to locate items... 68 location_fields = [ 'code', 'faculty_code']68 location_fields = [] 69 69 70 70 # A factory with this name must be registered... 71 factory_name = ' waeup.Department'71 factory_name = '' 72 72 73 73 @property … … 128 128 def applyMapping(self, row, mapping): 129 129 """Apply mapping to a row of CSV data. 130 131 130 """ 132 131 result = dict() … … 284 283 def doImport(self, path, headerfields, mode='create', user='Unknown', 285 284 logger=None, ignore_empty=True): 286 """In contrast to most other methods, ` `doImport`` is not supposed to285 """In contrast to most other methods, `doImport` is not supposed to 287 286 be customized, neither in custom packages nor in derived batch 288 287 processor classes. Therefore, this is the only place where we … … 317 316 record is stored in the pending data file. 318 317 319 Now ` `doImport`` tries to add the new object with the data318 Now `doImport` tries to add the new object with the data 320 319 from the conversion dictionary. In some cases this 321 may fail and a DuplicationErroris raised. For example, a new320 may fail and a `DuplicationError` is raised. For example, a new 322 321 payment ticket is created but the same payment for same session 323 322 has already been made. In this case the object id is unique, no … … 339 338 transitions or states. 340 339 341 Finally, ` `doImport`` updates the existing object with the data340 Finally, `doImport` updates the existing object with the data 342 341 from the conversion dictionary. 343 342 … … 348 347 stored in the pending data file. 349 348 350 Finally, ` `doImport`` removes the existing object.349 Finally, `doImport` removes the existing object. 351 350 352 351 """
Note: See TracChangeset for help on using the changeset viewer.