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

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

Fix course importer.

  • Property svn:eol-style set to native
File size: 8.6 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
162
163
164#
165# Viewing / Layout stuff...
166#
167class Content(grok.Viewlet):
168    grok.viewletmanager(MainArea)
169    grok.context(IFacultyContainer)
170    grok.view(Index)
171
172    def getFaculties(self):
173        """Convinience method to create a sorted list of faculties.
174
175        It provides a list of dicts with entries for all data needed by
176        usual list templates.
177        """
178        result = []
179        for key, val in self.context.items():
180            result.append(dict(id=key, name=val.title))
181        return result
182
183class ManageFacultyContainer(grok.Viewlet):
184    grok.viewletmanager(MainArea)
185    grok.context(IFacultyContainer)
186    grok.view(Manage)
187    grok.template('manage')   
188
189    def update(self):
190        form = self.request.form
191        if 'CANCEL' in form.keys():
192            self.view.redirect(self.view.url(self.context))
193        if not 'DELETE' in form.keys():
194            return
195        fac_id = form['fac_id']
196        if not isinstance(fac_id, list):
197            fac_id = [fac_id]
198        deleted = []
199        for id in fac_id:
200            try:
201                del self.context[id]
202                deleted.append(id)
203            except:
204                self.view.flash('Could not delete %s: %s: %s' % (
205                        id, sys.exc_info()[0], sys.exc_info()[1]))
206        if len(deleted):
207            self.view.flash('Successfully deleted: %s' % ', '.join(deleted))
208        # We have to redirect to let flash messages appear immediately...
209        self.view.redirect(self.view.url())
210        return
211       
212class AddFacultyForm(grok.AddForm):
213    grok.context(IFacultyContainer)
214    form_fields = grok.AutoFields(IFaculty)
215    label = 'Add a faculty'
216
217    @grok.action('Add faculty')
218    def addFaculty(self, **data):
219        faculty = createObject(u'waeup.Faculty')
220        self.applyData(faculty, **data)
221        try:
222            self.context.addFaculty(faculty)
223        except DuplicationError:
224            self.status = Invalid('The name chosen already exists '
225                                  'in the database')
226            return
227        self.redirect(self.url(self.context))
228
229       
230class AddFaculty(FormWrapMixin, grok.Viewlet):
231    """A viewlet that wraps the `AddFacultyForm`.
232    """
233    grok.viewletmanager(MainArea)
234    grok.context(IFacultyContainer)
235    grok.view(Add)
236    grok.require('waeup.manageUniversity')
237
238    formview_name = 'addfacultyform' # The name of the formview we
239                                     # want to be rendered in this
240                                     # viewlet.
241
242
243class AddFacultyLink(grok.Viewlet):
244    """A link in the left sidebar displaying 'Add faculty'
245    """
246    grok.viewletmanager(LeftSidebar)
247    grok.context(IFacultyContainer)
248    grok.view(Index)
249    grok.order(5)
250    # This is so cool! This link is only displayed, when the user is
251    # allowed to use it!
252    grok.require('waeup.manageUniversity')
253   
254    def render(self):
255        return u'<div class="portlet"><a href="add">Add faculty</a></div>'
256
257class ManageFacultyLink(grok.Viewlet):
258    """A link in the left sidebar displaying 'Manage faculty'
259    """
260    grok.viewletmanager(LeftSidebar)
261    grok.context(IFacultyContainer)
262    grok.view(Index)
263    grok.order(5)
264    grok.require('waeup.manageUniversity')
265   
266    def render(self):
267        return u'<div class="portlet"><a href="manage">Manage faculties</a></div>'
Note: See TracBrowser for help on using the repository browser.