source: WAeUP_SRP/base/WAeUPTool.py @ 2259

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

new feature bypass catalog_queue

  • Property svn:keywords set to Id
File size: 53.1 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 2259 2007-09-19 15:23:58Z joachim $
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
29
30from Products.CMFCore.utils import getToolByName
31from Products.CPSSchemas.DataStructure import DataStructure
32from Products.CPSSchemas.DataModel import DataModel
33from Products.CPSSchemas.StorageAdapter import MappingStorageAdapter
34from Products.CMFCore.ActionProviderBase import ActionProviderBase
35from Products.CMFCore.permissions import View
36from Products.ZCatalog.ZCatalog import ZCatalog
37from Products.CMFCore.permissions import ModifyPortalContent
38from Products.CMFCore.permissions import ManagePortal
39from Products.CMFCore.utils import UniqueObject
40from Products.CMFCore.URLTool import URLTool
41from Products.CMFCore.utils import getToolByName
42from Students import makeCertificateCode
43from Globals import package_home,INSTANCE_HOME
44p_home = package_home(globals())
45i_home = INSTANCE_HOME
46import DateTime,time
47import logging
48import transaction
49import csv,re,os,sys
50from Products.AdvancedQuery import Eq, Between, Le,In
51
52def getObject(object,name):
53    if object.hasObject(name):
54        return getattr(object,name)
55    return None
56
57class WAeUPTool(UniqueObject, SimpleItem, ActionProviderBase):
58    """WAeUP tool"""
59
60    id = 'waeup_tool'
61    meta_type = 'WAeUP Tool'
62    _actions = ()
63
64    security = ClassSecurityInfo()
65    security.declareObjectProtected(View)
66
67    manage_options = ( ActionProviderBase.manage_options
68                     + SimpleItem.manage_options
69                     )
70
71    def rwrite(self,s): ###(
72        response = self.REQUEST.RESPONSE
73        response.setHeader('Content-type','text/html; charset=ISO-8859-15')
74        response.write("%s<br />\r\n" % s)
75    ###)
76
77    def sleep(self,secs): ###(
78        "sleep"
79        import time
80        time.sleep(secs)
81        return
82
83###)
84
85    security.declareProtected(ModifyPortalContent,'openLog') ###(
86    def openLog(self,name):
87        """open a log file"""
88        version = 1
89        path = "%s/log/%s_%d.log" % (i_home,name,version)
90        while os.path.exists(path):
91            version += 1
92            path = "%s/log/%s_%d.log" % (i_home,name,version)
93        log = open(path,"w")
94        return log
95    ###)
96
97    security.declareProtected(ModifyPortalContent,'bypassQueueCatalog') ###(
98    def bypassQueueCatalog(self,enable=True):
99        """bypass the QueueCatalog by setting all indexes to process imediate,
100        if enable is True (default) the old settings are restored
101        """
102
103    ###)
104
105    security.declareProtected(ModifyPortalContent,'measureOaT') ###(
106    def measureOaT(self,method="a",probe="1000",nr_pts="1"):
107        """measure Object access Time"""
108        import random
109        if hasattr(self,'portal_catalog_real'):
110            aq_portal = self.portal_catalog_real.evalAdvancedQuery
111        else:
112            aq_portal = self.portal_catalog.evalAdvancedQuery
113        nr_pts = int(nr_pts)
114        probe = int(probe)
115        intervall = probe/10
116        objects = ("application","clearance","personal")
117        portal_types = ("StudentApplication","StudentClearance","StudentPersonal")
118        #i = random.randrange(num_objects)
119        count = 0
120        found = 0
121        not_found = 0
122        t_found = 0
123        t_not_found = 0
124        time_found = time_not_found = 0.0
125        t_time_found = t_time_not_found = 0.0
126        accessed = []
127        t_min = 1000
128        t_max = 0
129        #import pdb;pdb.set_trace()
130        students = self.portal_catalog(portal_type="Student")
131        num_students = len(students)
132        if method == "d":
133            query = Eq('path','/uniben/campus/students') & In('portal_type',portal_types[:nr_pts])
134            res = aq_portal(query)
135            brains = {}
136            for r in res:
137                sid = r.relative_path.split('/')[-2]
138                if brains.has_key(sid):
139                    brains[sid][r.portal_type] = r
140                else:
141                    brains[sid] = {r.portal_type : r}
142            brains_list = brains.keys()
143            num_objects = len(brains_list)
144        else:
145            num_objects = num_students
146        print "="*40
147        print "method: %s probes: %d nr_pts: %d num_objects: %d" % (method,
148                                                                        probe,
149                                                                        nr_pts,
150                                                                        num_objects)
151        print "nr found/not time found/not min/max"
152        elapse = time.time()
153        i_elapse = time.time()
154        c_elapse = time.clock()
155        for c in range(1,probe + 1):
156            i = random.randrange(num_objects)
157            if method in ('a','b','c'):
158                student_brain = students[i]
159            elif method == "d":
160                #import pdb;pdb.set_trace()
161                student_brain = brains[brains_list[i]]
162            if method == "c":
163                query = Eq('path',student_brain.getPath()) & In('portal_type',portal_types[:nr_pts])
164                res = aq_portal(query)
165                this_portal_types = [r.portal_type for r in res]
166            for i in range(nr_pts):
167                oid = objects[i]
168                if method == "a":
169                    try:
170                        student_path = student_brain.getPath()
171                        path = "%s/%s" % (student_path,oid)
172                        doc = self.unrestrictedTraverse(path).getContent()
173                        found += 1
174                        i_time = time.time() - i_elapse
175                        time_found += i_time
176                    except:
177                        not_found += 1
178                        i_time = time.time() - i_elapse
179                        time_not_found += i_time
180                        pass
181                elif method == "b":
182                    try:
183                        student_object = student_brain.getObject()
184                        doc = getattr(student_object,oid).getContent()
185                        found += 1
186                        i_time = time.time() - i_elapse
187                        time_found += i_time
188                    except:
189                        i_time = time.time() - i_elapse
190                        time_not_found += i_time
191                        not_found += 1
192                        pass
193                elif method == "c":
194                    if portal_types[i] in this_portal_types:
195                        found += 1
196                        doc = res[this_portal_types.index(portal_types[i])].getObject().getContent()
197                        i_time = time.time() - i_elapse
198                        time_found += i_time
199                    else:
200                        not_found += 1
201                        i_time = time.time() - i_elapse
202                        time_not_found += i_time
203                elif method == "d":
204                    if student_brain.has_key(portal_types[i]):
205                        found += 1
206                        doc = student_brain[portal_types[i]].getObject().getContent()
207                        i_time = time.time() - i_elapse
208                        time_found += i_time
209                    else:
210                        not_found += 1
211                        i_time = time.time() - i_elapse
212                        time_not_found += i_time
213                i_elapse = time.time()
214            if c and (c % intervall == 0):
215                #i_time = time.time() - i_elapse
216                t_per = 0.0
217                if found:
218                    t_per = time_found/found
219                if t_per > t_max:
220                    t_max = t_per
221                if t_per > 0.0 and t_per < t_min:
222                    t_min = t_per
223                itf = 0.0
224                if found:
225                    itf = time_found/found
226                itnf = 0.0
227                if not_found :
228                    itnf = time_not_found / not_found
229                interval_time = time_found + time_not_found
230                s = "%(c)d: %(found)d/%(not_found)d " % vars()
231                s += "%(interval_time)6.2f %(itf)6.4f/%(itnf)6.4f " % vars()
232                s += "%(t_min)6.4f/%(t_max)6.4f" %  vars()
233                print s
234                t_found += found
235                t_not_found += not_found
236                t_time_found += time_found
237                t_time_not_found += time_not_found
238                time_found = time_not_found = 0.0
239                found = not_found = 0
240        # t_found += found
241        # t_not_found += not_found
242        elapse = time.time() - elapse
243        itf = 0.0
244        if t_found:
245            itf = t_time_found/t_found
246        itnf = 0.0
247        if t_not_found:
248            itnf = t_time_not_found / t_not_found
249        #c_elapse = time.clock() - c_elapse
250        s = "%(probe)d: %(t_found)d/%(t_not_found)d " % vars()
251        s += "%(elapse)6.2f %(itf)6.4f/%(itnf)6.4f " % vars()
252        s += "%(t_min)6.4f/%(t_max)6.4f" %  vars()
253        print "-"*40
254        print s
255        rel_found = float(t_found)/probe
256        rel_not_found = float(t_not_found)/probe
257        estimated_total_time = num_objects*(rel_found*itf + rel_not_found*itnf)
258        print estimated_total_time
259    ###)
260
261    security.declareProtected(ModifyPortalContent,'writeLog') ###(
262    def writeLog(self,logfile,s):
263        """write to the log file"""
264        logfile.write(s)
265
266###)
267
268    def generateStudentId(self,letter): ###(
269        import random
270        r = random
271        ##if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
272        if letter == '?':
273            letter= r.choice('ABCDEFGHKLMNPQRSTUVWXY')
274        sid = "%c%d" % (letter,r.randint(99999,1000000))
275        students = self.portal_url.getPortalObject().campus.students
276##        while hasattr(students, sid):
277##            sid = "%c%d" % (letter,r.randint(99999,1000000))
278        while self.students_catalog(id = sid):
279            sid = "%c%d" % (letter,r.randint(99999,1000000))
280        return sid
281    ###)
282
283    def generatePassword(self,s=None): ###(
284        import random
285        r = random
286        ##if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
287        if s is None:
288            s = 'abcdefghklmnpqrstuvwxy23456789'
289        pw = ''
290        while len(pw) < 6:
291            pw += r.choice(s)
292        return pw
293    ###)
294
295    security.declareProtected(ManagePortal, 'removeDeletedDocIds') ###(
296    def removeDeletedDocIds(self, max=1000):
297        """
298        remove deleted docids from repository commit after max
299        """
300        logger = logging.getLogger('WAeUPTool.removeDeletedDocIds')
301        repository = getToolByName(self, 'portal_repository')
302        pxtool = getToolByName(self, 'portal_proxies')
303        pxtool_infos = pxtool.getRevisionsUsed()
304
305        nb_revs = 0
306        docids_d = {} # all docids
307        unused_docids_d = {} # all docids that are unused
308        ids_unused_revs_docids = [] # ids for revs of unused docids
309        ids_unused_revs = [] # ids for unused revs
310        total = 0
311        idlist = repository.objectIds()
312        for id in idlist:
313            docid, rev = repository._splitId(id)
314            if docid is None:
315                logger.info("invalid doc_id %s" % docid)
316                continue
317            nb_revs += 1
318            docids_d[docid] = None
319            if not pxtool_infos.has_key(docid):
320                unused_docids_d[docid] = None
321                ids_unused_revs_docids.append(id)
322                ids_unused_revs.append(id)
323            elif not pxtool_infos[docid].has_key(rev):
324                ids_unused_revs.append(id)
325            if len(ids_unused_revs) >= max:
326                repository.manage_delObjects(ids_unused_revs)
327                #import pdb;pdb.set_trace()
328                transaction.commit()
329                total += max
330                logger.info('removed %d total %d unused docids ' % (max,total))
331        anz = len(ids_unused_revs)
332        if anz > 0:
333            repository.manage_delObjects(ids_unused_revs)
334            transaction.commit()
335            total += anz
336            logger.info('finished removing %d unused docids ' % (total))
337
338
339###)
340
341    security.declareProtected(ModifyPortalContent,'getCredential') ###(
342    def getCredential(self,student_id):
343        "return a student password"
344        student_entry = getattr(self.portal_directories.students,student_id,None)
345        if student_entry is None:
346            return None
347        return getattr(student_entry,"password","not set")
348    ###)
349
350    security.declarePublic('checkPassword') ###(
351    def checkPassword(self,student_id,password):
352        "return a student password"
353        student_entry = getattr(self.portal_directories.students,student_id,None)
354        if student_entry is None:
355            return False
356        return getattr(student_entry,"password","not set") == password
357    ###)
358
359    security.declarePublic('editPassword') ###(
360    def editPassword(self,student_id,password):
361        "edit a student password"
362        student_entry = getattr(self.portal_directories.students,student_id,None)
363        if student_entry is None:
364            return
365        setattr(student_entry,'password',password)
366    ###)
367
368    security.declareProtected(View,'doCommit') ###(
369    def doCommit(self,logger=None):
370        "commit some transactions"
371        transaction.commit()
372    ###)
373
374    security.declarePublic('loadStudentFoto') ###(
375    def loadStudentFoto(self,student,filename,folder):
376        "return a student passport picture"
377        app = student.application
378        app_doc = app.getContent()
379        #clear = student.clearance
380        #clear_doc = clear.getContent()
381        #matric_no = clear_doc.matric_no.upper()
382        picture1 ="%s/import/%s/%s.jpg" % (i_home,folder,filename)
383        picture2 ="%s/import/%s/%s.JPG" % (i_home,folder,filename)
384        #import pdb;pdb.set_trace()
385        if os.path.exists(picture1):
386            file = open(picture1)
387        elif os.path.exists(picture2):
388            file = open(picture2)
389        else:
390            return "passport picture not found %s" % picture1
391        reopened = False
392        if self.portal_workflow.getInfoFor(app,'review_state',None) !='opened':
393            self.portal_workflow.doActionFor(app,'open')
394            reopened = True
395        outfile = file.read()
396        app_doc.manage_addFile('passport',
397                               file=outfile,
398                               title="%s.jpg" % filename)
399        if reopened:
400            self.portal_workflow.doActionFor(app,'close')
401        return "successfully loaded passport picture"
402    ###)
403
404    security.declareProtected(ModifyPortalContent,'createOne') ###(
405    def createOne(self,students_folder,student_brain,letter,commit=False):
406        sid = self.waeup_tool.generateStudentId(letter)
407        students_folder.invokeFactory('Student', sid)
408        student = getattr(students_folder,sid)
409        self.portal_workflow.doActionFor(student,'return')
410        student.manage_setLocalRoles(sid, ['Owner',])
411        matric_no = student_brain.matric_no
412        jamb_reg_no = student_brain.Entryregno
413        self.students_catalog.addRecord(id = sid,
414                                           matric_no = matric_no,
415                                           jamb_reg_no = jamb_reg_no,
416                                           sex = student_brain.Sex == "F",
417                                           name = "%s %s %s" % (student_brain.Firstname,
418                                                                student_brain.Middlename,
419                                                                student_brain.Lastname)
420                                        )
421        if commit:
422            transaction.commit()
423        return sid,jamb_reg_no
424    ###)
425
426    security.declareProtected(ModifyPortalContent,'addStudent') ###(
427    def addStudent(self,dict):
428        students_folder = self.portal_url.getPortalObject().campus.students
429        sid = self.waeup_tool.generateStudentId('?')
430        students_folder.invokeFactory('Student', sid)
431        student_obj = getattr(students_folder,sid)
432        f2t = self.student_field2types
433        #from pdb import set_trace; set_trace()
434        d = {}
435        d['jamb_sex']  = 'M'
436        if dict.get('sex'):
437            d['jamb_sex']  = 'F'
438
439        entry_session = dict.get('entry_session')
440        if entry_session == self.getSessionId()[-2:]:
441            wfaction = 'admit'
442            wft = 'wf_transition_admit'
443            password = None
444        else:
445            wfaction = 'return'
446            wft = 'wf_transition_return'
447            password = self.generatePassword()
448            self.makeStudentMember(sid,password)
449
450        for pt in f2t.keys():
451            student_obj.invokeFactory(pt,f2t[pt]['id'])
452            sub_obj = getattr(student_obj,f2t[pt]['id'])
453            sub_doc = sub_obj.getContent()
454            #self.portal_workflow.doActionFor(sub_obj,'open',dest_container=sub_obj)
455            d['Title'] = f2t[pt]['title']
456            for field in f2t[pt]['fields']:
457                d[field] = dict.get(field,'')
458            sub_doc.edit(mapping = d)
459            new_state = f2t[pt][wft]
460            if new_state != "remain":
461                self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
462        self.portal_workflow.doActionFor(student_obj,wfaction)
463        student_obj.manage_setLocalRoles(sid, ['Owner',])
464        return sid,password
465    ###)
466
467    security.declarePublic('getCertificateBrain') ###(
468    def getCertificateBrain(self,cert_id):
469        "do it"
470        res = ZCatalog.searchResults(self.portal_catalog_real,
471                                {'portal_type':"Certificate",
472                                      'id': cert_id})
473        if res:
474            return res[0]
475        return None
476    ###)
477
478    security.declareProtected(ModifyPortalContent,'get_csv_filenames') ###(
479    def get_csv_filenames(self):
480        "do it"
481        files = [file for file in os.listdir("%s/import/" % (i_home))
482                 if file.endswith('.csv') and file.find('imported') == -1]
483        return files
484    ###)
485
486    security.declarePublic('findStudentByMatricelNo') ###(
487    def findStudentByMatricelNo(self,matric_no):
488        "do it"
489        res = ZCatalog.searchResults(self.portal_catalog_real,
490                                {'portal_type':"StudentClearance",
491                                 'SearchableText': matric_no})
492        if res:
493            return res[0]
494        return None
495    ###)
496
497    security.declarePublic('makeStudentMember') ###(
498    def makeStudentMember(self,sid,password='uNsEt'):
499        """make the student a member"""
500        membership = self.portal_membership
501        membership.addMember(sid,
502                             password ,
503                             roles=('Member',
504                                     'Student',
505                                     ),
506                             domains='',
507                             properties = {'memberareaCreationFlag': False,
508                                           'homeless': True},)
509        member = membership.getMemberById(sid)
510        self.portal_registration.afterAdd(member, sid, password, None)
511        #self.manage_setLocalRoles(sid, ['Owner',])
512    ###)
513
514    security.declarePublic('makeStudentData') ###(
515    def makeStudentData(self,student_id,email=None,phone_nr=None):
516        "create Datastructure for a returning Student"
517        #import pdb;pdb.set_trace()
518        logger = logging.getLogger('WAeUPTool.makeStudentData')
519        students_folder = self.portal_url.getPortalObject().campus.students
520        #res = self.students_catalog(id=student_id)
521        #if res:
522        #    st = res[0]
523        #res = self.returning_import(matric_no = st.matric_no)
524        res = self.returning_import(id = student_id)
525        if res:
526            student = res[0]
527        else:
528            logger.info('Id %s not found in returning_import' % student_id)
529            return
530        logger.info('%s creates data structure' % student_id)
531        s_results = self.results_import(matric_no = student.matric_no)
532        if s_results:
533            lnr = self.getLevelFromResultsCosCode(s_results)
534            level = "%d00" % lnr
535            verdict,eligible = self.getVerdict(s_results[0].Verdict)
536            if eligible:
537                level = "%d00" % (lnr + 1)
538        else:
539            logger.info('matric_no %s not found in results_import' % student.matric_no)
540            level = 0
541            verdict = 'N/A'
542        #student should not be allowed to perform this transition
543        #wftool = self.portal_workflow
544        #wftool.doActionFor(student,'return')
545        certcode_org = student.Coursemajorcode
546        certcode = makeCertificateCode(certcode_org)
547        certificate_brain = self.getCertificateBrain(certcode)
548        if not certificate_brain:
549            em = 'Certificate %s org-code %s not found\n' % (certcode, certcode_org)
550            logger.info(em)
551        matric_no = student.matric_no
552        sid = student_id
553        student_obj = getattr(students_folder,sid)
554        student_obj.invokeFactory('StudentApplication','application')
555        application = student_obj.application
556        self.portal_workflow.doActionFor(application,'open',dest_container=application)
557        da = {'Title': 'Application Data'}
558        student_obj.invokeFactory('StudentPersonal','personal')
559        da['jamb_reg_no'] = student.Entryregno
560        em = self.getEntryMode(student.Entryregno)
561##        em = student.Mode_of_Entry
562##        if em in ('DIRECT', 'DIRECT ENTRY',):
563##            em = 'DE'
564##        elif em in ('U.M.E', 'UNE',):
565##            em = 'UME'
566##        elif not em:
567##            em = "unknown"
568        da['entry_mode'] = em
569        personal = student_obj.personal
570        self.portal_workflow.doActionFor(personal,'open',dest_container=personal)
571        dp = {'Title': 'Personal Data'}
572        student_obj.invokeFactory('StudentClearance','clearance')
573        clearance = student_obj.clearance
574        self.portal_workflow.doActionFor(clearance,'open',dest_container=clearance)
575        dc = {'Title': 'Clearance/Eligibility Record'}
576        dc['matric_no'] = matric_no
577        state = student.State
578        lga = student.LGA
579        if state and lga:
580            lga =  state + ' / ' + lga
581        else:
582            lga = "None"
583        da['jamb_lga'] = dc['lga'] = lga
584        da['app_email'] = dp['email'] = email
585        da['app_mobile'] = dp['phone'] = phone_nr
586        dp['firstname'] = student.Firstname
587        dp['middlename'] = student.Middlename
588        dp['lastname'] = student.Lastname
589        da['jamb_lastname'] = "%s %s %s" % (student.Firstname,student.Middlename,student.Lastname)
590        da['jamb_sex'] = student.Sex
591        dp['sex'] = student.Sex == 'F'
592        dp['perm_address'] = student.Permanent_Address
593        application.getContent().edit(mapping=da)
594        self.portal_workflow.doActionFor(application,'close',dest_container=application)
595        personal.getContent().edit(mapping=dp)
596        clearance.getContent().edit(mapping=dc)
597        self.portal_workflow.doActionFor(clearance,'close',dest_container=clearance)
598##        catd = {}
599##        catd['id'] = sid
600##        catd['entry_mode']= da['entry_mode']
601##        catd['matric_no'] = matric_no
602##        catd['jamb_reg_no'] = da['jamb_reg_no']
603##        catd['name'] = "%(firstname)s %(middlename)s %(lastname)s" % dp
604##        catd['sex'] = dp['sex']
605##        catd['level'] = level
606##        catd['verdict'] = verdict
607##        if certificate_brain:
608##            cpath = certificate_brain.getPath().split('/')
609##            catd['faculty'] = cpath[-4]
610##            catd['department'] = cpath[-3]
611##            catd['course'] = certcode
612##        self.students_catalog.modifyRecord(**catd)
613        #
614        # Study Course
615        #
616        student_obj.invokeFactory('StudentStudyCourse','study_course')
617        studycourse = student_obj.study_course
618        self.portal_workflow.doActionFor(studycourse,'open',dest_container=studycourse)
619        dsc = {}
620        dsc['study_course'] = certcode
621        dsc['current_level'] = level
622        dsc['current_verdict'] = verdict
623        dsc['current_mode'] = em
624        dsc['current_session'] = '06'
625        studycourse.getContent().edit(mapping=dsc)
626        #
627        # Level
628        #
629##        l = getattr(studycourse,level,None)
630##        if l is None:
631##            studycourse.invokeFactory('StudentStudyLevel', level)
632##            l = getattr(studycourse, level)
633##            self.portal_workflow.doActionFor(l,'open',dest_container=l)
634##            l.getContent().edit(mapping={'Title': "Level %s" % level})
635###)
636
637    security.declarePublic('makeStudentLevel') ###(
638    def makeStudentLevel(self,student_id):
639        "create the StudyLevel for a returning Student"
640        #import pdb;pdb.set_trace()
641        logger = logging.getLogger('WAeUPTool.makeStudentLevel')
642        students_folder = self.portal_url.getPortalObject().campus.students
643        res = self.students_catalog(id=student_id)
644        if res:
645            st = res[0]
646        course = st.course
647        matric_no = st.matric_no
648        level = st.level
649        res = self.results_import(matric_no = matric_no)
650        if res:
651            results = res
652        logger.info('%s creating Level %s' % (student_id,level))
653        #
654        # Level
655        #
656        student_obj = getattr(self.portal_url.getPortalObject().campus.students,student_id)
657        studycourse = getattr(student_obj,"study_course",None)
658        self.portal_workflow.doActionFor(studycourse,'close_for_edit',dest_container=studycourse)
659        l = getattr(studycourse,level,None)
660        if l is None:
661            studycourse.invokeFactory('StudentStudyLevel', level)
662            l = getattr(studycourse, level)
663            self.portal_workflow.doActionFor(l,'open',dest_container=l)
664            l.getContent().edit(mapping={'Title': "Level %s" % level})
665        ###)
666
667    security.declarePublic('getHallInfo') ###(
668    def getHallInfo(self,bed):
669        """return Hall Info"""
670        info = {}
671        hall,block,room,letter = bed.split('_')
672        res = ZCatalog.searchResults(self.portal_catalog_real,portal_type="AccoHall",id=hall)
673        if res and len(res) == 1:
674            hall_brain = res[0]
675            hall_doc = hall_brain.getObject().getContent()
676        else:
677            return info
678        info['hall_title'] = hall_brain.Title
679        info['maintenance_code'] = hall_doc.maintenance_code
680        res = ZCatalog.searchResults(self.portal_catalog_real,portal_type="ScratchCardBatch")
681        batch_doc = None
682        for brain in res:
683            if brain.id.startswith(info['maintenance_code']):
684                batch_doc = brain.getObject().getContent()
685                break
686        if batch_doc is None:
687            info['maintenance_fee'] = None
688        else:
689            info['maintenance_fee'] = batch_doc.cost
690        return info
691    ###)
692
693    security.declarePublic('showFsPicture') ###(
694    def showFsPicture(self,path):
695        """return a picture from the filesystem"""
696        picture_path = "%s/import/%s" % (i_home,path)
697        if os.path.exists(picture_path):
698            return open(picture_path).read()
699
700    ###)
701
702    security.declareProtected(ModifyPortalContent,'deleteAllCourses') ###(
703    def deleteAllCourses(self,department="All"):
704        ''' delete the courses'''
705        pm = self.portal_membership
706        member = pm.getAuthenticatedMember()
707
708        if str(member) not in ("henrik","joachim"):
709            return "not possible"
710        if department == "All":
711            res = self.portal_catalog({'meta_type': 'Department'})
712        if len(res) < 1:
713            return "No Departments found"
714
715        deleted = []
716        for dep in res:
717            cf = dep.getObject().courses
718            if cf:
719                cf.manage_delObjects(ids=cf.objectIds())
720                deleted.append("deleted Courses in %s" % dep.getId)
721        return "\r".join(deleted)
722    ###)
723
724    security.declareProtected(ModifyPortalContent,'getLogfileLines') ###(
725    def getLogfileLines(self,filename="event.log",numlines=20):
726        """Get last NUMLINES lines of logfile FILENAME.
727
728        Return last lines' of a file in the instances logfile directory as
729        a list. The number of returned lines equals `numlines' or less. If
730        less than `numlines' lines are available, the whole file ist
731        returned. If the file can not be opened or some other error
732        occurs, empty list is returend.
733        """
734        result = []
735        lines_hit = 0
736
737        # We only handle files in instances' log directory...
738        logpath = os.path.join(i_home, "log")
739        filename = str(os.path.abspath( os.path.join( logpath, filename )))
740        if not filename.startswith( logpath ):
741            # Attempt to access file outside log-dir...
742            return []
743
744        try:
745            fd = file( filename, "rb" )
746        except IOError:
747            return []
748        if not fd:
749            return []
750
751        if os.linesep == None:
752            linesep = '\n'
753        else:
754            linesep = os.linesep
755
756        # Try to find 'numlines' times a lineseparator, searching from end
757        # and moving to the beginning of file...
758        fd.seek( 0, 2) # Move to end of file...
759        while lines_hit < numlines:
760            if fd.read(1) == linesep[-1]: # This moves filedescriptor
761                                          # one step forward...
762                lines_hit += 1
763            try:
764                fd.seek( -2, 1) # Go two bytes back from current pos...
765            except IOError:
766                # We cannot go back two bytes. Maybe the file is too small...
767                break
768        fd.seek(2,1)
769
770        # Read all lines from current position...
771        result = fd.readlines()
772        # Remove line endings...
773        result = [x.strip() for x in result]
774        fd.close()
775        return result
776    ###)
777
778    security.declareProtected(ModifyPortalContent,"getCallbacksFromLog")###(
779    def getCallbacksFromLog(self,filename):
780        """fix Online Payment Transactions from Z2.log entries"""
781        import transaction
782        import random
783        from cgi import parse_qs
784        from urlparse import urlparse
785        #from pdb import set_trace
786        wftool = self.portal_workflow
787        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
788        students_folder = self.portal_url.getPortalObject().campus.students
789        s = r'(?P<client_ip>\S+) - (?P<member_id>\S+) \['
790        s += r'(?P<date>.*)\] "(?P<get>.*)" (?P<codes>\d+ \d+) "'
791        s += r'(?P<intersw>.*)" "(?P<agent>.*)"'
792        data = re.compile(s)
793        start = True
794        tr_count = 1
795        total = 0
796        #name = 'pume_results'
797        #name = 'epaymentsuccessful_z2log2'
798        name = filename
799        no_import = []
800        imported = []
801        logger = logging.getLogger('WAeUPTool.getFailedTransactions')
802        try:
803            transactions = open("%s/import/%s" % (i_home,name),"rb").readlines()
804        except:
805            logger.error('Error reading %s' % name)
806            return
807        tas = []
808        for line in transactions:
809            dict = {}
810            items = data.search(line)
811            dict['idict'] = idict = items.groupdict()
812            #print idict
813            #from pdb import set_trace;set_trace()
814            urlparsed = urlparse(idict['get'][4:])
815            #print urlparsed
816            path = urlparsed[2].split('/')
817            dict['student_id'] = student_id = path[8]
818            dict['payment_id'] = payment_id = path[10]
819            dict['qs_dict'] = qs_dict = parse_qs(urlparsed[4])
820            tas.append(dict)
821            tr_count += 1
822        return tas
823    ###)
824
825    security.declareProtected(ModifyPortalContent,"importOnlinePaymentTransactions")###(
826    def importOnlinePaymentTransactions(self):
827        """load Online Payment Transactions from CSV values"""
828        import transaction
829        import random
830        #from pdb import set_trace
831        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
832        opt = self.online_payments_import
833        students_folder = self.portal_url.getPortalObject().campus.students
834        start = True
835        tr_count = 1
836        total = 0
837        #name = 'pume_results'
838        name = 'OnlineTransactions'
839        no_import = []
840        imported = []
841        logger = logging.getLogger('WAeUPTool.importOnlinePaymentTransactions')
842        try:
843            transactions = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
844        except:
845            logger.error('Error reading %s.csv' % name)
846            return
847        for pay_transaction in transactions:
848            if start:
849                start = False
850                logger.info('Start loading from %s.csv' % name)
851                s = ','.join(['"%s"' % fn for fn in pay_transaction.keys()])
852                no_import.append('%s,"Error"' % s)
853                format = ','.join(['"%%(%s)s"' % fn for fn in pay_transaction.keys()])
854                format_error = format + ',"%(Error)s"'
855            data = {}
856
857            # format of the first file sent by Tayo
858            #data['datetime'] = date = DateTime.DateTime(pay_transaction['Date'])
859            #data['student_id'] = student_id = pay_transaction['Payer ID']
860            #data['order_id'] = order_id = pay_transaction['Order ID (Tranx Ref)']
861            #data['response_code'] = response_code = pay_transaction['Resp Code']
862            #data['amount'] = amount = pay_transaction['Amount']
863
864            # format of the second file sent by Tayo
865            #data['datetime'] = date = 0
866            #data['student_id'] = student_id = pay_transaction['Payer ID']
867            #data['order_id'] = order_id = pay_transaction['Order ID (Tranx Ref)']
868            #data['response_code'] = response_code = '00'
869            #data['amount'] = amount = pay_transaction['Amount']
870
871            # format of the third file sent by Kehinde
872            data['datetime'] = date = 0
873            data['student_id'] = student_id = pay_transaction['customer_id']
874            data['order_id'] = order_id = pay_transaction['merchant_reference']
875            data['response_code'] = response_code = '00'
876            data['amount'] = amount = pay_transaction['Amount']
877
878            dup = False
879            if response_code == "12":
880                continue
881            try:
882                opt.addRecord(**data)
883            except ValueError:
884                dup = True
885            #from pdb import set_trace;set_trace()
886            if dup:
887                if response_code == "00":
888                    try:
889                        opt.modifyRecord(**data)
890                    except:
891                        logger.info("duplicate uid, order_id %(order_id)s, student_id %(student_id)s, response_code %(response_code)s" % data)
892                        continue
893                else:
894                    pay_transaction['Error'] = "Duplicate order_id"
895                    no_import.append( format_error % pay_transaction)
896                    logger.info("duplicate order_id %(order_id)s for %(student_id)s %(response_code)s" % data)
897                    continue
898            tr_count += 1
899            if tr_count > 1000:
900                if len(no_import) > 0:
901                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
902                             '\n'.join(no_import) + '\n')
903                    no_import = []
904                em = '%d transactions committed\n' % (tr_count)
905                transaction.commit()
906                regs = []
907                logger.info(em)
908                total += tr_count
909                tr_count = 0
910        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
911                                                '\n'.join(no_import))
912        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
913    ###)
914
915    security.declareProtected(ModifyPortalContent,'mass_create_department') ###(
916    def mass_create_department(self,mapping):
917        "create a department in the correct faculty"
918        logger = logging.getLogger('WAeUPTool.mass_create_department')
919        fid = mapping['faculty_code']
920        if getattr(self,'_v_faculties',None) is None:
921            res = self.portal_catalog(portal_type = "Faculty")
922            self._v_faculties = {}
923            for f in res:
924                self._v_faculties[f.getId] = f.getObject()
925        f = self._v_faculties.get(fid,None)
926        if f is None:
927            return '', "No Faculty with ID: %s" % fid
928        else:
929            did = mapping.get('code')
930            d = getattr(f,did,None)
931            if d is None or d.portal_type == "Faculty":
932                logger.info('Creating Department %(code)s = %(title)s' % mapping)
933                f.invokeFactory('Department', did)
934                d = getattr(f,did)
935                d.invokeFactory('CoursesFolder','courses')
936                courses = getattr(d,'courses')
937                dict = {'Title': 'Courses'}
938                courses.getContent().edit(mapping=dict)
939                d.invokeFactory('CertificatesFolder','certificates')
940                certificates = getattr(d,'certificates')
941                dict = {'Title': 'Certificates'}
942                certificates.getContent().edit(mapping=dict)
943            d.getContent().edit(mapping=mapping)
944        return did,''
945    ###)
946
947    security.declareProtected(ModifyPortalContent,'mass_edit_department') ###(
948    def mass_edit_department(self,mapping):
949        "create a department in the correct faculty"
950        logger = logging.getLogger('WAeUPTool.mass_create_department')
951        academics_folder = self.portal_url.getPortalObject().campus.academics
952        fid = mapping['faculty_code']
953        did = mapping.get('code')
954        try:
955            d = getattr(getattr(academics_folder,fid),did,None)
956        except KeyError:
957            return '', "Department %s or Faculty %s wrong" % (did,fid)
958        else:
959            if d is None or d.portal_type == "Faculty":
960                logger.info('Editing Department %(code)s = %(title)s' % mapping)
961            d.getContent().edit(mapping=mapping)
962        return did,''
963    ###)
964
965    field2types_student = {   ###(
966                      'StudentApplication':
967                          {'id': 'application',
968                           'title': 'Application Data',
969                           'wf_transition_return': 'close',
970                           'wf_transition_admit': 'remain',
971                           'fields':
972                             ('jamb_reg_no',
973                              'entry_mode',
974                              'entry_session',
975                              'jamb_score',
976                              'app_email',
977                              'jamb_age',
978                              'jamb_state',
979                              'jamb_lga',
980                              )
981                              },
982                      #'StudentPume':
983                      #    {'id': 'pume',
984                      #     'title': 'Pume Data',
985                      #     'wf_transition_return': 'close',
986                      #     'wf_transition_admit': 'close',
987                      #     'fields':
988                      #       ('pume_score',
989                      #        )
990                      #        },
991                      'StudentClearance':
992                          {'id': 'clearance',
993                           'title': 'Clearance/Eligibility Record',
994                           'wf_transition_return': 'close',
995                           'wf_transition_admit': 'remain',
996                           'fields':
997                             ('matric_no',
998                              'nationality',
999                              'lga',
1000                              'birthday',
1001                              )
1002                              },
1003                         'StudentPersonal':
1004                          {'id': 'personal',
1005                           'title': 'Personal Data',
1006                           'wf_transition_return': 'open',
1007                           'wf_transition_admit': 'remain',
1008                           'fields':
1009                             ('firstname',
1010                              'middlename',
1011                              'lastname',
1012                              'sex',
1013                              'email',
1014                              'phone',
1015                              'perm_address',
1016                              )
1017                              },
1018                         'StudentStudyCourse':
1019                          {'id': 'study_course',
1020                           'title': 'Study Course',
1021                           'wf_transition_return': 'open',
1022                           'wf_transition_admit': 'remain',
1023                           'fields':
1024                             ('study_course',
1025                              'current_level',
1026                              'current_session',
1027                              'current_mode',
1028                              'current_verdict',
1029                              )
1030                              },
1031
1032                         'PaymentsFolder':
1033                          {'id': 'payments',
1034                           'title': 'Payments',
1035                           'wf_transition_return': 'open',
1036                           'wf_transition_admit': 'open',
1037                           'fields':
1038                             ()
1039                              },
1040                         }
1041    ###)
1042
1043    security.declareProtected(ModifyPortalContent,'mass_create_student') ###(
1044    def mass_create_student(self,mapping):
1045        "create a students record due import"
1046        logger = logging.getLogger('WAeUPTool.mass_create_student')
1047        students_folder = self.portal_url.getPortalObject().campus.students
1048        jamb_reg_no = mapping.get('jamb_reg_no',None)
1049        if jamb_reg_no:
1050            res = self.students_catalog(jamb_reg_no = jamb_reg_no)
1051            if res:
1052                return '',"jamb_reg_no exists"
1053        matric_no = mapping.get('matric_no',None)
1054        if matric_no:
1055            res = self.students_catalog(matric_no = matric_no)
1056            if res:
1057                return '',"matric_no exists"
1058        sid = self.waeup_tool.generateStudentId('?')
1059        students_folder.invokeFactory('Student', sid)
1060        student_obj = getattr(students_folder,sid)
1061        f2t = self.field2types_student
1062        d = {}
1063        d['jamb_sex']  = 'M'
1064        if mapping.get('sex'):
1065            d['jamb_sex']  = 'F'
1066        transition = mapping.get('reg_transition','admit')
1067        if transition not in ('admit','return'):
1068            return '',"no valid transition provided"
1069        for pt in f2t.keys():
1070            student_obj.invokeFactory(pt,f2t[pt]['id'])
1071            sub_obj = getattr(student_obj,f2t[pt]['id'])
1072            sub_doc = sub_obj.getContent()
1073            d['Title'] = f2t[pt]['title']
1074            for field in f2t[pt]['fields']:
1075                d[field] = mapping.get(field,'')
1076            if pt == "StudyCourse":
1077                for von,zu in (('entry_mode','current_mode'),
1078                               ('entry_session','current_session')):
1079                    if mapping.get(zu,None) is None and mapping.get(von,None) is not None:
1080                        d[zu] = mapping[von]
1081            sub_doc.edit(mapping = d)
1082
1083            #import pdb;pdb.set_trace()
1084            new_state = f2t[pt]['wf_transition_%(transition)s' % vars()]
1085            if new_state != "remain":
1086                self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
1087        self.portal_workflow.doActionFor(student_obj,transition)
1088        student_obj.manage_setLocalRoles(sid, ['Owner',])
1089        return sid,''
1090    ###)
1091
1092    security.declareProtected(ModifyPortalContent,'mass_edit_student') ###(
1093    def mass_edit_student(self,mapping):
1094        "edit a students record due import"
1095        logger = logging.getLogger('WAeUPTool.mass_edit_student')
1096        students_folder = self.portal_url.getPortalObject().campus.students
1097        sid = mapping.get('id',None)
1098        jamb_reg_no = mapping.get('jamb_reg_no',None)
1099        matric_no = mapping.get('matric_no',None)
1100        editable_keys = mapping.keys()
1101        if sid:
1102            res = self.students_catalog(id = sid)
1103            if not res:
1104                return '',"no student with id %s" % sid
1105            elif matric_no and res[0].matric_no and\
1106              matric_no != res[0].matric_no:
1107                return '%s' % res[0].id ,"student has no matric_no %s" % matric_no
1108            elif jamb_reg_no and res[0].jamb_reg_no and\
1109              jamb_reg_no != res[0].jamb_reg_no:
1110                return '%s' % res[0].id ,"student has no jamb_reg_no %s" % jamb_reg_no
1111        elif jamb_reg_no:
1112            res = self.students_catalog(jamb_reg_no = jamb_reg_no)
1113            if not res:
1114                return '',"no student with jamb_reg_no %s" % jamb_reg_no
1115            editable_keys.remove('jamb_reg_no')
1116        elif matric_no:
1117            res = self.students_catalog(matric_no = matric_no)
1118            if not res:
1119                return '',"no student with matric_no %s" % matric_no
1120            editable_keys.remove('matric_no')
1121
1122        # included only to change wf state from admitted to returning
1123        if res[0].review_state not in ('admitted','objection_raised'):
1124            return '%s' % res[0].id ,"student is not in state admitted or objection_raised"
1125        # end inclusion
1126
1127        sid = res[0].id
1128        student_obj = getattr(students_folder,sid)
1129        f2t = self.field2types_student
1130        d = {}
1131        #import pdb;pdb.set_trace()
1132        any_change = False
1133        for pt in f2t.keys():
1134            if pt == "student_application":
1135                d['jamb_sex']  = 'M'
1136                if mapping.get('sex'):
1137                    d['jamb_sex']  = 'F'
1138            intersect = set(f2t[pt]['fields']).intersection(set(editable_keys))
1139            if intersect:
1140                sub_obj = getattr(student_obj,f2t[pt]['id'],None)
1141                if sub_obj is None:
1142                    try:
1143                        student_obj.invokeFactory(pt,f2t[pt]['id'])
1144                    except:
1145                        continue
1146                    sub_obj = getattr(student_obj,f2t[pt]['id'])
1147                    d['Title'] = f2t[pt]['title']
1148                sub_doc = sub_obj.getContent()
1149                for field in intersect:
1150                    changed = False
1151                    if getattr(sub_doc,field) != mapping.get(field,''):
1152                        any_change = True
1153                        changed = True
1154                        d[field] = mapping.get(field,'')
1155                    if changed:
1156                        sub_doc.edit(mapping = d)
1157
1158
1159        # included only to change wf state from admitted to returning
1160            if res[0].review_state in ('admitted','objection_raised'):
1161                new_state = f2t[pt]['wf_transition_return']
1162                sub_obj = getattr(student_obj,f2t[pt]['id'],None)
1163                if sub_obj and new_state != "remain":
1164                    try:
1165                        self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
1166                    except:
1167                        #logger.info('%s, wf transition %s of %s failed' % (sid,new_state,sub_obj.id))
1168                        pass
1169        if res[0].review_state in ('admitted','objection_raised'):
1170            wfaction = 'return'
1171            try:
1172                self.portal_workflow.doActionFor(student_obj,wfaction)
1173                logger.info('%s, wf state changed' % sid)
1174                any_change = True
1175            except:
1176                logger.info('%s, wf transition failed, old state = %s' % (sid,res[0].review_state))
1177                pass
1178        # end inclusion
1179
1180
1181        if any_change:
1182            return sid,''
1183        else:
1184            return sid,'not modified'
1185    ###)
1186
1187    security.declareProtected(ModifyPortalContent,"importData")###(
1188    def importData(self,filename,name,edit=False,bypass_queue_catalog=False):
1189        """load data from CSV values"""
1190        import transaction
1191        import random
1192
1193        pm = self.portal_membership
1194        member = pm.getAuthenticatedMember()
1195
1196        logger = logging.getLogger('WAeUPTool.importData')
1197        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
1198        students_folder = self.portal_url.getPortalObject().campus.students
1199        start = True
1200        tr_count = 1
1201        total_imported = 0
1202        total_not_imported = 0
1203        total = 0
1204        iname = "import_%s" % name
1205        stool = getToolByName(self, 'portal_schemas')
1206        ltool = getToolByName(self, 'portal_layouts')
1207        schema = stool._getOb(iname)
1208        if schema is None:
1209            em = 'No such schema %s' % iname
1210            logger.error('No such schema %s' % iname)
1211            return em
1212        layout = ltool._getOb(iname)
1213        if layout is None:
1214            em = 'No such layout %s' % iname
1215            logger.error(em)
1216            return em
1217        validators = {}
1218        for widget in layout.keys():
1219            validators[widget] = layout[widget].validate
1220        #import pdb;pdb.set_trace()
1221        if edit:
1222            importer_name = "mass_edit_%s" % name
1223        else:
1224            importer_name = "mass_create_%s" % name
1225        importer = getattr(self, '%s' % importer_name,None)
1226        if importer is None:
1227            em = 'No importer function %s' % importer_name
1228            logger.error(em)
1229            return em
1230        not_imported = []
1231        imported = []
1232        try:
1233            items = csv.DictReader(open("%s/import/%s.csv" % (i_home,filename),"rb"))
1234        except:
1235            em = 'Error reading %s.csv' % filename
1236            logger.error(em)
1237            return em
1238        for item in items:
1239            if start:
1240                start = False
1241                adapters = [MappingStorageAdapter(schema, item)]
1242                logger.info('%s starts import from %s.csv' % (member,filename))
1243                #import_keys = [k for k in item.keys() if not k.startswith('ignore')]
1244                attrs = csv.reader(open("%s/import/%s.csv" % (i_home,filename),"rb")).next()
1245                #import pdb;pdb.set_trace()
1246                import_keys = [k for k in attrs if not k.startswith('ignore')]
1247                diff2schema = set(import_keys).difference(set(schema.keys()))
1248                diff2layout = set(import_keys).difference(set(layout.keys()))
1249                if diff2schema:
1250                    em = "not ignorable key(s) %s found in heading" % diff2schema
1251                    return em
1252                s = ','.join(['"%s"' % fn for fn in import_keys])
1253                open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(s + ',"Error"'+ '\n')
1254                s = '"id",' + s
1255                open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(s + '\n')
1256                format = ','.join(['"%%(%s)s"' % fn for fn in import_keys])
1257                format_error = format + ',"%(Error)s"'
1258                format = '"%(id)s",'+ format
1259                by_pass_queue = getattr(self.portal_catalog,"setBypassQueue",None)
1260                if by_pass_queue is not None:
1261                    bypass_queue(bypass_queue_catalog)
1262                           
1263            dm = DataModel(item, adapters,context=self)
1264            ds = DataStructure(data=item,datamodel=dm)
1265            error_string = ""
1266            for k in import_keys:
1267                if not validators[k](ds):
1268                    error_string += " %s : %s" % (k,ds.getError(k))
1269            if not error_string:
1270                item.update(dm)
1271                item['id'],error = importer(item)
1272                if error:
1273                    error_string += error
1274            if error_string:
1275                item['Error'] = error_string
1276                not_imported.append(format_error % item)
1277                total_not_imported += 1
1278            else:
1279                em = format % item
1280                imported.append(em)
1281                logger.info("%(total_imported)d of %(total)d %(em)s" % vars())
1282                tr_count += 1
1283                total_imported += 1
1284            total += 1
1285            if total and not total % 100:
1286                transaction.commit()
1287                if len(not_imported) > 0:
1288                    open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
1289                             '\n'.join(not_imported) + '\n')
1290                    not_imported = []
1291                if len(imported) > 0:
1292                    open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
1293                             '\n'.join(imported) + '\n')
1294                    imported = []
1295                em = '%d transactions committed\n' % (tr_count)
1296                regs = []
1297                logger.info(em)
1298                tr_count = 0
1299        if len(imported) > 0:
1300            open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
1301                                                '\n'.join(imported))
1302        if len(not_imported) > 0:
1303            open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
1304                                                '\n'.join(not_imported))
1305        em = "Imported: %d, not imported: %d of total %d" % (total_imported,total_not_imported,total)
1306        return em
1307    ###)
1308
1309InitializeClass(WAeUPTool)
Note: See TracBrowser for help on using the repository browser.