source: WAeUP_SRP/trunk/Students.py @ 1801

Last change on this file since 1801 was 1801, checked in by Henrik Bettermann, 17 years ago

do not import PIL if not necessary

  • Property svn:keywords set to Id
File size: 48.5 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Students.py 1801 2007-05-21 13:39:18Z henrik $
3from string import Template
4from Globals import InitializeClass
5from AccessControl import ClassSecurityInfo
6from AccessControl.SecurityManagement import newSecurityManager
7from zExceptions import BadRequest
8from Products.ZCatalog.ZCatalog import ZCatalog
9from Products.CMFCore.utils import UniqueObject, getToolByName
10from Products.CMFCore.permissions import View
11from Products.CMFCore.permissions import ModifyPortalContent
12from Products.CPSCore.CPSBase import CPSBase_adder, CPSBaseFolder
13#from Products.CPSCore.CPSBase import CPSBaseDocument as BaseDocument
14from Products.CPSDocument.CPSDocument import CPSDocument
15from Products.CPSCore.CPSBase import CPSBaseBTreeFolder as BaseBTreeFolder
16from Products.CPSCore.CPSMembershipTool import CPSUnrestrictedUser
17from Products.WAeUP_SRP.Academics import makeCertificateCode
18from Products.AdvancedQuery import Eq, Between, Le,In
19import logging
20import csv,re,os
21import Globals
22p_home = Globals.package_home(globals())
23i_home = Globals.INSTANCE_HOME
24MAX_TRANS = 1000
25from urllib import urlencode
26
27import DateTime
28#import PIL.Image
29from StringIO import StringIO
30
31def makeCertificateCode(code): ###(
32    code = code.replace('.','')
33    code = code.replace('(','')
34    code = code.replace(')','')
35    code = code.replace('/','')
36    code = code.replace(' ','')
37    code = code.replace('_','')
38    return code
39
40###)
41
42def response_write(response,s):
43    response.setHeader('Content-type','text/html; charset=ISO-8859-15')
44    while s.find('<') > -1:
45        s = s.replace('<','&lt;')
46    while s.find('>') > -1:
47        #from pdb import set_trace;set_trace()
48        s = s.replace('>','&gt;')
49    response.write("%s<br>\n" % s)
50
51def getInt(s): ###(
52    try:
53        return int(s)
54    except:
55        return 0
56
57def getFloat(s):
58    try:
59        return float(s)
60    except:
61        return 0.0
62
63###)
64
65def getStudentByRegNo(self,reg_no): ###(
66    """search student by JAMB Reg No and return StudentFolder"""
67    search = ZCatalog.searchResults(self.portal_catalog,{'meta_type': 'StudentApplication',
68                                  'SearchableText': reg_no,
69                                  })
70    if len(search) < 1:
71        return None
72    return search[0].getObject().aq_parent
73
74###)
75
76def checkJambNo(jnr):
77    try:
78        if len(jnr) != 10:
79            return False
80    except:
81        return False
82    try:
83        int(jnr[:8])
84        return True
85    except:
86        return False
87
88class StudentsFolder(CPSDocument): ###(
89    """
90    WAeUP container for the various WAeUP containers data
91    """
92    meta_type = 'StudentsFolder'
93    portal_type = meta_type
94    security = ClassSecurityInfo()
95
96    security.declareProtected(ModifyPortalContent,"loadPumeResultsFromCSV")###(
97    def loadPumeResultsFromCSV(self):
98        """load Fulltime Studentdata from CSV values into pumeresults catalog"""
99        import transaction
100        import random
101##        csv_d = {'jamb_reg_no': "RegNumber", ###(
102##                 'status': "Admission Status",
103##                 'name': "Name",
104##                 'score': "Score",
105##                 'sex': "Sex",
106##                 'faculty': "Faculty",
107##                 'department': "Dept",
108##                 'course': "Course",
109##                 'course_code_org': "Course Code",
110##                 }
111###)
112##        csv_d = {'jamb_reg_no': "JAMBRegno",
113##                'name': "Name",
114##                'score': "Score",
115##                 'sex': "Sex",
116##                 'course': "Course",
117##                 'faculty': "Faculty",
118##                 'department': "Dept",
119##                 'course_code_org': "Course Code",
120##                 'status': "Admission Status",
121##                 'result_type': None,
122##                 }
123
124        csv_d = {'jamb_reg_no': "reg_no",
125                 'name': "Firstame" + "Middlename" +"Lastname",
126                 'score': "pume_score",
127                 'sex': "sex",
128                 'course': "study_course",
129                 'status': "admission_status",
130                 'result_type': "entry_mode",
131                 }
132                                 
133        csv_fields = [f[1] for f in csv_d.items() if f[1]]
134        tr_count = 0
135        total = 0
136        #name = 'pup_new'
137        name = 'pup_update'
138        update = name.endswith('update')
139        no_import = []
140        ok_import = []
141        ok_import.append('%s' % ','.join(['"%s"' % fn for fn in csv_d.keys()]))
142        no_import.append('%s' % ','.join(['"%s"' % fn for fn in csv_fields]))
143        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
144        ok_import_name = "%s/import/%s_imported_%s.csv" % (i_home,name,current)
145        #open(ok_import_name,"w").write('\n'.join(no_import))
146        no_import_name = "%s/import/%s_not_imported_%s.csv" % (i_home,name,current)
147        #open(no_import_name,"w").write('\n'.join(no_import))
148        logger = logging.getLogger('Import.%s' % name)
149        starttime = DateTime.now()
150        logger.info('Start loading from %s.csv' % name)
151        try:
152            result = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
153        except:
154            logger.error('Error reading %s.csv' % name)
155            return
156        pume = self.portal_pumeresults
157        format = ','.join(['"%%(%s)s"' % fn for fn in csv_fields])
158        import_format = ','.join(['"%%(%s)s"' % fn for fn in csv_d.keys()])
159        eduplicate = '%s,"duplicate"' % format
160        einvalidjamb = '%s,"invalid JambRegNo"' % format
161        added = 'added ,%s' % format
162        #from pdb import set_trace;set_trace()
163        for jamb in result:
164            dict = {}
165            for f,fn in csv_d.items():
166                dict[f] = jamb.get(csv_d[f])
167            dict['result_type'] = 'DE'
168            jnr = jamb.get(csv_d['jamb_reg_no'])
169            if not checkJambNo(jnr):
170                logger.info(einvalidjamb % jamb)
171                dd = {}
172                for f,fn in csv_d.items():
173                    dd[fn] = getattr(data,f)
174                    no_import.append(eduplicate % dd)
175                    no_import.append(eduplicate % jamb)
176                continue
177            res = pume(jamb_reg_no=jnr)
178            if len(res) > 0:
179                if update:
180                    try:
181                        pume.modifyRecord(**dict)
182                    except ValueError:
183                        logger.info(eduplicate % jamb)
184                        continue
185                    except KeyError:
186                        pume.addRecord(**dict)
187                        logger.info(added % jamb)
188                        continue
189                else:
190                    data = res[0]
191                    if data.name != jamb.get(csv_d['name']):
192                        #set_trace()
193                        logger.info(eduplicate % jamb)
194                        #em = 'Student with REG-NO %(jamb_reg_no)s already exists\n' % dict
195                        #logger.info(em)
196                        dd = {}
197                        for f,fn in csv_d.items():
198                            dd[fn] = getattr(data,f)
199                        no_import.append(eduplicate % dd)
200                        no_import.append(eduplicate % jamb)
201                    continue
202            try:
203                pume.addRecord(**dict)
204                ok_import.append(import_format % dict)
205            except ValueError:
206                logger.info(eduplicate % jamb)
207                #em = 'Student with REG-NO %(jamb_reg_no)s already exists\n' % dict
208                #logger.info(em)
209                no_import.append(eduplicate % jamb)
210        logger.info('End loading from %s.csv' % name)
211        if len(no_import) > 1:
212            open(no_import_name,"w+").write('\n'.join(no_import))
213        open(ok_import_name,"w+").write('\n'.join(ok_import))
214        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
215    ###)
216
217
218    security.declareProtected(ModifyPortalContent,"createStudents")###(
219    def createStudents(self):
220        """load Studentdata from CSV values"""
221        import transaction
222        import random
223        #from pdb import set_trace
224        wftool = self.portal_workflow
225        students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
226        #entry_levels = {'ume_ft':'100',
227        #                'de_ft': '200',
228        #                'ug_pt': '100',
229        #                'de_pt': '200',
230        #                'pg_ft': '700',
231        #                'pg_pt': '700',
232        #                'dp_pt': '100',
233        #                'dp_ft': '100',
234        #                }
235        csv_d = {'jamb_reg_no': "reg_no",
236                 'entry_mode': 'entry_mode',
237                 'jamb_firstname': "firstname",
238                 'jamb_middlename': "middlename",
239                 'jamb_lastname': "lastname",
240                 'jamb_sex': "sex",
241                 'jamb_state': "state",
242                 'birthday': "date_of_birth",
243                 'app_email': "email",
244                 'study_course': "study_course",
245                 'perm_address': "address",
246                 }
247        csv_fields = [f[1] for f in csv_d.items()]
248        tr_count = 0
249        total = 0
250        #name = 'pume_results'
251        name = 'Admitted'
252        no_import = []
253        s = ','.join(['"%s"' % fn for fn in csv_fields])
254        no_import.append('"Error",%s' % s)
255        format = '"%(Error)s",' + ','.join(['"%%(%s)s"' % fn for fn in csv_fields])
256        no_certificate = "no certificate %s" % format
257        open("%s/import/%s_not_imported.csv" % (i_home,name),"w").write('\n'.join(no_import))
258        logger = logging.getLogger('Students.StudentsFolder.createStudents')
259        logger.info('Start loading from %s.csv' % name)
260        certs = {}
261        try:
262            results = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
263        except:
264            logger.error('Error reading %s.csv' % name)
265            return
266        for result in results:
267            #result['Error'] = "Processing "
268            #logger.info(format % result)
269            jamb_reg_no = result.get(csv_d['jamb_reg_no'])
270            res = self.students_catalog(jamb_reg_no = jamb_reg_no)
271            if res:
272                em = 'Student with RegNo %s already exists\n' % jamb_reg_no
273                logger.info(em)
274                result['Error'] = "Student exists"
275                no_import.append(format % result)
276                continue
277            cert_id = makeCertificateCode(result.get(csv_d['study_course']))
278            if cert_id not in certs.keys():
279                res = self.portal_catalog(meta_type = "Certificate",id = cert_id)
280                if not res:
281                    em = 'No Certificate with ID %s \n' % cert_id
282                    logger.info(em)
283                    result['Error'] = "No Certificate %s" % cert_id
284                    no_import.append( format % result)
285                    continue
286                cert = res[0]
287                cert_path = cert.getPath().split('/')
288                certificate = certs[cert_id] = {'faculty': cert_path[-4],
289                                     'department': cert_path[-3]}
290            cert_doc = certs[cert_id]
291            catalog_entry = {}
292            catalog_entry['jamb_reg_no'] = jamb_reg_no
293            firstname = result.get(csv_d['jamb_firstname'])
294            middlename = result.get(csv_d['jamb_middlename'])
295            lastname = result.get(csv_d['jamb_lastname'])
296            sid = self.generateStudentId('x')
297            students_folder.invokeFactory('Student', sid)
298            catalog_entry['id'] = sid
299            tr_count += 1
300            logger.info('%(total)s+%(tr_count)s: Creating Student with ID %(sid)s reg_no %(jamb_reg_no)s ' % vars())
301            student = getattr(self,sid)
302            student.manage_setLocalRoles(sid, ['Owner',])
303            student.invokeFactory('StudentApplication','application')
304            da = {'Title': 'Application Data'}
305            da["jamb_firstname"] = firstname
306            da["jamb_middlename"] = middlename
307            da["jamb_lastname"] = lastname
308            catalog_entry['entry_session'] = da["entry_session"] = self.getSessionId()[-2:]
309            catalog_entry['sex'] = sex = result.get(csv_d['jamb_sex']).startswith('F')
310            da_fields = ('jamb_reg_no',
311                         'jamb_sex',
312                         'jamb_state',
313                         'entry_mode',
314                         'app_email',
315                         )
316            for f in da_fields:
317                da[f] = result.get(csv_d[f])
318            catalog_entry['email'] = da['app_email']
319            catalog_entry['entry_mode'] = da['entry_mode']
320            #catalog_entry['entry_level'] = da["entry_level"] = entry_levels.get(da['entry_mode'],'100')
321            app = student.application
322            app_doc = app.getContent()
323            app.getContent().edit(mapping=da)
324            picture ="%s/import/pictures/%s.jpg" % (i_home,jamb_reg_no)
325            app.manage_setLocalRoles(sid, ['Owner',])
326
327            picture_id = da['jamb_reg_no'].replace('/','_')
328            file = None
329            for ext in ('jpg','JPG'):
330                picture ="%s/import/pictures_admitted_latest/%s.%s" % (i_home,picture_id,ext)
331                if os.path.exists(picture):
332                    file = open(picture)
333                    break
334            if file is not None:
335
336                ## file conversion does not work
337                #img = PIL.Image.open(file)
338                #img.thumbnail((150,200),
339                #              resample=PIL.Image.ANTIALIAS)
340                #outfile = StringIO()
341                #img.save(outfile, format=img.format)
342
343                outfile = file.read()
344                app_doc.manage_addFile('passport',
345                                       file=outfile,
346                                       title="%s.jpg" % jamb_reg_no)
347            #wftool.doActionFor(app,'close')
348            dp = {}
349            dp['firstname'] = firstname
350            dp['middlename'] = middlename
351            dp['lastname'] = lastname
352            dp['email'] = da['app_email']
353            dp['sex'] = sex
354            catalog_entry['name'] = "%(firstname)s %(middlename)s %(lastname)s" % dp
355            student.invokeFactory('StudentPersonal','personal')
356            per = student.personal
357            per_doc = per.getContent()
358            per_doc.edit(mapping = dp)
359            per.manage_setLocalRoles(sid, ['Owner',])
360            wftool.doActionFor(student,'pume_pass')
361            wftool.doActionFor(student,'admit')
362            #
363            # Clearance
364            #
365            student.invokeFactory('StudentClearance','clearance')
366            #wftool.doActionFor(student.clearance,'open')
367            clearance = student.clearance
368            dc = {'Title': 'Clearance/Eligibility Record'}
369            clearance = student.clearance
370            date_str = result.get(csv_d['birthday'])
371            try:
372                date = DateTime.DateTime(date_str)
373            except:
374                #import pdb;pdb.set_trace()
375                date = None
376            dc['birthday'] = date
377            clearance.getContent().edit(mapping=dc)
378            clearance.manage_setLocalRoles(sid, ['Owner',])
379            #
380            # Study Course
381            #
382            student.invokeFactory('StudentStudyCourse','study_course')
383            study_course = student.study_course
384            dsc = {}
385            #catalog_entry['level'] = getattr(cert_doc,'start_level')
386            catalog_entry['session'] = dsc['current_session'] = da['entry_session']
387            #catalog_entry['level'] = dsc['current_level'] = entry_levels.get(da['entry_mode'],'100')
388            catalog_entry['mode'] = dsc['current_mode'] = da['entry_mode']
389            catalog_entry['course'] = dsc['study_course'] = cert_id
390            catalog_entry['faculty'] = certificate['faculty']
391            catalog_entry['department'] = certificate['department']
392            catalog_entry['verdict'] = dsc['current_verdict'] = 'N/A'
393            catalog_entry['review_state'] = self.portal_workflow.getInfoFor(student,'review_state',None)
394            study_course.getContent().edit(mapping=dsc)
395            #import pdb;pdb.set_trace()
396            self.students_catalog.addRecord(**catalog_entry)
397            if tr_count > 10:
398                if len(no_import) > 0:
399                    open("%s/import/%s_not_imported.csv" % (i_home,name),"a").write(
400                             '\n'.join(no_import) + "\n")
401                    no_import = []
402                em = '%d transactions commited\n' % tr_count
403                transaction.commit()
404                logger.info(em)
405                total += tr_count
406                tr_count = 0
407        open("%s/import/%s_not_imported.csv" % (i_home,name),"a").write(
408                                                '\n'.join(no_import))
409        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
410    ###)
411
412    security.declareProtected(ModifyPortalContent,"importReturningStudents")###(
413    def importReturningStudents(self):
414        """load Returning Studentdata from CSV values"""
415        import transaction
416        import random
417        #from pdb import set_trace
418        wftool = self.portal_workflow
419        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
420        students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
421        #students_folder = self.portal_url().getPortalObject().campus.students
422        tr_count = 1
423        total = 0
424        #name = 'pume_results'
425        name = 'Returning'
426        table = self.returning_import
427        no_import = []
428        imported = []
429        logger = logging.getLogger('Students.StudentsFolder.importReturningStudents')
430        try:
431            returning = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
432        except:
433            logger.error('Error reading %s.csv' % name)
434            return
435        l = self.portal_catalog({'meta_type': "Certificate"})
436        certs = {}
437        cert_docs = {}
438        for f in l:
439            certs[f.getId] = f.getObject().getContent()
440        start = True
441        res = table()
442        regs = []
443        if len(res) > 0:
444            regs = [s.matric_no for s in res]
445        #import pdb;pdb.set_trace()
446        for student in returning:
447            if start:
448                start = False
449                logger.info('Start loading from %s.csv' % name)
450                s = ','.join(['"%s"' % fn for fn in student.keys()])
451                imported.append(s)
452                no_import.append('%s,"Error"' % s)
453                format = ','.join(['"%%(%s)s"' % fn for fn in student.keys()])
454                format_error = format + ',"%(Error)s"'
455                no_certificate = "no certificate %s" % format
456            student['matric_no'] = matric_no = student.get('matric_no').upper()
457            student['Mode_of_Entry'] = entry_mode = student.get('Mode of Entry').upper()
458            student['Permanent_Address'] = perm_address = student.get('Permanent Address')
459            if matric_no == '':
460                student['Error'] = "Empty matric_no"
461                no_import.append( format_error % student)
462                continue
463            if matric_no in regs or self.returning_import(matric_no = matric_no):
464                student['Error'] = "Duplicate"
465                no_import.append( format_error % student)
466                continue
467            cert_id = makeCertificateCode(student.get('Coursemajorcode'))
468            if cert_id not in certs.keys():
469                student['Error'] = "No Certificate %s" % cert_id
470                no_import.append( format_error % student)
471                continue
472            try:
473                table.addRecord(**student)
474            except ValueError:
475                student['Error'] = "Duplicate"
476                no_import.append( format_error % student)
477                continue
478            regs.append(student.get('matric_no'))
479            imported.append(format % student)
480            tr_count += 1
481            if tr_count > 1000:
482                if len(no_import) > 0:
483                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
484                             '\n'.join(no_import) + '\n')
485                    no_import = []
486                open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
487                                            '\n'.join(no_import) + "\n")
488                imported = []
489                em = '%d transactions commited total %s\n' % (tr_count,total)
490                transaction.commit()
491                regs = []
492                logger.info(em)
493                total += tr_count
494                tr_count = 0
495        open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
496                                            '\n'.join(imported))
497        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
498                                                '\n'.join(no_import))
499        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
500    ###)
501
502
503    security.declareProtected(ModifyPortalContent,"fixAllNames")###(
504    def fixAllNames(self):
505        "fix all students names"
506        import transaction
507        response = self.REQUEST.RESPONSE
508        logger = logging.getLogger('fixAllNames')
509        logger.info('Start')
510        students = self.portal_catalog(portal_type='Student')
511        count = 0
512        total = 0
513        for student in students:
514            scat_res = self.students_catalog(id = student.getId)
515            if not scat_res:
516                self.students_catalog.addRecord(id = student.getId)
517                scat_res = self.students_catalog(id = student.getId)
518            student_entry = scat_res[0]
519            old_new = self.fixName(student,student_entry)
520            count += 1
521            response_write(response,'"%d","%s",%s' % (count + total,student_entry.id,old_new))
522            if count > 2000:
523                transaction.commit()
524                logger.info("%d transactions commited" % count)
525                total += count
526                count = 0
527    ###)
528
529    security.declareProtected(ModifyPortalContent,"fixName")###(
530    def fixName(self,student_brain, student_entry):
531        "fix the name of a student"
532        fix = "first"
533        if student_entry.get('name_fixed',None) == fix:
534            return "Name already fixed"
535        student_id = student_entry.id
536        new_student = student_entry.jamb_reg_no.startswith('6')
537        student_obj = student_brain.getObject()
538        personal = getattr(student_obj,'personal',None)
539        invalid = ''
540        if personal is None:
541            return '"%s","Returning","%s","%s"' % (invalid,student_entry.name,"not logged in")
542        per_doc = personal.getContent()
543        old_first = per_doc.firstname
544        old_middle = per_doc.middlename
545        old_last = per_doc.lastname
546        new_first = ''
547        new_middle = ''
548        new_last = ''
549        if new_student:
550            if not old_first and not old_middle and old_last:
551                new_names = [n.capitalize() for n in old_last.split()]
552                if len(new_names) > 1:
553                    old_first = new_names[0]
554                    old_last = new_names[-1]
555                    old_middle = ' '.join(new_names[1:-1])
556                else:
557                    old_last = new_names[0]
558                    old_first = ''
559                    old_middle = ''
560            if old_first:
561                new_first = old_first
562            if old_middle:
563                new_middle = old_middle
564            if old_last:
565                new_last = old_last
566            if old_first.find('<') != -1 or\
567               old_first.find('>') != -1 or\
568               old_middle.find('<') != -1 or\
569               old_middle.find('>') != -1 or\
570               old_last.find('<') != -1 or\
571               old_last.find('>') != -1:
572                   invalid = "invalid characters"
573        else:
574            new_first = old_first
575            if new_first.strip() == '-':
576                new_first = ''
577            new_middle = old_middle
578            if new_middle.strip() == '-':
579                new_middle = ''
580            new_last = old_last
581            if new_last.strip() == '-':
582                new_last = ''
583        name = "%(new_first)s %(new_middle)s %(new_last)s" % vars()
584        if new_student:
585            text = "New"
586        else:
587            text = "Returning"
588        old_new = '"%s","%s","%s","%s"' % (invalid,text,
589                                           student_entry.name,
590                                           name)
591        if not invalid:
592            self.students_catalog.modifyRecord(id = student_id,
593                                      name_fixed = fix,
594                                      name = name)
595            per_doc.edit(mapping = {'firstname' : new_first,
596                                'middlename' : new_middle,
597                                'lastname' : new_last,
598                                })
599        return old_new
600    ###)
601
602
603
604    security.declareProtected(ModifyPortalContent,"updateReturningStudents")###(
605    def updateReturningStudents(self):
606        """load and overwrite Returning Student Data from CSV values"""
607        import transaction
608        import random
609        #from pdb import set_trace
610        wftool = self.portal_workflow
611        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
612        students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
613        tr_count = 1
614        total = 0
615        #name = 'pume_results'
616        name = 'Returning_update'
617        table = self.returning_import
618        no_import = []
619        imported = []
620        logger = logging.getLogger('Students.StudentsFolder.updateReturningStudents')
621        try:
622            returning = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
623        except:
624            logger.error('Error reading %s.csv' % name)
625            return
626        l = self.portal_catalog({'meta_type': "Certificate"})
627        certs = {}
628        cert_docs = {}
629        for f in l:
630            certs[f.getId] = f.getObject().getContent()
631        start = True
632        res = table()
633        regs = []
634        if len(res) > 0:
635            regs = [s.matric_no for s in res]
636        for student in returning:
637            if start:
638                start = False
639                logger.info('Start loading from %s.csv' % name)
640                s = ','.join(['"%s"' % fn for fn in student.keys()])
641                imported.append(s)
642                no_import.append('%s,"Error"' % s)
643                format = ','.join(['"%%(%s)s"' % fn for fn in student.keys()])
644                format_error = format + ',"%(Error)s"'
645                no_certificate = "no certificate %s" % format
646            matric_no = student.get('matric_no').upper()
647            student['matric_no'] = matric_no
648            if matric_no == '':
649                student['Error'] = "Empty matric_no"
650                no_import.append( format_error % student)
651                continue
652#            if matric_no in regs or self.returning_import(matric_no = matric_no):
653#                student['Error'] = "Duplicate"
654#                no_import.append( format_error % student)
655#                continue
656#            cert_id = makeCertificateCode(student.get('Coursemajorcode'))
657#            if cert_id not in certs.keys():
658#                student['Error'] = "No Certificate %s" % cert_id
659#                no_import.append( format_error % student)
660#                continue
661            try:
662                table.modifyRecord(**student)
663            except KeyError:
664                #import pdb;pdb.set_trace()
665                student['Error'] = "no Student found to update"
666                no_import.append( format_error % student)
667                continue
668            #s = self.students_catalog(matric_no=matric_no)
669            #if s:
670            #    level = "%s" % (int(student.get('Level')) + 100)
671            #    self.students_catalog.modifyRecord(id = s[0].id,
672            #                                           level=level)
673
674            regs.append(student.get('matric_no'))
675            imported.append(format % student)
676            tr_count += 1
677            if tr_count > 1000:
678                if len(no_import) > 0:
679                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
680                             '\n'.join(no_import) + '\n')
681                    no_import = []
682                open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
683                                            '\n'.join(no_import) + "\n")
684                imported = []
685                em = '%d transactions commited total %s\n' % (tr_count,total)
686                transaction.commit()
687                regs = []
688                logger.info(em)
689                total += tr_count
690                tr_count = 0
691        open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
692                                            '\n'.join(imported))
693        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
694                                                '\n'.join(no_import))
695        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
696    ###)
697
698    security.declareProtected(ModifyPortalContent,"importResults")###(
699    def importResults(self):
700        """load Returning Students Results from CSV"""
701        import transaction
702        import random
703        #from pdb import set_trace
704        wftool = self.portal_workflow
705        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
706        students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
707        tr_count = 1
708        total = 0
709        #name = 'pume_results'
710        name = 'Results'
711        table = self.results_import
712        no_import = []
713        imported = []
714        logger = logging.getLogger('Students.StudentsFolder.importResults')
715        try:
716            results = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
717        except:
718            logger.error('Error reading %s.csv' % name)
719            return
720        l = self.portal_catalog({'meta_type': "Course"})
721        courses = [f.getId for f in l]
722        start = True
723        res = table()
724        regs = []
725        if len(res) > 0:
726            regs = [s.key for s in res]
727        no_course = []
728        no_course_list = []
729        course_count = 0
730        for result in results:
731            if start:
732                start = False
733                logger.info('Start loading from %s.csv' % name)
734                s = ','.join(['"%s"' % fn for fn in result.keys()])
735                imported.append(s)
736                no_import.append('%s,"Error"' % s)
737                format = ','.join(['"%%(%s)s"' % fn for fn in result.keys()])
738                format_error = format + ',"%(Error)s"'
739                no_certificate = "no certificate %s" % format
740            course_id = result.get('CosCode')
741            if not course_id:
742                course_id = 'N/A'
743                result['CosCode'] = course_id
744            matric_no = result.get('matric_no').upper()
745            result['matric_no'] = matric_no
746            key = matric_no+course_id
747            if matric_no == '':
748                result['Error'] = "Empty matric_no"
749                no_import.append( format_error % result)
750                continue
751            if key in regs or self.results_import(key = key):
752                result['Error'] = "Duplicate"
753                no_import.append( format_error % result)
754                continue
755            if course_id not in courses:
756                if course_id not in no_course:
757                    course_count +=1
758                    no_course.append(course_id)
759                    no_course_list.append('"%s"' % course_id)
760                    #result['Error'] = "No Course"
761                    #logger.info(format_error % result)
762            regs.append(key)
763            imported.append(format % result)
764            tr_count += 1
765            if tr_count > 1000:
766                if len(no_import) > 0:
767                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
768                             '\n'.join(no_import)+'\n')
769                    no_import = []
770                open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
771                                            '\n'.join(imported) + '\n')
772                imported = []
773                if no_course_list:
774                    open("%s/import/%sno_courses%s.csv" % (i_home,name,current),"a").write(
775                                            '\n'.join(no_course_list) + '\n')
776                    no_course_list = []
777                em = '%d transactions commited total %s\n courses not found %s' % (tr_count,total,course_count)
778                transaction.commit()
779                logger.info(em)
780                regs = []
781                total += tr_count
782                tr_count = 0
783        open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
784                                            '\n'.join(imported))
785        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
786                                                '\n'.join(no_import))
787        if no_course_list:
788            open("%s/import/%sno_courses%s.csv" % (i_home,name,current),"a").write(
789                                    '\n'.join(no_course_list))
790        em = '%d transactions commited total %s\n courses not found %s' % (tr_count,total,course_count)
791        logger.info(em)
792        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
793    ###)
794
795
796    security.declareProtected(ModifyPortalContent,"updateStudyCourse")###(
797    def updateStudyCourse(self):
798        """update StudyCourse from CSV values"""
799        import transaction
800        import random
801        from pdb import set_trace
802        wftool = self.portal_workflow
803        students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
804        csv_d = {'jamb_reg_no': "RegNumber",
805                 'jamb_lastname': "Name",
806                 'session': "Session",
807                 'pume_tot_score': "PUME SCORE",
808                 'jamb_score': "JambScore",
809                 'jamb_sex': "Sex",
810                 'jamb_state': "State",
811##                 'jamb_first_cos': "AdminCourse",
812                 'faculty': "AdminFaculty",
813                 'course_code': "AdmitCoscode",
814                 'stud_status':"AdmitStatus",
815                 'department': "AdmitDept",
816                 'jamb_lga': "LGA",
817                 'app_email': "email",
818                 'app_mobile': "PhoneNumbers",
819                 }
820        csv_fields = [f[1] for f in csv_d.items()]
821        tr_count = 0
822        total = 0
823        #name = 'pume_results'
824        name = 'StudyCourseChange'
825        no_import = []
826        s = ','.join(['"%s"' % fn for fn in csv_fields])
827        no_import.append('"Error",%s' % s)
828        format = '"%(Error)s",' + ','.join(['"%%(%s)s"' % fn for fn in csv_fields])
829        no_certificate = "no certificate %s" % format
830        open("%s/import/%s_not_imported.csv" % (i_home,name),"w").write(
831                    '\n'.join(no_import))
832        logger = logging.getLogger('Students.StudentsFolder.updateStudyCourse')
833        logger.info('Start loading from %s.csv' % name)
834        l = self.portal_catalog({'meta_type': "Certificate"})
835        try:
836            result = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
837        except:
838            logger.error('Error reading %s.csv' % name)
839            return
840        for jamb in result:
841            jamb['Error'] = "Processing "
842            logger.info(format % jamb)
843            jamb_reg_no = jamb.get(csv_d['jamb_reg_no'])
844            res = self.portal_catalog({'portal_type': "StudentApplication",
845                                     'SearchableText': jamb_reg_no })
846            if not res:
847                em = 'Student with jamb_reg_no %s does not exists\n' % jamb_reg_no
848                logger.info(em)
849                jamb['Error'] = "Student does not exist"
850                no_import.append(format % jamb)
851                continue
852            sid = res[0].getPath().split('/')[-2]
853            cert_id = makeCertificateCode(jamb.get(csv_d['course_code']))
854            res = self.portal_catalog(portal_type = "Certificate", id = cert_id)
855            if not res:
856                em = 'No Certificate with ID %s \n' % cert_id
857                logger.info(em)
858                jamb['Error'] = "No Certificate %s" % cert_id
859                no_import.append( format % jamb)
860                continue
861            cert_brain = res[0]
862            catalog_entry = {}
863            student = getattr(self,sid)
864            #
865            # Study Course
866            #
867            study_course = student.study_course
868            dsc = {}
869            cert_pl = cert_brain.getPath().split('/')
870            catalog_entry['id'] = sid
871            catalog_entry['faculty'] = cert_pl[-4]
872            catalog_entry['department'] = cert_pl[-3]
873            catalog_entry['course'] = cert_id
874            dsc['study_course'] = cert_id
875            study_course.getContent().edit(mapping=dsc)
876            self.students_catalog.modifyRecord(**catalog_entry)
877            if tr_count > 10:
878                if len(no_import) > 1:
879                    open("%s/import/%s_not_imported.csv" % (i_home,name),"w+").write(
880                             '\n'.join(no_import))
881                    no_import = []
882                em = '%d transactions commited\n' % tr_count
883                transaction.commit()
884                logger.info(em)
885                total += tr_count
886                tr_count = 0
887            tr_count += 1
888        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
889    ###)
890
891    security.declareProtected(View,"fixOwnership") ###(
892    def fixOwnership(self):
893        """fix Ownership"""
894        for s in self.portal_catalog(meta_type = 'Student'):
895            student = s.getObject()
896            sid = s.getId
897            import pdb;pdb.set_trace()
898            student.application.manage_setLocalRoles(sid, ['Owner',])
899            student.personal.manage_setLocalRoles(sid, ['Owner',])
900    ###)
901
902    security.declareProtected(View,"Title") ###(
903    def Title(self):
904        """compose title"""
905        return "Student Section"
906    ###)
907
908    def generateStudentId(self,letter,students = None): ###(
909        import random
910        r = random
911        if students is None:
912            students = self.portal_url.getPortalObject().campus.students
913        if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
914            letter= r.choice('ABCDEFGHKLMNPQRSTUVWXY')
915        sid = "%c%d" % (letter,r.randint(99999,1000000))
916        while hasattr(students, sid):
917            sid = "%c%d" % (letter,r.randint(99999,1000000))
918        return sid
919        #return "%c%d" % (r.choice('ABCDEFGHKLMNPQRSTUVWXY'),r.randint(99999,1000000))
920    ###)
921
922InitializeClass(StudentsFolder)
923
924def addStudentsFolder(container, id, REQUEST=None, **kw): ###(
925    """Add a Student."""
926    ob = StudentsFolder(id, **kw)
927    return CPSBase_adder(container, ob, REQUEST=REQUEST)
928    ###)
929
930###)
931
932class Student(CPSDocument): ###(
933    """
934    WAeUP Student container for the various student data
935    """
936    meta_type = 'Student'
937    portal_type = meta_type
938    security = ClassSecurityInfo()
939
940    security.declareProtected(View,"Title")
941    def Title(self):
942        """compose title"""
943        reg_nr = self.getId()[1:]
944        data = getattr(self,'personal',None)
945        if data:
946            content = data.getContent()
947            return "%s %s %s" % (content.firstname,content.middlename,content.lastname)
948        data = getattr(self,'application',None)
949        if data:
950            content = data.getContent()
951            return "%s" % (content.jamb_lastname)
952        return self.title
953
954    security.declarePrivate('makeStudentMember') ###(
955    def makeStudentMember(self,sid,password='uNsEt'):
956        """make the student a member"""
957        membership = self.portal_membership
958        membership.addMember(sid,
959                             password ,
960                             roles=('Member',
961                                     'Student',
962                                     ),
963                             domains='',
964                             properties = {'memberareaCreationFlag': False,
965                                           'homeless': True},)
966        member = membership.getMemberById(sid)
967        self.portal_registration.afterAdd(member, sid, password, None)
968        self.manage_setLocalRoles(sid, ['Owner',])
969
970###)
971
972    security.declareProtected(View,'createSubObjects') ###(
973    def createSubObjects(self):
974        """make the student a member"""
975        dp = {'Title': 'Personal Data'}
976        app_doc = self.application.getContent()
977        names = app_doc.jamb_lastname.split()
978        if len(names) == 3:
979            dp['firstname'] = names[0].capitalize()
980            dp['middlename'] = names[1].capitalize()
981            dp['lastname'] = names[2].capitalize()
982        elif len(names) == 2:
983            dp['firstname'] = names[0].capitalize()
984            dp['lastname'] = names[1].capitalize()
985        else:
986            dp['lastname'] = app_doc.jamb_lastname
987        dp['sex'] = app_doc.jamb_sex == 'F'
988        dp['lga'] = "%s/%s" % (app_doc.jamb_state,app_doc.jamb_lga )
989        proxy = self.aq_parent
990        proxy.invokeFactory('StudentPersonal','personal')
991        per = proxy.personal
992        per_doc = per.getContent()
993        per_doc.edit(mapping = dp)
994        per.manage_setLocalRoles(proxy.getId(), ['Owner',])
995        #self.portal_workflow.doActionFor(per,'open',dest_container=per)
996
997###)
998
999InitializeClass(Student)
1000
1001def addStudent(container, id, REQUEST=None, **kw):
1002    """Add a Student."""
1003    ob = Student(id, **kw)
1004    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1005
1006###)
1007
1008class StudentAccommodation(CPSDocument): ###(
1009    """
1010    WAeUP Student container for the various student data
1011    """
1012    meta_type = 'StudentAccommodation'
1013    portal_type = meta_type
1014    security = ClassSecurityInfo()
1015
1016    security.declareProtected(View,"Title")
1017    def Title(self):
1018        """compose title"""
1019        content = self.getContent()
1020        #return "Accommodation Data for %s %s" % (content.firstname,content.lastname)
1021        return "Accommodation Data for Session %s" % content.session
1022
1023
1024InitializeClass(StudentAccommodation)
1025
1026def addStudentAccommodation(container, id, REQUEST=None, **kw):
1027    """Add a Students personal data."""
1028    ob = StudentAccommodation(id, **kw)
1029    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1030
1031###)
1032
1033class StudentPersonal(CPSDocument): ###(
1034    """
1035    WAeUP Student container for the various student data
1036    """
1037    meta_type = 'StudentPersonal'
1038    portal_type = meta_type
1039    security = ClassSecurityInfo()
1040
1041    security.declareProtected(View,"Title")
1042    def Title(self):
1043        """compose title"""
1044        content = self.getContent()
1045        #return "Personal Data for %s %s" % (content.firstname,content.lastname)
1046        return "Personal Data"
1047
1048
1049InitializeClass(StudentPersonal)
1050
1051def addStudentPersonal(container, id, REQUEST=None, **kw):
1052    """Add a Students personal data."""
1053    ob = StudentPersonal(id, **kw)
1054    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1055
1056###)
1057
1058class StudentClearance(CPSDocument): ###(
1059    """
1060    WAeUP Student container for the various student data
1061    """
1062    meta_type = 'StudentClearance'
1063    portal_type = meta_type
1064    security = ClassSecurityInfo()
1065
1066    security.declareProtected(View,"Title")
1067    def Title(self):
1068        """compose title"""
1069        content = self.getContent()
1070        #return "Clearance/Eligibility Record for %s %s" % (content.firstname,content.lastname)
1071        return "Clearance/Eligibility Record"
1072
1073
1074InitializeClass(StudentClearance)
1075
1076def addStudentClearance(container, id, REQUEST=None, **kw):
1077    """Add a Students personal data."""
1078    ob = StudentClearance(id, **kw)
1079    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1080
1081###)
1082
1083class StudentStudyLevel(CPSDocument): ###(
1084    """
1085    WAeUP Student container for the various student data
1086    """
1087    meta_type = 'StudentStudyLevel'
1088    portal_type = meta_type
1089    security = ClassSecurityInfo()
1090
1091    security.declareProtected(View,"Title")
1092    def Title(self):
1093        """compose title"""
1094        return "Level %s" % self.aq_parent.getId()
1095
1096    def create_course_results(self,cert_id,current_level): ###(
1097        "create all courses in a level"
1098        aq_portal = self.portal_catalog.evalAdvancedQuery
1099        res = self.portal_catalog(portal_type="Certificate", id = cert_id)
1100        l = []
1101        import transaction
1102        if res:
1103            cert = res[0]
1104            path = cert.getPath()
1105            query = Eq("path","%s/%s" % (path,current_level)) &\
1106                    Eq('portal_type','CertificateCourse')
1107            courses = aq_portal(query)
1108            #from pdb import set_trace;set_trace()
1109            self_proxy = self.aq_parent
1110            for c in courses:
1111                d = self.getCourseInfo(c.getId)
1112                cr_id = self_proxy.invokeFactory('StudentCourseResult',c.getId)
1113                course_result = getattr(self_proxy,cr_id)
1114                self.portal_workflow.doActionFor(course_result,'open')
1115                d['core_or_elective'] = getattr(c.getObject().getContent(),'core_or_elective')
1116                course_result.getContent().edit(mapping=d)
1117                transaction.commit()
1118    ###)
1119
1120InitializeClass(StudentStudyLevel)
1121
1122def addStudentStudyLevel(container, id, REQUEST=None, **kw):
1123    """Add a Students personal data."""
1124    ob = StudentStudyLevel(id, **kw)
1125    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1126
1127###)
1128
1129class StudentStudyCourse(CPSDocument): ###(
1130    """
1131    WAeUP Student container for the various student data
1132    """
1133    meta_type = 'StudentStudyCourse'
1134    portal_type = meta_type
1135    security = ClassSecurityInfo()
1136
1137    security.declareProtected(View,"Title")
1138    def Title(self):
1139        """compose title"""
1140        content = self.getContent()
1141        return "Study Course"
1142
1143
1144InitializeClass(StudentStudyCourse)
1145
1146def addStudentStudyCourse(container, id, REQUEST=None, **kw):
1147    """Add a Students personal data."""
1148    ob = StudentStudyCourse(id, **kw)
1149    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1150
1151###)
1152
1153class StudentApplication(CPSDocument): ###(
1154    """
1155    WAeUP Student container for the various student data
1156    """
1157    meta_type = 'StudentApplication'
1158    portal_type = meta_type
1159    security = ClassSecurityInfo()
1160
1161    security.declareProtected(View,"Title")
1162    def Title(self):
1163        """compose title"""
1164        return "Application Data"
1165
1166
1167InitializeClass(StudentApplication)
1168
1169def addStudentApplication(container, id, REQUEST=None, **kw):
1170    """Add a Students eligibility data."""
1171    ob = StudentApplication(id, **kw)
1172    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1173###)
1174
1175class StudentPume(CPSDocument): ###(
1176    """
1177    WAeUP Student container for the various student data
1178    """
1179    meta_type = 'StudentPume'
1180    portal_type = meta_type
1181    security = ClassSecurityInfo()
1182
1183    security.declareProtected(View,"Title")
1184    def Title(self):
1185        """compose title"""
1186        return "PUME Results"
1187
1188
1189InitializeClass(StudentPume)
1190
1191def addStudentPume(container, id, REQUEST=None, **kw):
1192    """Add a Students PUME data."""
1193    ob = StudentPume(id, **kw)
1194    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1195###)
1196
1197##class StudentSemester(CPSDocument): ###(
1198##    """
1199##    WAeUP StudentSemester containing the courses and students
1200##    """
1201##    meta_type = 'StudentSemester'
1202##    portal_type = meta_type
1203##    security = ClassSecurityInfo()
1204##
1205##InitializeClass(StudentSemester)
1206##
1207##def addStudentSemester(container, id, REQUEST=None, **kw):
1208##    """Add a StudentSemester."""
1209##    ob = StudentSemester(id, **kw)
1210##    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1211##
1212#####)
1213
1214##class Semester(CPSDocument): ###(
1215##    """
1216##    WAeUP Semester containing the courses and students
1217##    """
1218##    meta_type = 'Semester'
1219##    portal_type = meta_type
1220##    security = ClassSecurityInfo()
1221##
1222##InitializeClass(Semester)
1223##
1224##def addSemester(container, id, REQUEST=None, **kw):
1225##    """Add a Semester."""
1226##    ob = Semester(id, **kw)
1227##    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1228##
1229#####)
1230
1231class StudentCourseResult(CPSDocument): ###(
1232    """
1233    WAeUP StudentCourseResult
1234    """
1235    meta_type = 'StudentCourseResult'
1236    portal_type = meta_type
1237    security = ClassSecurityInfo()
1238
1239    def getCourseEntry(self,cid):
1240        res = self.portal_catalog({'meta_type': "Course",
1241                                           'id': cid})
1242        if res:
1243            return res[-1]
1244        else:
1245            return None
1246
1247    security.declareProtected(View,"Title")
1248    def Title(self):
1249        """compose title"""
1250        cid = self.aq_parent.getId()
1251        ce = self.getCourseEntry(cid)
1252        if ce:
1253            return "%s" % ce.Title
1254        return "No course with id %s" % cid
1255
1256InitializeClass(StudentCourseResult)
1257
1258def addStudentCourseResult(container, id, REQUEST=None, **kw):
1259    """Add a StudentCourseResult."""
1260    ob = StudentCourseResult(id, **kw)
1261    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1262###)
1263
1264# Backward Compatibility StudyLevel
1265
1266from Products.WAeUP_SRP.Academics import StudyLevel
1267
1268from Products.WAeUP_SRP.Academics import addStudyLevel
1269
Note: See TracBrowser for help on using the repository browser.