source: WAeUP_SRP/base/WAeUPTool.py @ 2714

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

logger was wrong

  • Property svn:keywords set to Id
File size: 80.4 KB
Line 
1#-*- mode: python; mode: fold -*-
2# (C) Copyright 2005 The WAeUP group  <http://www.waeup.org>
3# Author: Joachim Schmitz (js@aixtraware.de)
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17# 02111-1307, USA.
18#
19# $Id: WAeUPTool.py 2713 2007-11-20 07:25:25Z henrik $
20"""The WAeUP Tool Box.
21"""
22
23from AccessControl import ClassSecurityInfo
24from Acquisition import aq_inner
25from Acquisition import aq_parent
26from Globals import DTMLFile
27from Globals import InitializeClass
28from OFS.SimpleItem import SimpleItem
29from zExceptions import BadRequest
30
31from Products.CMFCore.utils import getToolByName
32from Products.CPSSchemas.DataStructure import DataStructure
33from Products.CPSSchemas.DataModel import DataModel
34from Products.CPSSchemas.StorageAdapter import MappingStorageAdapter
35from Products.CMFCore.ActionProviderBase import ActionProviderBase
36from Products.CMFCore.permissions import View
37from Products.ZCatalog.ZCatalog import ZCatalog
38from Products.CMFCore.permissions import ModifyPortalContent
39from Products.CMFCore.permissions import ManagePortal
40from Products.CMFCore.utils import UniqueObject
41from Products.CMFCore.URLTool import URLTool
42from Products.CMFCore.utils import getToolByName
43from Students import makeCertificateCode
44from Globals import package_home,INSTANCE_HOME
45import DateTime,time
46import logging
47import transaction
48import csv,re,os,sys
49from shutil import copy2
50from Products.AdvancedQuery import Eq, Between, Le,In
51
52p_home = package_home(globals())
53i_home = INSTANCE_HOME
54images_base = os.path.join(i_home,"images")
55
56def getImagesDir(student_id):
57    return os.path.join("%s" % images_base,student_id[0],student_id)
58
59def getObject(object,name):
60    if object.hasObject(name):
61        return getattr(object,name)
62    return None
63
64class WAeUPTool(UniqueObject, SimpleItem, ActionProviderBase):
65    """WAeUP tool"""
66
67    id = 'waeup_tool'
68    meta_type = 'WAeUP Tool'
69    _actions = ()
70    security = ClassSecurityInfo()
71    security.declareObjectProtected(View)
72    manage_options = ( ActionProviderBase.manage_options
73                     + SimpleItem.manage_options
74                     )
75
76    def rwrite(self,s): ###(
77        response = self.REQUEST.RESPONSE
78        response.setHeader('Content-type','text/html; charset=ISO-8859-15')
79        response.write("%s<br />\r\n" % s)
80    ###)
81
82    def addtodict(self,d,key,item): ###(
83        d[key].append(item)
84        return d[key]
85    ###)
86
87    def sleep(self,secs): ###(
88        "sleep"
89        import time
90        time.sleep(secs)
91        return
92
93###)
94
95    security.declareProtected(View,'updateRoleMappingsFor') ###(
96    def updateRoleMappingsFor(self,wf_definition,ob):
97        "do so for public"
98        wf_def = getattr(self.portal_workflow,wf_definition)
99        wf_def.updateRoleMappingsFor(ob)
100    ###)
101
102    security.declareProtected(ModifyPortalContent,'openLog') ###(
103    def openLog(self,name):
104        """open a log file"""
105        version = 1
106        path = "%s/log/%s_%d.log" % (i_home,name,version)
107        while os.path.exists(path):
108            version += 1
109            path = "%s/log/%s_%d.log" % (i_home,name,version)
110        log = open(path,"w")
111        return log
112    ###)
113
114    security.declareProtected(ModifyPortalContent,'bypassQueueCatalog') ###(
115    def bypassQueueCatalog(self,enable=True):
116        """bypass the QueueCatalog by setting all indexes to process imediate,
117        if enable is True (default) the old settings are restored
118        """
119
120    ###)
121
122    security.declareProtected(ModifyPortalContent,'measureOaT') ###(
123    def measureOaT(self,method="a",probe="1000",nr_pts="1"):
124        """measure Object access Time"""
125        import random
126        if hasattr(self,'portal_catalog_real'):
127            aq_portal = self.portal_catalog_real.evalAdvancedQuery
128        else:
129            aq_portal = self.portal_catalog.evalAdvancedQuery
130        nr_pts = int(nr_pts)
131        probe = int(probe)
132        intervall = probe/10
133        objects = ("application","clearance","personal")
134        portal_types = ("StudentApplication","StudentClearance","StudentPersonal")
135        #i = random.randrange(num_objects)
136        count = 0
137        found = 0
138        not_found = 0
139        t_found = 0
140        t_not_found = 0
141        time_found = time_not_found = 0.0
142        t_time_found = t_time_not_found = 0.0
143        accessed = []
144        t_min = 1000
145        t_max = 0
146        #import pdb;pdb.set_trace()
147        students = self.portal_catalog(portal_type="Student")
148        num_students = len(students)
149        if method == "d":
150            query = Eq('path','/uniben/campus/students') & In('portal_type',portal_types[:nr_pts])
151            res = aq_portal(query)
152            brains = {}
153            for r in res:
154                sid = r.relative_path.split('/')[-2]
155                if brains.has_key(sid):
156                    brains[sid][r.portal_type] = r
157                else:
158                    brains[sid] = {r.portal_type : r}
159            brains_list = brains.keys()
160            num_objects = len(brains_list)
161        else:
162            num_objects = num_students
163        print "="*40
164        print "method: %s probes: %d nr_pts: %d num_objects: %d" % (method,
165                                                                        probe,
166                                                                        nr_pts,
167                                                                        num_objects)
168        print "nr found/not time found/not min/max"
169        elapse = time.time()
170        i_elapse = time.time()
171        c_elapse = time.clock()
172        for c in range(1,probe + 1):
173            i = random.randrange(num_objects)
174            if method in ('a','b','c'):
175                student_brain = students[i]
176            elif method == "d":
177                #import pdb;pdb.set_trace()
178                student_brain = brains[brains_list[i]]
179            if method == "c":
180                query = Eq('path',student_brain.getPath()) & In('portal_type',portal_types[:nr_pts])
181                res = aq_portal(query)
182                this_portal_types = [r.portal_type for r in res]
183            for i in range(nr_pts):
184                oid = objects[i]
185                if method == "a":
186                    try:
187                        student_path = student_brain.getPath()
188                        path = "%s/%s" % (student_path,oid)
189                        doc = self.unrestrictedTraverse(path).getContent()
190                        found += 1
191                        i_time = time.time() - i_elapse
192                        time_found += i_time
193                    except:
194                        not_found += 1
195                        i_time = time.time() - i_elapse
196                        time_not_found += i_time
197                        pass
198                elif method == "b":
199                    try:
200                        student_object = student_brain.getObject()
201                        doc = getattr(student_object,oid).getContent()
202                        found += 1
203                        i_time = time.time() - i_elapse
204                        time_found += i_time
205                    except:
206                        i_time = time.time() - i_elapse
207                        time_not_found += i_time
208                        not_found += 1
209                        pass
210                elif method == "c":
211                    if portal_types[i] in this_portal_types:
212                        found += 1
213                        doc = res[this_portal_types.index(portal_types[i])].getObject().getContent()
214                        i_time = time.time() - i_elapse
215                        time_found += i_time
216                    else:
217                        not_found += 1
218                        i_time = time.time() - i_elapse
219                        time_not_found += i_time
220                elif method == "d":
221                    if student_brain.has_key(portal_types[i]):
222                        found += 1
223                        doc = student_brain[portal_types[i]].getObject().getContent()
224                        i_time = time.time() - i_elapse
225                        time_found += i_time
226                    else:
227                        not_found += 1
228                        i_time = time.time() - i_elapse
229                        time_not_found += i_time
230                i_elapse = time.time()
231            if c and (c % intervall == 0):
232                #i_time = time.time() - i_elapse
233                t_per = 0.0
234                if found:
235                    t_per = time_found/found
236                if t_per > t_max:
237                    t_max = t_per
238                if t_per > 0.0 and t_per < t_min:
239                    t_min = t_per
240                itf = 0.0
241                if found:
242                    itf = time_found/found
243                itnf = 0.0
244                if not_found :
245                    itnf = time_not_found / not_found
246                interval_time = time_found + time_not_found
247                s = "%(c)d: %(found)d/%(not_found)d " % vars()
248                s += "%(interval_time)6.2f %(itf)6.4f/%(itnf)6.4f " % vars()
249                s += "%(t_min)6.4f/%(t_max)6.4f" %  vars()
250                print s
251                t_found += found
252                t_not_found += not_found
253                t_time_found += time_found
254                t_time_not_found += time_not_found
255                time_found = time_not_found = 0.0
256                found = not_found = 0
257        # t_found += found
258        # t_not_found += not_found
259        elapse = time.time() - elapse
260        itf = 0.0
261        if t_found:
262            itf = t_time_found/t_found
263        itnf = 0.0
264        if t_not_found:
265            itnf = t_time_not_found / t_not_found
266        #c_elapse = time.clock() - c_elapse
267        s = "%(probe)d: %(t_found)d/%(t_not_found)d " % vars()
268        s += "%(elapse)6.2f %(itf)6.4f/%(itnf)6.4f " % vars()
269        s += "%(t_min)6.4f/%(t_max)6.4f" %  vars()
270        print "-"*40
271        print s
272        rel_found = float(t_found)/probe
273        rel_not_found = float(t_not_found)/probe
274        estimated_total_time = num_objects*(rel_found*itf + rel_not_found*itnf)
275        print estimated_total_time
276    ###)
277
278    security.declareProtected(ModifyPortalContent,'writeLog') ###(
279    def writeLog(self,logfile,s):
280        """write to the log file"""
281        logfile.write(s)
282
283###)
284
285    def generateStudentId(self,letter): ###(
286        import random
287        r = random
288        ##if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
289        if letter == '?':
290            letter= r.choice('ABCDEFGHKLMNPQRSTUVWXY')
291        sid = "%c%d" % (letter,r.randint(99999,1000000))
292        students = self.portal_url.getPortalObject().campus.students
293##        while hasattr(students, sid):
294##            sid = "%c%d" % (letter,r.randint(99999,1000000))
295        while self.students_catalog(id = sid):
296            sid = "%c%d" % (letter,r.randint(99999,1000000))
297        return sid
298    ###)
299
300    def generatePassword(self,s=None): ###(
301        import random
302        r = random
303        ##if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
304        if s is None:
305            s = 'abcdefghklmnpqrstuvwxy23456789'
306        pw = ''
307        while len(pw) < 6:
308            pw += r.choice(s)
309        return pw
310    ###)
311
312    security.declareProtected(ModifyPortalContent, 'dumpSchoolfeePayments') ###(
313    def dumpSchoolfeePayments(self):
314        "dump paid schoolfees"
315        mtool = self.portal_membership
316        member = mtool.getAuthenticatedMember()
317        logger = logging.getLogger('WAeUPTool.dumpSchoolfees')
318        aq_student = self.students_catalog.evalAdvancedQuery
319        query = In('review_state',('schoolfee_paid',
320                                   'courses_registered',
321                                   'courses_validated',
322                                   ))
323        res = aq_student(query)
324        #import pdb;pdb.set_trace()
325        l = []
326        logger.info("start for %d" % len(res))
327        count = 1
328        log_after = 100
329        for student in res:
330            if not count % log_after:
331                logger.info("processed %d total %d" % (log_after,count))
332            count += 1
333            fee_dict =self.getSchoolFee(student)
334            fulltime = student.mode.endswith('_ft')
335            d = {}
336            d['student_id'] = student.id
337            d['name'] = student.name
338            d['amount'] = fee_dict.get(new_returning)
339            l += d,
340        csv_name = self.dumpListToCSV(l,'payments')
341        logger.info('%s dumped payments to %s' % (member,export_file))
342    ###)
343
344    security.declarePublic('dumpListToCSV') ###(
345    def dumpListToCSV(self,l,filename,fields=None):
346        """dump a list of dicts to a CSV file"""
347        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
348        export_file = "%s/export/%s_%s.csv" % (i_home,filename,current,)
349        if fields is None:
350            fields = l[0].keys()
351        headline = ','.join(fields)
352        out = open(export_file,"wb")
353        out.write(headline +'\n')
354        out.close()
355        out = open(export_file,"a")
356        csv_writer = csv.DictWriter(out,fields,)
357        csv_writer.writerows(l)
358        return export_file
359    ###)
360
361    security.declareProtected(ManagePortal, 'listMembers') ###(
362    def listMembers(self):
363        "list all members"
364        mtool = self.portal_membership
365        member = mtool.getAuthenticatedMember()
366        logger = logging.getLogger('WAeUPTool.listMembers')
367        if str(member) not in ('admin','joachim'):
368            logger.info('%s tried to list members' % (member))
369            return None
370        members = self.portal_directories.members
371        all = members.listEntryIdsAndTitles()
372        l = []
373        for user_id,name in all:
374            d = {}
375            d['user_id'] = user_id
376            d['name'] = name
377            d['pw'] = getattr(getattr(members,user_id),'password')
378            d['email'] = getattr(getattr(members,user_id),'email')
379            d['groups'] = " ".join(getattr(getattr(members,user_id),'groups'))
380            d['roles'] = " ".join(getattr(getattr(members,user_id),'roles'))
381            l += d,
382        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
383        export_file = "%s/export/member_list_%s.csv" % (i_home,current,)
384        logger.info('%s dumped memberlist to %s' % (member,export_file))
385        fields = l[0].keys()
386        headline = ','.join(fields)
387        out = open(export_file,"wb")
388        out.write(headline +'\n')
389        out.close()
390        out = open(export_file,"a")
391        csv_writer = csv.DictWriter(out,fields,)
392        csv_writer.writerows(l)
393    ###)
394
395    security.declareProtected(ManagePortal, 'removeDeletedDocIds') ###(
396    def removeDeletedDocIds(self, max=1000):
397        """
398        remove deleted docids from repository commit after max
399        """
400        logger = logging.getLogger('WAeUPTool.removeDeletedDocIds')
401        repository = getToolByName(self, 'portal_repository')
402        pxtool = getToolByName(self, 'portal_proxies')
403        logger.info('start')
404        pxtool_infos = pxtool.getRevisionsUsed()
405        logger.info('found  %d used revisions ' % (len(pxtool_infos)))
406
407        nb_revs = 0
408        docids_d = {} # all docids
409        unused_docids_d = {} # all docids that are unused
410        ids_unused_revs_docids = [] # ids for revs of unused docids
411        unused_ids = [] # ids for unused revs
412        total = 0
413        idlist = repository.objectIds()
414        to_delete = 0
415        found = False
416        for id in idlist:
417            docid, rev = repository._splitId(id)
418            if docid is None:
419                logger.info("invalid doc_id %s" % docid)
420                continue
421            nb_revs += 1
422            if not pxtool_infos.has_key(docid):
423                found = True
424                to_delete += 1
425                unused_ids.append(id)
426            elif not pxtool_infos[docid].has_key(rev):
427                found = True
428                to_delete += 1
429                unused_ids.append(id)
430            if found and not to_delete % max:
431                found = False
432                #import pdb;pdb.set_trace()
433                repository.manage_delObjects(unused_ids)
434                transaction.commit()
435                logger.info('removed %d total %d unused docids ' % (max,to_delete))
436        else:
437            if unused_ids:
438                repository.manage_delObjects(unused_ids)
439                transaction.commit()
440        logger.info('finished removing %d unused docids ' % (to_delete))
441
442
443###)
444
445    security.declareProtected(View,'getCredential') ###(
446    def getCredential(self,student_id):
447        student_entry = getattr(self.portal_directories.students,student_id,None)
448        if not self.isStaff():
449            mtool = self.portal_membership
450            member = mtool.getAuthenticatedMember()
451            logger = logging.getLogger('WAeUPTool.getCredential')
452            logger.info('%s tried to access password of %s' % (member,student_id))
453            return None
454        if student_entry is None:
455            return None
456        return getattr(student_entry,"password","not set")
457    ###)
458
459    security.declarePublic('checkPassword')
460    def checkPassword(self,student_id,password):
461        student_entry = getattr(self.portal_directories.students,student_id,None)
462        if student_entry is None:
463            return False
464        return getattr(student_entry,"password","not set") == password
465
466    security.declarePublic('checkGenericPassword')
467    def checkGenericPassword(self,member_id):
468        member_entry = getattr(self.portal_directories.members,member_id,None)
469        if member_entry is None:
470            return False
471        ltool = getToolByName(self, 'portal_layouts')
472        unsecure_words = ltool._getOb('members')['w__password'].check_words
473        password = getattr(member_entry,"password","not set")
474        is_unsecure = password in unsecure_words
475        if is_unsecure:
476            logger = logging.getLogger('WAeUPTool.checkGenericPassword')
477            logger.info('Member %s tried to log in with unsecure password %s' %(member_id,password))
478        return is_unsecure
479
480
481    security.declareProtected(ModifyPortalContent,'editPassword') ###(
482    def editPassword(self,student_id,password):
483        "edit a student password"
484        student_entry = getattr(self.portal_directories.students,student_id,None)
485        if student_entry is None:
486            return
487        setattr(student_entry,'password',password)
488    ###)
489
490    security.declareProtected(ModifyPortalContent,'doCommit') ###(
491    def doCommit(self,logger=None):
492        "commit some transactions"
493        transaction.commit()
494    ###)
495
496
497    security.declarePublic('loadStudentFoto') ###(
498    def loadStudentFoto(self,student,filename,folder):
499        "return a student passport picture"
500        #import pdb;pdb.set_trace()
501        picture ="%s/import/%s/%s" % (i_home,folder,filename)
502        student_id = student.getId()
503        images_dir = getImagesDir(student_id)
504        if not os.path.exists(images_dir):
505            os.mkdir(images_dir)
506        image_name = os.path.join(images_dir,"passport_%(student_id)s.jpg" % vars())
507        for extension in ('.jpg','.JPG'):
508            fullname = "%(picture)s%(extension)s" % vars()
509            if os.path.exists(fullname):
510                copy2(fullname,image_name)
511                return "successfully copied passport picture"
512        return "passport picture not found: %s.jpg or .JPG" % picture
513    ###)
514
515    def old____loadStudentFoto(self,student,filename,folder): ###(
516        "return a student passport picture"
517        app = student.application
518        app_doc = app.getContent()
519        #clear = student.clearance
520        #clear_doc = clear.getContent()
521        #matric_no = clear_doc.matric_no.upper()
522        picture1 ="%s/import/%s/%s.jpg" % (i_home,folder,filename)
523        picture2 ="%s/import/%s/%s.JPG" % (i_home,folder,filename)
524        #import pdb;pdb.set_trace()
525        if os.path.exists(picture1):
526            file = open(picture1)
527        elif os.path.exists(picture2):
528            file = open(picture2)
529        else:
530            return "passport picture not found %s" % picture1
531        reopened = False
532        if self.portal_workflow.getInfoFor(app,'review_state',None) !='opened':
533            self.portal_workflow.doActionFor(app,'open')
534            reopened = True
535        outfile = file.read()
536        app_doc.manage_addFile('passport',
537                               file=outfile,
538                               title="%s.jpg" % filename)
539        if reopened:
540            self.portal_workflow.doActionFor(app,'close')
541        return "successfully loaded passport picture"
542    ###)
543
544    security.declareProtected(ModifyPortalContent,'createOne') ###(
545    def createOne(self,students_folder,student_brain,letter,commit=False):
546        sid = self.waeup_tool.generateStudentId(letter)
547        students_folder.invokeFactory('Student', sid)
548        student = getattr(students_folder,sid)
549        self.portal_workflow.doActionFor(student,'return')
550        student.manage_setLocalRoles(sid, ['Owner',])
551        matric_no = student_brain.matric_no
552        jamb_reg_no = student_brain.Entryregno
553        self.students_catalog.addRecord(id = sid,
554                                           matric_no = matric_no,
555                                           jamb_reg_no = jamb_reg_no,
556                                           sex = student_brain.Sex == "F",
557                                           name = "%s %s %s" % (student_brain.Firstname,
558                                                                student_brain.Middlename,
559                                                                student_brain.Lastname)
560                                        )
561        if commit:
562            transaction.commit()
563        return sid,jamb_reg_no
564    ###)
565
566    security.declareProtected(ModifyPortalContent,'addStudent') ###(
567    def addStudent(self,dict):
568        students_folder = self.portal_url.getPortalObject().campus.students
569        sid = self.waeup_tool.generateStudentId('?')
570        students_folder.invokeFactory('Student', sid)
571        student_obj = getattr(students_folder,sid)
572        f2t = self.student_field2types
573        #from pdb import set_trace; set_trace()
574        d = {}
575        #d['jamb_sex']  = 'M'
576        #if dict.get('sex'):
577        #    d['jamb_sex']  = 'F'
578
579        entry_session = dict.get('entry_session')
580        if entry_session == self.getSessionId()[0]:
581            wfaction = 'admit'
582            wft = 'wf_transition_admit'
583            password = None
584        else:
585            wfaction = 'return'
586            wft = 'wf_transition_return'
587            password = self.generatePassword()
588            self.makeStudentMember(sid,password)
589
590        for pt in f2t.keys():
591            student_obj.invokeFactory(pt,f2t[pt]['id'])
592            sub_obj = getattr(student_obj,f2t[pt]['id'])
593            sub_doc = sub_obj.getContent()
594            #self.portal_workflow.doActionFor(sub_obj,'open',dest_container=sub_obj)
595            d['Title'] = f2t[pt]['title']
596            for field in f2t[pt]['fields']:
597                d[field] = dict.get(field,'')
598            sub_doc.edit(mapping = d)
599            new_state = f2t[pt][wft]
600            if new_state != "remain":
601                self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
602        self.portal_workflow.doActionFor(student_obj,wfaction)
603        student_obj.manage_setLocalRoles(sid, ['Owner',])
604        return sid,password
605    ###)
606
607    security.declarePublic('getCertificateBrain') ###(
608    def getCertificateBrain(self,cert_id):
609        "do it"
610        res = ZCatalog.searchResults(self.portal_catalog_real,
611                                {'portal_type':"Certificate",
612                                      'id': cert_id})
613        if res:
614            return res[0]
615        return None
616    ###)
617
618    security.declareProtected(ModifyPortalContent,'get_csv_filenames') ###(
619    def get_csv_filenames(self):
620        "do it"
621        files = [file for file in os.listdir("%s/import/" % (i_home))
622                 if file.endswith('.csv') and file.find('imported') == -1]
623        return files
624    ###)
625
626    security.declarePublic('findStudentByMatricelNo') ###(
627    def findStudentByMatricelNo(self,matric_no):
628        "do it"
629        res = ZCatalog.searchResults(self.portal_catalog_real,
630                                {'portal_type':"StudentClearance",
631                                 'SearchableText': matric_no})
632        if res:
633            return res[0]
634        return None
635    ###)
636
637    security.declarePublic('makeStudentMember') ###(
638    def makeStudentMember(self,sid,password='uNsEt'):
639        """make the student a member"""
640        membership = self.portal_membership
641        membership.addMember(sid,
642                             password ,
643                             roles=('Member',
644                                     'Student',
645                                     ),
646                             domains='',
647                             properties = {'memberareaCreationFlag': False,
648                                           'homeless': True},)
649        member = membership.getMemberById(sid)
650        self.portal_registration.afterAdd(member, sid, password, None)
651        #self.manage_setLocalRoles(sid, ['Owner',])
652    ###)
653
654    security.declareProtected(View,'makeStudentData') ###(
655    def makeStudentData(self,student_id,email=None,phone_nr=None):
656        "create Datastructure for a returning Student"
657        #import pdb;pdb.set_trace()
658        logger = logging.getLogger('WAeUPTool.makeStudentData')
659        students_folder = self.portal_url.getPortalObject().campus.students
660        #res = self.students_catalog(id=student_id)
661        #if res:
662        #    st = res[0]
663        #res = self.returning_import(matric_no = st.matric_no)
664        res = self.returning_import(id = student_id)
665        if res:
666            student = res[0]
667        else:
668            logger.info('Id %s not found in returning_import' % student_id)
669            return
670        logger.info('%s creates data structure' % student_id)
671        s_results = self.results_import(matric_no = student.matric_no)
672        if s_results:
673            lnr = self.getLevelFromResultsCosCode(s_results)
674            level = "%d00" % lnr
675            verdict,eligible = self.getVerdict(s_results[0].Verdict)
676            #if eligible:
677            #    level = "%d00" % (lnr + 1)
678        else:
679            logger.info('matric_no %s not found in results_import' % student.matric_no)
680            level = ''
681            verdict = ''
682        #student should not be allowed to perform this transition
683        #wftool = self.portal_workflow
684        #wftool.doActionFor(student,'return')
685        certcode_org = student.Coursemajorcode
686        certcode = makeCertificateCode(certcode_org)
687        certificate_brain = self.getCertificateBrain(certcode)
688        if not certificate_brain:
689            em = 'Certificate %s org-code %s not found\n' % (certcode, certcode_org)
690            logger.info(em)
691        matric_no = student.matric_no
692        sid = student_id
693        student_obj = getattr(students_folder,sid)
694        student_obj.invokeFactory('StudentApplication','application')
695        application = student_obj.application
696        self.portal_workflow.doActionFor(application,'open',dest_container=application)
697        da = {'Title': 'Application Data'}
698        student_obj.invokeFactory('StudentPersonal','personal')
699        da['jamb_reg_no'] = student.Entryregno
700        em = self.getEntryMode(student.Entryregno)
701        da['entry_mode'] = em
702        personal = student_obj.personal
703        self.portal_workflow.doActionFor(personal,'open',dest_container=personal)
704        dp = {'Title': 'Personal Data'}
705        student_obj.invokeFactory('StudentClearance','clearance')
706        clearance = student_obj.clearance
707        self.portal_workflow.doActionFor(clearance,'open',dest_container=clearance)
708        dc = {'Title': 'Clearance/Eligibility Record'}
709        dc['matric_no'] = matric_no
710        state = student.State
711        lga = student.LGA
712        if state and lga:
713            lga =  state + ' / ' + lga
714        else:
715            lga = "None"
716        da['jamb_lga'] = dc['lga'] = lga
717        da['app_email'] = dp['email'] = email
718        da['app_mobile'] = dp['phone'] = phone_nr
719        dp['firstname'] = student.Firstname
720        dp['middlename'] = student.Middlename
721        dp['lastname'] = student.Lastname
722        da['jamb_lastname'] = "%s %s %s" % (student.Firstname,student.Middlename,student.Lastname)
723        da['jamb_sex'] = student.Sex
724        dp['sex'] = student.Sex == 'F'
725        dp['perm_address'] = student.Permanent_Address
726        application.getContent().edit(mapping=da)
727        self.portal_workflow.doActionFor(application,'close',dest_container=application)
728        personal.getContent().edit(mapping=dp)
729        clearance.getContent().edit(mapping=dc)
730        self.portal_workflow.doActionFor(clearance,'close',dest_container=clearance)
731        #
732        # Study Course
733        #
734        student_obj.invokeFactory('StudentStudyCourse','study_course')
735        studycourse = student_obj.study_course
736        self.portal_workflow.doActionFor(studycourse,'open',dest_container=studycourse)
737        dsc = {}
738        dsc['study_course'] = certcode
739        dsc['current_level'] = level
740        dsc['current_verdict'] = verdict
741        dsc['current_mode'] = em
742        dsc['current_session'] = '05'
743        studycourse.getContent().edit(mapping=dsc)
744        #
745        # Level
746        #
747##        l = getattr(studycourse,level,None)
748##        if l is None:
749##            studycourse.invokeFactory('StudentStudyLevel', level)
750##            l = getattr(studycourse, level)
751##            self.portal_workflow.doActionFor(l,'open',dest_container=l)
752##            l.getContent().edit(mapping={'Title': "Level %s" % level})
753###)
754
755    security.declareProtected(ModifyPortalContent,'admitOneStudent') ###(
756    def admitOneStudent(self,brain,entry_session,pin_password):
757        "create Datastructure for an admitted Student"
758        #import pdb;pdb.set_trace()
759        students_folder = self.portal_url.getPortalObject().campus.students
760        logger = logging.getLogger('WAeUPTool.admitStudent')
761        if brain.status != "admitted":
762            logger.info('status of %s is %s' % (brain.reg_no,brain.status))
763            return
764        pin_parts = brain.pin.split('-')
765        if len(pin_parts) != 3:
766            logger.info('invalid pin %s for %s' % (brain.pin,brain.reg_no))
767            return
768        student_id = self.generateStudentId('?')
769        students_folder.invokeFactory('Student', student_id)
770        student_object = getattr(students_folder,student_id)
771        if pin_password:
772            password = pin_parts[2]
773            self.makeStudentMember(student_id,password = password)
774        student_object.manage_setLocalRoles(student_id, ['Owner',])
775        #logger.info("creating %s reg_no %s" % (student_id,brain.reg_no))
776        #
777        # application
778        #
779        student_object.invokeFactory('StudentApplication','application')
780        application = student_object.application
781        #self.portal_workflow.doActionFor(application,'open',dest_container=application)
782        da = {'Title': 'Application Data'}
783        da['jamb_reg_no'] = brain.reg_no
784
785        sex = 'M'
786        if brain.sex:
787            sex = 'F'
788        da['jamb_sex'] = sex
789        da['jamb_age'] = brain.jamb_age
790        #da['app_ac_pin'] = brain.pin
791        da['jamb_lga'] = brain.jamb_lga
792        da['jamb_state'] = brain.jamb_state
793        da['jamb_score'] = brain.aggregate
794        da['app_email'] = brain.email
795        da['app_mobile'] = brain.phone
796        if brain.entry_mode:
797            da['entry_mode'] = brain.entry_mode
798        elif brain.screening_type == 'pume':
799            da['entry_mode'] = 'ume_ft'
800        elif brain.screening_type == 'pde':
801            da['entry_mode'] = 'de_ft'
802        else:
803            da['entry_mode'] = brain.screening_type
804        da['entry_session'] = entry_session
805        da['jamb_lastname'] = brain.lastname
806        da['jamb_middlename'] = brain.middlenames   # different field names!
807        da['jamb_firstname'] = brain.firstname
808        da['screening_application_date'] = brain.application_date
809        da['date_of_birth'] = brain.date_of_birth
810        da['jamb_first_cos'] = brain.course1
811        da['jamb_second_cos'] = brain.course2
812        da['course3'] = brain.course3
813        da['screening_type'] = brain.screening_type
814        da['screening_score'] = brain.screening_score
815        da['screening_date'] = brain.screening_date
816        da['hq_type'] = brain.hq_type
817        da['hq_grade'] = brain.hq_grade
818        da['aos'] = brain.aos
819
820        application.getContent().edit(mapping=da)
821        #self.portal_workflow.doActionFor(application,'close',dest_container=application)
822        #
823        # personal
824        #
825        student_object.invokeFactory('StudentPersonal','personal')
826        personal = student_object.personal
827        #self.portal_workflow.doActionFor(personal,'open',dest_container=personal)
828        dp = {'Title': 'Personal Data'}
829        dp['sex'] = brain.sex
830        dp['email'] = brain.email
831        dp['phone'] = brain.phone
832        dp['lastname'] = brain.lastname
833        dp['middlename'] = brain.middlenames   # different field names!
834        dp['firstname'] = brain.firstname
835        personal.getContent().edit(mapping=dp)
836        #
837        # clearance
838        #
839        student_object.invokeFactory('StudentClearance','clearance')
840        clearance = student_object.clearance
841        #self.portal_workflow.doActionFor(clearance,'open',dest_container=clearance)
842        dc = {'Title': 'Clearance/Eligibility Record'}
843        dc['lga'] = brain.lga
844        dc['birthday'] = brain.date_of_birth
845        clearance.getContent().edit(mapping=dc)
846        #self.portal_workflow.doActionFor(clearance,'close',dest_container=clearance)
847        #
848        # study Course
849        #
850        student_object.invokeFactory('StudentStudyCourse','study_course')
851        studycourse = student_object.study_course
852        #self.portal_workflow.doActionFor(studycourse,'open',dest_container=studycourse)
853        dsc = {}
854        dsc['study_course'] = brain.course_admitted
855        dsc['current_verdict'] = ''
856        dsc['current_mode'] = da['entry_mode']
857        if da['entry_mode'].startswith('de'):
858            dsc['current_level'] = '200'
859        else:
860            dsc['current_level'] = '100'
861        dsc['current_session'] = entry_session
862        studycourse.getContent().edit(mapping=dsc)
863        #
864        # payments folder
865        student_object.invokeFactory('PaymentsFolder','payments')
866        payments = getattr(student_object,'payments')
867        dpay = {}
868        dpay['Title'] = 'Payments'
869        payments.getContent().edit(mapping=dpay)
870        self.portal_workflow.doActionFor(payments,'open')
871        #
872        # passport foto
873        app_picture ="%s/import/images/%s/%s_passport.jpg" % (i_home,
874                                                              brain.screening_type,
875                                                              brain.reg_no)
876        images_dir = getImagesDir(student_id)
877        #images_dir = os.path.join("%s" % images_base,student_id)
878        letter_dir,student_dir = os.path.split(images_dir)
879        if not os.path.exists(letter_dir):
880            os.mkdir(letter_dir)
881        if not os.path.exists(images_dir):
882            os.mkdir(images_dir)
883        image_name = os.path.join(images_dir,"passport_%(student_id)s.jpg" % vars())
884        if os.path.exists(app_picture):
885            copy2(app_picture,image_name)
886        else:
887            logger.info('passport of %s/%s not found: %s' % (student_id,
888                                                             brain.reg_no,
889                                                             app_picture))
890
891        return student_id
892    ###)
893
894    security.declareProtected(ModifyPortalContent,'makeStudentLevel') ###(
895    def makeStudentLevel(self,student_id):
896        "create the StudyLevel for a returning Student"
897        #import pdb;pdb.set_trace()
898        logger = logging.getLogger('WAeUPTool.makeStudentLevel')
899        students_folder = self.portal_url.getPortalObject().campus.students
900        res = self.students_catalog(id=student_id)
901        if res:
902            st = res[0]
903        course = st.course
904        matric_no = st.matric_no
905        level = st.level
906        res = self.results_import(matric_no = matric_no)
907        if res:
908            results = res
909        logger.info('%s creating Level %s' % (student_id,level))
910        #
911        # Level
912        #
913        student_obj = getattr(self.portal_url.getPortalObject().campus.students,student_id)
914        studycourse = getattr(student_obj,"study_course",None)
915        self.portal_workflow.doActionFor(studycourse,'close_for_edit',dest_container=studycourse)
916        l = getattr(studycourse,level,None)
917        if l is None:
918            studycourse.invokeFactory('StudentStudyLevel', level)
919            l = getattr(studycourse, level)
920            self.portal_workflow.doActionFor(l,'open',dest_container=l)
921            l.getContent().edit(mapping={'Title': "Level %s" % level})
922        ###)
923
924    security.declarePublic('getHallInfo') ###(
925    def getHallInfo(self,bed):
926        """return Hall Info"""
927        info = {}
928        hall,block,room,letter = bed.split('_')
929        res = ZCatalog.searchResults(self.portal_catalog_real,portal_type="AccoHall",id=hall)
930        if res and len(res) == 1:
931            hall_brain = res[0]
932            hall_doc = hall_brain.getObject().getContent()
933        else:
934            return info
935        info['hall_title'] = hall_brain.Title
936        info['maintenance_code'] = hall_doc.maintenance_code
937        res = ZCatalog.searchResults(self.portal_catalog_real,portal_type="ScratchCardBatch")
938        batch_doc = None
939        for brain in res:
940            if brain.id.startswith(info['maintenance_code']):
941                batch_doc = brain.getObject().getContent()
942                break
943        if batch_doc is None:
944            info['maintenance_fee'] = None
945        else:
946            info['maintenance_fee'] = batch_doc.cost
947        return info
948    ###)
949
950    security.declareProtected(ModifyPortalContent,'removePictureFolder') ###(
951    def removePictureFolder(self,student_id):
952        """remove picture_folder by renaming it"""
953        path = 'images'
954        picture_path = os.path.join(i_home,path,student_id)
955        if not os.path.exists(picture_path):
956            return False
957        os.rename(picture_path,picture_path + "_removed")
958        return True
959    ###)
960
961    security.declareProtected(ModifyPortalContent,'restorePictureFolder') ###(
962    def restorePictureFolder(self,student_id):
963        """restore picture_folder by renaming it"""
964        path = 'images'
965        picture_path = os.path.join(i_home,path,student_id)
966        if not os.path.exists(picture_path + "_removed"):
967            return False
968        os.rename(picture_path + "_removed",picture_path)
969        return True
970    ###)
971
972    security.declarePublic('picturesExist') ###(
973    def picturesExist(self, ids,student_id=None):
974        """check if pictures exist in the filesystem"""
975        if student_id is None:
976            student_id = self.getStudentId()
977        if student_id is None:
978            return False
979        picture_path = getImagesDir(student_id)
980        #picture_path = os.path.join(images_base,student_id)
981        if not os.path.exists(picture_path):
982            return False
983        pictures  = [picture[:picture.rfind('_')] for picture in os.listdir(picture_path)]
984        return set(ids).issubset(set(pictures))
985    ###)
986
987    security.declarePublic('picturesList') ###(
988    def picturesList(self):
989        """check if pictures exist in the filesystem"""
990        path = 'images'
991        student_id = self.getStudentId()
992        #picture_path = os.path.join(i_home,path,student_id)
993        picture_path = getImagesDir(student_id)
994        if not os.path.exists(picture_path):
995            return []
996        return [picture[:picture.rfind('_')] for picture in os.listdir(picture_path)]
997    ###)
998
999    security.declarePublic('showFsPicture') ###(
1000    def showFsPicture(self,path):
1001        """return a picture from the filesystem"""
1002        #picture_path = os.path.join(i_home,path)
1003        picture_path = os.path.join(images_base,path)
1004        response = self.REQUEST.RESPONSE
1005        #import pdb;pdb.set_trace()
1006        registry = getToolByName(self, 'mimetypes_registry')
1007        mimetype = str(registry.lookupExtension(path.lower()) or
1008                    registry.lookupExtension('file.bin'))
1009        if os.path.exists(picture_path):
1010            response.setHeader('Content-type',mimetype)
1011            return open(picture_path).read()
1012        picture_path = os.path.join(i_home,'import',path)
1013        if os.path.exists(picture_path):
1014            return open(picture_path).read()
1015    ###)
1016
1017    security.declareProtected(ModifyPortalContent,'deleteAllCourses') ###(
1018    def deleteAllCourses(self,department="All"):
1019        ''' delete the courses'''
1020        pm = self.portal_membership
1021        member = pm.getAuthenticatedMember()
1022
1023        if str(member) not in ("henrik","joachim"):
1024            return "not possible"
1025        if department == "All":
1026            res = self.portal_catalog({'meta_type': 'Department'})
1027        if len(res) < 1:
1028            return "No Departments found"
1029
1030        deleted = []
1031        for dep in res:
1032            cf = dep.getObject().courses
1033            if cf:
1034                cf.manage_delObjects(ids=cf.objectIds())
1035                deleted.append("deleted Courses in %s" % dep.getId)
1036        return "\r".join(deleted)
1037    ###)
1038
1039    security.declareProtected(ModifyPortalContent,'getLogfileLines') ###(
1040    def getLogfileLines(self,filename="event.log",numlines=20):
1041        """Get last NUMLINES lines of logfile FILENAME.
1042
1043        Return last lines' of a file in the instances logfile directory as
1044        a list. The number of returned lines equals `numlines' or less. If
1045        less than `numlines' lines are available, the whole file ist
1046        returned. If the file can not be opened or some other error
1047        occurs, empty list is returend.
1048        """
1049        result = []
1050        lines_hit = 0
1051
1052        # We only handle files in instances' log directory...
1053        logpath = os.path.join(i_home, "log")
1054        filename = str(os.path.abspath( os.path.join( logpath, filename )))
1055        if not filename.startswith( logpath ):
1056            # Attempt to access file outside log-dir...
1057            return []
1058
1059        try:
1060            fd = file( filename, "rb" )
1061        except IOError:
1062            return []
1063        if not fd:
1064            return []
1065
1066        if os.linesep == None:
1067            linesep = '\n'
1068        else:
1069            linesep = os.linesep
1070
1071        # Try to find 'numlines' times a lineseparator, searching from end
1072        # and moving to the beginning of file...
1073        fd.seek( 0, 2) # Move to end of file...
1074        while lines_hit < numlines:
1075            if fd.read(1) == linesep[-1]: # This moves filedescriptor
1076                                          # one step forward...
1077                lines_hit += 1
1078            try:
1079                fd.seek( -2, 1) # Go two bytes back from current pos...
1080            except IOError:
1081                # We cannot go back two bytes. Maybe the file is too small...
1082                break
1083        fd.seek(2,1)
1084
1085        # Read all lines from current position...
1086        result = fd.readlines()
1087        # Remove line endings...
1088        result = [x.strip() for x in result]
1089        fd.close()
1090        return result
1091    ###)
1092
1093    security.declareProtected(ModifyPortalContent,"getCallbacksFromLog")###(
1094    def getCallbacksFromLog(self,filename):
1095        """fix Online Payment Transactions from Z2.log entries"""
1096        import transaction
1097        import random
1098        from cgi import parse_qs
1099        from urlparse import urlparse
1100        #from pdb import set_trace
1101        wftool = self.portal_workflow
1102        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
1103        students_folder = self.portal_url.getPortalObject().campus.students
1104        s = r'(?P<client_ip>\S+) - (?P<member_id>\S+) \['
1105        s += r'(?P<date>.*)\] "(?P<get>.*)" (?P<codes>\d+ \d+) "'
1106        s += r'(?P<intersw>.*)" "(?P<agent>.*)"'
1107        data = re.compile(s)
1108        start = True
1109        tr_count = 1
1110        total = 0
1111        #name = 'pume_results'
1112        #name = 'epaymentsuccessful_z2log2'
1113        name = filename
1114        no_import = []
1115        imported = []
1116        logger = logging.getLogger('WAeUPTool.getFailedTransactions')
1117        try:
1118            transactions = open("%s/import/%s" % (i_home,name),"rb").readlines()
1119        except:
1120            logger.error('Error reading %s' % name)
1121            return
1122        tas = []
1123        for line in transactions:
1124            dict = {}
1125            items = data.search(line)
1126            dict['idict'] = idict = items.groupdict()
1127            #print idict
1128            #from pdb import set_trace;set_trace()
1129            urlparsed = urlparse(idict['get'][4:])
1130            #print urlparsed
1131            path = urlparsed[2].split('/')
1132            dict['student_id'] = student_id = path[8]
1133            dict['payment_id'] = payment_id = path[10]
1134            dict['qs_dict'] = qs_dict = parse_qs(urlparsed[4])
1135            tas.append(dict)
1136            tr_count += 1
1137        return tas
1138    ###)
1139
1140    security.declareProtected(ModifyPortalContent,"importOnlinePaymentTransactions")###(
1141    def importOnlinePaymentTransactions(self):
1142        """load Online Payment Transactions from CSV values"""
1143        import transaction
1144        import random
1145        #from pdb import set_trace
1146        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
1147        opt = self.online_payments_import
1148        students_folder = self.portal_url.getPortalObject().campus.students
1149        start = True
1150        tr_count = 1
1151        total = 0
1152        #name = 'pume_results'
1153        name = 'OnlineTransactions'
1154        no_import = []
1155        imported = []
1156        logger = logging.getLogger('WAeUPTool.importOnlinePaymentTransactions')
1157        try:
1158            transactions = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
1159        except:
1160            logger.error('Error reading %s.csv' % name)
1161            return
1162        for pay_transaction in transactions:
1163            if start:
1164                start = False
1165                logger.info('Start loading from %s.csv' % name)
1166                s = ','.join(['"%s"' % fn for fn in pay_transaction.keys()])
1167                no_import.append('%s,"Error"' % s)
1168                format = ','.join(['"%%(%s)s"' % fn for fn in pay_transaction.keys()])
1169                format_error = format + ',"%(Error)s"'
1170            data = {}
1171
1172            # format of the first file sent by Tayo
1173            #data['datetime'] = date = DateTime.DateTime(pay_transaction['Date'])
1174            #data['student_id'] = student_id = pay_transaction['Payer ID']
1175            #data['order_id'] = order_id = pay_transaction['Order ID (Tranx Ref)']
1176            #data['response_code'] = response_code = pay_transaction['Resp Code']
1177            #data['amount'] = amount = pay_transaction['Amount']
1178
1179            # format of the second file sent by Tayo
1180            #data['datetime'] = date = 0
1181            #data['student_id'] = student_id = pay_transaction['Payer ID']
1182            #data['order_id'] = order_id = pay_transaction['Order ID (Tranx Ref)']
1183            #data['response_code'] = response_code = '00'
1184            #data['amount'] = amount = pay_transaction['Amount']
1185
1186            # format of the third file sent by Kehinde
1187            data['datetime'] = date = 0
1188            data['student_id'] = student_id = pay_transaction['customer_id']
1189            data['order_id'] = order_id = pay_transaction['merchant_reference']
1190            data['response_code'] = response_code = '00'
1191            data['amount'] = amount = pay_transaction['Amount']
1192
1193            dup = False
1194            if response_code == "12":
1195                continue
1196            try:
1197                opt.addRecord(**data)
1198            except ValueError:
1199                dup = True
1200            #from pdb import set_trace;set_trace()
1201            if dup:
1202                if response_code == "00":
1203                    try:
1204                        opt.modifyRecord(**data)
1205                    except:
1206                        logger.info("duplicate uid, order_id %(order_id)s, student_id %(student_id)s, response_code %(response_code)s" % data)
1207                        continue
1208                else:
1209                    pay_transaction['Error'] = "Duplicate order_id"
1210                    no_import.append( format_error % pay_transaction)
1211                    logger.info("duplicate order_id %(order_id)s for %(student_id)s %(response_code)s" % data)
1212                    continue
1213            tr_count += 1
1214            if tr_count > 1000:
1215                if len(no_import) > 0:
1216                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
1217                             '\n'.join(no_import) + '\n')
1218                    no_import = []
1219                em = '%d transactions committed\n' % (tr_count)
1220                transaction.commit()
1221                regs = []
1222                logger.info(em)
1223                total += tr_count
1224                tr_count = 0
1225        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
1226                                                '\n'.join(no_import))
1227        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
1228    ###)
1229
1230    security.declareProtected(ModifyPortalContent,'mass_create_faculty') ###(
1231    def mass_create_faculty(self,mapping):
1232        "create a faculty"
1233        logger = logging.getLogger('WAeUPTool.mass_create_faculty')
1234        academics_folder = self.portal_url.getPortalObject().campus.academics
1235        fid = mapping['code']
1236        if getattr(academics_folder,fid,None) is not None:
1237            return '', "Faculty with ID: %s exists" % fid
1238        logger.info('Creating Faculty %(code)s, %(title)s' % mapping)
1239        try:
1240            academics_folder.invokeFactory('Faculty', fid)
1241        except BadRequest,E:
1242            return '', "%s" % E
1243        f = getattr(academics_folder,fid,None)
1244        f.getContent().edit(mapping=mapping)
1245        return fid,''
1246    ###)
1247
1248    security.declareProtected(ModifyPortalContent,'mass_edit_faculty') ###(
1249    def mass_edit_faculty(self,mapping):
1250        "edit a faculty"
1251        logger = logging.getLogger('WAeUPTool.mass_edit_faculty')
1252        academics_folder = self.portal_url.getPortalObject().campus.academics
1253        fid = mapping['code']
1254        f = getattr(academics_folder,fid,None)
1255        if f is None:
1256            return '', "Faculty with ID: %s does not exist" % fid
1257        logger.info('Editing Faculty %(code)s, %(title)s' % mapping)
1258        f.getContent().edit(mapping=mapping)
1259        return fid,''
1260    ###)
1261
1262    security.declareProtected(ModifyPortalContent,'mass_create_department') ###(
1263    def mass_create_department(self,mapping):
1264        "create a department in the correct faculty"
1265        logger = logging.getLogger('WAeUPTool.mass_create_department')
1266        fid = mapping['faculty_code']
1267        if getattr(self,'_v_faculties',None) is None:
1268            res = self.portal_catalog(portal_type = "Faculty")
1269            self._v_faculties = {}
1270            for f in res:
1271                self._v_faculties[f.getId] = f.getObject()
1272        f = self._v_faculties.get(fid,None)
1273        if f is None:
1274            return '', "No Faculty with ID: %s" % fid
1275        else:
1276            did = mapping.get('code')
1277            d = getattr(f,did,None)
1278            if d is None or d.portal_type == "Faculty":
1279                logger.info('Creating Department %(code)s, %(title)s' % mapping)
1280                try:
1281                    f.invokeFactory('Department', did)
1282                except BadRequest,E:
1283                    return '', "%s" % E
1284                d = getattr(f,did)
1285                d.invokeFactory('CoursesFolder','courses')
1286                courses = getattr(d,'courses')
1287                dict = {'Title': 'Courses'}
1288                courses.getContent().edit(mapping=dict)
1289                d.invokeFactory('CertificatesFolder','certificates')
1290                certificates = getattr(d,'certificates')
1291                dict = {'Title': 'Certificates'}
1292                certificates.getContent().edit(mapping=dict)
1293            d.getContent().edit(mapping=mapping)
1294        return did,''
1295    ###)
1296
1297    security.declareProtected(ModifyPortalContent,'mass_edit_department') ###(
1298    def mass_edit_department(self,mapping):
1299        "create a department in the correct faculty"
1300        logger = logging.getLogger('WAeUPTool.mass_create_department')
1301        academics_folder = self.portal_url.getPortalObject().campus.academics
1302        fid = mapping['faculty_code']
1303        did = mapping.get('code')
1304        try:
1305            d = getattr(getattr(academics_folder,fid),did,None)
1306        except KeyError:
1307            return '', "Department %s or Faculty %s wrong" % (did,fid)
1308        else:
1309            if d is None or d.portal_type == "Faculty":
1310                logger.info('Editing Department %(code)s, %(title)s' % mapping)
1311            d.getContent().edit(mapping=mapping)
1312        return did,''
1313    ###)
1314
1315    security.declareProtected(ModifyPortalContent,'mass_create_course') ###(
1316    def mass_create_course(self,mapping):
1317        #import pdb;pdb.set_trace()
1318        if getattr(self,'_v_course_list',None) is None:
1319            self._v_course_list = []
1320        if getattr(self,'_v_departments',None) is None:
1321            res = self.portal_catalog(portal_type = "Department")
1322            self._v_department_courses = {}
1323            for d in res:
1324                self._v_department_courses[d.getId] = getattr(d.getObject(),"courses",None)
1325        did = mapping['department_code']
1326        d = self._v_department_courses.get(did,None)
1327        if d is None:
1328            return '', "No Department with ID: %s" % did
1329        course_id = mapping.get('code')
1330        if course_id in self._v_course_list:
1331            return '', "Duplicate Course ID: %s" % did
1332        c = getattr(d,course_id,None)
1333        if c is not None:
1334            return '', "Duplicate Course ID: %s" % did
1335        try:
1336            d.invokeFactory('Course', course_id)
1337        except BadRequest,E:
1338            return '', "%s" % E
1339        self._v_course_list.append(course_id)
1340        c = getattr(d,course_id)
1341        c.getContent().edit(mapping=mapping)
1342        return course_id,''
1343    ###)
1344
1345    security.declareProtected(ModifyPortalContent,'mass_edit_course') ###(
1346    def mass_edit_course(self,mapping):
1347        #import pdb;pdb.set_trace()
1348        course_id = mapping.get('code')
1349        res = self.portal_catalog(id=course_id)
1350        if not res:
1351            return '', "No Course with ID: %s" % course_id
1352        c = res[0].getObject()
1353        c.getContent().edit(mapping=mapping)
1354        return course_id,''
1355    ###)
1356
1357    security.declareProtected(ModifyPortalContent,'mass_create_certificate') ###(
1358    def mass_create_certificate(self,mapping):
1359        if getattr(self,'_v_certificate_list',None) is None:
1360            self._v_certificate_list = []
1361        if getattr(self,'_v_department_certificates',None) is None:
1362            res = self.portal_catalog(portal_type = "Department")
1363            self._v_department_certificates = {}
1364            for d in res:
1365                self._v_department_certificates[d.getId] = getattr(d.getObject(),"certificates",None)
1366        did = mapping['department_code']
1367        d = self._v_department_certificates.get(did,None)
1368        if d is None:
1369            return '', "No Department with ID: %s" % did
1370        certificate_id = mapping.get('code')
1371        if certificate_id in self._v_certificate_list:
1372            return '', "Duplicate Certificate ID: %s" % did
1373        c = getattr(d,certificate_id,None)
1374        if c is not None:
1375            return '', "Duplicate Certificate ID: %s" % did
1376        try:
1377            d.invokeFactory('Certificate', certificate_id)
1378        except BadRequest,E:
1379            return '', "%s" % E
1380        self._v_certificate_list.append(certificate_id)
1381        c = getattr(d,certificate_id)
1382        c.getContent().edit(mapping=mapping)
1383        return certificate_id,''
1384    ###)
1385
1386    security.declareProtected(ModifyPortalContent,'mass_edit_certificate') ###(
1387    def mass_edit_certificate(self,mapping):
1388        #import pdb;pdb.set_trace()
1389        certificate_id = mapping.get('code')
1390        res = self.portal_catalog(id=certificate_id)
1391        if not res:
1392            return '', "No Certificate with ID: %s" % did
1393        c = res[0].getObject()
1394        c.getContent().edit(mapping=mapping)
1395        return certificate_id,''
1396    ###)
1397
1398    security.declareProtected(ModifyPortalContent,'mass_create_application') ###(
1399    def mass_create_application(self,mapping):
1400        #import pdb;pdb.set_trace()
1401        reg_no = mapping.get('reg_no')
1402        try:
1403            self.applicants_catalog.addRecord(**mapping)
1404        except ValueError:
1405            return '', "applicant record with reg_no %s already exists" % reg_no
1406        return reg_no,''
1407    ###)
1408
1409    security.declareProtected(ModifyPortalContent,'mass_edit_application') ###(
1410    def mass_edit_application(self,mapping):
1411        #import pdb;pdb.set_trace()
1412        reg_no = mapping.get('reg_no')
1413        res = self.applicants_catalog(reg_no = reg_no)
1414        if len(res):
1415            if res[0].status == 'created':
1416                return '', "student object with id %s for %s already created, status not changed" % (res[0].student_id, reg_no)
1417            else:
1418                self.applicants_catalog.modifyRecord(**mapping)
1419                return reg_no,''
1420        else:
1421            return '', "applicant record with reg_no %s does not exist" % reg_no
1422
1423    ###)
1424
1425    security.declareProtected(ModifyPortalContent,'mass_create_course_result') ###(
1426    def mass_create_course_result(self,mapping):
1427        #import pdb;pdb.set_trace()
1428        if getattr(self,'_v_courses',None) is None:
1429            res = self.courses_catalog()
1430            self._v_courses = {}
1431            for brain in res:
1432                self._v_courses[brain.code] = brain
1433        course_id = mapping.get('code')
1434        if course_id not in self._v_courses.keys():
1435            return '', "No course with ID: %s" % did
1436        id_key = ''
1437        for id_key in ('student_id','matric_no'):
1438            id_field = mapping.get(id_key,None)
1439            if id_field is not None:
1440                student_id = id_field
1441                break
1442        query = Eq(id_key,id_field)
1443        res = self.students_catalog.evalAdvancedQuery(query)
1444        if not res:
1445            return '', "No student with %(id_field)s: %(id_key)s" % vars()
1446        if id_field != "student_id":
1447            mapping['student_id'] = res[0].id
1448        mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % mapping
1449        for k in ('semester',):
1450            mapping[k] = getattr(self._v_courses[course_id],k)
1451        try:
1452            self.course_results.addRecord(**mapping)
1453        except ValueError:
1454            return '', "course result already exists: %s" % key
1455        return key,''
1456    ###)
1457
1458    security.declareProtected(ModifyPortalContent,'mass_edit_course_result') ###(
1459    def mass_edit_course_result(self,mapping):
1460        #import pdb;pdb.set_trace()
1461        # if getattr(self,'_v_courses',None) is None:
1462        #     res = self.courses_catalog()
1463        #     self._v_courses = {}
1464        #     for brain in res:
1465        #         self._v_courses[brain.code] = brain
1466        # course_id = mapping.get('code')
1467        # if course_id not in self._v_courses.keys():
1468        #     return '', "No course with ID: %s" % did
1469        id_key = ''
1470        for id_key in ('student_id','matric_no'):
1471            id_field = mapping.get(id_key,None)
1472            if id_field is not None:
1473                student_id = id_field
1474                break
1475        query = Eq(id_key,id_field)
1476        res = self.students_catalog.evalAdvancedQuery(query)
1477        if not res:
1478            return '', "No student with %(id_field)s: %(id_key)s" % vars()
1479        if id_field != "student_id":
1480            mapping['student_id'] = res[0].id
1481        mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % mapping
1482        # for k in ('semester',):
1483        #     mapping[k] = getattr(self._v_courses[course_id],k)
1484        try:
1485            self.course_results.modifyRecord(**mapping)
1486        except KeyError:
1487            return '', "No course result to edit: %s" % key
1488        return key,''
1489    ###)
1490
1491    security.declareProtected(ModifyPortalContent,'mass_create_certificate_course') ###(
1492    def mass_create_certificate_course(self,mapping):
1493        if getattr(self,'_v_courses',None) is None:
1494            res = self.courses_catalog()
1495            self._v_courses= [course.code for course in res]
1496        if getattr(self,'_v_ceritficates',None) is None:
1497            res = self.portal_catalog(portal_type = "Certificate")
1498            self._v_certificates = {}
1499            for cert in res:
1500                self._v_certificates[cert.getId] = cert.getObject()
1501        certificate_course_id = mapping.get('code')
1502        if certificate_course_id not in self._v_courses:
1503            return '', "No Course with ID: %s" % certificate_course_id
1504        cert_id = mapping['certificate_code']
1505        cert = self._v_certificates.get(cert_id,None)
1506        if cert is None:
1507            return '', "No Certificate with ID: %s" % cert_id
1508        level_id = mapping.get('level')
1509        level = getattr(cert,level_id,None)
1510        if level is None:
1511            cert.invokeFactory('StudyLevel', level_id)
1512            level = getattr(cert,level_id,None)
1513        elif hasattr(level,certificate_course_id):
1514            return '', "Duplicate CertificateCourse ID: %s in %s/ %s" %\
1515            (certificate_course_id,cert_id,level_id)
1516        level.invokeFactory('CertificateCourse', certificate_course_id)
1517        c = getattr(level,certificate_course_id)
1518        c.getContent().edit(mapping=mapping)
1519        return certificate_course_id,''
1520    ###)
1521
1522    field2types_student = {   ###(
1523                      'StudentApplication':
1524                          {'id': 'application',
1525                           'title': 'Application Data',
1526                           'wf_transition_return': 'close',
1527                           'wf_transition_admit': 'remain',
1528                           'fields':
1529                             ('jamb_reg_no',
1530                              'entry_mode',
1531                              'entry_session',
1532                              'jamb_score',
1533                              'app_email',
1534                              'jamb_age',
1535                              'jamb_state',
1536                              'jamb_lga',
1537                              )
1538                              },
1539                      #'StudentPume':
1540                      #    {'id': 'pume',
1541                      #     'title': 'Pume Data',
1542                      #     'wf_transition_return': 'close',
1543                      #     'wf_transition_admit': 'close',
1544                      #     'fields':
1545                      #       ('pume_score',
1546                      #        )
1547                      #        },
1548                      'StudentClearance':
1549                          {'id': 'clearance',
1550                           'title': 'Clearance/Eligibility Record',
1551                           'wf_transition_return': 'close',
1552                           'wf_transition_admit': 'remain',
1553                           'fields':
1554                             ('matric_no',
1555                              'nationality',
1556                              'lga',
1557                              'birthday',
1558                              )
1559                              },
1560                         'StudentPersonal':
1561                          {'id': 'personal',
1562                           'title': 'Personal Data',
1563                           'wf_transition_return': 'open',
1564                           'wf_transition_admit': 'remain',
1565                           'fields':
1566                             ('firstname',
1567                              'middlename',
1568                              'lastname',
1569                              'sex',
1570                              'email',
1571                              'phone',
1572                              'perm_address',
1573                              )
1574                              },
1575                         'StudentStudyCourse':
1576                          {'id': 'study_course',
1577                           'title': 'Study Course',
1578                           'wf_transition_return': 'open',
1579                           'wf_transition_admit': 'remain',
1580                           'fields':
1581                             ('study_course',
1582                              'current_level',
1583                              'current_session',
1584                              'current_mode',
1585                              'current_verdict',
1586                              'previous_verdict',
1587                              )
1588                              },
1589
1590                         'PaymentsFolder':
1591                          {'id': 'payments',
1592                           'title': 'Payments',
1593                           'wf_transition_return': 'open',
1594                           'wf_transition_admit': 'open',
1595                           'fields':
1596                             ()
1597                              },
1598                         }
1599    ###)
1600
1601    security.declareProtected(ModifyPortalContent,'mass_create_student') ###(
1602    def mass_create_student(self,mapping):
1603        "create a students record due import"
1604        logger = logging.getLogger('WAeUPTool.mass_create_student')
1605        students_folder = self.portal_url.getPortalObject().campus.students
1606        jamb_reg_no = mapping.get('jamb_reg_no',None)
1607        if jamb_reg_no:
1608            res = self.students_catalog(jamb_reg_no = jamb_reg_no)
1609            if res:
1610                return '',"jamb_reg_no exists"
1611        matric_no = mapping.get('matric_no',None)
1612        if matric_no:
1613            res = self.students_catalog(matric_no = matric_no)
1614            if res:
1615                return '',"matric_no exists"
1616        sid = self.waeup_tool.generateStudentId('?')
1617        students_folder.invokeFactory('Student', sid)
1618        student_obj = getattr(students_folder,sid)
1619        f2t = self.field2types_student
1620        d = {}
1621        transition = mapping.get('reg_transition','admit')
1622        if transition not in ('admit','return'):
1623            return '',"no valid transition provided"
1624        for pt in f2t.keys():
1625            student_obj.invokeFactory(pt,f2t[pt]['id'])
1626            sub_obj = getattr(student_obj,f2t[pt]['id'])
1627            sub_doc = sub_obj.getContent()
1628            d['Title'] = f2t[pt]['title']
1629            for field in f2t[pt]['fields']:
1630                d[field] = mapping.get(field,'')
1631
1632            if pt == "StudentApplication":
1633                d['jamb_sex']  = 'M'
1634                if mapping.get('sex'):
1635                    d['jamb_sex']  = 'F'
1636                d['jamb_firstname'] = mapping.get('firstname',None)
1637                d['jamb_middlename'] = mapping.get('middlename',None)
1638                d['jamb_lastname'] = mapping.get('lastname',None)
1639
1640            # if pt == "StudyCourse":
1641            #     for von,zu in (('entry_mode','current_mode'),
1642            #                    ('entry_session','current_session')):
1643            #         if mapping.get(zu,None) is None and mapping.get(von,None) is not None:
1644            #             d[zu] = mapping[von]
1645            sub_doc.edit(mapping = d)
1646
1647            #import pdb;pdb.set_trace()
1648            new_state = f2t[pt]['wf_transition_%(transition)s' % vars()]
1649            if new_state != "remain":
1650                self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
1651        self.portal_workflow.doActionFor(student_obj,transition)
1652        student_obj.manage_setLocalRoles(sid, ['Owner',])
1653        return sid,''
1654    ###)
1655
1656    security.declareProtected(ModifyPortalContent,'mass_edit_student') ###(
1657    def mass_edit_student(self,mapping):
1658        "edit a students record due import"
1659        logger = logging.getLogger('WAeUPTool.mass_edit_student')
1660        students_folder = self.portal_url.getPortalObject().campus.students
1661        sid = mapping.get('id',None)
1662        jamb_reg_no = mapping.get('jamb_reg_no',None)
1663        matric_no = mapping.get('matric_no',None)
1664        editable_keys = mapping.keys()
1665        if sid:
1666            res = self.students_catalog(id = sid)
1667            if not res:
1668                return '',"no student with id %s" % sid
1669            if matric_no and res[0].matric_no and\
1670              matric_no != res[0].matric_no:
1671                logger.info("%s, old matric_no %s overwritten with %s" % (res[0].id,res[0].matric_no,matric_no))
1672            if jamb_reg_no and res[0].jamb_reg_no and\
1673              jamb_reg_no != res[0].jamb_reg_no:
1674                logger.info("%s, old reg_no %s overwritten with %s" % (res[0].id,res[0].jamb_reg_no,jamb_reg_no))
1675        elif jamb_reg_no:
1676            res = self.students_catalog(jamb_reg_no = jamb_reg_no)
1677            if not res:
1678                return '',"no student with jamb_reg_no %s" % jamb_reg_no
1679            editable_keys.remove('jamb_reg_no')
1680        elif matric_no:
1681            res = self.students_catalog(matric_no = matric_no)
1682            if not res:
1683                return '',"no student with matric_no %s" % matric_no
1684            editable_keys.remove('matric_no')
1685
1686        ## included only to change wf state from admitted to returning
1687        #if res[0].review_state not in ('admitted','objection_raised'):
1688        #    return '%s' % res[0].id ,"student is not in state admitted or objection_raised"
1689        ## end inclusion
1690
1691        sid = res[0].id
1692        student_obj = getattr(students_folder,sid)
1693        f2t = self.field2types_student
1694        d = {}
1695        #import pdb;pdb.set_trace()
1696        any_change = False
1697        for pt in f2t.keys():
1698            if pt == "student_application":
1699                d['jamb_sex']  = 'M'
1700                if mapping.get('sex'):
1701                    d['jamb_sex']  = 'F'
1702            intersect = set(f2t[pt]['fields']).intersection(set(editable_keys))
1703            if intersect:
1704                sub_obj = getattr(student_obj,f2t[pt]['id'],None)
1705                if sub_obj is None:
1706                    try:
1707                        student_obj.invokeFactory(pt,f2t[pt]['id'])
1708                    except:
1709                        continue
1710                    sub_obj = getattr(student_obj,f2t[pt]['id'])
1711                    d['Title'] = f2t[pt]['title']
1712                sub_doc = sub_obj.getContent()
1713                for field in intersect:
1714                    changed = False
1715                    if getattr(sub_doc,field,None) != mapping.get(field,''):
1716                        any_change = True
1717                        changed = True
1718                        d[field] = mapping.get(field,'')
1719                    if changed:
1720                        sub_doc.edit(mapping = d)
1721
1722
1723        ## included only to change wf state from admitted to returning
1724        #    if res[0].review_state in ('admitted','objection_raised'):
1725        #        new_state = f2t[pt]['wf_transition_return']
1726        #        sub_obj = getattr(student_obj,f2t[pt]['id'],None)
1727        #        if sub_obj and new_state != "remain":
1728        #            try:
1729        #                self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
1730        #            except:
1731        #                #logger.info('%s, wf transition %s of %s failed' % (sid,new_state,sub_obj.id))
1732        #                pass
1733        #if res[0].review_state in ('admitted','objection_raised'):
1734        #    wfaction = 'return'
1735        #    try:
1736        #        self.portal_workflow.doActionFor(student_obj,wfaction)
1737        #        logger.info('%s, wf state changed' % sid)
1738        #        any_change = True
1739        #    except:
1740        #        logger.info('%s, wf transition failed, old state = %s' % (sid,res[0].review_state))
1741        #        pass
1742        ## end inclusion
1743
1744
1745        if any_change:
1746            return sid,''
1747        else:
1748            return sid,'not modified'
1749    ###)
1750
1751    security.declareProtected(ModifyPortalContent,"importData")###(
1752    def importData(self,filename,name,edit=False,bypass_queue_catalog=False):
1753        """load data from CSV values"""
1754        import transaction
1755        import random
1756
1757        pm = self.portal_membership
1758        member = pm.getAuthenticatedMember()
1759
1760        logger = logging.getLogger('WAeUPTool.importData')
1761        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
1762        students_folder = self.portal_url.getPortalObject().campus.students
1763        start = True
1764        tr_count = 0
1765        total_imported = 0
1766        total_not_imported = 0
1767        total = 0
1768        iname = "import_%s" % name
1769        if iname == 'import_application':
1770            commit_after = 2000
1771        else:
1772            commit_after = 100
1773        stool = getToolByName(self, 'portal_schemas')
1774        ltool = getToolByName(self, 'portal_layouts')
1775        schema = stool._getOb(iname)
1776        if schema is None:
1777            em = 'No such schema %s' % iname
1778            logger.error('No such schema %s' % iname)
1779            return em
1780        layout = ltool._getOb(iname)
1781        if layout is None:
1782            em = 'No such layout %s' % iname
1783            logger.error(em)
1784            return em
1785        validators = {}
1786        for widget in layout.keys():
1787            validators[widget] = layout[widget].validate
1788        mode = "create"
1789        if edit:
1790            mode = "edit"
1791        importer_name = "mass_%(mode)s_%(name)s" % vars()
1792        importer = getattr(self, '%s' % importer_name,None)
1793        if importer is None:
1794            em = 'No importer function %s' % importer_name
1795            logger.error(em)
1796            return em
1797        not_imported = []
1798        imported = []
1799        try:
1800            items = csv.DictReader(open("%s/import/%s.csv" % (i_home,filename),"rb"))
1801        except:
1802            em = 'Error reading %s.csv' % filename
1803            logger.error(em)
1804            return em
1805        for item in items:
1806            #import pdb;pdb.set_trace()
1807            item = dict((k.strip(),l.strip()) for (k,l) in item.items())
1808            if start:
1809                start = False
1810                adapters = [MappingStorageAdapter(schema, item)]
1811                logger.info('%s starts import from %s.csv in %s mode with schema and layout %s' % (member,filename,mode,iname))
1812                attrs = csv.reader(open("%s/import/%s.csv" % (i_home,filename),"rb")).next()
1813                import_keys = [k.strip() for k in attrs if not k.startswith('ignore')]
1814                diff2schema = set(import_keys).difference(set(schema.keys()))
1815                diff2layout = set(import_keys).difference(set(layout.keys()))
1816                if diff2schema:
1817                    em = 'not ignorable key(s): "%s" found in heading' % ", ".join(diff2schema)
1818                    return em
1819                if mode == "create":
1820                    required_keys = [layout.getIdUnprefixed(id)
1821                                     for id,widget in layout.objectItems()
1822                                     if widget.is_required]
1823                    if not set(required_keys).issubset(set(import_keys)):
1824                        diff2import = set(required_keys).difference(set(import_keys))
1825                        em = 'required key(s): "%s" not found in heading' % ", ".join(diff2import)
1826                        return em
1827                s = ','.join(['"%s"' % fn for fn in import_keys])
1828                open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(s + ',"Error"'+ '\n')
1829                s = '"id",' + s
1830                open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(s + '\n')
1831                format = ','.join(['"%%(%s)s"' % fn for fn in import_keys])
1832                format_error = format + ',"%(Error)s"'
1833                format = '"%(id)s",'+ format
1834
1835            dm = DataModel(item, adapters,context=self)
1836            ds = DataStructure(data=item,datamodel=dm)
1837            error_string = ""
1838            total += 1
1839            error_count = 0
1840            for k in import_keys:
1841                if not validators[k](ds,mode=mode):
1842                    if error_count:
1843                        error_string += ' ++ '
1844                    error_string += "%s: %s" % (k,
1845                                                  self.translation_service(ds.getError(k),
1846                                                                           ds.getErrorMapping(k)))
1847                    error_count += 1
1848            if not error_string:
1849                temp_item = item.copy()
1850                temp_item.update(dm)
1851                temp_item['id'],error = importer(temp_item)
1852                if error:
1853                    error_string += error
1854                else:
1855                    item = temp_item
1856            if error_string:
1857                item['Error'] = error_string
1858                not_imported.append(format_error % item)
1859                total_not_imported += 1
1860            else:
1861                em = format % item
1862                imported.append(em)
1863                tr_count += 1
1864                total_imported += 1
1865                logger.info("%(total_imported)d of %(total)d %(em)s" % vars())
1866
1867            if total and not total % commit_after:
1868                transaction.commit()
1869                if len(not_imported) > 0:
1870                    open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
1871                             '\n'.join(not_imported) + '\n')
1872                    not_imported = []
1873                if len(imported) > 0:
1874                    open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
1875                             '\n'.join(imported) + '\n')
1876                    imported = []
1877                em = '%d transactions committed\n' % (tr_count)
1878                regs = []
1879                logger.info(em)
1880                tr_count = 0
1881                #if total > 100:
1882                #    return
1883        if len(imported) > 0:
1884            open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
1885                                                '\n'.join(imported))
1886        if len(not_imported) > 0:
1887            open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
1888                                                '\n'.join(not_imported))
1889        em = "Finished: %d imported, %d not imported (of total %d)" % (total_imported,total_not_imported,total)
1890        logger.info(em)
1891        return em
1892    ###)
1893
1894    security.declareProtected(ModifyPortalContent,"moveImagesToFS")###(
1895    def moveImagesToFS(self,student_id="O738726"):
1896        "move the images to the filesystem"
1897        images_dir = getImagesDir(student_id)
1898        #images_dir = os.path.join("%s" % images_base,student_id)
1899        student_folder = getattr(self.portal_url.getPortalObject().campus.students,student_id)
1900        stool = getToolByName(self, 'portal_schemas')
1901        schemas = ['student_application',
1902                   'student_clearance',
1903                   ]
1904        created = False
1905        for schema_id in schemas:
1906            schema = stool._getOb(schema_id)
1907            object = getattr(student_folder,schema_id[len('student_'):],None)
1908            if object is None:
1909                continue
1910            doc = object.getContent()
1911            for key in schema.keys():
1912                if schema[key].meta_type != "CPS Image Field":
1913                    continue
1914                #import pdb;pdb.set_trace()
1915                image = getattr(doc,key,None)
1916                if not image or not hasattr(image,"data"):
1917                    continue
1918                if not created:
1919                    if not os.path.exists(images_dir):
1920                        os.mkdir(images_dir)
1921                    created = True
1922                filename = os.path.join(images_dir,"%(key)s_%(student_id)s.jpg" % vars())
1923                open(filename,"wb").write(str(image.data))
1924    ###)
1925
1926    security.declareProtected(ModifyPortalContent,"movePassportToFS")###(
1927    def movePassportToFS(self,student_id="O738726"):
1928        "move the passports to the filesystem"
1929        images_dir = os.path.join("%s" % i_home,'passports')
1930        student_folder = getattr(self.portal_url.getPortalObject().campus.students,student_id)
1931        stool = getToolByName(self, 'portal_schemas')
1932        schemas = ['student_application',
1933                   #'student_clearance',
1934                   ]
1935        created = False
1936        for schema_id in schemas:
1937            schema = stool._getOb(schema_id)
1938            object = getattr(student_folder,schema_id[len('student_'):],None)
1939            if object is None:
1940                continue
1941            doc = object.getContent()
1942            for key in schema.keys():
1943                if schema[key].meta_type != "CPS Image Field":
1944                    continue
1945                #import pdb;pdb.set_trace()
1946                image = getattr(doc,key)
1947                if not hasattr(image,"data"):
1948                    continue
1949                if not created:
1950                    if not os.path.exists(images_dir):
1951                        os.mkdir(images_dir)
1952                    created = True
1953                filename = os.path.join(images_dir,"%(student_id)s.jpg" % vars())
1954                open(filename,"wb").write(str(image.data))
1955    ###)
1956
1957InitializeClass(WAeUPTool)
Note: See TracBrowser for help on using the repository browser.