source: WAeUP_SRP/branches/joachim-event-branch/WAeUPTool.py @ 1653

Last change on this file since 1653 was 1596, checked in by joachim, 18 years ago

merged changes from trunk to joachim-event-branch

  • Property svn:keywords set to Id
File size: 20.9 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 1596 2007-03-19 21:45:44Z 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
40import logging,os
[1170]41import transaction
[197]42
[1151]43
[1171]44
45
[828]46class WAeUPTool(UniqueObject, SimpleItem, ActionProviderBase):
[197]47    """WAeUP tool"""
48
[828]49    id = 'waeup_tool'
[197]50    meta_type = 'WAeUP Tool'
[828]51    _actions = ()
[197]52
53    security = ClassSecurityInfo()
[828]54    security.declareObjectProtected(View)
[197]55
[828]56    manage_options = ( ActionProviderBase.manage_options
57                     + SimpleItem.manage_options
58                     )
59
[1174]60
[1151]61    def generateStudentId(self,letter): ###(
62        import random
63        r = random
[1194]64        ##if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
65        if letter == '?':
[1151]66            letter= r.choice('ABCDEFGHKLMNPQRSTUVWXY')
67        sid = "%c%d" % (letter,r.randint(99999,1000000))
[1194]68##        students = self.portal_url.getPortalObject().campus.students
69##        while hasattr(students, sid):
70##            sid = "%c%d" % (letter,r.randint(99999,1000000))
71        while self.students_catalog(id = sid):
[1151]72            sid = "%c%d" % (letter,r.randint(99999,1000000))
73        return sid
[1460]74    ###)
[1415]75
76    def generatePassword(self,s=None): ###(
77        import random
78        r = random
79        ##if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
80        if s is None:
81            s = 'abcdefghklmnpqrstuvwxy23456789'
82        pw = ''
83        while len(pw) < 6:
84            pw += r.choice(s)
85        return pw
[1151]86    ###)
[828]87
[1261]88    security.declareProtected(ModifyPortalContent,'getCredential') ###(
[1250]89    def getCredential(self,student_id):
90        "return a student password"
91        student_entry = getattr(self.portal_directories.students,student_id,None)
92        if student_entry is None:
93            return None
[1263]94        return getattr(student_entry,"password","not set")
[1261]95    ###)
[1250]96
[1460]97    security.declarePublic('checkPassword') ###(
[1467]98    def checkPassword(self,student_id,password):
[1460]99        "return a student password"
100        student_entry = getattr(self.portal_directories.students,student_id,None)
101        if student_entry is None:
102            return False
103        return getattr(student_entry,"password","not set") == password
104    ###)
105
[1467]106    security.declarePublic('editPassword') ###(
107    def editPassword(self,student_id,password):
108        "edit a student password"
109        student_entry = getattr(self.portal_directories.students,student_id,None)
110        if student_entry is None:
[1596]111            return
[1467]112        setattr(student_entry,'password',password)
113    ###)
114
[1401]115    security.declareProtected(ModifyPortalContent,'doCommit') ###(
116    def doCommit(self,logger=None):
117        "commit some transactions"
118        transaction.commit()
119    ###)
120
[1285]121    security.declarePublic('loadStudentFoto') ###(
122    def loadStudentFoto(self,student):
123        "return a student passport picture"
124        app_doc = student.application.getContent()
125        clear = student.clearance
126        clear_doc = clear.getContent()
127        matric_no = clear_doc.matric_no.upper()
[1286]128        picture1 ="%s/import/pictures_returning/%s.jpg" % (i_home,matric_no)
129        picture2 ="%s/import/pictures_returning/%s.JPG" % (i_home,matric_no)
[1285]130        #import pdb;pdb.set_trace()
[1286]131        if os.path.exists(picture1):
132            file = open(picture1)
133        elif os.path.exists(picture2):
[1287]134            file = open(picture2)
[1286]135        else:
[1287]136            return "passport picture not found %s" % picture1
[1286]137
[1285]138        outfile = file.read()
139        app_doc.manage_addFile('passport',
140                               file=outfile,
141                               title="%s.jpg" % matric_no)
[1286]142        return "successfully loaded passport picture"
[1285]143    ###)
144
[1170]145    security.declareProtected(ModifyPortalContent,'createOne') ###(
[1194]146    def createOne(self,students_folder,student_brain,letter,commit=False):
147        sid = self.waeup_tool.generateStudentId(letter)
[1170]148        students_folder.invokeFactory('Student', sid)
149        student = getattr(students_folder,sid)
150        self.portal_workflow.doActionFor(student,'return')
151        student.manage_setLocalRoles(sid, ['Owner',])
152        matric_no = student_brain.matric_no
153        jamb_reg_no = student_brain.Entryregno
154        self.students_catalog.addRecord(id = sid,
155                                           matric_no = matric_no,
156                                           jamb_reg_no = jamb_reg_no,
157                                           sex = student_brain.Sex == "F",
158                                           name = "%s %s %s" % (student_brain.Firstname,
159                                                                student_brain.Middlename,
160                                                                student_brain.Lastname)
161                                        )
162        if commit:
163            transaction.commit()
164        return sid,jamb_reg_no
165    ###)
166
[1415]167    security.declareProtected(ModifyPortalContent,'createStudent') ###(
168    def createStudent(self,dict):
169        students_folder = self.portal_url.getPortalObject().campus.students
170        sid = self.waeup_tool.generateStudentId('?')
171        students_folder.invokeFactory('Student', sid)
172        student_obj = getattr(students_folder,sid)
173        password = self.generatePassword()
174        self.makeStudentMember(sid,password)
175        status,entry_mode = dict.get('entry_mode').split('_')
176        wfaction = 'return'
177        if status == "NEW":
178            wfaction = 'admit'
179        matric_no = dict.get('matric_no')
180        email = dict.get('email')
181        level = dict.get('level')
[1426]182        jamb_reg_no = dict.get('jamb_reg_no')
[1415]183        study_course = dict.get('study_course')
184        self.portal_workflow.doActionFor(student_obj,wfaction)
185        student_obj.manage_setLocalRoles(sid, ['Owner',])
186        student_obj.invokeFactory('StudentApplication','application')
187        application = student_obj.application
188        self.portal_workflow.doActionFor(application,'open',dest_container=application)
189        da = {'Title': 'Application Data'}
190        student_obj.invokeFactory('StudentPersonal','personal')
191        da['entry_mode'] = entry_mode
192        personal = student_obj.personal
193        self.portal_workflow.doActionFor(personal,'open',dest_container=personal)
194        dp = {'Title': 'Personal Data'}
195        student_obj.invokeFactory('StudentClearance','clearance')
196        clearance = student_obj.clearance
197        self.portal_workflow.doActionFor(clearance,'open',dest_container=clearance)
198        dc = {'Title': 'Clearance/Eligibility Record'}
199        dc['matric_no'] = matric_no
200        da['app_email'] = dp['email'] = email
[1426]201        da['jamb_reg_no'] = jamb_reg_no
[1415]202        dp['firstname'] = dict.get('firstname')
203        dp['middlename'] = dict.get('middlename')
204        dp['lastname'] = dict.get('lastname')
205        da['jamb_lastname'] = "%(firstname)s %(middlename)s %(lastname)s" % dict
206        sex = dict.get('sex')
207        if sex:
208            da['jamb_sex'] = 'F'
209        else:
210            da['jamb_sex'] = 'M'
211        dp['sex'] = sex
212        application.getContent().edit(mapping=da)
213        self.portal_workflow.doActionFor(application,'close',dest_container=application)
214        personal.getContent().edit(mapping=dp)
215        clearance.getContent().edit(mapping=dc)
216        self.portal_workflow.doActionFor(clearance,'close',dest_container=clearance)
217        catd = {}
218        catd['id'] = sid
219        catd['entry_mode']= entry_mode
220        catd['email'] = email
[1426]221        catd['jamb_reg_no'] = jamb_reg_no
[1415]222        catd['matric_no'] = matric_no
223        catd['name'] = "%(firstname)s %(middlename)s %(lastname)s" % dp
224        catd['sex'] = dp['sex']
225        catd['level'] = level
226        certificate_brain = self.getCertificateBrain(study_course)
227        if certificate_brain:
228            cpath = certificate_brain.getPath().split('/')
229            catd['faculty'] = cpath[-4]
230            catd['department'] = cpath[-3]
231            catd['course'] = study_course
232        self.students_catalog.addRecord(**catd)
233        #
234        # Study Course
235        #
236        student_obj.invokeFactory('StudentStudyCourse','study_course')
237        sc = student_obj.study_course
238        self.portal_workflow.doActionFor(sc,'open',dest_container=sc)
239        dsc = {}
240        dsc['study_course'] = study_course
241        dsc['current_level'] = level
242        sc.getContent().edit(mapping=dsc)
243
244        return sid,password
245    ###)
246
[1151]247    security.declarePublic('getCertificateBrain') ###(
248    def getCertificateBrain(self,cert_id):
249        "do it"
250        res = ZCatalog.searchResults(self.portal_catalog,
251                                {'portal_type':"Certificate",
252                                      'id': cert_id})
253        if res:
254            return res[0]
255        return None
256    ###)
[1160]257
[1151]258    security.declarePublic('findStudentByMatricelNo') ###(
259    def findStudentByMatricelNo(self,matric_no):
260        "do it"
261        res = ZCatalog.searchResults(self.portal_catalog,
262                                {'portal_type':"StudentClearance",
263                                 'SearchableText': matric_no})
264        if res:
265            return res[0]
266        return None
267    ###)
268
269    security.declarePublic('makeStudentMember') ###(
270    def makeStudentMember(self,sid,password='uNsEt'):
271        """make the student a member"""
272        membership = self.portal_membership
273        membership.addMember(sid,
274                             password ,
275                             roles=('Member',
276                                     'Student',
277                                     ),
278                             domains='',
279                             properties = {'memberareaCreationFlag': False,
280                                           'homeless': True},)
281        member = membership.getMemberById(sid)
282        self.portal_registration.afterAdd(member, sid, password, None)
[1261]283        #self.manage_setLocalRoles(sid, ['Owner',])
[1151]284    ###)
[1160]285
[1151]286    security.declarePublic('makeStudentData') ###(
[1158]287    def makeStudentData(self,student_id,email=None,phone_nr=None):
[1151]288        "create Datastructure for a returning Student"
[1406]289        #import pdb;pdb.set_trace()
[1596]290        logger = logging.getLogger('WAeUPTool.makeStudentData')
[1151]291        students_folder = self.portal_url.getPortalObject().campus.students
292        res = self.students_catalog(id=student_id)
293        if res:
294            st = res[0]
295        res = self.returning_import(matric_no = st.matric_no)
296        if res:
[1160]297            student = res[0]
[1596]298        logger.info('%s creates data structure' % student_id)
[1401]299        s_results = self.results_import(matric_no = st.matric_no)
300        lnr = self.getLevelFromResultsCosCode(s_results)
301        level = "%d00" % lnr
302        verdict,elegible = self.getVerdict(s_results[0].Verdict)
303        if elegible:
304            level = "%d00" % (lnr + 1)
305##        level = s_results[0].Level
306##        for result in s_results:
307##            if level != result.Level:
308##                logger.info('"%s", "Levels differ","%s != %s"' % (student_id,level,result.Level))
[1171]309        #student should not be allowed to perform this transition
[1174]310        #wftool = self.portal_workflow
311        #wftool.doActionFor(student,'return')
[1151]312        certcode_org = student.Coursemajorcode
313        certcode = makeCertificateCode(certcode_org)
314        certificate_brain = self.getCertificateBrain(certcode)
315        if not certificate_brain:
316            em = 'Certificate %s org-code %s not found\n' % (certcode, certcode_org)
317            logger.info(em)
318        matric_no = student.matric_no
319        sid = student_id
320        student_obj = getattr(students_folder,sid)
321        student_obj.invokeFactory('StudentApplication','application')
322        application = student_obj.application
[1169]323        self.portal_workflow.doActionFor(application,'open',dest_container=application)
[1151]324        da = {'Title': 'Application Data'}
325        student_obj.invokeFactory('StudentPersonal','personal')
326        da['jamb_reg_no'] = student.Entryregno
[1462]327        em = self.getEntryMode(student.Entryregno)
[1460]328##        em = student.Mode_of_Entry
329##        if em in ('DIRECT', 'DIRECT ENTRY',):
330##            em = 'DE'
331##        elif em in ('U.M.E', 'UNE',):
332##            em = 'UME'
333##        elif not em:
334##            em = "unknown"
[1401]335        da['entry_mode'] = em
[1151]336        personal = student_obj.personal
337        self.portal_workflow.doActionFor(personal,'open',dest_container=personal)
338        dp = {'Title': 'Personal Data'}
339        student_obj.invokeFactory('StudentClearance','clearance')
340        clearance = student_obj.clearance
[1169]341        self.portal_workflow.doActionFor(clearance,'open',dest_container=clearance)
[1151]342        dc = {'Title': 'Clearance/Eligibility Record'}
343        dc['matric_no'] = matric_no
344        state = student.State
345        lga = student.LGA
346        if state and lga:
347            lga =  state + ' / ' + lga
348        else:
349            lga = "None"
[1174]350        da['jamb_lga'] = dc['lga'] = lga
[1173]351        da['app_email'] = dp['email'] = email
352        da['app_mobile'] = dp['phone'] = phone_nr
[1411]353        dp['firstname'] = student.Firstname
354        dp['middlename'] = student.Middlename
355        dp['lastname'] = student.Lastname
356        da['jamb_lastname'] = "%s %s %s" % (student.Firstname,student.Middlename,student.Lastname)
[1174]357        da['jamb_sex'] = student.Sex
[1151]358        dp['sex'] = student.Sex == 'F'
359        dp['perm_address'] = student.Permanent_Address
360        application.getContent().edit(mapping=da)
[1169]361        self.portal_workflow.doActionFor(application,'close',dest_container=application)
[1151]362        personal.getContent().edit(mapping=dp)
363        clearance.getContent().edit(mapping=dc)
[1169]364        self.portal_workflow.doActionFor(clearance,'close',dest_container=clearance)
[1158]365        catd = {}
366        catd['id'] = sid
367        catd['entry_mode']= da['entry_mode']
368        catd['matric_no'] = matric_no
[1171]369        catd['jamb_reg_no'] = da['jamb_reg_no']
370        catd['name'] = "%(firstname)s %(middlename)s %(lastname)s" % dp
371        catd['sex'] = dp['sex']
372        catd['level'] = level
[1401]373        catd['verdict'] = verdict
[1158]374        if certificate_brain:
375            cpath = certificate_brain.getPath().split('/')
[1171]376            catd['faculty'] = cpath[-4]
377            catd['department'] = cpath[-3]
[1158]378            catd['course'] = certcode
379        self.students_catalog.modifyRecord(**catd)
[1151]380        #
381        # Study Course
382        #
383        student_obj.invokeFactory('StudentStudyCourse','study_course')
384        studycourse = student_obj.study_course
385        self.portal_workflow.doActionFor(studycourse,'open',dest_container=studycourse)
386        dsc = {}
387        dsc['study_course'] = certcode
[1401]388        dsc['current_level'] = level
389        dsc['current_verdict'] = verdict
[1151]390        studycourse.getContent().edit(mapping=dsc)
391        #
392        # Level
393        #
[1198]394##        l = getattr(studycourse,level,None)
395##        if l is None:
396##            studycourse.invokeFactory('StudentStudyLevel', level)
397##            l = getattr(studycourse, level)
398##            self.portal_workflow.doActionFor(l,'open',dest_container=l)
399##            l.getContent().edit(mapping={'Title': "Level %s" % level})
[1194]400###)
[1160]401
[1194]402    security.declarePublic('makeStudentLevel') ###(
403    def makeStudentLevel(self,student_id):
404        "create the StudyLevel for a returning Student"
405        #import pdb;pdb.set_trace()
[1596]406        logger = logging.getLogger('WAeUPTool.makeStudentLevel')
[1194]407        students_folder = self.portal_url.getPortalObject().campus.students
408        res = self.students_catalog(id=student_id)
409        if res:
410            st = res[0]
411        course = st.course
412        matric_no = st.matric_no
413        level = st.level
414        res = self.results_import(matric_no = matric_no)
415        if res:
416            results = res
[1596]417        logger.info('%s creating Level %s' % (student_id,level))
[1194]418        #
419        # Level
420        #
421        student_obj = getattr(self.portal_url.getPortalObject().campus.students,student_id)
422        studycourse = getattr(student_obj,"study_course",None)
423        self.portal_workflow.doActionFor(studycourse,'close_for_edit',dest_container=studycourse)
424        l = getattr(studycourse,level,None)
425        if l is None:
426            studycourse.invokeFactory('StudentStudyLevel', level)
427            l = getattr(studycourse, level)
428            self.portal_workflow.doActionFor(l,'open',dest_container=l)
429            l.getContent().edit(mapping={'Title': "Level %s" % level})
430        ###)
431
[1151]432    security.declarePublic('getAccommodationInfo') ###(
[828]433    def getAccommodationInfo(self,bed):
434        """return Accommodation Info"""
435        info = {}
436        hall,block,room,letter = bed.split('_')
437        res = ZCatalog.searchResults(self.portal_catalog,portal_type="AccoHall",id=hall)
438        if res and len(res) == 1:
439            hall_brain = res[0]
440            hall_doc = hall_brain.getObject().getContent()
441        else:
442            return info
443        info['hall_title'] = hall_brain.Title
444        info['maintenance_code'] = hall_doc.maintenance_code
445        res = ZCatalog.searchResults(self.portal_catalog,portal_type="ScratchCardBatch")
446        batch_doc = None
447        for brain in res:
448            if brain.id.startswith(info['maintenance_code']):
449                batch_doc = brain.getObject().getContent()
450                break
451        if batch_doc is None:
452            info['maintenance_fee'] = None
453        else:
454            info['maintenance_fee'] = batch_doc.cost
455        return info
[1151]456    ###)
[828]457
[1151]458    security.declareProtected(ModifyPortalContent,'deleteAllCourses') ###(
459    def deleteAllCourses(self,department="All"):
460        ''' delete the courses'''
461        pm = self.portal_membership
462        member = pm.getAuthenticatedMember()
[1160]463
[1151]464        if str(member) not in ("henrik","joachim"):
465            return "not possible"
466        if department == "All":
467            res = self.portal_catalog({'meta_type': 'Department'})
468        if len(res) < 1:
469            return "No Departments found"
[1160]470
[1151]471        deleted = []
472        for dep in res:
473            cf = dep.getObject().courses
474            if cf:
475                cf.manage_delObjects(ids=cf.objectIds())
476                deleted.append("deleted Courses in %s" % dep.getId)
477        return "\r".join(deleted)
[1160]478    ###)
[1151]479
[1596]480    security.declareProtected(ModifyPortalContent,'getLogfileLines') ###(
481    def getLogfileLines(self,filename="event.log",numlines=20):
482        """Get last NUMLINES lines of logfile FILENAME.
[1160]483
[1596]484        Return last lines' of a file in the instances logfile directory as
485        a list. The number of returned lines equals `numlines' or less. If
486        less than `numlines' lines are available, the whole file ist
487        returned. If the file can not be opened or some other error
488        occurs, empty list is returend.
489        """
490        result = []
491        lines_hit = 0
492
493        # We only handle files in instances' log directory...
494        logpath = os.path.join(i_home, "log")
495        filename = str(os.path.abspath( os.path.join( logpath, filename )))
496        if not filename.startswith( logpath ):
497            # Attempt to access file outside log-dir...
498            return []
499
500        try:
501            fd = file( filename, "rb" )
502        except IOError:
503            return []
504        if not fd:
505            return []
506
507        if os.linesep == None:
508            linesep = '\n'
509        else:
510            linesep = os.linesep
511
512        # Try to find 'numlines' times a lineseparator, searching from end
513        # and moving to the beginning of file...
514        fd.seek( 0, 2) # Move to end of file...
515        while lines_hit < numlines:
516            if fd.read(1) == linesep[-1]: # This moves filedescriptor
517                                          # one step forward...
518                lines_hit += 1
519            try:
520                fd.seek( -2, 1) # Go two bytes back from current pos...
521            except IOError:
522                # We cannot go back two bytes. Maybe the file is too small...
523                break
524        fd.seek(2,1)
525
526        # Read all lines from current position...
527        result = fd.readlines()
528        # Remove line endings...
529        result = [x.strip() for x in result]
530        fd.close()
531        return result
532    ###)
533
[828]534InitializeClass(WAeUPTool)
Note: See TracBrowser for help on using the repository browser.