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

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

Add 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 faculties.
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            #data = row.items()
112            faculty_code = row['faculty_code']
113            faculty = self.receiver[faculty_code]
114            del row['faculty_code']
115            for key, val in row.items():
116                setattr(new_item, key, val)
117            faculty.addDepartment(new_item)
118        return
119
120class ICourseCSVFile(ICSVFile):
121    """A CSV file that contains course data.
122    """
123
124class CourseCSVFile(CSVFile):
125    """An abstraction of a CSV file containing courses.
126    """
127    grok.implements(ICourseCSVFile)
128    grok.provides(ICourseCSVFile)
129    required_fields = ['code', 'title', 'level', 'passmark', 'credits',
130                       'semester', 'faculty', 'department']
131
132class CourseCSVImporter(CSVImporter):
133    """Shuffle data from course CSV files into faculty containers.
134    """
135    # Tell, what kinds of objects we connect...
136    grok.adapts(ICourseCSVFile, IFacultyContainer)
137    # Tell the world, that we are an importer...
138    grok.implements(IWAeUPCSVImporter)
139    grok.provides(IWAeUPCSVImporter)
140
141    datatype = u'Course Importer'
142
143    def doImport(self, clear_old_data=True, overwrite=True):
144        # CSVImporter instances have a `csvfile` and a `receiver`
145        # object defined which refer to the CSV file and the container.
146        for row in self.csvfile.getData():
147            new_item = createObject(u'waeup.Course')
148            faculty_code = row['faculty']
149            faculty = self.receiver[faculty_code]
150            del row[faculty_code]
151            dept_code = row['department']
152            dept = faculty[dept_code]
153            del row[dept_code]
154            for key, val in row.items():
155                setattr(new_item, key, val)
156            dept.addCourse(new_item)
157        return
158
159
160
161
162#
163# Viewing / Layout stuff...
164#
165class Content(grok.Viewlet):
166    grok.viewletmanager(MainArea)
167    grok.context(IFacultyContainer)
168    grok.view(Index)
169
170    def getFaculties(self):
171        """Convinience method to create a sorted list of faculties.
172
173        It provides a list of dicts with entries for all data needed by
174        usual list templates.
175        """
176        result = []
177        for key, val in self.context.items():
178            result.append(dict(id=key, name=val.title))
179        return result
180
181class ManageFacultyContainer(grok.Viewlet):
182    grok.viewletmanager(MainArea)
183    grok.context(IFacultyContainer)
184    grok.view(Manage)
185    grok.template('manage')   
186
187    def update(self):
188        form = self.request.form
189        if 'CANCEL' in form.keys():
190            self.view.redirect(self.view.url(self.context))
191        if not 'DELETE' in form.keys():
192            return
193        fac_id = form['fac_id']
194        if not isinstance(fac_id, list):
195            fac_id = [fac_id]
196        deleted = []
197        for id in fac_id:
198            try:
199                del self.context[id]
200                deleted.append(id)
201            except:
202                self.view.flash('Could not delete %s: %s: %s' % (
203                        id, sys.exc_info()[0], sys.exc_info()[1]))
204        if len(deleted):
205            self.view.flash('Successfully deleted: %s' % ', '.join(deleted))
206        # We have to redirect to let flash messages appear immediately...
207        self.view.redirect(self.view.url())
208        return
209       
210class AddFacultyForm(grok.AddForm):
211    grok.context(IFacultyContainer)
212    form_fields = grok.AutoFields(IFaculty)
213    label = 'Add a faculty'
214
215    @grok.action('Add faculty')
216    def addFaculty(self, **data):
217        faculty = createObject(u'waeup.Faculty')
218        self.applyData(faculty, **data)
219        try:
220            self.context.addFaculty(faculty)
221        except DuplicationError:
222            self.status = Invalid('The name chosen already exists '
223                                  'in the database')
224            return
225        self.redirect(self.url(self.context))
226
227       
228class AddFaculty(FormWrapMixin, grok.Viewlet):
229    """A viewlet that wraps the `AddFacultyForm`.
230    """
231    grok.viewletmanager(MainArea)
232    grok.context(IFacultyContainer)
233    grok.view(Add)
234    grok.require('waeup.manageUniversity')
235
236    formview_name = 'addfacultyform' # The name of the formview we
237                                     # want to be rendered in this
238                                     # viewlet.
239
240
241class AddFacultyLink(grok.Viewlet):
242    """A link in the left sidebar displaying 'Add faculty'
243    """
244    grok.viewletmanager(LeftSidebar)
245    grok.context(IFacultyContainer)
246    grok.view(Index)
247    grok.order(5)
248    # This is so cool! This link is only displayed, when the user is
249    # allowed to use it!
250    grok.require('waeup.manageUniversity')
251   
252    def render(self):
253        return u'<div class="portlet"><a href="add">Add faculty</a></div>'
254
255class ManageFacultyLink(grok.Viewlet):
256    """A link in the left sidebar displaying 'Manage faculty'
257    """
258    grok.viewletmanager(LeftSidebar)
259    grok.context(IFacultyContainer)
260    grok.view(Index)
261    grok.order(5)
262    grok.require('waeup.manageUniversity')
263   
264    def render(self):
265        return u'<div class="portlet"><a href="manage">Manage faculties</a></div>'
Note: See TracBrowser for help on using the repository browser.