source: waeup/branches/ulif-rewrite/src/waeup/university/facultycontainer.py @ 4329

Last change on this file since 4329 was 4329, checked in by uli, 16 years ago

Add importer for CSV certificate files.

  • Property svn:eol-style set to native
File size: 10.2 KB
Line 
1import sys
2import grok
3from zope.component import getUtility
4from zope.component.factory import Factory
5from zope.component.interfaces import Invalid, IFactory
6from zope.component import createObject
7from zope.exceptions import DuplicationError
8from zope.interface import implementedBy
9from waeup.csvfile import CSVFile
10from waeup.csvfile.interfaces import ICSVFile
11from waeup.interfaces import IFacultyContainer, IFaculty, IWAeUPCSVImporter
12from waeup.utils.importexport import CSVImporter
13from waeup.viewlets import (MainArea, LeftSidebar, Index, Add, Manage,
14                            FormWrapMixin)
15
16
17class FacultyContainer(grok.Container):
18    """See interfaces for description.
19    """
20    grok.implements(IFacultyContainer)
21    grok.require('waeup.manageUniversity')
22
23    def addFaculty(self, faculty):
24        if not IFaculty.providedBy(faculty):
25            raise TypeError('FacultyContainers contain only IFaculty instances')
26        self[faculty.code] = faculty
27        return
28
29    def clear(self):
30        keys = self.keys()
31        for key in keys:
32            del self[key]
33
34class FacultyContainerFactory(grok.GlobalUtility):
35    """A factory for faculty containers.
36    """
37    grok.implements(IFactory)
38    grok.name(u'waeup.FacultyContainer')
39    title = u"Create a new faculty container.",
40    description = u"This factory instantiates new faculty containers."
41
42    def __call__(self):
43        return FacultyContainer()
44
45    def getInterfaces(self):
46        return implementedBy(FacultyContainer)
47
48
49#
50# CSV import stuff
51#
52class IFacultyCSVFile(ICSVFile):
53    """A CSV file that contains faculty data.
54    """
55
56class FacultyCSVFile(CSVFile):
57    """An abstraction of a CSV file containing faculties.
58    """
59    grok.implements(IFacultyCSVFile)
60    grok.provides(IFacultyCSVFile)
61    required_fields = ['code', 'title', 'title_prefix']
62
63class FacultyCSVImporter(CSVImporter):
64    """Shuffle data from faculty CSV files into faculty containers.
65    """
66    # Tell, what kinds of objects we connect...
67    grok.adapts(IFacultyCSVFile, IFacultyContainer)
68    # Tell the world, that we are an importer...
69    grok.implements(IWAeUPCSVImporter)
70    grok.provides(IWAeUPCSVImporter)
71
72    datatype = u'Faculty Importer'
73
74    def doImport(self, clear_old_data=True, overwrite=True):
75        # CSVImporter instances have a `csvfile` and a `receiver`
76        # object defined which refer to the CSV file and the container.
77        for row in self.csvfile.getData():
78            new_item = createObject(u'waeup.Faculty')
79            for key, val in row.items():
80                setattr(new_item, key, val)
81            self.receiver.addFaculty(new_item)
82        return
83
84class IDepartmentCSVFile(ICSVFile):
85    """A CSV file that contains department data.
86    """
87
88class DepartmentCSVFile(CSVFile):
89    """An abstraction of a CSV file containing departments.
90    """
91    grok.implements(IDepartmentCSVFile)
92    grok.provides(IDepartmentCSVFile)
93    required_fields = ['code', 'title', 'title_prefix', 'faculty_code']
94
95class DepartmentCSVImporter(CSVImporter):
96    """Shuffle data from department CSV files into faculty containers.
97    """
98    # Tell, what kinds of objects we connect...
99    grok.adapts(IDepartmentCSVFile, IFacultyContainer)
100    # Tell the world, that we are an importer...
101    grok.implements(IWAeUPCSVImporter)
102    grok.provides(IWAeUPCSVImporter)
103
104    datatype = u'Department Importer'
105
106    def doImport(self, clear_old_data=True, overwrite=True):
107        # CSVImporter instances have a `csvfile` and a `receiver`
108        # object defined which refer to the CSV file and the container.
109        for row in self.csvfile.getData():
110            new_item = createObject(u'waeup.Department')
111            faculty_code = row['faculty_code']
112            faculty = self.receiver[faculty_code]
113            del row['faculty_code']
114            for key, val in row.items():
115                setattr(new_item, key, val)
116            faculty.addDepartment(new_item)
117        return
118
119class ICourseCSVFile(ICSVFile):
120    """A CSV file that contains course data.
121    """
122
123class CourseCSVFile(CSVFile):
124    """An abstraction of a CSV file containing courses.
125    """
126    grok.implements(ICourseCSVFile)
127    grok.provides(ICourseCSVFile)
128    required_fields = ['code', 'title', 'level', 'passmark', 'credits',
129                       'semester', 'faculty', 'department']
130
131class CourseCSVImporter(CSVImporter):
132    """Shuffle data from course CSV files into faculty containers.
133    """
134    # Tell, what kinds of objects we connect...
135    grok.adapts(ICourseCSVFile, IFacultyContainer)
136    # Tell the world, that we are an importer...
137    grok.implements(IWAeUPCSVImporter)
138    grok.provides(IWAeUPCSVImporter)
139
140    datatype = u'Course Importer'
141
142    def doImport(self, clear_old_data=True, overwrite=True):
143        # CSVImporter instances have a `csvfile` and a `receiver`
144        # object defined which refer to the CSV file and the container.
145        for row in self.csvfile.getData():
146
147            new_item = createObject(u'waeup.Course')
148           
149            faculty_code = row['faculty']
150            faculty = self.receiver[faculty_code]
151            del row['faculty']
152
153            dept_code = row['department']
154            dept = faculty[dept_code]
155            del row['department']
156
157            for key, val in row.items():
158                setattr(new_item, key, val)
159            dept.courses.addCourse(new_item)
160        return
161
162class ICertificateCSVFile(ICSVFile):
163    """A CSV file that contains certificate data.
164    """
165
166class CertificateCSVFile(CSVFile):
167    """An abstraction of a CSV file containing certificates.
168    """
169    grok.implements(ICertificateCSVFile)
170    grok.provides(ICertificateCSVFile)
171    required_fields = ['code', 'title', 'faculty_code', 'department_code',
172                       'category', 'study_mode', 'start_level', 'end_level',
173                       'm_prefix', 'max_pass', 'application_category']
174
175class CertificateCSVImporter(CSVImporter):
176    """Shuffle data from certificate CSV files into faculty containers.
177    """
178    # Tell, what kinds of objects we connect...
179    grok.adapts(ICertificateCSVFile, IFacultyContainer)
180    # Tell the world, that we are an importer...
181    grok.implements(IWAeUPCSVImporter)
182    grok.provides(IWAeUPCSVImporter)
183
184    datatype = u'Certificate Importer'
185
186    def doImport(self, clear_old_data=True, overwrite=True):
187        # CSVImporter instances have a `csvfile` and a `receiver`
188        # object defined which refer to the CSV file and the container.
189        for row in self.csvfile.getData():
190
191            new_item = createObject(u'waeup.Certificate')
192           
193            faculty_code = row['faculty_code']
194            faculty = self.receiver[faculty_code]
195            del row['faculty_code']
196
197            dept_code = row['department_code']
198            dept = faculty[dept_code]
199            del row['department_code']
200
201            for key, val in row.items():
202                setattr(new_item, key, val)
203            dept.certificates.addCertificate(new_item)
204        return
205
206
207
208#
209# Viewing / Layout stuff...
210#
211class Content(grok.Viewlet):
212    grok.viewletmanager(MainArea)
213    grok.context(IFacultyContainer)
214    grok.view(Index)
215
216    def getFaculties(self):
217        """Convinience method to create a sorted list of faculties.
218
219        It provides a list of dicts with entries for all data needed by
220        usual list templates.
221        """
222        result = []
223        for key, val in self.context.items():
224            result.append(dict(id=key, name=val.title))
225        return result
226
227class ManageFacultyContainer(grok.Viewlet):
228    grok.viewletmanager(MainArea)
229    grok.context(IFacultyContainer)
230    grok.view(Manage)
231    grok.template('manage')   
232
233    def update(self):
234        form = self.request.form
235        if 'CANCEL' in form.keys():
236            self.view.redirect(self.view.url(self.context))
237        if not 'DELETE' in form.keys():
238            return
239        fac_id = form['fac_id']
240        if not isinstance(fac_id, list):
241            fac_id = [fac_id]
242        deleted = []
243        for id in fac_id:
244            try:
245                del self.context[id]
246                deleted.append(id)
247            except:
248                self.view.flash('Could not delete %s: %s: %s' % (
249                        id, sys.exc_info()[0], sys.exc_info()[1]))
250        if len(deleted):
251            self.view.flash('Successfully deleted: %s' % ', '.join(deleted))
252        # We have to redirect to let flash messages appear immediately...
253        self.view.redirect(self.view.url())
254        return
255       
256class AddFacultyForm(grok.AddForm):
257    grok.context(IFacultyContainer)
258    form_fields = grok.AutoFields(IFaculty)
259    label = 'Add a faculty'
260
261    @grok.action('Add faculty')
262    def addFaculty(self, **data):
263        faculty = createObject(u'waeup.Faculty')
264        self.applyData(faculty, **data)
265        try:
266            self.context.addFaculty(faculty)
267        except DuplicationError:
268            self.status = Invalid('The name chosen already exists '
269                                  'in the database')
270            return
271        self.redirect(self.url(self.context))
272
273       
274class AddFaculty(FormWrapMixin, grok.Viewlet):
275    """A viewlet that wraps the `AddFacultyForm`.
276    """
277    grok.viewletmanager(MainArea)
278    grok.context(IFacultyContainer)
279    grok.view(Add)
280    grok.require('waeup.manageUniversity')
281
282    formview_name = 'addfacultyform' # The name of the formview we
283                                     # want to be rendered in this
284                                     # viewlet.
285
286
287class AddFacultyLink(grok.Viewlet):
288    """A link in the left sidebar displaying 'Add faculty'
289    """
290    grok.viewletmanager(LeftSidebar)
291    grok.context(IFacultyContainer)
292    grok.view(Index)
293    grok.order(5)
294    # This is so cool! This link is only displayed, when the user is
295    # allowed to use it!
296    grok.require('waeup.manageUniversity')
297   
298    def render(self):
299        return u'<div class="portlet"><a href="add">Add faculty</a></div>'
300
301class ManageFacultyLink(grok.Viewlet):
302    """A link in the left sidebar displaying 'Manage faculty'
303    """
304    grok.viewletmanager(LeftSidebar)
305    grok.context(IFacultyContainer)
306    grok.view(Index)
307    grok.order(5)
308    grok.require('waeup.manageUniversity')
309   
310    def render(self):
311        return u'<div class="portlet"><a href="manage">Manage faculties</a></div>'
Note: See TracBrowser for help on using the repository browser.