source: waeup_product/trunk/exportimport.py @ 259

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

=import from csv

File size: 24.3 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    try:
138        faculties = csv.DictReader(open("%s/import/faculty.csv" % i_home,"rb"))
139    except:
140        return
141    l = site.portal_catalog({'meta_type': "Faculty"})
142    facs = {}
143    for f in l:
144        facs[f.id] = f.getObject()
145    for faculty in faculties:
146        logger.info('processing %(Session)s %(FacultyCode)s %(Description)s %(CollegeCode)s %(FacultyKey)s %(Status)s %(degree_grade)s %(Bankcode)s' % faculty)
147        fid = faculty['FacultyCode']
148        f = facs.get(fid,None)
149        if f is None:
150            #self.log('Creating Faculty %(id)s = %(Title)s' % faculty)
151            logger.info('Creating Faculty with ID %(FacultyCode)s %(Description)s' % faculty)
152            academics.invokeFactory('Faculty', fid)
153            f = getattr(academics,fid)
154        d = {'Title': faculty['Description']}
155        f.getContent().edit(mapping=d)
156###)
157
158def loadDepartmentsFromCSV(academics,site,context): ###(
159    """install Universityspecific Faculies from CSV values"""
160    #return
161    logger = context.getLogger('loaddepartments')
162    try:
163        deps = csv.DictReader(open("%s/import/departments.csv" % i_home,"rb"))
164    except:
165        return
166    l = site.portal_catalog({'meta_type': "Faculty"})
167    facs = {}
168    for f in l:
169        facs[f.id] = f.getObject()
170    for dep in deps:
171        logger.info('Processing %(Session)s %(DeptCode)s %(Description)s %(FacultyCode)s' % dep)
172        fid = dep['FacultyCode']
173        f = facs.get(fid,None)
174        if f is None:
175            logger.info( "No Faculty with ID: %s" % fid)
176        else:
177            did = dep.get('DeptCode')
178            d = getattr(f,did,None)
179            if d is None or d.portal_type == "Faculty":
180                #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
181                logger.info('Creating Department %(DeptCode)s = %(Description)s' % dep)
182                f.invokeFactory('Department', did)
183                d = getattr(f,did)
184            dict = {'Title': dep['Description']}
185            d.getContent().edit(mapping=dict)
186###)
187
188def loadCoursesFromCSV(academics,site,context): ###(
189    """install Universityspecific Courses from CSV values"""
190    #return
191    logger = context.getLogger('loadcourses')
192    try:
193        courses = csv.DictReader(open("%s/import/courses.csv" % i_home,"rb"))
194    except:
195        return
196    l = site.portal_catalog({'meta_type': "Faculty"})
197    facs = {}
198    for f in l:
199        facs[f.id] = f.getObject()
200    dl = site.portal_catalog({'meta_type': "Department"})
201    deps = {}
202    for d in dl:
203        deps[d.id] = d.getObject()
204    cl = site.portal_catalog({'meta_type': "Course"})
205    course_list = [ c.id for c in cl]
206    for course in courses:
207        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)
208        if course.get("FORMERCODE").endswith('BITS'):
209            continue
210        depid = course.get('Dept').upper()
211        if depid in deps.keys():
212            dept= deps.get(depid)
213##        elif depid in facs.keys():
214##            dept= facs.get(depid)
215        else:
216            logger.info("Dep %(Dept)s for Course %(CourseCode)s not found" % course)
217            continue
218        course_id = ''.join(re.split('\W+',course.get('CourseCode')))
219        if len(course_id) == 3:
220            course_id = "%s000" % course_id
221        elif len(course_id) != 6:
222            logger.info("invalid course_code %(CourseCode)s" % course)
223            #print course_id,course.get('CourseCode'),course.get('Description')
224            continue
225##        if course_id in course_list:
226##            continue
227        c = getattr(dept,course_id,None)
228        if c is None:
229            #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
230            logger.info('Creating Course %(CourseCode)s  %(Description)s in Department %(Dept)s' % course)
231            dept.invokeFactory('Course', course_id)
232            c = getattr(dept,course_id)
233        dict = {'Title': course['Description']}
234        dict['code'] = course_id
235        dict['org_code'] = course.get('CourseCode')
236        dict['credits'] = course.get('Credits')
237        dict['semester'] = course.get('Semester')
238        dict['session'] = course.get('Session')
239        dict['category'] = course.get('Category')
240        dict['passmark'] = course.get('PassMark')
241        c.getContent().edit(mapping=dict)
242###)
243
244def loadCertificatesFromCSV(site,context): ###(
245    """install Universityspecific Certificates from CSV values"""
246    #return
247    logger = context.getLogger('loadcertificates')
248    try:
249        certificates = csv.DictReader(open("%s/import/certificates.csv" % i_home,"rb"))
250    except:
251        return
252    f_ids = [f.id for f in site.portal_catalog({'meta_type': "Faculty"})]
253    #d_ids = [d.id for d in site.portal_catalog({'meta_type': "Department"})]
254    dl = site.portal_catalog({'meta_type': "Department"})
255    deps = {}
256    for d in dl:
257        deps[d.id] = d.getObject()
258    for certificate in certificates:
259        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)
260        depid = certificate.get('Dept')
261        facid = certificate.get('Faculty')
262        if facid not in f_ids:
263            logger.info('Faculty %(Faculty)s for %(CertCode)s %(Description)s not found' % certificate)
264            continue
265        if not deps.has_key(depid):
266            logger.info('Department %(Dept)s for %(CertCode)s %(Description)s not found' % certificate)
267            continue
268        certificate_id = "%(category)s_%(Admstatus)s_%(Dept)s" % certificate
269        dep = deps[depid]
270        c = getattr(dep,certificate_id,None)
271        if c is None:
272            #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
273            logger.info('Creating certificate %(CertCode)s  %(Description)s in Department %(Dept)s' % certificate)
274            dep.invokeFactory('Certificate', certificate_id)
275            c = getattr(dep,certificate_id)
276        dict = {'Title': certificate['Description']}
277        code = certificate.get('CertCode')
278        code = code.replace('.','')
279        code = code.replace('(','')
280        code = code.replace(')','')
281        code = code.replace('/','')
282        code = code.replace(' ','')
283        code = code.replace('_','')
284        dict['code'] = code
285        dict['faculty'] = certificate.get('Faculty')
286        dict['department'] = certificate.get('Dept')
287        dict['max_pass'] = certificate.get('MaxPass')
288        dict['max_load'] = certificate.get('MaxLoad')
289        dict['admin_status'] = certificate.get('Admstatus')
290        dict['category'] = certificate.get('category')
291        dict['m_prefix'] = certificate.get('MPREFIX')
292        dict['nr_years'] = int(certificate.get('Nyears'))
293        nc = certificate.get('Ncore','1')
294        try:
295            dict['n_core'] = int(nc)
296        except:
297            dict['n_core'] = 1
298        dict['start_level'] = certificate.get('StartLevel')
299        dict['end_level'] = certificate.get('endLevel')
300        dict['promotion_credits'] = certificate.get('PromotionCredits')
301        dict['probation_credits'] = certificate.get('ProbationCredits')
302        c.getContent().edit(mapping=dict)
303###)
304
305def oldloadCertificatesFromCSV(certfolder,site,context): ###(
306    """install Universityspecific Certificates from CSV values"""
307    logger = context.getLogger('loadcertificates')
308    certificates = csv.DictReader(open("%s/import/certificates.csv" % i_home,"rb"))
309    f_ids = [f.id for f in site.portal_catalog({'meta_type': "Faculty"})]
310    d_ids = [d.id for d in site.portal_catalog({'meta_type': "Department"})]
311    for certificate in certificates:
312        depid = certificate.get('Dept')
313        facid = certificate.get('Faculty')
314        if facid not in f_ids:
315            logger.info('Faculty %(Faculty)s for %(CertCode)s %(Description)s not found' % certificate)
316            continue
317        if depid not in d_ids:
318            logger.info('Department %(Dept)s for %(CertCode)s %(Description)s not found' % certificate)
319            continue
320        certificate_id = "%(category)s_%(Admstatus)s_%(Dept)s" % certificate
321        c = getattr(certfolder,certificate_id,None)
322        if c is None:
323            #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
324            logger.info('Creating certificate %(CertCode)s  %(Description)s in Department %(Dept)s' % certificate)
325            certfolder.invokeFactory('Certificate', certificate_id)
326            c = getattr(certfolder,certificate_id)
327        dict = {'Title': certificate['Description']}
328        code = certificate.get('CertCode')
329        code = code.replace('.','')
330        code = code.replace('(','')
331        code = code.replace(')','')
332        code = code.replace('/','')
333        code = code.replace(' ','')
334        code = code.replace('_','')
335        dict['code'] = code
336        dict['faculty'] = certificate.get('Faculty')
337        dict['department'] = certificate.get('Dept')
338        dict['max_pass'] = certificate.get('MaxPass')
339        dict['max_load'] = certificate.get('MaxLoad')
340        dict['admin_status'] = certificate.get('Admstatus')
341        dict['category'] = certificate.get('category')
342        dict['m_prefix'] = certificate.get('MPREFIX')
343        dict['nr_years'] = int(certificate.get('Nyears'))
344        nc = certificate.get('Ncore','1')
345        try:
346            dict['n_core'] = int(nc)
347        except:
348            dict['n_core'] = 1
349        dict['start_level'] = certificate.get('StartLevel')
350        dict['end_level'] = certificate.get('endLevel')
351        dict['promotion_credits'] = certificate.get('PromotionCredits')
352        dict['probation_credits'] = certificate.get('ProbationCredits')
353        c.getContent().edit(mapping=dict)
354###)
355
356def loadCertificateCoursesFromCSV(site,context): ###(
357    """install Certificate Courses from CSV values"""
358    #return
359    logger = context.getLogger('loadcertificatecourses')
360    try:
361        cert_courses = csv.DictReader(open("%s/import/course_level_courses.csv" % i_home,"rb"))
362    except:
363        return
364    d_ids = [d.id for d in site.portal_catalog({'meta_type': "Department"})]
365    for cert_course in cert_courses:
366        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)
367        depid = cert_course.get('Dept')
368        code = cert_course.get('CertCode')
369        code = code.replace('.','')
370        code = code.replace('(','')
371        code = code.replace(')','')
372        code = code.replace('/','')
373        code = code.replace(' ','')
374        code = code.replace('_','')
375        if cert_course.get('Session') != '2002/2003':
376            continue
377        certificate = site.portal_catalog({'meta_type': "Certificate",
378                                           'SearchableText': code})
379        if not certificate:
380            print code
381            logger.info('CertCode %(CertCode)s for %(CosCode)s not found' % cert_course)
382            continue
383        certificate = certificate[-1].getObject()
384        certificate_code = certificate.getId()
385        if depid not in d_ids:
386            logger.info('Department %(Dept)s for %(CertCode)s not found' % cert_course)
387            continue
388        course_code = cert_course.get('CosCode')
389        level = cert_course.get('Level')
390        l = getattr(certificate,level,None)
391        if l is None:
392            #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
393            logger.info('Creating Level %(Level)s in certificate %(CertCode)s' % cert_course)
394            certificate.invokeFactory('StudyLevel', level)
395            l = getattr(certificate, level)
396            l.invokeFactory('Semester','first')
397            l.invokeFactory('Semester','second')
398        first_s = getattr(l,'first')
399        second_s = getattr(l,'second')
400        if cert_course.get('Semester') == '1':
401            semester = first_s
402        else:
403            semester = second_s
404        if hasattr(semester,course_code):
405            logger.info('Duplicate %(CosCode)s in Level %(Level)s' % cert_course)
406            continue
407           
408        semester.invokeFactory('CertificateCourse',course_code)
409        cc = getattr(semester,course_code)
410        dict = {}
411        dict['code'] = cert_course.get('CosCode')
412        dict['certificate_code'] = code
413        dict['certificate_code_org'] = cert_course.get('CertCode')
414        dict['department'] = cert_course.get('Dept')
415        dict['admin_status'] = cert_course.get('Admstatus')
416        dict['session'] = cert_course.get('Session')
417        if cert_course.get('Core') != '':
418            dict['core_or_elective'] = True
419        else:
420            dict['core_or_elective'] = False
421        dict['level'] = cert_course.get('Level')
422        cc.getContent().edit(mapping=dict)
423###)
424
425def old_loadCertificateCoursesFromCSV(certfolder,site,context): ###(
426    """install Certificate Courses from CSV values"""
427    return
428    logger = context.getLogger('loadcertificatecourses')
429    cert_courses = csv.DictReader(open("%s/import/course_level_courses.csv" % i_home,"rb"))
430    d_ids = [d.id for d in site.portal_catalog({'meta_type': "Department"})]
431    for cert_course in cert_courses:
432        depid = cert_course.get('Dept')
433        code = cert_course.get('CertCode')
434        code = code.replace('.','')
435        code = code.replace('(','')
436        code = code.replace(')','')
437        code = code.replace('/','')
438        code = code.replace(' ','')
439        code = code.replace('_','')
440        if cert_course.get('Session') != '2002/2003':
441            continue
442        certificate = site.portal_catalog({'meta_type': "Certificate",
443                                           'SearchableText': code})
444        if not certificate:
445            print code
446            logger.info('CertCode %(CertCode)s for %(CosCode)s not found' % cert_course)
447            continue
448        certificate = certificate[-1].getObject()
449        certificate_code = certificate.getId()
450        if depid not in d_ids:
451            logger.info('Department %(Dept)s for %(CertCode)s not found' % cert_course)
452            continue
453        course_code = cert_course.get('CosCode')
454        level = cert_course.get('Level')
455        l = getattr(certificate,level,None)
456        if l is None:
457            #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
458            logger.info('Creating Level %(Level)s in certificate %(CertCode)s' % cert_course)
459            certificate.invokeFactory('StudyLevel', level)
460            l = getattr(certificate, level)
461            l.invokeFactory('Semester','first')
462            l.invokeFactory('Semester','second')
463        first_s = getattr(l,'first')
464        second_s = getattr(l,'second')
465        if cert_course.get('Semester') == '1':
466            semester = first_s
467        else:
468            semester = second_s
469        if hasattr(semester,course_code):
470            logger.info('Duplicate %(CosCode)s in Level %(Level)s' % cert_course)
471            continue
472           
473        semester.invokeFactory('CertificateCourse',course_code)
474        cc = getattr(semester,course_code)
475        dict = {}
476        dict['code'] = cert_course.get('CosCode')
477        dict['certificate_code'] = code
478        dict['certificate_code_org'] = cert_course.get('CertCode')
479        dict['department'] = cert_course.get('Dept')
480        dict['admin_status'] = cert_course.get('Admstatus')
481        dict['session'] = cert_course.get('Session')
482        if cert_course.get('Core') != '':
483            dict['core_or_elective'] = True
484        else:
485            dict['core_or_elective'] = False
486        dict['level'] = cert_course.get('Level')
487        cc.getContent().edit(mapping=dict)
488###)
489
490def setupStructure(site,context): ###(
491    sections = getattr(site,'sections')
492    portal = getattr(sections,'uniportal',None)
493    if portal is None:
494        sections.invokeFactory('University','uniportal')
495        portal = getattr(site,'uniportal',None)
496        portal.getContent().edit(mapping={'Title':SRPP_TITLE})
497    students =  getattr(portal,'students',None)
498    if students is None:
499        portal.invokeFactory('StudentsFolder','students')
500        students = getattr(portal,'students').getContent()
501        students.edit(mapping={'Title':'Students'})
502    academics = getattr(portal,'academics',None)
503    if academics is None:
504        portal.invokeFactory('AcademicsFolder','academics')
505        academics = getattr(portal,'academics')
506        academics.getContent().edit(mapping={'Title':'Academics'})
507    loadFacultiesFromCSV(academics,site,context)
508    loadDepartmentsFromCSV(academics,site,context)
509    loadCoursesFromCSV(academics,site,context)
510##    certificates = getattr(academics,'certificates',None)
511##    if certificates is None:
512##        academics.invokeFactory('SCFolder','certificates')
513##        certificates = getattr(academics,'certificates')
514##        certificates.getContent().edit(mapping={'Title':'Certificates'})
515    loadCertificatesFromCSV(site,context)
516    loadCertificateCoursesFromCSV(site,context)
517    if not hasattr(portal,'accommodation'):
518        portal.invokeFactory('AccoFolder','accommodation')
519        accommodation = getattr(portal,'accommodation').getContent()
520        accommodation.edit(mapping={'Title':'Accommodation'})
521###)
522
523
524def exportWAeUP(context):
525    """Export our WAeUP tool configuration
526    """
527    site = context.getSite()
528    tool = getToolByName(site, TOOL, None)
529    if tool is None:
530        logger = context.getLogger(NAME)
531        logger.info("Nothing to export.")
532        return
533    exportObjects(tool, '', context)
534
535def importWAeUP(context):
536    """Import WAeUP tool configuration
537    """
538    site = context.getSite()
539    setupStructure(site,context)
540    #import pdb; pdb.set_trace()
541    pass
542    #site = context.getSite()
543    #tool = getToolByName(site, TOOL)
544    #importObjects(tool, '', context)
545
546
547# This the XMLAdapter itself. It encodes the im- / export logic that is specific
548# to our tool. `im- / exportObjects` functions will find it thanks to the zope
549# components machinery and the associations made in the configure.zcml file.
550
551class WAeUPXMLAdapter(XMLAdapterBase, PropertyManagerHelpers):
552    """XML importer and exporter for the WAeUP tool.
553
554    Hence this XMLAdapter is really simple. To get more complete examples of
555    what XMLAdapters are meant to do, please have a look at the
556    CPSSkins.exportimport.py or CPSDirectory.exportimport.py files, for
557    instance.
558    """
559
560    adapts(IWAeUPTool, ISetupEnviron)
561    implements(IBody)
562
563    _LOGGER_ID = NAME
564    name = NAME
565
566    def _exportNode(self):
567        """Export the object as a DOM node.
568        """
569        node = self._getObjectNode('object')
570        node.appendChild(self._extractProperties())
571        self._logger.info("WAeUP tool exported.")
572        return node
573
574    def _importNode(self, node):
575        """Import the object from the DOM node.
576        """
577        if self.environ.shouldPurge():
578            self._purgeProperties()
579        self._initProperties(node)
580        self._logger.info("WAeUP tool imported.")
581
Note: See TracBrowser for help on using the repository browser.