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
RevLine 
[4236]1import sys
[3526]2import grok
[3912]3from zope.component import getUtility
[4079]4from zope.component.factory import Factory
5from zope.component.interfaces import Invalid, IFactory
[4161]6from zope.component import createObject
[3878]7from zope.exceptions import DuplicationError
[4079]8from zope.interface import implementedBy
[4222]9from waeup.csvfile import CSVFile
10from waeup.csvfile.interfaces import ICSVFile
[4161]11from waeup.interfaces import IFacultyContainer, IFaculty, IWAeUPCSVImporter
12from waeup.utils.importexport import CSVImporter
[4236]13from waeup.viewlets import (MainArea, LeftSidebar, Index, Add, Manage,
14                            FormWrapMixin)
[3526]15
[4222]16
[3878]17class FacultyContainer(grok.Container):
[3912]18    """See interfaces for description.
19    """
[3828]20    grok.implements(IFacultyContainer)
[3884]21    grok.require('waeup.manageUniversity')
[3919]22
[3878]23    def addFaculty(self, faculty):
24        if not IFaculty.providedBy(faculty):
25            raise TypeError('FacultyContainers contain only IFaculty instances')
[4230]26        self[faculty.code] = faculty
27        return
[3878]28
[4161]29    def clear(self):
30        keys = self.keys()
31        for key in keys:
32            del self[key]
33
[4079]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."
[3878]41
[4079]42    def __call__(self):
43        return FacultyContainer()
44
45    def getInterfaces(self):
46        return implementedBy(FacultyContainer)
47
[4222]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
[4161]63class FacultyCSVImporter(CSVImporter):
[4222]64    """Shuffle data from faculty CSV files into faculty containers.
[4161]65    """
[4222]66    # Tell, what kinds of objects we connect...
67    grok.adapts(IFacultyCSVFile, IFacultyContainer)
68    # Tell the world, that we are an importer...
[4161]69    grok.implements(IWAeUPCSVImporter)
[4222]70    grok.provides(IWAeUPCSVImporter)
[4161]71
[4222]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():
[4161]78            new_item = createObject(u'waeup.Faculty')
[4222]79            for key, val in row.items():
80                setattr(new_item, key, val)
81            self.receiver.addFaculty(new_item)
[4161]82        return
83
[4250]84class IDepartmentCSVFile(ICSVFile):
85    """A CSV file that contains department data.
86    """
[4161]87
[4250]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']
[4222]94
[4250]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)
[4222]103
[4250]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
[4268]120class ICourseCSVFile(ICSVFile):
121    """A CSV file that contains course data.
122    """
[4250]123
[4268]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']
[4250]131
[4268]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)
[4250]140
[4268]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
[3912]162#
163# Viewing / Layout stuff...
164#
[3878]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():
[4132]178            result.append(dict(id=key, name=val.title))
[3878]179        return result
180
[4236]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       
[3878]210class AddFacultyForm(grok.AddForm):
211    grok.context(IFacultyContainer)
212    form_fields = grok.AutoFields(IFaculty)
[3884]213    label = 'Add a faculty'
[3878]214
215    @grok.action('Add faculty')
216    def addFaculty(self, **data):
[4161]217        faculty = createObject(u'waeup.Faculty')
[3878]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
[3910]227       
228class AddFaculty(FormWrapMixin, grok.Viewlet):
[3878]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
[3910]236    formview_name = 'addfacultyform' # The name of the formview we
237                                     # want to be rendered in this
238                                     # viewlet.
[3884]239
[3910]240
[3884]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>'
[4161]254
[4236]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.