source: WAeUP_SRP/trunk/Students.py @ 1804

Last change on this file since 1804 was 1802, checked in by joachim, 17 years ago

a little code cleanup

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