source: main/waeup.kofa/trunk/src/waeup/kofa/university/course.py @ 12395

Last change on this file since 12395 was 10685, checked in by Henrik Bettermann, 11 years ago

Remove other redundant interfaces, see previous revision.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.0 KB
Line 
1## $Id: course.py 10685 2013-11-02 09:02:26Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""Courses.
19"""
20import grok
21import zope.location.location
22from zope.catalog.interfaces import ICatalog
23from zope.interface import implementedBy
24from zope.schema import getFields
25from zope.intid.interfaces import IIntIds
26from zope.component import getUtility
27from zope.component.interfaces import IFactory, ComponentLookupError
28from waeup.kofa.interfaces import IKofaPluggable
29from waeup.kofa.university.interfaces import ICourse
30from waeup.kofa.utils.batching import VirtualExportJobContainer
31
32class VirtualCourseExportJobContainer(VirtualExportJobContainer):
33    """A virtual export job container for courses.
34    """
35
36class Course(grok.Model):
37    """A university course.
38    """
39    grok.implements(ICourse)
40
41    local_roles = ['waeup.local.Lecturer']
42
43    def __init__(self,
44                 title=u'Unnamed Course',
45                 code=u'NA',
46                 credits=0,
47                 passmark=40,
48                 semester=1,
49                 former_course=False,
50                 **kw):
51        super(Course, self).__init__(**kw)
52        self.title = title
53        self.code = code
54        self.credits = credits
55        self.passmark = passmark
56        self.semester = semester
57        self.former_course = former_course
58
59    def traverse(self, name):
60        """Deliver appropriate containers.
61        """
62        if name == 'exports':
63            # create a virtual exports container and return it
64            container = VirtualCourseExportJobContainer()
65            zope.location.location.located(container, self, 'exports')
66            return container
67        return None
68
69    @property
70    def longtitle(self):
71        return "%s (%s)" % (self.title,self.code)
72
73class CourseFactory(grok.GlobalUtility):
74    """A factory for courses.
75    """
76    grok.implements(IFactory)
77    grok.name(u'waeup.Course')
78    title = u"Create a new course.",
79    description = u"This factory instantiates new course instances."
80
81    def __call__(self, *args, **kw):
82        return Course(*args, **kw)
83
84    def getInterfaces(self):
85        return implementedBy(Course)
86
87@grok.subscribe(ICourse, grok.IObjectRemovedEvent)
88def handle_course_removed(course, event):
89    """If a course is deleted, we make sure that also referrers in a
90       certificatescontainer are removed.
91    """
92    code = course.code
93
94    # Find all certificatecourses that refer to given course
95    try:
96        cat = getUtility(ICatalog, name='certcourses_catalog')
97    except ComponentLookupError:
98        # catalog not available. This might happen during tests.
99        return
100
101    results = cat.searchResults(course_code=(code, code))
102
103    # remove each found referrer (certs might refer to same course multiple
104    # times)
105    certs = [x.__parent__ for x in results]
106    unique_certs = list(set(certs))
107    for cert in unique_certs:
108        cert.delCertCourses(code)
109    return
110
111@grok.subscribe(ICourse, grok.IObjectModifiedEvent)
112def handle_set_former_course(course, event):
113    """If a former course attribute is set, we make sure that referrers in a
114       certificatescontainer are removed.
115    """
116    if event.object.former_course:
117        handle_course_removed(course, event)
118    return
119
120class CoursesPlugin(grok.GlobalUtility):
121    """A plugin that updates courses.
122    """
123
124    grok.implements(IKofaPluggable)
125    grok.name('courses')
126
127    deprecated_attributes = []
128
129    def setup(self, site, name, logger):
130        return
131
132    def update(self, site, name, logger):
133        cat = getUtility(ICatalog, name='courses_catalog')
134        results = cat.apply({'code':(None,None)})
135        uidutil = getUtility(IIntIds, context=cat)
136        items = getFields(ICourse).items()
137        for r in results:
138            o = uidutil.getObject(r)
139            # Add new attributes
140            for i in items:
141                if not hasattr(o,i[0]):
142                    setattr(o,i[0],i[1].missing_value)
143                    logger.info(
144                        'CoursesPlugin: %s attribute %s added.' % (
145                        o.code,i[0]))
146            # Remove deprecated attributes
147            for i in self.deprecated_attributes:
148                try:
149                    delattr(o,i)
150                    logger.info(
151                        'CoursesPlugin: %s attribute %s deleted.' % (
152                        o.code,i))
153                except AttributeError:
154                    pass
155        return
Note: See TracBrowser for help on using the repository browser.