Ignore:
Timestamp:
18 Feb 2008, 08:51:45 (17 years ago)
Author:
joachim
Message:

import completely reworked.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • WAeUP_SRP/base/WAeUPTool.py

    r3162 r3172  
    4343from Students import makeCertificateCode
    4444from Globals import package_home,INSTANCE_HOME
     45from WAeUPImport import ApplicationImport,CertificateImport,CertificateCourseImport
     46from WAeUPImport import CourseImport,CourseResultImport
     47from WAeUPImport import DepartmentImport,FacultyImport,StudentImport,VerdictImport
     48from utils import makeDigest
    4549import DateTime,time
    4650import logging
    4751import transaction
    4852import csv,re,os,sys
     53import md5
    4954from shutil import copy2
    5055from Products.AdvancedQuery import Eq, Between, Le,In
     
    6166        return getattr(object,name)
    6267    return None
    63 
    6468
    6569class WAeUPTool(UniqueObject, SimpleItem, ActionProviderBase):
     
    13351339    ###)
    13361340
    1337     security.declareProtected(ModifyPortalContent,'mass_create_faculty') ###(
    1338     def mass_create_faculty(self,mapping):
    1339         "create a faculty"
    1340         logger = logging.getLogger('WAeUPTool.mass_create_faculty')
    1341         academics_folder = self.portal_url.getPortalObject().campus.academics
    1342         fid = mapping['code']
    1343         if getattr(academics_folder,fid,None) is not None:
    1344             return '', "Faculty with ID: %s exists" % fid
    1345         logger.info('Creating Faculty %(code)s, %(title)s' % mapping)
    1346         try:
    1347             academics_folder.invokeFactory('Faculty', fid)
    1348         except BadRequest,E:
    1349             return '', "%s" % E
    1350         f = getattr(academics_folder,fid,None)
    1351         f.getContent().edit(mapping=mapping)
    1352         return fid,''
    1353     ###)
    1354 
    1355     security.declareProtected(ModifyPortalContent,'mass_edit_faculty') ###(
    1356     def mass_edit_faculty(self,mapping):
    1357         "edit a faculty"
    1358         logger = logging.getLogger('WAeUPTool.mass_edit_faculty')
    1359         academics_folder = self.portal_url.getPortalObject().campus.academics
    1360         fid = mapping['code']
    1361         f = getattr(academics_folder,fid,None)
    1362         if f is None:
    1363             return '', "Faculty with ID: %s does not exist" % fid
    1364         logger.info('Editing Faculty %(code)s, %(title)s' % mapping)
    1365         f.getContent().edit(mapping=mapping)
    1366         return fid,''
    1367     ###)
    1368 
    1369     security.declareProtected(ModifyPortalContent,'mass_create_department') ###(
    1370     def mass_create_department(self,mapping):
    1371         "create a department in the correct faculty"
    1372         logger = logging.getLogger('WAeUPTool.mass_create_department')
    1373         fid = mapping['faculty_code']
    1374         if getattr(self,'_v_faculties',None) is None:
    1375             res = self.portal_catalog(portal_type = "Faculty")
    1376             self._v_faculties = {}
    1377             for f in res:
    1378                 self._v_faculties[f.getId] = f.getObject()
    1379         f = self._v_faculties.get(fid,None)
    1380         if f is None:
    1381             return '', "No Faculty with ID: %s" % fid
    1382         else:
    1383             did = mapping.get('code')
    1384             d = getattr(f,did,None)
    1385             if d is None or d.portal_type == "Faculty":
    1386                 logger.info('Creating Department %(code)s, %(title)s' % mapping)
    1387                 try:
    1388                     f.invokeFactory('Department', did)
    1389                 except BadRequest,E:
    1390                     return '', "%s" % E
    1391                 d = getattr(f,did)
    1392                 d.invokeFactory('CoursesFolder','courses')
    1393                 courses = getattr(d,'courses')
    1394                 dict = {'Title': 'Courses'}
    1395                 courses.getContent().edit(mapping=dict)
    1396                 d.invokeFactory('CertificatesFolder','certificates')
    1397                 certificates = getattr(d,'certificates')
    1398                 dict = {'Title': 'Certificates'}
    1399                 certificates.getContent().edit(mapping=dict)
    1400             d.getContent().edit(mapping=mapping)
    1401         return did,''
    1402     ###)
    1403 
    1404     security.declareProtected(ModifyPortalContent,'mass_edit_department') ###(
    1405     def mass_edit_department(self,mapping):
    1406         "create a department in the correct faculty"
    1407         logger = logging.getLogger('WAeUPTool.mass_create_department')
    1408         academics_folder = self.portal_url.getPortalObject().campus.academics
    1409         fid = mapping['faculty_code']
    1410         did = mapping.get('code')
    1411         try:
    1412             d = getattr(getattr(academics_folder,fid),did,None)
    1413         except KeyError:
    1414             return '', "Department %s or Faculty %s wrong" % (did,fid)
    1415         else:
    1416             if d is None or d.portal_type == "Faculty":
    1417                 logger.info('Editing Department %(code)s, %(title)s' % mapping)
    1418             d.getContent().edit(mapping=mapping)
    1419         return did,''
    1420     ###)
    1421 
    1422     security.declareProtected(ModifyPortalContent,'mass_create_course') ###(
    1423     def mass_create_course(self,mapping):
    1424         #import pdb;pdb.set_trace()
    1425         if getattr(self,'_v_course_list',None) is None:
    1426             self._v_course_list = []
    1427         if getattr(self,'_v_departments',None) is None:
    1428             res = self.portal_catalog(portal_type = "Department")
    1429             self._v_department_courses = {}
    1430             for d in res:
    1431                 self._v_department_courses[d.getId] = getattr(d.getObject(),"courses",None)
    1432         did = mapping['department_code']
    1433         d = self._v_department_courses.get(did,None)
    1434         if d is None:
    1435             return '', "No Department with ID: %s" % did
    1436         course_id = mapping.get('code')
    1437         if course_id in self._v_course_list:
    1438             return '', "Duplicate Course ID: %s" % did
    1439         c = getattr(d,course_id,None)
    1440         if c is not None:
    1441             return '', "Duplicate Course ID: %s" % did
    1442         try:
    1443             d.invokeFactory('Course', course_id)
    1444         except BadRequest,E:
    1445             return '', "%s" % E
    1446         self._v_course_list.append(course_id)
    1447         c = getattr(d,course_id)
    1448         c.getContent().edit(mapping=mapping)
    1449         return course_id,''
    1450     ###)
    1451 
    1452     security.declareProtected(ModifyPortalContent,'mass_edit_course') ###(
    1453     def mass_edit_course(self,mapping):
    1454         #import pdb;pdb.set_trace()
    1455         course_id = mapping.get('code')
    1456         res = self.portal_catalog(id=course_id)
    1457         if not res:
    1458             return '', "No Course with ID: %s" % course_id
    1459         c = res[0].getObject()
    1460         c.getContent().edit(mapping=mapping)
    1461         return course_id,''
    1462     ###)
    1463 
    1464     security.declareProtected(ModifyPortalContent,'mass_create_certificate') ###(
    1465     def mass_create_certificate(self,mapping):
    1466         if getattr(self,'_v_certificate_list',None) is None:
    1467             self._v_certificate_list = []
    1468         if getattr(self,'_v_department_certificates',None) is None:
    1469             res = self.portal_catalog(portal_type = "Department")
    1470             self._v_department_certificates = {}
    1471             for d in res:
    1472                 self._v_department_certificates[d.getId] = getattr(d.getObject(),"certificates",None)
    1473         did = mapping['department_code']
    1474         d = self._v_department_certificates.get(did,None)
    1475         if d is None:
    1476             return '', "No Department with ID: %s" % did
    1477         certificate_id = mapping.get('code')
    1478         if certificate_id in self._v_certificate_list:
    1479             return '', "Duplicate Certificate ID: %s" % did
    1480         c = getattr(d,certificate_id,None)
    1481         if c is not None:
    1482             return '', "Duplicate Certificate ID: %s" % did
    1483         try:
    1484             d.invokeFactory('Certificate', certificate_id)
    1485         except BadRequest,E:
    1486             return '', "%s" % E
    1487         self._v_certificate_list.append(certificate_id)
    1488         c = getattr(d,certificate_id)
    1489         c.getContent().edit(mapping=mapping)
    1490         return certificate_id,''
    1491     ###)
    1492 
    1493     security.declareProtected(ModifyPortalContent,'mass_edit_certificate') ###(
    1494     def mass_edit_certificate(self,mapping):
    1495         #import pdb;pdb.set_trace()
    1496         certificate_id = mapping.get('code')
    1497         res = self.portal_catalog(id=certificate_id)
    1498         if not res:
    1499             return '', "No Certificate with ID: %s" % certificate_id
    1500         c = res[0].getObject()
    1501         c.getContent().edit(mapping=mapping)
    1502         return certificate_id,''
    1503     ###)
    1504 
    1505     security.declareProtected(ModifyPortalContent,'mass_create_application') ###(
    1506     def mass_create_application(self,mapping):
    1507         #import pdb;pdb.set_trace()
    1508         reg_no = mapping.get('reg_no')
    1509         try:
    1510             self.applicants_catalog.addRecord(**mapping)
    1511         except ValueError:
    1512             return '', "applicant record with reg_no %s already exists" % reg_no
    1513         return reg_no,''
    1514     ###)
    1515 
    1516     security.declareProtected(ModifyPortalContent,'mass_edit_application') ###(
    1517     def mass_edit_application(self,mapping):
    1518         #import pdb;pdb.set_trace()
    1519         reg_no = mapping.get('reg_no')
    1520         status = mapping.get('status')
    1521         res = self.applicants_catalog(reg_no = reg_no)
    1522         if len(res):
    1523             if res[0].status == 'created' and status != 'created':
    1524                 return '', "student object with id %s for %s already created, status cannot be changed" % (res[0].student_id, reg_no)
    1525             elif status == 'created' and res[0].status != 'created':
    1526                 return '', "student object for %s has not yet been created, status cannot be set to 'created'" % (reg_no)
    1527             else:
    1528                 self.applicants_catalog.modifyRecord(**mapping)
    1529                 return reg_no,''
    1530         else:
    1531             return '', "applicant record with reg_no %s does not exist" % reg_no
    1532 
    1533     ###)
    1534 
    1535     security.declareProtected(ModifyPortalContent,'mass_create_course_result') ###(
    1536     def mass_create_course_result(self,mapping):
    1537         #import pdb;pdb.set_trace()
    1538         students_folder = self.portal_url.getPortalObject().campus.students
    1539         if getattr(self,'_v_courses',None) is None:
    1540             res = self.courses_catalog()
    1541             self._v_courses = {}
    1542             for brain in res:
    1543                 self._v_courses[brain.code] = brain
    1544         if getattr(self,'_v_level_created',None) is None:
    1545             self._v_level_created = []
    1546         course_id = mapping.get('code')
    1547         if course_id not in self._v_courses.keys():
    1548             return '', "No course with ID: %s" % course_id
    1549         id_key = ''
    1550         for id_key in ('student_id','matric_no'):
    1551             id_field = mapping.get(id_key,None)
    1552             if id_field is not None:
    1553                 student_id = id_field
    1554                 break
    1555         query = Eq(id_key,id_field)
    1556         res = self.students_catalog.evalAdvancedQuery(query)
    1557         if not res:
    1558             return '', "no student with %(id_key)s %(id_field)s" % vars()
    1559         student_rec = res[0]
    1560         if id_field != "student_id":
    1561             mapping['student_id'] = student_rec.id
    1562         student_id = student_rec.id
    1563         level_id = mapping['level_id']
    1564         code = mapping['code']
    1565         if student_id not in self._v_level_created:
    1566             try:
    1567                 context = getattr(getattr(students_folder,
    1568                                           "%(student_id)s" % vars()),
    1569                                   'study_course')
    1570             except:
    1571                 return '', "could not create level %(level_id)s for %(student_id)s" % vars()
    1572             if level_id not in context.objectIds():
    1573                 context.invokeFactory('StudentStudyLevel',"%(level_id)s" % vars())
    1574                 level = getattr(context,"%(level_id)s" % vars())
    1575                 self.portal_workflow.doActionFor(level,'open')
    1576                 # the session string must not be copied into the level object
    1577                 current_verdict = getattr(student_rec,'current_verdict','')
    1578                 current_session = getattr(student_rec,'current_session','')
    1579                 if current_verdict and student_rec.current_level == level_id:
    1580                     level.getContent().edit(mapping={'verdict': "%s" %
    1581                                                      current_verdict,
    1582                                                      'session': "%s" %
    1583                                                      current_session,
    1584                                                     })
    1585                     self.portal_workflow.doActionFor(level,'close')
    1586             self._v_level_created += student_id,
    1587         mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
    1588         for k in ('semester','credits',):
    1589             mapping[k] = getattr(self._v_courses[course_id],k)
    1590         try:
    1591             self.course_results.addRecord(**mapping)
    1592         except ValueError:
    1593             return '', "course result already exists: %s" % key
    1594         return key,''
    1595     ###)
    1596 
    1597     security.declareProtected(ModifyPortalContent,'mass_edit_course_result') ###(
    1598     def mass_edit_course_result(self,mapping):
    1599         #import pdb;pdb.set_trace()
    1600         while True:
    1601             result_id = mapping.get('id',None)
    1602             if result_id is not None:
    1603                 mapping['key'] = key = result_id
    1604                 break
    1605             for id_key in ('student_id','matric_no'):
    1606                 id_field = mapping.get(id_key,None)
    1607                 if id_field is not None:
    1608                     student_id = id_field
    1609                     break
    1610             query = Eq(id_key,id_field)
    1611             res = self.students_catalog.evalAdvancedQuery(query)
    1612             if not res:
    1613                 return '', "No student with %(id_key)s %(id_field)s" % vars()
    1614             if id_field == "matric_no":
    1615                 mapping['student_id'] = res[0].id
    1616             elif id_field == "student_id":
    1617                 mapping['matric_no'] = res[0].matric_no
    1618             if not res:
    1619                 return '', "No student with %(id_key)s %(id_field)s" % vars()
    1620             student_rec = res[0]
    1621             student_id = student_rec.id
    1622             level_id = mapping['level_id']
    1623             code = mapping['code']
    1624             mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
    1625             break
    1626         try:
    1627             self.course_results.modifyRecord(**mapping)
    1628         except KeyError:
    1629             return key, "No course result to edit: %s" % key,mapping
    1630         return key,''
    1631     ###)
    1632 
    1633     security.declareProtected(ModifyPortalContent,'mass_delete_course_result') ###(
    1634     def mass_delete_course_result(self,mapping):
    1635         id_key = ''
    1636         for id_key in ('student_id','matric_no'):
    1637             id_field = mapping.get(id_key,None)
    1638             if id_field is not None:
    1639                 student_id = id_field
    1640                 break
    1641         query = Eq(id_key,id_field)
    1642         res = self.students_catalog.evalAdvancedQuery(query)
    1643         if not res:
    1644             return '', "No student with %(id_field)s: %(id_key)s" % vars()
    1645         if id_field != "student_id":
    1646             mapping['student_id'] = res[0].id
    1647         if not res:
    1648             return '', "no student with %(id_key)s %(id_field)s" % vars()
    1649         student_rec = res[0]
    1650         student_id = student_rec.id
    1651         level_id = mapping['level_id']
    1652         code = mapping['code']
    1653         key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
    1654         # for k in ('semester',):
    1655         #     mapping[k] = getattr(self._v_courses[course_id],k)
    1656         if self.course_results.getRecordByKey(key) is None:
    1657             return '', "no course-result with %(key)s" % vars()
    1658         self.course_results.deleteRecord(key)
    1659         return key,''
    1660     ###)
    1661 
    1662     security.declareProtected(ModifyPortalContent,'mass_create_certificate_course') ###(
    1663     def mass_create_certificate_course(self,mapping):
    1664         if getattr(self,'_v_courses',None) is None:
    1665             res = self.courses_catalog()
    1666             self._v_courses= [course.code for course in res]
    1667         if getattr(self,'_v_ceritficates',None) is None:
    1668             res = self.portal_catalog(portal_type = "Certificate")
    1669             self._v_certificates = {}
    1670             for cert in res:
    1671                 self._v_certificates[cert.getId] = cert.getObject()
    1672         certificate_course_id = mapping.get('code')
    1673         if certificate_course_id not in self._v_courses:
    1674             return '', "No Course with ID: %s" % certificate_course_id
    1675         cert_id = mapping['certificate_code']
    1676         cert = self._v_certificates.get(cert_id,None)
    1677         if cert is None:
    1678             return '', "No Certificate with ID: %s" % cert_id
    1679         level_id = mapping.get('level')
    1680         level = getattr(cert,level_id,None)
    1681         if level is None:
    1682             cert.invokeFactory('StudyLevel', level_id)
    1683             level = getattr(cert,level_id,None)
    1684         elif hasattr(level,certificate_course_id):
    1685             return '', "Duplicate CertificateCourse ID: %s in %s/ %s" %\
    1686             (certificate_course_id,cert_id,level_id)
    1687         level.invokeFactory('CertificateCourse', certificate_course_id)
    1688         c = getattr(level,certificate_course_id)
    1689         c.getContent().edit(mapping=mapping)
    1690         return certificate_course_id,''
    1691     ###)
    1692 
    1693     field2types_student = {   ###(
    1694                       'StudentApplication':
    1695                           {'id': 'application',
    1696                            'title': 'Application Data',
    1697                            'wf_transition_return': 'close',
    1698                            'wf_transition_admit': 'remain',
    1699                            'fields':
    1700                              ('jamb_reg_no',
    1701                               'entry_mode',
    1702                               'entry_session',
    1703                               'jamb_score',
    1704                               'app_email',
    1705                               'jamb_age',
    1706                               'jamb_state',
    1707                               'jamb_lga',
    1708                               'jamb_sex',
    1709                               )
    1710                               },
    1711                       #'StudentPume':
    1712                       #    {'id': 'pume',
    1713                       #     'title': 'Pume Data',
    1714                       #     'wf_transition_return': 'close',
    1715                       #     'wf_transition_admit': 'close',
    1716                       #     'fields':
    1717                       #       ('pume_score',
    1718                       #        )
    1719                       #        },
    1720                       'StudentClearance':
    1721                           {'id': 'clearance',
    1722                            'title': 'Clearance/Eligibility Record',
    1723                            'wf_transition_return': 'close',
    1724                            'wf_transition_admit': 'remain',
    1725                            'fields':
    1726                              ('matric_no',
    1727                               'nationality',
    1728                               'lga',
    1729                               'birthday',
    1730                               )
    1731                               },
    1732                          'StudentPersonal':
    1733                           {'id': 'personal',
    1734                            'title': 'Personal Data',
    1735                            'wf_transition_return': 'open',
    1736                            'wf_transition_admit': 'remain',
    1737                            'fields':
    1738                              ('firstname',
    1739                               'middlename',
    1740                               'lastname',
    1741                               'sex',
    1742                               'email',
    1743                               'phone',
    1744                               'perm_address',
    1745                               )
    1746                               },
    1747                          'StudentStudyCourse':
    1748                           {'id': 'study_course',
    1749                            'title': 'Study Course',
    1750                            'wf_transition_return': 'open',
    1751                            'wf_transition_admit': 'remain',
    1752                            'fields':
    1753                              ('study_course',
    1754                               'current_level',
    1755                               'current_session',
    1756                               'current_mode',
    1757                               'current_verdict',
    1758                               'previous_verdict',
    1759                               )
    1760                               },
    1761                          # 'StudentStudyLevel':
    1762                          #  {'id': 'current_level',
    1763                          #   'title': '',
    1764                          #   'wf_transition_return': 'open',
    1765                          #   'wf_transition_admit': 'remain',
    1766                          #   'fields':
    1767                          #     ('verdict',
    1768                          #      'session',
    1769                          #      )
    1770                          #      },
    1771                          'PaymentsFolder':
    1772                           {'id': 'payments',
    1773                            'title': 'Payments',
    1774                            'wf_transition_return': 'open',
    1775                            'wf_transition_admit': 'open',
    1776                            'fields':
    1777                              ()
    1778                               },
    1779                          }
    1780     ###)
    1781 
    1782     security.declareProtected(ModifyPortalContent,'mass_create_student') ###(
    1783     def mass_create_student(self,mapping):
    1784         "create student records due import"
    1785         logger = logging.getLogger('WAeUPTool.mass_create_student')
    1786         students_folder = self.portal_url.getPortalObject().campus.students
    1787         jamb_reg_no = mapping.get('jamb_reg_no',None)
    1788         if jamb_reg_no:
    1789             res = self.students_catalog(jamb_reg_no = jamb_reg_no)
    1790             if res:
    1791                 return '',"jamb_reg_no exists"
    1792         matric_no = mapping.get('matric_no',None)
    1793         if matric_no:
    1794             res = self.students_catalog(matric_no = matric_no)
    1795             if res:
    1796                 return '',"matric_no exists"
    1797         sid = self.waeup_tool.generateStudentId('?')
    1798         students_folder.invokeFactory('Student', sid)
    1799         student_obj = getattr(students_folder,sid)
    1800         f2t = self.field2types_student
    1801         d = {}
    1802         transition = mapping.get('reg_transition','admit')
    1803         if transition not in ('admit','return'):
    1804             return '',"no valid transition provided"
    1805         for pt in f2t.keys():
    1806             student_obj.invokeFactory(pt,f2t[pt]['id'])
    1807             sub_obj = getattr(student_obj,f2t[pt]['id'])
    1808             sub_doc = sub_obj.getContent()
    1809             d['Title'] = f2t[pt]['title']
    1810             for field in f2t[pt]['fields']:
    1811                 d[field] = mapping.get(field,'')
    1812 
    1813             if pt == "StudentApplication":
    1814                 #d['jamb_sex']  = 'M'
    1815                 #if mapping.get('sex'):
    1816                 #    d['jamb_sex']  = 'F'
    1817                 d['jamb_firstname'] = mapping.get('firstname',None)
    1818                 d['jamb_middlename'] = mapping.get('middlename',None)
    1819                 d['jamb_lastname'] = mapping.get('lastname',None)
    1820 
    1821             # if pt == "StudyCourse":
    1822             #     for von,zu in (('entry_mode','current_mode'),
    1823             #                    ('entry_session','current_session')):
    1824             #         if mapping.get(zu,None) is None and mapping.get(von,None) is not None:
    1825             #             d[zu] = mapping[von]
    1826             sub_doc.edit(mapping = d)
    1827 
    1828             #import pdb;pdb.set_trace()
    1829             new_state = f2t[pt]['wf_transition_%(transition)s' % vars()]
    1830             if new_state != "remain":
    1831                 self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
    1832         self.portal_workflow.doActionFor(student_obj,transition)
    1833         student_obj.manage_setLocalRoles(sid, ['Owner',])
    1834         return sid,''
    1835     ###)
    1836 
    1837     security.declareProtected(ModifyPortalContent,'mass_edit_student') ###(
    1838     def mass_edit_student(self,mapping):
    1839         wftool = self.portal_workflow
    1840         "edit student records due import"
    1841         logger = logging.getLogger('WAeUPTool.mass_edit_student')
    1842         students_folder = self.portal_url.getPortalObject().campus.students
    1843         sid = mapping.get('id',None)
    1844         jamb_reg_no = mapping.get('jamb_reg_no',None)
    1845         matric_no = mapping.get('matric_no',None)
    1846         editable_keys = mapping.keys()
    1847         if sid:
    1848             res = self.students_catalog(id = sid)
    1849             if not res:
    1850                 return '',"no student with id %s" % sid
    1851             if matric_no and res[0].matric_no and\
    1852               matric_no != res[0].matric_no:
    1853                 logger.info("%s, old matric_no %s overwritten with %s" % (res[0].id,res[0].matric_no,matric_no))
    1854             if jamb_reg_no and res[0].jamb_reg_no and\
    1855               jamb_reg_no != res[0].jamb_reg_no:
    1856                 logger.info("%s, old reg_no %s overwritten with %s" % (res[0].id,res[0].jamb_reg_no,jamb_reg_no))
    1857         elif jamb_reg_no:
    1858             res = self.students_catalog(jamb_reg_no = jamb_reg_no)
    1859             if not res:
    1860                 return '',"no student with jamb_reg_no %s" % jamb_reg_no
    1861             editable_keys.remove('jamb_reg_no')
    1862         elif matric_no:
    1863             res = self.students_catalog(matric_no = matric_no)
    1864             if not res:
    1865                 return '',"no student with matric_no %s" % matric_no
    1866             editable_keys.remove('matric_no')
    1867 
    1868         ## included only to change wf state from admitted to returning
    1869         #if res[0].review_state not in ('admitted','objection_raised'):
    1870         #    return '%s' % res[0].id ,"student is not in state admitted or objection_raised"
    1871         ## end inclusion
    1872 
    1873         sid = res[0].id
    1874         student_obj = getattr(students_folder,sid)
    1875         f2t = self.field2types_student
    1876         d = {}
    1877         #import pdb;pdb.set_trace()
    1878         any_change = False
    1879         #special treatment for StudentStudyLevel
    1880         d['verdict']  = mapping.get('current_verdict','')
    1881         d['session']  = mapping.get('current_session','')
    1882         current_level = mapping.get('current_level','')
    1883         while d['session'] and d['verdict'] and current_level:
    1884             sub_obj = getattr(student_obj,'study_course',None)
    1885             if sub_obj is None:
    1886                 break
    1887             level_obj = getattr(sub_obj,current_level,None)
    1888             if  level_obj is None:
    1889                 break
    1890             any_change = True
    1891             level_obj.getContent().edit(mapping = d)
    1892             try:
    1893                 wftool.doActionFor(level_obj,'close')
    1894             except:
    1895                 pass
    1896             break
    1897         for pt in f2t.keys():
    1898             #if pt == "StudentApplication":
    1899             #    d['jamb_sex']  = 'M'
    1900             #    if mapping.get('sex'):
    1901             #        d['jamb_sex']  = 'F'
    1902             intersect = set(f2t[pt]['fields']).intersection(set(editable_keys))
    1903             if intersect and pt not in ('StudentStudyLevel',):
    1904                 object_id = f2t[pt]['id']
    1905                 sub_obj = getattr(student_obj,object_id,None)
    1906                 if sub_obj is None:
    1907                     try:
    1908                         student_obj.invokeFactory(pt,object_id)
    1909                     except:
    1910                         continue
    1911                     sub_obj = getattr(student_obj,object_id)
    1912                     if f2t[pt]['title'] != '':
    1913                         d['Title'] = f2t[pt]['title']
    1914                 sub_doc = sub_obj.getContent()
    1915                 for field in intersect:
    1916                     changed = False
    1917                     if getattr(sub_doc,field,None) != mapping.get(field,''):
    1918                         any_change = True
    1919                         changed = True
    1920                         d[field] = mapping.get(field,'')
    1921                     if changed:
    1922                         sub_doc.edit(mapping = d)
    1923 
    1924 
    1925         ## included only to change wf state from admitted to returning
    1926         #    if res[0].review_state in ('admitted','objection_raised'):
    1927         #        new_state = f2t[pt]['wf_transition_return']
    1928         #        sub_obj = getattr(student_obj,f2t[pt]['id'],None)
    1929         #        if sub_obj and new_state != "remain":
    1930         #            try:
    1931         #                self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
    1932         #            except:
    1933         #                #logger.info('%s, wf transition %s of %s failed' % (sid,new_state,sub_obj.id))
    1934         #                pass
    1935         #if res[0].review_state in ('admitted','objection_raised'):
    1936         #    wfaction = 'return'
    1937         #    try:
    1938         #        self.portal_workflow.doActionFor(student_obj,wfaction)
    1939         #        logger.info('%s, wf state changed' % sid)
    1940         #        any_change = True
    1941         #    except:
    1942         #        logger.info('%s, wf transition failed, old state = %s' % (sid,res[0].review_state))
    1943         #        pass
    1944         ## end inclusion
    1945 
    1946 
    1947         if any_change:
    1948             return sid,''
    1949         else:
    1950             return sid,'not modified'
    1951     ###)
    1952 
    1953     security.declareProtected(ModifyPortalContent,'mass_edit_verdict') ###(
    1954     def mass_edit_verdict(self,mapping):
    1955         wftool = self.portal_workflow
    1956         "edit student verdicts"
    1957         logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
    1958         students_folder = self.portal_url.getPortalObject().campus.students
    1959         student_id = mapping.get('id',None)
    1960         matric_no = mapping.get('matric_no',None)
    1961         editable_keys = mapping.keys()
    1962         if student_id:
    1963             student_record = self.students_catalog.getRecordByKey(student_id)
    1964             if student_record is None:
    1965                 return '',"no student with id %s" % student_id
    1966             if matric_no and student_record.matric_no and\
    1967               matric_no != student_record.matric_no:
    1968                 return '', 'student %s: matric_no %s does not match %s' % (student_record.id,
    1969                                                                           student_record.matric_no,
    1970                                                                           matric_no)
    1971             mapping['matric_no'] = student_record.matric_no
    1972         elif matric_no:
    1973             res = self.students_catalog(matric_no = matric_no)
    1974             if not res:
    1975                 return '',"no student with matric_no %s" % matric_no
    1976             student_record = res[0]
    1977             editable_keys.remove('matric_no')
    1978         else:
    1979             return '',"no id or matric_no specified"
    1980         student_id = student_record.id
    1981         d = {}
    1982         #import pdb;pdb.set_trace()
    1983         any_change = False
    1984         #special treatment for StudentStudyLevel
    1985         current_session = d['session'] = mapping.get('current_session','')
    1986         if current_session and student_record.session != current_session:
    1987             msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
    1988                                                                                         current_session,
    1989                                                                                         student_record.session)
    1990             return student_id,msg,mapping
    1991         current_level = mapping.get('current_level','')
    1992         if not current_level.isdigit():
    1993             return '','student %s: imported level is empty' % (student_id,)
    1994         if current_level and student_record.level != current_level:
    1995             msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
    1996                                                                                     current_level,
    1997                                                                                     student_record.level)
    1998             return student_id,msg,mapping
    1999         student_review_state =  student_record.review_state
    2000         if student_review_state == 'deactivated':
    2001             return '',"student %s in review_state %s" % (student_id, student_review_state)
    2002         if student_review_state not in ('courses_validated','returning'):
    2003             msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
    2004             return student_id,msg,mapping
    2005         student_obj = getattr(students_folder,student_id)
    2006         f2t = self.field2types_student
    2007         study_course_obj = getattr(student_obj,'study_course',None)
    2008         if study_course_obj is None:
    2009             return '','student %s: no study_course object' % student_id
    2010         level_obj = getattr(study_course_obj,current_level,None)
    2011         if  level_obj is None:
    2012             return '','student %s: no study_level object for level %s' % (student_id,
    2013                                                                              current_level)
    2014         verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
    2015 
    2016         #if verdict == student_record.verdict:
    2017         #    return '','student %s: verdict already set to %s' % (student_id,
    2018         #                                                            verdict)
    2019 
    2020         level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
    2021         if level_review_state != "closed":
    2022             wftool.doActionFor(level_obj,'close')
    2023             # return '','student %s: level %s is not closed' % (student_id,
    2024             #                                                      current_level)
    2025 
    2026         study_course_obj.getContent().edit(mapping = d)
    2027         level_obj.getContent().edit(mapping = d)
    2028         if student_review_state != "returning":
    2029             wftool.doActionFor(student_obj,'return')
    2030         # try:
    2031         #     wftool.doActionFor(level_obj,'close')
    2032         # except:
    2033         #     pass
    2034         return student_id,''
    2035     ###)
    2036 
    20371341    security.declareProtected(ModifyPortalContent,"importData")###(
    20381342    def importData(self,filename,name,edit=False,bypass_queue_catalog=False):
     1343        """load data from CSV values"""
     1344        import transaction
     1345        import random
     1346        students_folder = self.portal_url.getPortalObject().campus.students
     1347        pending_only = False
     1348        pend_str = '_pending'
     1349        elapse = time.time()
     1350        #
     1351        # preparations
     1352        #
     1353        if name.endswith(pend_str):
     1354            pending_only = True
     1355            name = name[:-len(pend_str)]
     1356        mode = "create"
     1357        if edit:
     1358            if filename.endswith('_toDelete'):
     1359                mode = "delete"
     1360            else:
     1361                mode = "edit"
     1362        # schema = stool._getOb(iname)
     1363        # if schema is None:
     1364        #     em = 'No such schema %s' % iname
     1365        #     logger.error('No such schema %s' % iname)
     1366        #     return em
     1367        # pending_schema = stool._getOb("%s_pending" % iname)
     1368        # if pending_schema is None:
     1369        #     em = 'No such schema %s_pending' % iname
     1370        #     logger.error('No such schema %s_pending' % iname)
     1371        #     return em
     1372        # layout = ltool._getOb(iname)
     1373        # if layout is None:
     1374        #     em = 'No such layout %s' % iname
     1375        #     logger.error(em)
     1376        #     return em
     1377        importer_name = ''.join([part.capitalize() for part in name.split('_')])
     1378        importer = eval("%sImport" % importer_name)(mode,self)
     1379        logger = importer.logger
     1380        if importer.init_errors:
     1381            logger.info(self.init_errors)
     1382            return self.init_errors
     1383        member = importer.member
     1384        current = importer.current
     1385        import_date = importer.import_date
     1386        #
     1387        # not_imported
     1388        #
     1389        info = importer.info
     1390        data_keys = importer.data_keys
     1391        csv_keys = importer.csv_keys
     1392        #csv_keys.extend(info.keys())
     1393        headline_mapping = dict((k,k) for k in csv_keys)
     1394        #
     1395        # pending
     1396        #
     1397        pending_path = importer.pending_path
     1398        pending_tmp = importer.pending_tmp
     1399        pending_backup = importer.pending_backup
     1400        pending_fn = importer.pending_fn
     1401        imported_path = importer.imported_path
     1402        imported_fn = importer.imported_fn
     1403        pending = []
     1404        pending_digests = []
     1405        #total_added_to_pending = 0
     1406        if not pending_only:
     1407            pending,pending_digests = importer.makeIdLists()
     1408            pending_at_start = len(pending)
     1409        datafile = open(pending_tmp,"w")
     1410        pending_csv_writer = csv.DictWriter(datafile,
     1411                                                    csv_keys,
     1412                                                    extrasaction='ignore')
     1413        pending_csv_writer.writerow(headline_mapping)
     1414        datafile.close()
     1415        #
     1416        # imported
     1417        #
     1418        if not os.path.exists(imported_path):
     1419            datafile = open(imported_path,"w")
     1420            imported_csv_writer = csv.DictWriter(datafile,
     1421                                                 csv_keys,
     1422                                                 extrasaction='ignore')
     1423            imported_csv_writer.writerow(headline_mapping)
     1424            datafile.close()
     1425        start = True
     1426        tr_count = 0
     1427        total = 0
     1428        total_added_to_imported = 0
     1429        total_pending = 0
     1430        if pending_only:
     1431            import_source_path = pending_path
     1432        else:
     1433            import_source_path = "%s/import/%s.csv" % (i_home,filename)
     1434        if not os.path.exists(import_source_path):
     1435            em = 'No  %(import_source_fn)s' % vars()
     1436            return em
     1437        import_source_fn = os.path.split(import_source_path)[1]
     1438        info['imported_from'] = import_source_fn
     1439        attrs = csv.reader(open(import_source_path,"rb")).next()
     1440        import_keys = [k.strip() for k in attrs if not (k.strip().startswith('ignore')
     1441                                                        or k.strip() in info.keys())]
     1442        diff2schema = set(import_keys).difference(set(importer.schema.keys()))
     1443        diff2layout = set(import_keys).difference(set(importer.layout.keys()))
     1444        if diff2schema and diff2schema != set(['id',]):
     1445            msg = 'not ignorable key(s): "%s" found in heading' % ", ".join(diff2schema)
     1446            return msg
     1447        if mode in importer.required_modes:
     1448            required_keys = [importer.layout.getIdUnprefixed(id)
     1449                                for id,widget in importer.layout.objectItems()
     1450                                if widget.is_required]
     1451            if not set(required_keys).issubset(set(import_keys)):
     1452                diff2import = set(required_keys).difference(set(import_keys))
     1453                msg = 'required key(s): "%s" not found in heading' % ", ".join(diff2import)
     1454                return msg
     1455        #
     1456        # start importing
     1457        #
     1458        try:
     1459            reader = csv.DictReader(open(import_source_path,"rb"))
     1460        except:
     1461            msg = 'Error reading %s.csv' % filename
     1462            logger.error(msg)
     1463            return msg
     1464        items = [item for item in reader]
     1465        total_to_import = len(items)
     1466        tti_float = float(total_to_import)
     1467        if pending_only:
     1468            pending_at_start = total_to_import
     1469        count = 0
     1470        imported = []
     1471        old_commit_count = 0
     1472        with_error_count = imported_count = 0
     1473        already_in = 0
     1474        for record in items:
     1475            item = {}
     1476            for k,v in record.items():
     1477                if v:
     1478                    item[k.strip()] = v.strip()
     1479            count += 1
     1480            #item = dict((k.strip(),l.strip()) for (k,l) in item.items())
     1481            if start:
     1482                start = False
     1483                adapters = [MappingStorageAdapter(importer.schema, item)]
     1484                logger.info('%(member)s starts import from %(import_source_fn)s in %(mode)s mode' % vars())
     1485                #logger.info('%s starts import from %s in %s mode with schema and layout %s' % (member,filename,mode,iname))
     1486            dm = DataModel(item, adapters,context=self)
     1487            ds = DataStructure(data=item,datamodel=dm)
     1488            error_string = ""
     1489            total += 1
     1490            for k in import_keys:
     1491                if k not in item.keys() or k not in importer.validators.keys():
     1492                    continue
     1493                if not importer.validators[k](ds,mode=mode):
     1494                    if error_count:
     1495                        error_string += ' ++ '
     1496                    error_string += "%s: %s" % (k,self.translation_service(ds.getError(k),
     1497                                                                           ds.getErrorMapping(k)))
     1498                    error_count += 1
     1499            if error_string:
     1500                error = error_string
     1501                id = ''
     1502                mapping = item
     1503            else:
     1504                temp_item = item.copy()
     1505                temp_item.update(dm)
     1506                results = importer.import_method(temp_item)
     1507                id = results[0]
     1508                error = results[1]
     1509                mapping = results[2]
     1510            data_string = ",".join("%s : %s" % (k,v) for k,v in mapping.items())
     1511            info['error'] = error
     1512            mapping.update(info)
     1513            if error:
     1514                digest = makeDigest(mapping,data_keys)
     1515                with_error_count += 1
     1516                percent_finished = (with_error_count + imported_count)/tti_float*100
     1517                if digest not in pending_digests:
     1518                    pending_digests += digest,
     1519                    pending.append(mapping)
     1520                    if not pending_only:
     1521                        logger.info("%(percent_finished)6.3f %% done added to %(pending_fn)s %(data_string)s" % vars())
     1522                else:
     1523                    already_in += 1
     1524                    #logger.info("already in %(pending_fn)s %(data_string)s" % vars())
     1525                    pass
     1526            else:
     1527                imported_count += 1
     1528                imported += mapping,
     1529                percent_finished = (with_error_count + imported_count)/tti_float*100
     1530                logger.info("%(percent_finished)6.3f %% done  imported and added to  %(imported_fn)s %(data_string)s" % vars())
     1531            finished = count > total_to_import - 1
     1532            must_commit = False
     1533            if len(imported) != old_commit_count:
     1534                if not len(imported) % importer.commit_after:
     1535                    must_commit = True
     1536                    old_commit_count = len(imported)
     1537                   
     1538            if must_commit or finished:
     1539                if len(imported):
     1540                    transaction.commit()
     1541                    datafile = open(imported_path,"a")
     1542                    writer = csv.DictWriter(datafile,
     1543                                            csv_keys,
     1544                                            extrasaction='ignore')
     1545                    writer.writerows(imported)
     1546                    datafile.close()
     1547                    total_added_to_imported += len(imported)
     1548                    imported = []
     1549                if len(pending) > 0:
     1550                    datafile = open(pending_tmp,"a")
     1551                    writer = csv.DictWriter(datafile,
     1552                                            csv_keys,
     1553                                            extrasaction='ignore')
     1554                    writer.writerows(pending)
     1555                    datafile.close()
     1556                    total_pending += len(pending)
     1557                    #total_added_to_pending += len(pending)
     1558                    pending = []
     1559                if not finished:
     1560                    msg = '%(commit_after)d imports committed of total %(total_added_to_imported)d\n' % vars()
     1561                    logger.info(msg)
     1562        elapse = time.time() - elapse
     1563        copy2(pending_tmp,pending_path)
     1564        msg = "Finished importing in %(mode)s mode from %(import_source_fn)s in %(elapse)6.2f seconds: " % vars()
     1565        msg += "read = %(count)d; %(imported_fn)s: added = %(total_added_to_imported)d; " % vars()
     1566        if pending_only:
     1567            removed_pending = pending_at_start - total_pending
     1568            msg += "%(pending_fn)s: removed = %(removed_pending)d, " % vars()
     1569        else:
     1570            added_pending = total_pending - pending_at_start
     1571            msg += "%(pending_fn)s: added = %(added_pending)d, already in = %(already_in)s " % vars()
     1572        msg += ", total %(total_pending)d; " % vars()
     1573        logger.info(msg)
     1574        return msg
     1575    ###)
     1576
     1577    def d1402_importData(self,filename,name,edit=False,bypass_queue_catalog=False): ###(
    20391578        """load data from CSV values"""
    20401579        import transaction
     
    23221861    ###)
    23231862
    2324     def old_importData(self,filename,name,edit=False,bypass_queue_catalog=False):###(
    2325         """load data from CSV values"""
    2326         import transaction
    2327         import random
    2328 
    2329         pm = self.portal_membership
    2330         member = pm.getAuthenticatedMember()
    2331 
    2332         logger = logging.getLogger('WAeUPTool.importData')
    2333         current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
    2334         students_folder = self.portal_url.getPortalObject().campus.students
    2335         start = True
    2336         tr_count = 0
    2337         total_imported = 0
    2338         total_not_imported = 0
    2339         total = 0
    2340         iname = "import_%s" % name
    2341         if iname in ('import_application','import_course_result',):
    2342             commit_after = 2000
    2343         else:
    2344             commit_after = 100
    2345         stool = getToolByName(self, 'portal_schemas')
    2346         ltool = getToolByName(self, 'portal_layouts')
    2347         schema = stool._getOb(iname)
    2348         if schema is None:
    2349             em = 'No such schema %s' % iname
    2350             logger.error('No such schema %s' % iname)
    2351             return em
    2352         layout = ltool._getOb(iname)
    2353         if layout is None:
    2354             em = 'No such layout %s' % iname
    2355             logger.error(em)
    2356             return em
    2357         validators = {}
    2358         for widget in layout.keys():
    2359             validators[widget] = layout[widget].validate
    2360         mode = "create"
    2361         if edit:
    2362             if filename.endswith('_toDelete'):
    2363                 mode = "delete"
    2364             else:
    2365                 mode = "edit"
    2366         importer_name = "mass_%(mode)s_%(name)s" % vars()
    2367         importer = getattr(self, '%s' % importer_name,None)
    2368         if importer is None:
    2369             em = 'No importer function %s' % importer_name
    2370             logger.error(em)
    2371             return em
    2372         not_imported = []
    2373         imported = []
    2374         try:
    2375             items = csv.DictReader(open("%s/import/%s.csv" % (i_home,filename),"rb"))
    2376         except:
    2377             em = 'Error reading %s.csv' % filename
    2378             logger.error(em)
    2379             return em
    2380         for item in items:
    2381             #import pdb;pdb.set_trace()
    2382             item = dict((k.strip(),l.strip()) for (k,l) in item.items())
    2383             if start:
    2384                 start = False
    2385                 adapters = [MappingStorageAdapter(schema, item)]
    2386                 logger.info('%s starts import from %s.csv in %s mode with schema and layout %s' % (member,filename,mode,iname))
    2387                 attrs = csv.reader(open("%s/import/%s.csv" % (i_home,filename),"rb")).next()
    2388                 import_keys = [k.strip() for k in attrs if not k.strip().startswith('ignore')]
    2389                 diff2schema = set(import_keys).difference(set(schema.keys()))
    2390                 diff2layout = set(import_keys).difference(set(layout.keys()))
    2391                 if diff2schema:
    2392                     em = 'not ignorable key(s): "%s" found in heading' % ", ".join(diff2schema)
    2393                     return em
    2394                 if mode == "create":
    2395                     required_keys = [layout.getIdUnprefixed(id)
    2396                                      for id,widget in layout.objectItems()
    2397                                      if widget.is_required]
    2398                     if not set(required_keys).issubset(set(import_keys)):
    2399                         diff2import = set(required_keys).difference(set(import_keys))
    2400                         em = 'required key(s): "%s" not found in heading' % ", ".join(diff2import)
    2401                         return em
    2402                 s = ','.join(['"%s"' % fn for fn in import_keys])
    2403                 open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(s + ',"Error"'+ '\n')
    2404                 s = '"id",' + s
    2405                 open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(s + '\n')
    2406                 format = ','.join(['"%%(%s)s"' % fn for fn in import_keys])
    2407                 format_error = format + ',"%(Error)s"'
    2408                 format = '"%(id)s",'+ format
    2409 
    2410             dm = DataModel(item, adapters,context=self)
    2411             ds = DataStructure(data=item,datamodel=dm)
    2412             error_string = ""
    2413             total += 1
    2414             error_count = 0
    2415             for k in import_keys:
    2416                 if not validators[k](ds,mode=mode):
    2417                     if error_count:
    2418                         error_string += ' ++ '
    2419                     error_string += "%s: %s" % (k,
    2420                                                   self.translation_service(ds.getError(k),
    2421                                                                            ds.getErrorMapping(k)))
    2422                     error_count += 1
    2423             if not error_string:
    2424                 temp_item = item.copy()
    2425                 temp_item.update(dm)
    2426                 temp_item['id'],error = importer(temp_item)
    2427                 if error:
    2428                     error_string += error
    2429                 else:
    2430                     item = temp_item
    2431             if error_string:
    2432                 item['Error'] = error_string
    2433                 not_imported.append(format_error % item)
    2434                 total_not_imported += 1
    2435             else:
    2436                 em = format % item
    2437                 imported.append(em)
    2438                 tr_count += 1
    2439                 total_imported += 1
    2440                 logger.info("%(total_imported)d of %(total)d imported in %(mode)s mode, %(em)s" % vars())
    2441 
    2442             if total and not total % commit_after:
    2443                 transaction.commit()
    2444                 if len(not_imported) > 0:
    2445                     open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
    2446                              '\n'.join(not_imported) + '\n')
    2447                     not_imported = []
    2448                 if len(imported) > 0:
    2449                     open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
    2450                              '\n'.join(imported) + '\n')
    2451                     imported = []
    2452                 em = '%d transactions committed\n' % (tr_count)
    2453                 regs = []
    2454                 logger.info(em)
    2455                 tr_count = 0
    2456                 #if total > 100:
    2457                 #    return
    2458         if len(imported) > 0:
    2459             open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
    2460                                                 '\n'.join(imported))
    2461         if len(not_imported) > 0:
    2462             open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
    2463                                                 '\n'.join(not_imported))
    2464         #if mode.endswith('e'):
    2465         #    mode = mode[:-1]
    2466         em = "Finished importing in %(mode)s mode from %(filename)s.csv: %(total_imported)d imported, %(total_not_imported)d not imported (of total %(total)d)" % vars()
    2467         logger.info(em)
    2468         return em
    2469     ###)
    2470 
    24711863    security.declareProtected(ModifyPortalContent,"moveImagesToFS")###(
    24721864    def moveImagesToFS(self,student_id="O738726"):
Note: See TracChangeset for help on using the changeset viewer.