source: WAeUP_SRP/trunk/WAeUPTool.py @ 1744

Last change on this file since 1744 was 1730, checked in by joachim, 18 years ago

fix for clearance display error

  • Property svn:keywords set to Id
File size: 33.1 KB
RevLine 
[197]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 1730 2007-05-03 14:01:40Z joachim $
[1174]20"""The WAeUP Tool Box.
[197]21"""
22
23from AccessControl import ClassSecurityInfo
[828]24from Acquisition import aq_inner
25from Acquisition import aq_parent
26from Globals import DTMLFile
27from Globals import InitializeClass
28from OFS.SimpleItem import SimpleItem
[197]29
[828]30from Products.CMFCore.ActionProviderBase import ActionProviderBase
31from Products.CMFCore.permissions import View
32from Products.ZCatalog.ZCatalog import ZCatalog
33from Products.CMFCore.permissions import ModifyPortalContent
[197]34from Products.CMFCore.utils import UniqueObject
[1194]35from Products.CMFCore.URLTool import URLTool
[1151]36from Students import makeCertificateCode
[1285]37from Globals import package_home,INSTANCE_HOME
38p_home = package_home(globals())
39i_home = INSTANCE_HOME
[1620]40import DateTime
41import logging
[1170]42import transaction
[1620]43import csv,re,os
[1707]44from Products.AdvancedQuery import Eq, Between, Le,In
[197]45
[1707]46def getObject(object,name):
47    if object.hasObject(name):
48        return getattr(object,name)
49    return None
[1720]50
[828]51class WAeUPTool(UniqueObject, SimpleItem, ActionProviderBase):
[197]52    """WAeUP tool"""
53
[828]54    id = 'waeup_tool'
[197]55    meta_type = 'WAeUP Tool'
[828]56    _actions = ()
[197]57
58    security = ClassSecurityInfo()
[828]59    security.declareObjectProtected(View)
[197]60
[828]61    manage_options = ( ActionProviderBase.manage_options
62                     + SimpleItem.manage_options
63                     )
64
[1728]65    student_field2types = {   ###(
66                      'StudentApplication':
67                          {'id': 'application',
68                           'title': 'Application Data',
69                           'fields':
70                             ('jamb_reg_no',
71                              'entry_mode',
72                              'entry_level',
73                              'entry_session',
74                              'jamb_score',
75                              'email',
76                              'phone',
77                              )
78                              },
79                      'StudentPume':
80                          {'id': 'pume',
81                           'title': 'Pume Data',
82                           'fields':
83                             ('pume_score',
84                              )
85                              },
86                      'StudentClearance':
87                          {'id': 'clearance',
88                           'title': 'Clearance Data',
89                           'fields':
90                             ('matric_no',
91                              'entry_level',
92                              'entry_session',
93                              'nationality',
94                              'lga',
95                              )
96                              },
97                         'StudentPersonal':
98                          {'id': 'personal',
99                           'title': 'Personal Data',
100                           'fields':
101                             ('firstname',
102                              'middlename',
103                              'lastname',
104                              'sex',
105                              'email',
106                              'phone',
107                              )
108                              },
109                         'StudentStudyCourse':
110                          {'id': 'study_course',
111                           'title': 'Study Course',
112                           'fields':
113                             ('study_course',
114                              'current_level',
115                              'current_session',
116                              'current_verdict',
117                              )
118                              },
119                         }
120    ###)
121
[1707]122    def rwrite(self,s):
123        response = self.REQUEST.RESPONSE
124        response.setHeader('Content-type','text/html; charset=ISO-8859-15')
125        response.write("%s<br />\r\n" % s)
[1174]126
[1720]127    security.declareProtected(ModifyPortalContent,'openLog')
[1716]128    def openLog(self,name):
129        """open a log file"""
130        version = 1
131        path = "%s/log/%s_%d.log" % (i_home,name,version)
132        while os.path.exists(path):
133            version += 1
134            path = "%s/log/%s_%d.log" % (i_home,name,version)
135        log = open(path,"w")
136        return log
137
[1720]138    security.declareProtected(ModifyPortalContent,'writeLog')
[1716]139    def writeLog(self,logfile,s):
140        """write to the log file"""
141        logfile.write(s)
142
[1720]143
[1151]144    def generateStudentId(self,letter): ###(
145        import random
146        r = random
[1194]147        ##if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
148        if letter == '?':
[1151]149            letter= r.choice('ABCDEFGHKLMNPQRSTUVWXY')
150        sid = "%c%d" % (letter,r.randint(99999,1000000))
[1720]151        students = self.portal_url.getPortalObject().campus.students
[1721]152##        while hasattr(students, sid):
153##            sid = "%c%d" % (letter,r.randint(99999,1000000))
154        while self.students_catalog(id = sid):
[1720]155            sid = "%c%d" % (letter,r.randint(99999,1000000))
[1151]156        return sid
[1460]157    ###)
[1415]158
159    def generatePassword(self,s=None): ###(
160        import random
161        r = random
162        ##if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
163        if s is None:
164            s = 'abcdefghklmnpqrstuvwxy23456789'
165        pw = ''
166        while len(pw) < 6:
167            pw += r.choice(s)
168        return pw
[1151]169    ###)
[828]170
[1261]171    security.declareProtected(ModifyPortalContent,'getCredential') ###(
[1250]172    def getCredential(self,student_id):
173        "return a student password"
174        student_entry = getattr(self.portal_directories.students,student_id,None)
175        if student_entry is None:
176            return None
[1263]177        return getattr(student_entry,"password","not set")
[1261]178    ###)
[1250]179
[1460]180    security.declarePublic('checkPassword') ###(
[1467]181    def checkPassword(self,student_id,password):
[1460]182        "return a student password"
183        student_entry = getattr(self.portal_directories.students,student_id,None)
184        if student_entry is None:
185            return False
186        return getattr(student_entry,"password","not set") == password
187    ###)
188
[1467]189    security.declarePublic('editPassword') ###(
190    def editPassword(self,student_id,password):
191        "edit a student password"
192        student_entry = getattr(self.portal_directories.students,student_id,None)
193        if student_entry is None:
[1571]194            return
[1467]195        setattr(student_entry,'password',password)
196    ###)
197
[1647]198    security.declareProtected(View,'doCommit') ###(
[1401]199    def doCommit(self,logger=None):
200        "commit some transactions"
201        transaction.commit()
202    ###)
203
[1285]204    security.declarePublic('loadStudentFoto') ###(
205    def loadStudentFoto(self,student):
206        "return a student passport picture"
207        app_doc = student.application.getContent()
208        clear = student.clearance
209        clear_doc = clear.getContent()
210        matric_no = clear_doc.matric_no.upper()
[1286]211        picture1 ="%s/import/pictures_returning/%s.jpg" % (i_home,matric_no)
212        picture2 ="%s/import/pictures_returning/%s.JPG" % (i_home,matric_no)
[1285]213        #import pdb;pdb.set_trace()
[1286]214        if os.path.exists(picture1):
215            file = open(picture1)
216        elif os.path.exists(picture2):
[1287]217            file = open(picture2)
[1286]218        else:
[1287]219            return "passport picture not found %s" % picture1
[1286]220
[1285]221        outfile = file.read()
222        app_doc.manage_addFile('passport',
223                               file=outfile,
224                               title="%s.jpg" % matric_no)
[1286]225        return "successfully loaded passport picture"
[1285]226    ###)
227
[1170]228    security.declareProtected(ModifyPortalContent,'createOne') ###(
[1194]229    def createOne(self,students_folder,student_brain,letter,commit=False):
230        sid = self.waeup_tool.generateStudentId(letter)
[1170]231        students_folder.invokeFactory('Student', sid)
232        student = getattr(students_folder,sid)
233        self.portal_workflow.doActionFor(student,'return')
234        student.manage_setLocalRoles(sid, ['Owner',])
235        matric_no = student_brain.matric_no
236        jamb_reg_no = student_brain.Entryregno
237        self.students_catalog.addRecord(id = sid,
238                                           matric_no = matric_no,
239                                           jamb_reg_no = jamb_reg_no,
240                                           sex = student_brain.Sex == "F",
241                                           name = "%s %s %s" % (student_brain.Firstname,
242                                                                student_brain.Middlename,
243                                                                student_brain.Lastname)
244                                        )
245        if commit:
246            transaction.commit()
247        return sid,jamb_reg_no
248    ###)
249
[1415]250    security.declareProtected(ModifyPortalContent,'createStudent') ###(
251    def createStudent(self,dict):
252        students_folder = self.portal_url.getPortalObject().campus.students
253        sid = self.waeup_tool.generateStudentId('?')
254        students_folder.invokeFactory('Student', sid)
255        student_obj = getattr(students_folder,sid)
256        password = self.generatePassword()
257        self.makeStudentMember(sid,password)
[1728]258        f2t = self.student_field2types
259        for pt in f2t.keys():
260            student_obj.invokeFactory(pt,f2t[pt]['id'])
261            sub_obj = getattr(student_obj,f2t[pt]['id'])
262            sub_doc = sub_obj.getContent()
263            self.portal_workflow.doActionFor(sub_obj,'open',dest_container=sub_obj)
264            d = {'Title': f2t[pt]['title']}
265            for field in f2t[pt]['fields']:
[1730]266                d[field] = dict.get(field,'')
[1728]267            if pt == 'StudentPersonal':
268                d['sex'] = dict.get('sex') == 'F'
269            sub_doc.edit(mapping = d)
270            self.portal_workflow.doActionFor(sub_obj,'close',dest_container=sub_obj)
271           
272        entry_session = dict.get('entry_session')
[1415]273        wfaction = 'return'
[1728]274        if entry_session == self.getSessionId():
[1415]275            wfaction = 'admit'
276        self.portal_workflow.doActionFor(student_obj,wfaction)
277        student_obj.manage_setLocalRoles(sid, ['Owner',])
[1728]278##        matric_no = dict.get('matric_no')
279##        email = dict.get('email')
280##        #level = dict.get('level')
281##        jamb_reg_no = dict.get('jamb_reg_no')
282##        study_course = dict.get('study_course')
283##        self.portal_workflow.doActionFor(student_obj,wfaction)
284##        student_obj.manage_setLocalRoles(sid, ['Owner',])
285##        student_obj.invokeFactory('StudentApplication','application')
286##        application = student_obj.application
287##        self.portal_workflow.doActionFor(application,'open',dest_container=application)
288##        da = {'Title': 'Application Data'}
289##        student_obj.invokeFactory('StudentPersonal','personal')
290##        da['entry_mode'] = entry_mode
291##        personal = student_obj.personal
292##        self.portal_workflow.doActionFor(personal,'open',dest_container=personal)
293##        dp = {'Title': 'Personal Data'}
294##        student_obj.invokeFactory('StudentClearance','clearance')
295##        clearance = student_obj.clearance
296##        self.portal_workflow.doActionFor(clearance,'open',dest_container=clearance)
297##        dc = {'Title': 'Clearance/Eligibility Record'}
298##        dc['matric_no'] = matric_no
299##        da['app_email'] = dp['email'] = email
300##        da['jamb_reg_no'] = jamb_reg_no
301##        dp['firstname'] = dict.get('firstname')
302##        dp['middlename'] = dict.get('middlename')
303##        dp['lastname'] = dict.get('lastname')
304##        da['jamb_lastname'] = "%(firstname)s %(middlename)s %(lastname)s" % dict
305##        sex = dict.get('sex')
306##        if sex:
307##            da['jamb_sex'] = 'F'
308##        else:
309##            da['jamb_sex'] = 'M'
310##        dp['sex'] = sex
311##        application.getContent().edit(mapping=da)
312##        self.portal_workflow.doActionFor(application,'close',dest_container=application)
313##        personal.getContent().edit(mapping=dp)
314##        clearance.getContent().edit(mapping=dc)
315##        self.portal_workflow.doActionFor(clearance,'close',dest_container=clearance)
316####        catd = {}
317####        catd['id'] = sid
318####        catd['entry_mode']= entry_mode
319####        catd['email'] = email
320####        catd['jamb_reg_no'] = jamb_reg_no
321####        catd['matric_no'] = matric_no
322####        catd['name'] = "%(firstname)s %(middlename)s %(lastname)s" % dp
323####        catd['sex'] = dp['sex']
324####        catd['level'] = level
325####        certificate_brain = self.getCertificateBrain(study_course)
326####        if certificate_brain:
327####            cpath = certificate_brain.getPath().split('/')
328####            catd['faculty'] = cpath[-4]
329####            catd['department'] = cpath[-3]
330####            catd['course'] = study_course
331####        self.students_catalog.addRecord(**catd)
332##        #
333##        # Study Course
334##        #
335##        student_obj.invokeFactory('StudentStudyCourse','study_course')
336##        sc = student_obj.study_course
337##        self.portal_workflow.doActionFor(sc,'open',dest_container=sc)
338##        dsc = {}
339##        dsc['study_course'] = study_course
340##        #dsc['current_level'] = level
341##        sc.getContent().edit(mapping=dsc)
342##
[1415]343        return sid,password
344    ###)
345
[1151]346    security.declarePublic('getCertificateBrain') ###(
347    def getCertificateBrain(self,cert_id):
348        "do it"
349        res = ZCatalog.searchResults(self.portal_catalog,
350                                {'portal_type':"Certificate",
351                                      'id': cert_id})
352        if res:
353            return res[0]
354        return None
355    ###)
[1160]356
[1151]357    security.declarePublic('findStudentByMatricelNo') ###(
358    def findStudentByMatricelNo(self,matric_no):
359        "do it"
360        res = ZCatalog.searchResults(self.portal_catalog,
361                                {'portal_type':"StudentClearance",
362                                 'SearchableText': matric_no})
363        if res:
364            return res[0]
365        return None
366    ###)
367
368    security.declarePublic('makeStudentMember') ###(
369    def makeStudentMember(self,sid,password='uNsEt'):
370        """make the student a member"""
371        membership = self.portal_membership
372        membership.addMember(sid,
373                             password ,
374                             roles=('Member',
375                                     'Student',
376                                     ),
377                             domains='',
378                             properties = {'memberareaCreationFlag': False,
379                                           'homeless': True},)
380        member = membership.getMemberById(sid)
381        self.portal_registration.afterAdd(member, sid, password, None)
[1261]382        #self.manage_setLocalRoles(sid, ['Owner',])
[1151]383    ###)
[1160]384
[1151]385    security.declarePublic('makeStudentData') ###(
[1158]386    def makeStudentData(self,student_id,email=None,phone_nr=None):
[1151]387        "create Datastructure for a returning Student"
[1406]388        #import pdb;pdb.set_trace()
[1571]389        logger = logging.getLogger('WAeUPTool.makeStudentData')
[1151]390        students_folder = self.portal_url.getPortalObject().campus.students
391        res = self.students_catalog(id=student_id)
392        if res:
393            st = res[0]
394        res = self.returning_import(matric_no = st.matric_no)
395        if res:
[1160]396            student = res[0]
[1580]397        logger.info('%s creates data structure' % student_id)
[1401]398        s_results = self.results_import(matric_no = st.matric_no)
399        lnr = self.getLevelFromResultsCosCode(s_results)
400        level = "%d00" % lnr
[1695]401        verdict,eligible = self.getVerdict(s_results[0].Verdict)
402        if eligible:
[1401]403            level = "%d00" % (lnr + 1)
404##        level = s_results[0].Level
405##        for result in s_results:
406##            if level != result.Level:
407##                logger.info('"%s", "Levels differ","%s != %s"' % (student_id,level,result.Level))
[1171]408        #student should not be allowed to perform this transition
[1174]409        #wftool = self.portal_workflow
410        #wftool.doActionFor(student,'return')
[1151]411        certcode_org = student.Coursemajorcode
412        certcode = makeCertificateCode(certcode_org)
413        certificate_brain = self.getCertificateBrain(certcode)
414        if not certificate_brain:
415            em = 'Certificate %s org-code %s not found\n' % (certcode, certcode_org)
416            logger.info(em)
417        matric_no = student.matric_no
418        sid = student_id
419        student_obj = getattr(students_folder,sid)
420        student_obj.invokeFactory('StudentApplication','application')
421        application = student_obj.application
[1169]422        self.portal_workflow.doActionFor(application,'open',dest_container=application)
[1151]423        da = {'Title': 'Application Data'}
424        student_obj.invokeFactory('StudentPersonal','personal')
425        da['jamb_reg_no'] = student.Entryregno
[1462]426        em = self.getEntryMode(student.Entryregno)
[1460]427##        em = student.Mode_of_Entry
428##        if em in ('DIRECT', 'DIRECT ENTRY',):
429##            em = 'DE'
430##        elif em in ('U.M.E', 'UNE',):
431##            em = 'UME'
432##        elif not em:
433##            em = "unknown"
[1401]434        da['entry_mode'] = em
[1151]435        personal = student_obj.personal
436        self.portal_workflow.doActionFor(personal,'open',dest_container=personal)
437        dp = {'Title': 'Personal Data'}
438        student_obj.invokeFactory('StudentClearance','clearance')
439        clearance = student_obj.clearance
[1169]440        self.portal_workflow.doActionFor(clearance,'open',dest_container=clearance)
[1151]441        dc = {'Title': 'Clearance/Eligibility Record'}
442        dc['matric_no'] = matric_no
443        state = student.State
444        lga = student.LGA
445        if state and lga:
446            lga =  state + ' / ' + lga
447        else:
448            lga = "None"
[1174]449        da['jamb_lga'] = dc['lga'] = lga
[1173]450        da['app_email'] = dp['email'] = email
451        da['app_mobile'] = dp['phone'] = phone_nr
[1411]452        dp['firstname'] = student.Firstname
453        dp['middlename'] = student.Middlename
454        dp['lastname'] = student.Lastname
455        da['jamb_lastname'] = "%s %s %s" % (student.Firstname,student.Middlename,student.Lastname)
[1174]456        da['jamb_sex'] = student.Sex
[1151]457        dp['sex'] = student.Sex == 'F'
458        dp['perm_address'] = student.Permanent_Address
459        application.getContent().edit(mapping=da)
[1169]460        self.portal_workflow.doActionFor(application,'close',dest_container=application)
[1151]461        personal.getContent().edit(mapping=dp)
462        clearance.getContent().edit(mapping=dc)
[1169]463        self.portal_workflow.doActionFor(clearance,'close',dest_container=clearance)
[1158]464        catd = {}
465        catd['id'] = sid
466        catd['entry_mode']= da['entry_mode']
467        catd['matric_no'] = matric_no
[1171]468        catd['jamb_reg_no'] = da['jamb_reg_no']
469        catd['name'] = "%(firstname)s %(middlename)s %(lastname)s" % dp
470        catd['sex'] = dp['sex']
471        catd['level'] = level
[1401]472        catd['verdict'] = verdict
[1158]473        if certificate_brain:
474            cpath = certificate_brain.getPath().split('/')
[1171]475            catd['faculty'] = cpath[-4]
476            catd['department'] = cpath[-3]
[1158]477            catd['course'] = certcode
478        self.students_catalog.modifyRecord(**catd)
[1151]479        #
480        # Study Course
481        #
482        student_obj.invokeFactory('StudentStudyCourse','study_course')
483        studycourse = student_obj.study_course
484        self.portal_workflow.doActionFor(studycourse,'open',dest_container=studycourse)
485        dsc = {}
486        dsc['study_course'] = certcode
[1401]487        dsc['current_level'] = level
488        dsc['current_verdict'] = verdict
[1151]489        studycourse.getContent().edit(mapping=dsc)
490        #
491        # Level
492        #
[1198]493##        l = getattr(studycourse,level,None)
494##        if l is None:
495##            studycourse.invokeFactory('StudentStudyLevel', level)
496##            l = getattr(studycourse, level)
497##            self.portal_workflow.doActionFor(l,'open',dest_container=l)
498##            l.getContent().edit(mapping={'Title': "Level %s" % level})
[1194]499###)
[1160]500
[1194]501    security.declarePublic('makeStudentLevel') ###(
502    def makeStudentLevel(self,student_id):
503        "create the StudyLevel for a returning Student"
504        #import pdb;pdb.set_trace()
[1571]505        logger = logging.getLogger('WAeUPTool.makeStudentLevel')
[1194]506        students_folder = self.portal_url.getPortalObject().campus.students
507        res = self.students_catalog(id=student_id)
508        if res:
509            st = res[0]
510        course = st.course
511        matric_no = st.matric_no
512        level = st.level
513        res = self.results_import(matric_no = matric_no)
514        if res:
515            results = res
[1571]516        logger.info('%s creating Level %s' % (student_id,level))
[1194]517        #
518        # Level
519        #
520        student_obj = getattr(self.portal_url.getPortalObject().campus.students,student_id)
521        studycourse = getattr(student_obj,"study_course",None)
522        self.portal_workflow.doActionFor(studycourse,'close_for_edit',dest_container=studycourse)
523        l = getattr(studycourse,level,None)
524        if l is None:
525            studycourse.invokeFactory('StudentStudyLevel', level)
526            l = getattr(studycourse, level)
527            self.portal_workflow.doActionFor(l,'open',dest_container=l)
528            l.getContent().edit(mapping={'Title': "Level %s" % level})
529        ###)
530
[1151]531    security.declarePublic('getAccommodationInfo') ###(
[828]532    def getAccommodationInfo(self,bed):
533        """return Accommodation Info"""
534        info = {}
535        hall,block,room,letter = bed.split('_')
536        res = ZCatalog.searchResults(self.portal_catalog,portal_type="AccoHall",id=hall)
537        if res and len(res) == 1:
538            hall_brain = res[0]
539            hall_doc = hall_brain.getObject().getContent()
540        else:
541            return info
542        info['hall_title'] = hall_brain.Title
543        info['maintenance_code'] = hall_doc.maintenance_code
544        res = ZCatalog.searchResults(self.portal_catalog,portal_type="ScratchCardBatch")
545        batch_doc = None
546        for brain in res:
547            if brain.id.startswith(info['maintenance_code']):
548                batch_doc = brain.getObject().getContent()
549                break
550        if batch_doc is None:
551            info['maintenance_fee'] = None
552        else:
553            info['maintenance_fee'] = batch_doc.cost
554        return info
[1151]555    ###)
[828]556
[1151]557    security.declareProtected(ModifyPortalContent,'deleteAllCourses') ###(
558    def deleteAllCourses(self,department="All"):
559        ''' delete the courses'''
560        pm = self.portal_membership
561        member = pm.getAuthenticatedMember()
[1160]562
[1151]563        if str(member) not in ("henrik","joachim"):
564            return "not possible"
565        if department == "All":
566            res = self.portal_catalog({'meta_type': 'Department'})
567        if len(res) < 1:
568            return "No Departments found"
[1160]569
[1151]570        deleted = []
571        for dep in res:
572            cf = dep.getObject().courses
573            if cf:
574                cf.manage_delObjects(ids=cf.objectIds())
575                deleted.append("deleted Courses in %s" % dep.getId)
576        return "\r".join(deleted)
[1160]577    ###)
[1151]578
[1572]579    security.declareProtected(ModifyPortalContent,'getLogfileLines') ###(
580    def getLogfileLines(self,filename="event.log",numlines=20):
581        """Get last NUMLINES lines of logfile FILENAME.
[1160]582
[1572]583        Return last lines' of a file in the instances logfile directory as
584        a list. The number of returned lines equals `numlines' or less. If
585        less than `numlines' lines are available, the whole file ist
586        returned. If the file can not be opened or some other error
587        occurs, empty list is returend.
588        """
589        result = []
590        lines_hit = 0
591
592        # We only handle files in instances' log directory...
593        logpath = os.path.join(i_home, "log")
594        filename = str(os.path.abspath( os.path.join( logpath, filename )))
595        if not filename.startswith( logpath ):
596            # Attempt to access file outside log-dir...
597            return []
598
599        try:
600            fd = file( filename, "rb" )
601        except IOError:
602            return []
603        if not fd:
604            return []
605
606        if os.linesep == None:
607            linesep = '\n'
608        else:
609            linesep = os.linesep
610
611        # Try to find 'numlines' times a lineseparator, searching from end
612        # and moving to the beginning of file...
613        fd.seek( 0, 2) # Move to end of file...
614        while lines_hit < numlines:
615            if fd.read(1) == linesep[-1]: # This moves filedescriptor
616                                          # one step forward...
617                lines_hit += 1
618            try:
619                fd.seek( -2, 1) # Go two bytes back from current pos...
620            except IOError:
621                # We cannot go back two bytes. Maybe the file is too small...
622                break
623        fd.seek(2,1)
624
625        # Read all lines from current position...
626        result = fd.readlines()
627        # Remove line endings...
628        result = [x.strip() for x in result]
629        fd.close()
630        return result
631    ###)
632
[1700]633    security.declareProtected(ModifyPortalContent,"getCallbacksFromLog")###(
[1665]634    def getCallbacksFromLog(self,filename):
635        """fix Online Payment Transactions from Z2.log entries"""
636        import transaction
637        import random
638        from cgi import parse_qs
639        from urlparse import urlparse
640        #from pdb import set_trace
641        wftool = self.portal_workflow
642        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
643        students_folder = self.portal_url.getPortalObject().campus.students
644        s = r'(?P<client_ip>\S+) - (?P<member_id>\S+) \['
645        s += r'(?P<date>.*)\] "(?P<get>.*)" (?P<codes>\d+ \d+) "'
646        s += r'(?P<intersw>.*)" "(?P<agent>.*)"'
647        data = re.compile(s)
648        start = True
649        tr_count = 1
650        total = 0
651        #name = 'pume_results'
652        #name = 'epaymentsuccessful_z2log2'
653        name = filename
654        no_import = []
655        imported = []
656        logger = logging.getLogger('WAeUPTool.getFailedTransactions')
657        try:
658            transactions = open("%s/import/%s" % (i_home,name),"rb").readlines()
659        except:
660            logger.error('Error reading %s' % name)
661            return
662        tas = []
663        for line in transactions:
664            dict = {}
665            items = data.search(line)
666            dict['idict'] = idict = items.groupdict()
667            #print idict
668            #from pdb import set_trace;set_trace()
669            urlparsed = urlparse(idict['get'][4:])
670            #print urlparsed
671            path = urlparsed[2].split('/')
672            dict['student_id'] = student_id = path[8]
673            dict['payment_id'] = payment_id = path[10]
674            dict['qs_dict'] = qs_dict = parse_qs(urlparsed[4])
675            tas.append(dict)
676            tr_count += 1
677        return tas
678    ###)
679
[1620]680    security.declareProtected(ModifyPortalContent,"importOnlinePaymentTransactions")###(
681    def importOnlinePaymentTransactions(self):
682        """load Online Payment Transactions from CSV values"""
683        import transaction
684        import random
685        #from pdb import set_trace
686        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
[1625]687        opt = self.online_payments_import
[1620]688        students_folder = self.portal_url.getPortalObject().campus.students
689        start = True
690        tr_count = 1
691        total = 0
692        #name = 'pume_results'
693        name = 'OnlineTransactions'
694        no_import = []
695        imported = []
696        logger = logging.getLogger('WAeUPTool.importOnlinePaymentTransactions')
697        try:
698            transactions = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
699        except:
700            logger.error('Error reading %s.csv' % name)
701            return
702        for pay_transaction in transactions:
703            if start:
704                start = False
705                logger.info('Start loading from %s.csv' % name)
706                s = ','.join(['"%s"' % fn for fn in pay_transaction.keys()])
707                no_import.append('%s,"Error"' % s)
708                format = ','.join(['"%%(%s)s"' % fn for fn in pay_transaction.keys()])
709                format_error = format + ',"%(Error)s"'
710            data = {}
[1644]711
[1643]712            # format of the first file sent from Tayo
713            #data['datetime'] = date = DateTime.DateTime(pay_transaction['Date'])
714            #data['student_id'] = student_id = pay_transaction['Payer ID']
715            #data['order_id'] = order_id = pay_transaction['Order ID (Tranx Ref)']
716            #data['response_code'] = response_code = pay_transaction['Resp Code']
717            #data['amount'] = amount = pay_transaction['Amount']
[1644]718
[1643]719            # format of the second file sent from Tayo
720            data['datetime'] = date = 0
[1625]721            data['student_id'] = student_id = pay_transaction['Payer ID']
722            data['order_id'] = order_id = pay_transaction['Order ID (Tranx Ref)']
[1644]723            data['response_code'] = response_code = '00'
724            data['amount'] = amount = pay_transaction['Amount']
725
[1620]726            dup = False
727            if response_code == "12":
728                continue
729            try:
730                opt.addRecord(**data)
731            except ValueError:
732                dup = True
733            #from pdb import set_trace;set_trace()
734            if dup:
735                if response_code == "00":
736                    opt.modifyRecord(**data)
737                else:
[1674]738                    pay_transaction['Error'] = "Duplicate order_id"
[1620]739                    no_import.append( format_error % pay_transaction)
[1674]740                    logger.info("duplicate order_id %(order_id)s for %(student_id)s %(response_code)s" % data)
[1620]741                    continue
742            tr_count += 1
743            if tr_count > 1000:
744                if len(no_import) > 0:
745                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
746                             '\n'.join(no_import) + '\n')
747                    no_import = []
[1645]748                em = '%d transactions committed\n' % (tr_count)
[1620]749                transaction.commit()
750                regs = []
751                logger.info(em)
752                total += tr_count
753                tr_count = 0
754        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
755                                                '\n'.join(no_import))
756        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
757    ###)
758
[1730]759    security.declareProtected(ModifyPortalContent,"importData")###(
760    def importData(self,name):
761        """load data from CSV values"""
762        import transaction
763        import random
764        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
765        students_folder = self.portal_url.getPortalObject().campus.students
766        start = True
767        tr_count = 1
768        total = 0
769        from pdb import set_trace;set_trace()
770        iname = "import_%s" % name
771        schema = getattr(self.portal_schemas,iname ,None)
772        if schema is None:
773            logger.error('No such schema %s' % iname)
774            return
775        layout = getattr(self.portal_layouts,iname,None)
776        if layout is None:
777            logger.error('No such layout %s' % iname)
778            return
779        validators = {}
780        for widget in layout.keys():
781            validators[widget] = layout[widget].validate 
782        no_import = []
783        imported = []
784        logger = logging.getLogger('WAeUPTool.importData')
785        try:
786            items = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
787        except:
788            logger.error('Error reading %s.csv' % name)
789            return
790        for item in items:
791            tr_count += 1
792            if start:
793                start = False
794                logger.info('Start importing from %s.csv' % name)
795                import_keys = item.keys()
796                diff_set = set(import_keys).difference(set(schema.keys()))
797                if diff_set:
798                    logger.error('%s not in schema.' % diff_set)
799                    return
800                diff_set = set(import_keys).difference(set(layout.keys()))
801                if diff_set:
802                    logger.error('%s not in layout.' % diff_set)
803                    return
804                s = ','.join(['"%s"' % fn for fn in import_keys])
805                imported.append(s)
806                no_import.append('%s,"Error"' % s)
807                format = ','.join(['"%%(%s)s"' % fn for fn in import_keys])
808                format_error = format + ',"%(Error)s"'
809            for k in import_keys:
810                if validators[k](item):
811                    pass
812            if tr_count > 1000:
813                if len(no_import) > 0:
814                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
815                             '\n'.join(no_import) + '\n')
816                    no_import = []
817                em = '%d transactions committed\n' % (tr_count)
818                transaction.commit()
819                regs = []
820                logger.info(em)
821                total += tr_count
822                tr_count = 0
823        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
824                                                '\n'.join(no_import))
825        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
826    ###)
827
[828]828InitializeClass(WAeUPTool)
Note: See TracBrowser for help on using the repository browser.