source: WAeUP_SRP/branches/uli/WAeUPTables.py @ 14312

Last change on this file since 14312 was 1653, checked in by uli, 18 years ago

Incorporated changeset 1593:1652 of trunk into uli-branch.

  • Property svn:keywords set to Id
File size: 17.1 KB
RevLine 
[966]1#-*- mode: python; mode: fold -*-
[363]2# (C) Copyright 2005 AixtraWare <http://aixtraware.de>
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: WAeUPTables.py 1653 2007-03-28 02:35:25Z uli $
20
21from zope.interface import implements
22from Globals import InitializeClass
23from Products.ZCatalog.ZCatalog import ZCatalog
[1653]24from Products.ZCatalog.ProgressHandler import ZLogHandler
[780]25from AccessControl import ClassSecurityInfo
26from Products.CMFCore.permissions import ModifyPortalContent
[363]27
[1653]28import DateTime,time
[780]29import csv,re
30import logging
31import Globals
32p_home = Globals.package_home(globals())
33i_home = Globals.INSTANCE_HOME
34
[363]35from interfaces import IWAeUPTable
36
37class AttributeHolder(object):
38    pass
39
40def dict2ob(dict):
41    ob = AttributeHolder()
42    for key, value in dict.items():
43        setattr(ob, key, value)
44    return ob
45
[834]46
[1146]47class WAeUPTable(ZCatalog): ###(
[834]48
[363]49    implements(IWAeUPTable)
[780]50    security = ClassSecurityInfo()
[834]51
[1653]52    def refreshCatalog(self, clear=0, pghandler=None):
53        """ don't refresh for a normal table """
54
55        if self.REQUEST and self.REQUEST.RESPONSE:
56            self.REQUEST.RESPONSE.redirect(
57              URL1 +
58              '/manage_catalogAdvanced?manage_tabs_message=Catalog%20refresh%20not%20implemented')
59
60    def manage_catalogClear(self, REQUEST=None, RESPONSE=None, URL1=None):
61        """ clears the whole enchilada """
62        #self._catalog.clear()
63
64        if REQUEST and RESPONSE:
65            RESPONSE.redirect(
66              URL1 +
67              '/manage_catalogAdvanced?manage_tabs_message=Catalog%20Clearing%20disabled')
68
[363]69    def addRecord(self, **data):
[502]70        # The uid is the same as "bed".
71        uid = data[self.key]
72        res = self.searchResults({"%s" % self.key : uid})
73        if len(res) > 0:
74            raise ValueError("More than one record with uid %s" % uid)
75        self.catalog_object(dict2ob(data), uid=uid)
76        return uid
[834]77
[363]78    def deleteRecord(self, uid):
[635]79        #import pdb;pdb.set_trace()
[363]80        self.uncatalog_object(uid)
[834]81
[502]82    def searchAndSetRecord(self, **data):
83        raise NotImplemented
84
85    def modifyRecord(self, **data):
86        #records = self.searchResults(uid=uid)
87        uid = data[self.key]
88        records = self.searchResults({"%s" % self.key : uid})
[363]89        if len(records) > 1:
90            # Can not happen, but anyway...
91            raise ValueError("More than one record with uid %s" % uid)
92        if len(records) == 0:
93            raise KeyError("No record for uid %s" % uid)
94        record = records[0]
95        record_data = {}
96        for field in self.schema() + self.indexes():
97            record_data[field] = getattr(record, field)
98        # Add the updated data:
99        record_data.update(data)
100        self.catalog_object(dict2ob(record_data), uid)
101
[1062]102    def reindexIndex(self, name, REQUEST,pghandler=None):
103        if isinstance(name, str):
104            name = (name,)
105        paths = self._catalog.uids.items()
106        i = 0
107        #import pdb;pdb.set_trace()
108        for p,rid in paths:
109            i += 1
110            metadata = self.getMetadataForRID(rid)
111            record_data = {}
112            for field in name:
113                record_data[field] = metadata.get(field)
114            uid = metadata.get(self.key)
115            self.catalog_object(dict2ob(record_data), uid, idxs=name,
116                                update_metadata=0)
[1082]117
[780]118    security.declareProtected(ModifyPortalContent,"exportAllRecords")
119    def exportAllRecords(self):
120        "export a WAeUPTable"
121        #import pdb;pdb.set_trace()
122        fields = [field for field in self.schema()]
123        format = ','.join(['"%%(%s)s"' % fn for fn in fields])
124        csv = []
125        csv.append(','.join(['"%s"' % fn for fn in fields]))
126        for uid in self._catalog.uids:
127            records = self.searchResults({"%s" % self.key : uid})
128            if len(records) > 1:
129                # Can not happen, but anyway...
130                raise ValueError("More than one record with uid %s" % uid)
131            if len(records) == 0:
132                raise KeyError("No record for uid %s" % uid)
133            rec = records[0]
134            csv.append(format % rec)
135        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
136        open("%s/import/%s-%s.csv" % (i_home,self.getId(),current),"w+").write('\n'.join(csv))
[834]137
[1146]138###)
[834]139
[1146]140class AccommodationTable(WAeUPTable): ###(
[834]141
[404]142    meta_type = 'WAeUP Accommodation Tool'
[502]143    name = "accommodation"
144    key = "bed"
[363]145    def __init__(self):
[404]146        WAeUPTable.__init__(self, 'portal_accommodation')
[363]147
[635]148    def searchAndReserveBed(self, student_id,bed_type):
149        records = self.searchResults({'student' : student_id})
150        if len(records) > 0:
[1293]151            return -1,"Student with Id %s already booked bed %s." % (student_id,records[0].bed)
[834]152
[673]153        records = [r for r in self.searchResults({'bed_type' : bed_type}) if not r.student]
[686]154        #import pdb;pdb.set_trace()
[635]155        if len(records) == 0:
[1306]156            return -2,"No bed available"
[635]157        rec = records[0]
158        self.modifyRecord(bed=rec.bed,student=student_id)
[1593]159        s_logger = logging.getLogger('WAeUPTables.AccommodationTable.searchAndReserveBed')
160        s_logger.info('%s reserved bed %s' % (student_id,rec.bed))
[635]161        return 1,rec.bed
[363]162
[834]163
[404]164InitializeClass(AccommodationTable)
[411]165
[1146]166###)
167
168class PinTable(WAeUPTable): ###(
[1030]169    from ZODB.POSException import ConflictError
[440]170    meta_type = 'WAeUP Pin Tool'
[502]171    name = "pins"
172    key = 'pin'
[440]173    def __init__(self):
174        WAeUPTable.__init__(self, 'portal_pins')
[1082]175
176
[710]177    def searchAndSetRecord(self, uid, student_id,prefix):
[502]178        #records = self.searchResults(uid=uid)
[710]179        records = self.searchResults(student = student_id)
[990]180        #import pdb;pdb.set_trace()
[710]181        if len(records) > 0:
182            for r in records:
[834]183                if r.pin != uid and r.prefix_batch.startswith(prefix):
[710]184                    return -2
[502]185        records = self.searchResults({"%s" % self.key : uid})
186        if len(records) > 1:
187            # Can not happen, but anyway...
188            raise ValueError("More than one record with uid %s" % uid)
189        if len(records) == 0:
190            return -1
191        record = records[0]
192        if record.student == "":
193            record_data = {}
194            for field in self.schema() + self.indexes():
195                record_data[field] = getattr(record, field)
196            # Add the updated data:
[635]197            record_data['student'] = student_id
[1030]198            try:
199                self.catalog_object(dict2ob(record_data), uid)
200                return 1
201            except ConflictError:
202                return 2
[990]203        if record.student.upper() != student_id.upper():
[502]204            return 0
[997]205        if record.student.upper() == student_id.upper():
[502]206            return 2
[997]207        return -3
[440]208
209InitializeClass(PinTable)
210
[1146]211###)
[966]212
[1146]213class PumeResultsTable(WAeUPTable): ###(
214
[966]215    meta_type = 'WAeUP PumeResults Tool'
216    name = "pumeresults"
217    key = "jamb_reg_no"
218    def __init__(self):
219        WAeUPTable.__init__(self, 'portal_pumeresults')
220
221
222InitializeClass(PumeResultsTable)
223
[1146]224###)
[971]225
[1146]226class StudentsCatalog(WAeUPTable): ###(
[1653]227    security = ClassSecurityInfo()
[1146]228
[971]229    meta_type = 'WAeUP Students Catalog'
230    name = "students_catalog"
231    key = "id"
[1653]232    interesting_types = ('Student',
233                         'StudentApplication',
234                         'StudentCLearance',
235                         'StudentPersonal',
236                         'StudentStudyCourse',
237                         )
238
[971]239    def __init__(self):
240        WAeUPTable.__init__(self, 'students_catalog')
[1653]241        return
[971]242
[1653]243    def get_review_state(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc): ###(
244        "return the students review_state from portal_catalog"
245        cat_res = self.portal_catalog(id = sid)
246        if len(cat_res) != 1:
247            return None
248        return cat_res[0].review_state
[971]249
[1653]250    def get_course(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
251        "return the students study_course"
252        if study_course_doc is None:
253            return None
254        return getattr(study_course_doc,'study_course',None)
255
256    def get_department(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
257        "return the students department"
258        if study_course_doc is None:
259            return None
260        certificate_res = self.portal_catalog(id = study_course_doc.study_course)
261        if len(certificate_res) != 1:
262            return None
263        return certificate_res[0].getPath().split('/')[-3]
264
265    def get_email(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
266        "return the students email from the personal"
267        if personal_doc is None:
268            return None
269        return getattr(personal_doc,'email',None)
270
271    def get_entry_mode(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
272        "return the students entry_mode from the application"
273        if application_doc is None:
274            return None
275        return getattr(application_doc,'entry_mode',None)
276
277    def get_jamb_reg_no(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
278        "return the students jamb_reg_no from the application"
279        if application_doc is None:
280            return None
281        return getattr(application_doc,'jamb_reg_no',None)
282
283    def get_faculty(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
284        "return the students faculty"
285        if study_course_doc is None:
286            return None
287        certificate_res = self.portal_catalog(id = study_course_doc.study_course)
288        if len(certificate_res) != 1:
289            return None
290        return certificate_res[0].getPath().split('/')[-4]
291
292    def get_level(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
293        "return the students study_course"
294        if study_course_doc is None:
295            return None
296        #from pdb import set_trace;set_trace()
297        return getattr(study_course_doc,'current_level',None)
298
299    def get_matric_no(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
300        "return the students matric_no from the clearance "
301        if clearance_doc is None:
302            return None
303        return getattr(clearance_doc,'matric_no',None)
304
305    def get_name(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
306        "return the students name from the personal"
307        if personal_doc is None:
308            return None
309        doc = personal_doc
310        return "%s %s %s" % (doc.firstname,doc.middlename,doc.lastname)
311
312    def get_phone(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
313        "return the students phone from the personal"
314        if personal_doc is None:
315            return None
316        return getattr(personal_doc,'phone',None)
317
318    def get_sex(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
319        "return the students sex from the personal"
320        if personal_doc is None:
321            return None
322        return getattr(personal_doc,'sex',None)
323
324    def get_verdict(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
325        "return the students study_course"
326        if study_course_doc is None:
327            return None
328        return getattr(study_course_doc,'current_verdict',None)
329    ###)
330
331    def refreshCatalog(self, clear=0, pghandler=None): ###(
332        """ re-index everything we can find """
333        students_folder = self.portal_url.getPortalObject().campus.students
334
335        cat = self._catalog
336        paths = self._catalog.uids.items()
337        if clear:
338            paths = tuple(paths)
339            cat.clear()
340
341        num_objects = len(paths)
342        if pghandler:
343            pghandler.init('Refreshing catalog: %s' % self.absolute_url(1), num_objects)
344        for i in xrange(num_objects):
345            if pghandler: pghandler.report(i)
346            p = paths[i]
347            sid = p[0]
348            pcat_res = self.portal_catalog(id=sid)
349            if len(pcat_res) != 1:
350                continue
351            student_brain = pcat_res[0]
352            student_obj = student_brain.getObject()
353            if student_obj.hasObject('application'):
354                application_doc = getattr(student_obj,'application').getContent()
355            else:
356                application_doc = None
357            if student_obj.hasObject('clearance'):
358                clearance_doc = getattr(student_obj,'clearance').getContent()
359            else:
360                clearance_doc = None
361            if student_obj.hasObject('personal'):
362                personal_doc = getattr(student_obj,'personal').getContent()
363            else:
364                personal_doc = None
365            if student_obj.hasObject('study_course'):
366                study_course_doc = getattr(student_obj,'study_course').getContent()
367            else:
368                study_course_doc = None
369            data = {}
370            data['id'] = sid
371            for field in self.schema():
372                function = getattr(self,"get_%s" % field, None)
373                if function is None:
374                    continue
375                value = function(sid,application_doc,clearance_doc,personal_doc,study_course_doc)
376                if value is not None:
377                    data[field] = value
378            self.modifyRecord(**data)
379        if pghandler: pghandler.finish()
380    ###)
381
382    def manage_catalogReindex(self, REQUEST, RESPONSE, URL1):
383        """ clear the catalog, then re-index everything """
384
385        elapse = time.time()
386        c_elapse = time.clock()
387
388        pgthreshold = self._getProgressThreshold()
389        handler = (pgthreshold > 0) and ZLogHandler(pgthreshold) or None
390        self.refreshCatalog(clear=0, pghandler=handler)
391
392        elapse = time.time() - elapse
393        c_elapse = time.clock() - c_elapse
394
395        RESPONSE.redirect(
396            URL1 +
397            '/manage_catalogAdvanced?manage_tabs_message=' +
398            urllib.quote('Catalog Updated \n'
399                         'Total time: %s\n'
400                         'Total CPU time: %s' % (`elapse`, `c_elapse`)))
401
402
403    security.declarePrivate('notify_event_listener')
404    def notify_event_listener(self,event_type,object,infos):
405        "listen for events"
406        pt = object.portal_type
407        mt = object.meta_type
408        students_catalog = self.students_catalog
409        #if pt not in self.interesting_types:
410        #    return
411        #print "%(pt)s\n %(event_type)s \n %(infos)s\n" % vars()
412        if not infos.has_key('rpath'):
413            return
414        if pt == 'Student' and event_type == "workflow":
415            pass
416        elif mt == 'StudentApplication':
417            if event_type not in ('sys_modify_object'):
418                return
419            print "%(pt)s\n %(event_type)s \n %(infos)s\n" % vars()
420            from pdb import set_trace;set_trace()
421            jamb_reg_no = getattr(object,'jamb_reg_no',None)
422            if jamb_reg_no is None:
423                return
424            student_id = infos['rpath'].split('/')[2]
425            self.fixName(student_id)
426            student_entry = students_catalog(id = student_id)[0]
427            if student_entry.jamb_reg_no == jamb_reg_no:
428                return
429            students_catalog.modifyRecord(id = student_id,
430                                          jamb_reg_no = jamb_reg_no)
431        elif mt == 'StudentPersonal':
432            if event_type not in ('sys_modify_object'):
433                return
434            print "%(pt)s\n %(event_type)s \n %(infos)s\n" % vars()
435            student_id = infos['rpath'].split('/')[2]
436            self.fixName(student_id)
437
438
[971]439InitializeClass(StudentsCatalog)
440
[1146]441###)
442
443class CoursesCatalog(WAeUPTable): ###(
444
445    meta_type = 'WAeUP Courses Catalog'
446    name = "students_catalog"
447    key = "code"
448    def __init__(self):
449        WAeUPTable.__init__(self, 'courses_catalog')
450
451
452InitializeClass(CoursesCatalog)
[1151]453###)
[1146]454
[1653]455class OnlinePaymentsImport(WAeUPTable): ###(
456
457    meta_type = 'WAeUP Online Payment Transactions'
458    name = "online_payments_import"
459    key = "order_id"
460    def __init__(self):
461        WAeUPTable.__init__(self, self.name)
462
463
464InitializeClass(CoursesCatalog)
465###)
466
[1151]467class ReturningImport(WAeUPTable): ###(
[1146]468
[1151]469    meta_type = 'Returning Import Table'
470    name = "returning_import"
[1146]471    key = "matric_no"
472    def __init__(self):
[1151]473        WAeUPTable.__init__(self, 'returning_import')
[1146]474
475
[1151]476InitializeClass(ReturningImport)
477###)
[1146]478
479class ResultsImport(WAeUPTable): ###(
480
481    meta_type = 'Results Import Table'
482    name = "results_import"
483    key = "key"
484    def __init__(self):
485        WAeUPTable.__init__(self, 'results_import')
486
487
488InitializeClass(ResultsImport)
489
490###)
491
492class PaymentsCatalog(WAeUPTable): ###(
493
494    meta_type = 'WAeUP Payments Catalog'
495    name = "students_catalog"
496    key = "id"
497    def __init__(self):
498        WAeUPTable.__init__(self, 'payments_catalog')
499
500
501InitializeClass(PaymentsCatalog)
502
503###)
504
[414]505# BBB:
506AccomodationTable = AccommodationTable
Note: See TracBrowser for help on using the repository browser.