source: waeup_product/trunk/exportimport.py @ 256

Last change on this file since 256 was 256, checked in by joachim, 18 years ago

=import from csv

File size: 24.1 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: exportimport.py 31640 2006-01-15 19:22:29Z ogrisel $
3"""WAeUP Tool XML Adapter.
4
5An XML adapter tells the GenericSetup machinery howto im- / export persistent
6configuration that is relative to a specific CMF component such as our WAeUP
7Tool.
8
9GenericSetup uses the Zope3 interfaces and components machinery to find the
10right XML adapter for the right object. This is why we flagged our waeup tool
11with the `implements(IWAeUPTool)` class attribute and made an adapter
12association in the `configure.zcml` file.
13"""
14import csv,re
15
16# Zope3 component architecture
17from zope.component import adapts
18from zope.interface import implements
19
20# Standard GenericSetup base classes and functions
21from Products.GenericSetup.utils import exportObjects
22from Products.GenericSetup.utils import importObjects
23from Products.GenericSetup.utils import XMLAdapterBase
24from Products.GenericSetup.utils import PropertyManagerHelpers
25
26from Products.CMFCore.utils import getToolByName
27
28# GenericSetup multi adapts a class that implement IWAeUP and a particular
29# ISetupEnvironment to and IBody (piece of XML configuration).
30from Products.GenericSetup.interfaces import IBody
31from Products.GenericSetup.interfaces import ISetupEnviron
32from Products.WAeUP.interfaces import IWAeUPTool
33import Globals
34p_home = Globals.package_home(globals())
35i_home = Globals.INSTANCE_HOME
36
37TOOL = 'portal_waeup'
38NAME = 'waeup'
39
40# The exportWAeUP and importWAeUP methods are called by the specific
41# im- / export steps defined in the corresponding XML files in the
42# WAeUP/profiles/default/ directory.
43
44def installFaculties( academics): ###(
45    """install Universityspecific Faculies with Departments"""
46    faculties = [ ###(
47                  {'id': 'agriculture', ###(
48                      'Title': 'Agriculture',
49                      'departments': [
50##                                     { 'id': 'dep1', ###(
51##                                       'Title': 'One',
52##                                     },
53                                     ],
54                      },###)
55                  ###)
56                  {'id': 'arts', ###(
57                      'Title': 'Arts',
58                      'departments': [
59##                                     { 'id': 'dep1', ###(
60##                                       'Title': 'One',
61##                                     },
62                                     ],
63                      },###)
64                  ###)
65                  {'id': 'BasicMedicalSciences', ###(
66                      'Title': 'Basic Medical Sciences',
67                      'departments': [
68##                                     { 'id': 'dep1', ###(
69##                                       'Title': 'One',
70##                                     },
71                                     ],
72                      },###)
73                  ###)
74                  {'id': 'science', ###(
75                  'Title': 'Science',
76                  'departments': [
77                                 { 'id': 'bio', ###(
78                                   'Title': 'Biochemistry',
79                                 },
80                                 { 'id': 'bot',
81                                   'Title': 'Botany',
82                                 },
83                                 { 'id': 'che',
84                                   'Title': 'Chemistry',
85                                 },
86                                 { 'id': 'com',
87                                   'Title': 'Computer Science',
88                                 },
89                                 { 'id': 'geo',
90                                   'Title': 'Geologie',
91                                 },
92                                 { 'id': 'mat',
93                                   'Title': 'Mathematics',
94                                 },
95                                 { 'id': 'mic',
96                                   'Title': 'Microbiology',
97                                 },
98                                 { 'id': 'opt',
99                                   'Title': 'Optometry',
100                                 },
101                                 { 'id': 'phy',
102                                   'Title': 'Physics',
103                                 },
104                                 { 'id': 'zoo',
105                                   'Title': 'Zoology',
106                                 },
107                                 ],
108                  },###)
109                 ]###)
110                 
111                ###)
112
113    for faculty in faculties:
114        fid = faculty['id']
115        f = getattr(academics,fid,None)
116        if f is None:
117            #self.log('Creating Faculty %(id)s = %(Title)s' % faculty)
118            academics.invokeFactory('Faculty', fid)
119            f = getattr(academics,fid)
120            f.getContent().edit(mapping=faculty)
121        for department in faculty['departments']:
122            #self.log('Checking Department %(id)s = %(Title)s' % department)
123            did = department['id']
124            d = getattr(f,did,None)
125            if d is None:
126                #self.log('Creating Department %(id)s = %(Title)s' % department)
127                f.invokeFactory('Department', did)
128                d = getattr(f,did)
129                d.getContent().edit(mapping=department)
130###)
131
132def loadFacultiesFromCSV(academics,site,context): ###(
133    """install Universityspecific Faculies from CSV values"""
134    #return
135    logger = context.getLogger('loadfaculties')
136    logger.info('Start loading Faculties')
137    faculties = csv.DictReader(open("%s/import/faculty.csv" % i_home,"rb"))
138    l = site.portal_catalog({'meta_type': "Faculty"})
139    facs = {}
140    for f in l:
141        facs[f.id] = f.getObject()
142    for faculty in faculties:
143        logger.info('processing %(Session)s %(FacultyCode)s %(Description)s %(CollegeCode)s %(FacultyKey)s %(Status)s %(degree_grade)s %(Bankcode)s' % faculty)
144        fid = faculty['FacultyCode']
145        f = facs.get(fid,None)
146        if f is None:
147            #self.log('Creating Faculty %(id)s = %(Title)s' % faculty)
148            logger.info('Creating Faculty with ID %(FacultyCode)s %(Description)s' % faculty)
149            academics.invokeFactory('Faculty', fid)
150            f = getattr(academics,fid)
151        d = {'Title': faculty['Description']}
152        f.getContent().edit(mapping=d)
153###)
154
155def loadDepartmentsFromCSV(academics,site,context): ###(
156    """install Universityspecific Faculies from CSV values"""
157    #return
158    logger = context.getLogger('loaddepartments')
159    deps = csv.DictReader(open("%s/import/departments.csv" % i_home,"rb"))
160    l = site.portal_catalog({'meta_type': "Faculty"})
161    facs = {}
162    for f in l:
163        facs[f.id] = f.getObject()
164    for dep in deps:
165        logger.info('Processing %(Session)s %(DeptCode)s %(Description)s %(FacultyCode)s' % dep)
166        fid = dep['FacultyCode']
167        f = facs.get(fid,None)
168        if f is None:
169            logger.info( "No Faculty with ID: %s" % fid)
170        else:
171            did = dep.get('DeptCode')
172            d = getattr(f,did,None)
173            if d is None or d.portal_type == "Faculty":
174                #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
175                logger.info('Creating Department %(DeptCode)s = %(Description)s' % dep)
176                f.invokeFactory('Department', did)
177                d = getattr(f,did)
178            dict = {'Title': dep['Description']}
179            d.getContent().edit(mapping=dict)
180###)
181
182def loadCoursesFromCSV(academics,site,context): ###(
183    """install Universityspecific Courses from CSV values"""
184    #return
185    logger = context.getLogger('loadcourses')
186    courses = csv.DictReader(open("%s/import/courses.csv" % i_home,"rb"))
187    l = site.portal_catalog({'meta_type': "Faculty"})
188    facs = {}
189    for f in l:
190        facs[f.id] = f.getObject()
191    dl = site.portal_catalog({'meta_type': "Department"})
192    deps = {}
193    for d in dl:
194        deps[d.id] = d.getObject()
195    cl = site.portal_catalog({'meta_type': "Course"})
196    course_list = [ c.id for c in cl]
197    for course in courses:
198        logger.info('Processing %(CourseCode)s %(Description)s %(Credits)s %(Dept)s %(Semester)s %(Session)s %(PassMark)s %(CourseKey)s %(Category)s %(AdmStatus)s %(FORMERCODE)s' % course)
199        if course.get("FORMERCODE").endswith('BITS'):
200            continue
201        depid = course.get('Dept').upper()
202        if depid in deps.keys():
203            dept= deps.get(depid)
204        elif depid in facs.keys():
205            dept= facs.get(depid)
206        else:
207            logger.info("Dep %(Dept)s for Course %(CourseCode)s not found" % course)
208            continue
209        course_id = ''.join(re.split('\W+',course.get('CourseCode')))
210        if len(course_id) == 3:
211            course_id = "%s000" % course_id
212        elif len(course_id) != 6:
213            logger.info("invalid course_code %(CourseCode)s" % course)
214            #print course_id,course.get('CourseCode'),course.get('Description')
215            continue
216##        if course_id in course_list:
217##            continue
218        c = getattr(dept,course_id,None)
219        if c is None:
220            #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
221            logger.info('Creating Course %(CourseCode)s  %(Description)s in Department %(Dept)s' % course)
222            dept.invokeFactory('Course', course_id)
223            c = getattr(dept,course_id)
224        dict = {'Title': course['Description']}
225        dict['code'] = course_id
226        dict['org_code'] = course.get('CourseCode')
227        dict['credits'] = course.get('Credits')
228        dict['semester'] = course.get('Semester')
229        dict['session'] = course.get('Session')
230        dict['category'] = course.get('Category')
231        dict['passmark'] = course.get('PassMark')
232        c.getContent().edit(mapping=dict)
233###)
234
235def loadCertificatesFromCSV(site,context): ###(
236    """install Universityspecific Certificates from CSV values"""
237    #return
238    logger = context.getLogger('loadcertificates')
239    certificates = csv.DictReader(open("%s/import/certificates.csv" % i_home,"rb"))
240    f_ids = [f.id for f in site.portal_catalog({'meta_type': "Faculty"})]
241    #d_ids = [d.id for d in site.portal_catalog({'meta_type': "Department"})]
242    dl = site.portal_catalog({'meta_type': "Department"})
243    deps = {}
244    for d in dl:
245        deps[d.id] = d.getObject()
246    for certificate in certificates:
247        logger.info('Processing %(CertCode)s %(Description)s %(Faculty)s %(MaxPass)s %(MaxLoad)s %(session)s %(PromotionCredits)s %(Probationcredits)s %(StartLevel)s %(endLevel)s %(Nyears)s %(Ncore)s %(MaxElect)s %(MPREFIX)s %(Dept)s %(Admstatus)s %(category)s' % certificate)
248        depid = certificate.get('Dept')
249        facid = certificate.get('Faculty')
250        if facid not in f_ids:
251            logger.info('Faculty %(Faculty)s for %(CertCode)s %(Description)s not found' % certificate)
252            continue
253        if not deps.has_key(depid):
254            logger.info('Department %(Dept)s for %(CertCode)s %(Description)s not found' % certificate)
255            continue
256        certificate_id = "%(category)s_%(Admstatus)s_%(Dept)s" % certificate
257        dep = deps[depid]
258        c = getattr(dep,certificate_id,None)
259        if c is None:
260            #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
261            logger.info('Creating certificate %(CertCode)s  %(Description)s in Department %(Dept)s' % certificate)
262            dep.invokeFactory('Certificate', certificate_id)
263            c = getattr(dep,certificate_id)
264        dict = {'Title': certificate['Description']}
265        code = certificate.get('CertCode')
266        code = code.replace('.','')
267        code = code.replace('(','')
268        code = code.replace(')','')
269        code = code.replace('/','')
270        code = code.replace(' ','')
271        code = code.replace('_','')
272        dict['code'] = code
273        dict['faculty'] = certificate.get('Faculty')
274        dict['department'] = certificate.get('Dept')
275        dict['max_pass'] = certificate.get('MaxPass')
276        dict['max_load'] = certificate.get('MaxLoad')
277        dict['admin_status'] = certificate.get('Admstatus')
278        dict['category'] = certificate.get('category')
279        dict['m_prefix'] = certificate.get('MPREFIX')
280        dict['nr_years'] = int(certificate.get('Nyears'))
281        nc = certificate.get('Ncore','1')
282        try:
283            dict['n_core'] = int(nc)
284        except:
285            dict['n_core'] = 1
286        dict['start_level'] = certificate.get('StartLevel')
287        dict['end_level'] = certificate.get('endLevel')
288        dict['promotion_credits'] = certificate.get('PromotionCredits')
289        dict['probation_credits'] = certificate.get('ProbationCredits')
290        c.getContent().edit(mapping=dict)
291###)
292
293def oldloadCertificatesFromCSV(certfolder,site,context): ###(
294    """install Universityspecific Certificates from CSV values"""
295    logger = context.getLogger('loadcertificates')
296    certificates = csv.DictReader(open("%s/import/certificates.csv" % i_home,"rb"))
297    f_ids = [f.id for f in site.portal_catalog({'meta_type': "Faculty"})]
298    d_ids = [d.id for d in site.portal_catalog({'meta_type': "Department"})]
299    for certificate in certificates:
300        depid = certificate.get('Dept')
301        facid = certificate.get('Faculty')
302        if facid not in f_ids:
303            logger.info('Faculty %(Faculty)s for %(CertCode)s %(Description)s not found' % certificate)
304            continue
305        if depid not in d_ids:
306            logger.info('Department %(Dept)s for %(CertCode)s %(Description)s not found' % certificate)
307            continue
308        certificate_id = "%(category)s_%(Admstatus)s_%(Dept)s" % certificate
309        c = getattr(certfolder,certificate_id,None)
310        if c is None:
311            #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
312            logger.info('Creating certificate %(CertCode)s  %(Description)s in Department %(Dept)s' % certificate)
313            certfolder.invokeFactory('Certificate', certificate_id)
314            c = getattr(certfolder,certificate_id)
315        dict = {'Title': certificate['Description']}
316        code = certificate.get('CertCode')
317        code = code.replace('.','')
318        code = code.replace('(','')
319        code = code.replace(')','')
320        code = code.replace('/','')
321        code = code.replace(' ','')
322        code = code.replace('_','')
323        dict['code'] = code
324        dict['faculty'] = certificate.get('Faculty')
325        dict['department'] = certificate.get('Dept')
326        dict['max_pass'] = certificate.get('MaxPass')
327        dict['max_load'] = certificate.get('MaxLoad')
328        dict['admin_status'] = certificate.get('Admstatus')
329        dict['category'] = certificate.get('category')
330        dict['m_prefix'] = certificate.get('MPREFIX')
331        dict['nr_years'] = int(certificate.get('Nyears'))
332        nc = certificate.get('Ncore','1')
333        try:
334            dict['n_core'] = int(nc)
335        except:
336            dict['n_core'] = 1
337        dict['start_level'] = certificate.get('StartLevel')
338        dict['end_level'] = certificate.get('endLevel')
339        dict['promotion_credits'] = certificate.get('PromotionCredits')
340        dict['probation_credits'] = certificate.get('ProbationCredits')
341        c.getContent().edit(mapping=dict)
342###)
343
344def loadCertificateCoursesFromCSV(site,context): ###(
345    """install Certificate Courses from CSV values"""
346    return
347    logger = context.getLogger('loadcertificatecourses')
348    cert_courses = csv.DictReader(open("%s/import/course_level_courses.csv" % i_home,"rb"))
349    d_ids = [d.id for d in site.portal_catalog({'meta_type': "Department"})]
350    for cert_course in cert_courses:
351        logger.info('Processing %(CosCode)s %(CertCode)s %(CoreKey)s %(Session)s %(Level)s %(Core)s %(Elective)s %(Mandatory)s %(AdmStatus)s %(Dept)s %(Semester)s' % cert_course)
352        depid = cert_course.get('Dept')
353        code = cert_course.get('CertCode')
354        code = code.replace('.','')
355        code = code.replace('(','')
356        code = code.replace(')','')
357        code = code.replace('/','')
358        code = code.replace(' ','')
359        code = code.replace('_','')
360        if cert_course.get('Session') != '2002/2003':
361            continue
362        certificate = site.portal_catalog({'meta_type': "Certificate",
363                                           'SearchableText': code})
364        if not certificate:
365            print code
366            logger.info('CertCode %(CertCode)s for %(CosCode)s not found' % cert_course)
367            continue
368        certificate = certificate[-1].getObject()
369        certificate_code = certificate.getId()
370        if depid not in d_ids:
371            logger.info('Department %(Dept)s for %(CertCode)s not found' % cert_course)
372            continue
373        course_code = cert_course.get('CosCode')
374        level = cert_course.get('Level')
375        l = getattr(certificate,level,None)
376        if l is None:
377            #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
378            logger.info('Creating Level %(Level)s in certificate %(CertCode)s' % cert_course)
379            certificate.invokeFactory('StudyLevel', level)
380            l = getattr(certificate, level)
381            l.invokeFactory('Semester','first')
382            l.invokeFactory('Semester','second')
383        first_s = getattr(l,'first')
384        second_s = getattr(l,'second')
385        if cert_course.get('Semester') == '1':
386            semester = first_s
387        else:
388            semester = second_s
389        if hasattr(semester,course_code):
390            logger.info('Duplicate %(CosCode)s in Level %(Level)s' % cert_course)
391            continue
392           
393        semester.invokeFactory('CertificateCourse',course_code)
394        cc = getattr(semester,course_code)
395        dict = {}
396        dict['code'] = cert_course.get('CosCode')
397        dict['certificate_code'] = code
398        dict['certificate_code_org'] = cert_course.get('CertCode')
399        dict['department'] = cert_course.get('Dept')
400        dict['admin_status'] = cert_course.get('Admstatus')
401        dict['session'] = cert_course.get('Session')
402        if cert_course.get('Core') != '':
403            dict['core_or_elective'] = True
404        else:
405            dict['core_or_elective'] = False
406        dict['level'] = cert_course.get('Level')
407        cc.getContent().edit(mapping=dict)
408###)
409
410def old_loadCertificateCoursesFromCSV(certfolder,site,context): ###(
411    """install Certificate Courses from CSV values"""
412    return
413    logger = context.getLogger('loadcertificatecourses')
414    cert_courses = csv.DictReader(open("%s/import/course_level_courses.csv" % i_home,"rb"))
415    d_ids = [d.id for d in site.portal_catalog({'meta_type': "Department"})]
416    for cert_course in cert_courses:
417        depid = cert_course.get('Dept')
418        code = cert_course.get('CertCode')
419        code = code.replace('.','')
420        code = code.replace('(','')
421        code = code.replace(')','')
422        code = code.replace('/','')
423        code = code.replace(' ','')
424        code = code.replace('_','')
425        if cert_course.get('Session') != '2002/2003':
426            continue
427        certificate = site.portal_catalog({'meta_type': "Certificate",
428                                           'SearchableText': code})
429        if not certificate:
430            print code
431            logger.info('CertCode %(CertCode)s for %(CosCode)s not found' % cert_course)
432            continue
433        certificate = certificate[-1].getObject()
434        certificate_code = certificate.getId()
435        if depid not in d_ids:
436            logger.info('Department %(Dept)s for %(CertCode)s not found' % cert_course)
437            continue
438        course_code = cert_course.get('CosCode')
439        level = cert_course.get('Level')
440        l = getattr(certificate,level,None)
441        if l is None:
442            #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
443            logger.info('Creating Level %(Level)s in certificate %(CertCode)s' % cert_course)
444            certificate.invokeFactory('StudyLevel', level)
445            l = getattr(certificate, level)
446            l.invokeFactory('Semester','first')
447            l.invokeFactory('Semester','second')
448        first_s = getattr(l,'first')
449        second_s = getattr(l,'second')
450        if cert_course.get('Semester') == '1':
451            semester = first_s
452        else:
453            semester = second_s
454        if hasattr(semester,course_code):
455            logger.info('Duplicate %(CosCode)s in Level %(Level)s' % cert_course)
456            continue
457           
458        semester.invokeFactory('CertificateCourse',course_code)
459        cc = getattr(semester,course_code)
460        dict = {}
461        dict['code'] = cert_course.get('CosCode')
462        dict['certificate_code'] = code
463        dict['certificate_code_org'] = cert_course.get('CertCode')
464        dict['department'] = cert_course.get('Dept')
465        dict['admin_status'] = cert_course.get('Admstatus')
466        dict['session'] = cert_course.get('Session')
467        if cert_course.get('Core') != '':
468            dict['core_or_elective'] = True
469        else:
470            dict['core_or_elective'] = False
471        dict['level'] = cert_course.get('Level')
472        cc.getContent().edit(mapping=dict)
473###)
474
475def setupStructure(site,context): ###(
476    sections = getattr(site,'sections')
477    portal = getattr(sections,'uniportal',None)
478    if portal is None:
479        sections.invokeFactory('University','uniportal')
480        portal = getattr(site,'uniportal',None)
481        portal.getContent().edit(mapping={'Title':SRPP_TITLE})
482    students =  getattr(portal,'students',None)
483    if students is None:
484        portal.invokeFactory('StudentsFolder','students')
485        students = getattr(portal,'students').getContent()
486        students.edit(mapping={'Title':'Students'})
487    academics = getattr(portal,'academics',None)
488    if academics is None:
489        portal.invokeFactory('AcademicsFolder','academics')
490        academics = getattr(portal,'academics')
491        academics.getContent().edit(mapping={'Title':'Academics'})
492    loadFacultiesFromCSV(academics,site,context)
493    loadDepartmentsFromCSV(academics,site,context)
494    loadCoursesFromCSV(academics,site,context)
495##    certificates = getattr(academics,'certificates',None)
496##    if certificates is None:
497##        academics.invokeFactory('SCFolder','certificates')
498##        certificates = getattr(academics,'certificates')
499##        certificates.getContent().edit(mapping={'Title':'Certificates'})
500    loadCertificatesFromCSV(site,context)
501    loadCertificateCoursesFromCSV(site,context)
502    if not hasattr(portal,'accommodation'):
503        portal.invokeFactory('AccoFolder','accommodation')
504        accommodation = getattr(portal,'accommodation').getContent()
505        accommodation.edit(mapping={'Title':'Accommodation'})
506###)
507
508
509def exportWAeUP(context):
510    """Export our WAeUP tool configuration
511    """
512    site = context.getSite()
513    tool = getToolByName(site, TOOL, None)
514    if tool is None:
515        logger = context.getLogger(NAME)
516        logger.info("Nothing to export.")
517        return
518    exportObjects(tool, '', context)
519
520def importWAeUP(context):
521    """Import WAeUP tool configuration
522    """
523    site = context.getSite()
524    setupStructure(site,context)
525    #import pdb; pdb.set_trace()
526    pass
527    #site = context.getSite()
528    #tool = getToolByName(site, TOOL)
529    #importObjects(tool, '', context)
530
531
532# This the XMLAdapter itself. It encodes the im- / export logic that is specific
533# to our tool. `im- / exportObjects` functions will find it thanks to the zope
534# components machinery and the associations made in the configure.zcml file.
535
536class WAeUPXMLAdapter(XMLAdapterBase, PropertyManagerHelpers):
537    """XML importer and exporter for the WAeUP tool.
538
539    Hence this XMLAdapter is really simple. To get more complete examples of
540    what XMLAdapters are meant to do, please have a look at the
541    CPSSkins.exportimport.py or CPSDirectory.exportimport.py files, for
542    instance.
543    """
544
545    adapts(IWAeUPTool, ISetupEnviron)
546    implements(IBody)
547
548    _LOGGER_ID = NAME
549    name = NAME
550
551    def _exportNode(self):
552        """Export the object as a DOM node.
553        """
554        node = self._getObjectNode('object')
555        node.appendChild(self._extractProperties())
556        self._logger.info("WAeUP tool exported.")
557        return node
558
559    def _importNode(self, node):
560        """Import the object from the DOM node.
561        """
562        if self.environ.shouldPurge():
563            self._purgeProperties()
564        self._initProperties(node)
565        self._logger.info("WAeUP tool imported.")
566
Note: See TracBrowser for help on using the repository browser.