source: main/waeup.sirp/branches/ulif-fasttables/src/waeup/sirp/jambtables/jambtables.py @ 5235

Last change on this file since 5235 was 5235, checked in by uli, 14 years ago

Add first sketch for JAMB tables.

File size: 4.6 KB
Line 
1##
2## jambtables.py
3## Login : <uli@pu.smp.net>
4## Started on  Tue Jun 22 06:31:42 2010 Uli Fouquet
5## $Id$
6##
7## Copyright (C) 2010 Uli Fouquet
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22import csv
23import os
24import shutil
25import tempfile
26import grok
27
28from datetime import datetime
29from BTrees.OOBTree import OOBTree
30from BTrees.Length import Length
31
32def filter_data(datadict):
33    """Filter items whose key contains 'ignore'
34    """
35    keys = datadict.keys()
36    for key in keys:
37        if not 'ignore' in key:
38            continue
39        del datadict[key]
40    for name in ['firstname', 'lastname', 'middlenames', 'screening_type',
41                 'screening_venue', 'reg_no', 'sex', 'course1', 'jamb_state',
42                 'screening_date', 'jamb_lga', 'fst_sit_fname',]:
43        datadict[name] = unicode(datadict[name])
44    datadict['date_of_birth'] = datetime.strptime(
45        datadict['date_of_birth'],
46        '%d/%m/%Y'
47        ).date()
48   
49    return datadict
50
51
52class JAMBDataTable(grok.Model):
53    """A data table that contains JAMB data.
54
55    JAMB data tables are plain but fast as they store nearly no data
56    inside the ZODB. All data is held on-disk in CSV tables.
57
58    As a consequence these tables are read-only.
59    """
60
61    import_datetime = None
62   
63    def __init__(self):
64        super(JAMBDataTable, self).__init__()
65        self._datafile_path = None
66        self._data_len = 0
67        self._temporary = False
68        return
69
70    def __del__(self):
71        self.clear()
72
73    def __iter__(self):
74        reader = None
75        if self._datafile_path is not None:
76            reader = csv.DictReader(open(self._datafile_path, 'rb'))
77        if reader is None:
78            raise StopIteration
79        for line in reader:
80            data_dict = filter_data(line)
81            yield data_dict
82
83    def clear(self):
84        """Remove all existing entries.
85        """
86        if self._datafile_path is None:
87            return
88        if self._temporary:
89            if not os.path.exists(self._datafile_path):
90                return
91            shutil.rmtree(os.path.dirname(self._datafile_path))
92           
93    def importFromCSV(self, filepath):
94        """Importing data from a CSV file means to copy the source to a safe
95           location.
96        """
97        self.clear()
98        self.import_datetime = datetime.now()
99        self._copyDataFile(filepath)
100
101    #def add(self, reg_no, data_dict):
102    #    item = filter_data(data_dict)
103    #    item.__name__ = reg_no
104    #    item.__parent__ = self
105    #    #if send_events:
106    #    #    objectEventNotify(ObjectWillBeAddedEvent(item, self, reg_no))
107    #    #self._data[reg_no] = item
108    #    self._data_len += 1
109    #    #if senf_event:
110    #    #    objectEventNotify(ObjectAddedEvent(item, self, reg_no))
111
112    def _copyDataFile(self, path):
113        """Copy file in path to the JAMBData storage.
114
115        See :meth:`_getJAMBTableStorage`.
116        """
117        storage = self._getJAMBTableStorage()
118        self._datafile_path = os.path.join(
119            storage, os.path.basename(path)
120            )
121        shutil.copy2(path, self._datafile_path)
122        return
123
124    def _getJAMBTableStorage(self):
125        """Get a path to store copies of datatables.
126
127        We normally store data in a ``jambdata`` subdir of datacenter,
128        but if none exists, we create a temporary dir and set
129        `temporary` to ``True``.
130
131        Any not existent directory is created.
132
133        Note, that temporary dirs will be deleted when the
134        JAMBDataTable object is destroyed.
135
136        Returns absolute path to the JAMB data storage.
137        """
138        site = grok.getSite()
139        if site is None:
140            jambtable_storage = tempfile.mkdtemp()
141            self._temporary = True
142        else:
143            datacenter = site['datacenter']
144            jambtable_storage = os.path.join(datacenter.storage, 'jambdata')
145        if not os.path.isdir(jambtable_storage):
146            os.mkdir(jambtable_storage)
147        return os.path.abspath(jambtable_storage)
Note: See TracBrowser for help on using the repository browser.