source: main/waeup.sirp/trunk/src/waeup/sirp/university/catalog.py @ 7197

Last change on this file since 7197 was 7195, checked in by Henrik Bettermann, 13 years ago

More copyright adjustments.

  • Property svn:keywords set to Id
File size: 6.6 KB
Line 
1## $Id: catalog.py 7195 2011-11-25 07:34:07Z 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"""Catalog and searching components for academics stuff.
19"""
20import grok
21from hurry.query import Eq, Text
22from hurry.query.query import Query
23from zope.catalog.interfaces import ICatalog
24from zope.component import getUtility
25from zope.component.interfaces import ComponentLookupError
26from zope.index.text.parsetree import ParseError
27from zope.intid import IIntIds
28#from waeup.sirp.catalog import QueryResultItem
29from waeup.sirp.interfaces import IUniversity, IQueryResultItem
30from waeup.sirp.university.interfaces import (
31    ICourse, ICertificateCourse, IDepartment,
32    ICertificate,
33    )
34
35class CourseIndexes(grok.Indexes):
36    """This catalog is needed for building sources.
37    """
38    grok.site(IUniversity)
39    grok.name('courses_catalog')
40    grok.context(ICourse)
41
42    code = grok.index.Field(attribute='code')
43    title = grok.index.Text(attribute='title')
44
45class CertificatesIndexes(grok.Indexes):
46    """This catalog is needed for building sources.
47    """
48    grok.site(IUniversity)
49    grok.name('certificates_catalog')
50    grok.context(ICertificate)
51
52    code = grok.index.Field(attribute='code')
53    application_category = grok.index.Field(attribute='application_category')
54    title = grok.index.Text(attribute='title')
55
56class CertificateCoursesIndexes(grok.Indexes):
57    """This catalog is needed for automatic removal of certificate courses
58    and later for selection course tickets in the students section.
59    """
60    grok.site(IUniversity)
61    grok.name('certcourses_catalog')
62    grok.context(ICertificateCourse)
63
64    course_code = grok.index.Field(attribute='getCourseCode')
65    level = grok.index.Field(attribute='level')
66
67@grok.subscribe(ICourse, grok.IObjectAddedEvent)
68def handle_course_added(obj, event):
69    """Index an added course with the local catalog.
70
71    Courses are not indexed automatically, as they are not a
72    dictionary subitem of the accompanied site object
73    (`IUniversity`). I.e. one cannot get them by asking for
74    ``app['FACCODE']['DEPTCODE']['COURSECODE']`` but one has to ask for
75    ``app.faculties['FACCODE']['DEPTCODE'].courses['COURSECODE']``.
76
77    Once, a course is indexed we can leave the further handling to
78    the default component architechture. At least removals will
79    be handled correctly then (and the course unindexed).
80    """
81    try:
82        cat = getUtility(ICatalog, name='courses_catalog')
83    except ComponentLookupError:
84        # catalog not available. This might happen during tests.
85        return
86    intids = getUtility(IIntIds)
87    index = cat['code']
88    index.index_doc(intids.getId(obj), obj)
89
90@grok.subscribe(ICourse, grok.IObjectAddedEvent)
91def handle_certificate_added(obj, event):
92    """Index an added certificate with the local catalog.
93
94    See handleCourseAdd.
95    """
96    try:
97      cat = getUtility(ICatalog, name='certificates_catalog')
98    except ComponentLookupError:
99      # catalog not available. This might happen during tests.
100      return
101    intids = getUtility(IIntIds)
102    index = cat['code']
103    index.index_doc(intids.getId(obj), obj)
104
105@grok.subscribe(ICertificateCourse, grok.IObjectAddedEvent)
106def handlecertificatecourse_added(obj, event):
107    """Index an added certificatecourse with the local catalog.
108
109    See handleCourseAdd.
110    """
111    try:
112      cat = getUtility(ICatalog, name='certcourses_catalog')
113    except ComponentLookupError:
114      # catalog not available. This might happen during tests.
115      return
116    intids = getUtility(IIntIds)
117    index = cat['course_code']
118    index.index_doc(intids.getId(obj), obj)
119
120@grok.subscribe(IDepartment, grok.IObjectRemovedEvent)
121def handle_department_removed(obj, event):
122    """Clear courses and certificates when a department is killed.
123    """
124    obj.courses.clear()
125    obj.certificates.clear()
126    return
127
128class CoursesQueryResultItem(object):
129    grok.implements(IQueryResultItem)
130
131    def __init__(self, context, view):
132        self.context = context
133        self.url = view.url(context)
134        self.title = context.title
135        self.code = context.code
136        self.type = 'Course'
137
138class CertificatesQueryResultItem(object):
139    grok.implements(IQueryResultItem)
140
141    def __init__(self, context, view):
142        self.context = context
143        self.url = view.url(context)
144        self.title = context.title
145        self.code = context.code
146        self.type = 'Certificate'
147
148class CertificateCoursesQueryResultItem(object):
149    grok.implements(IQueryResultItem)
150
151    def __init__(self, context, view):
152        self.context = context
153        self.url = view.url(context)
154        self.title = context.course.title
155        self.code = context.getCourseCode
156        self.type = 'Course Referrer'
157
158def search(query=None, view=None):
159    if not query:
160        view.flash('Empty search string.')
161        return
162
163    hitlist = []
164    try:
165        results = Query().searchResults(
166            Eq(('courses_catalog', 'code'), query))
167        for result in results:
168            hitlist.append(CoursesQueryResultItem(result, view=view))
169        results = Query().searchResults(
170            Text(('courses_catalog', 'title'), query))
171        for result in results:
172            hitlist.append(CoursesQueryResultItem(result, view=view))
173        results = Query().searchResults(
174            Eq(('certificates_catalog', 'code'), query))
175        for result in results:
176            hitlist.append(CertificatesQueryResultItem(result, view=view))
177        results = Query().searchResults(
178            Text(('certificates_catalog', 'title'), query))
179        for result in results:
180            hitlist.append(CertificatesQueryResultItem(result, view=view))
181        results = Query().searchResults(
182            Eq(('certcourses_catalog', 'course_code'), query))
183        for result in results:
184            hitlist.append(CertificateCoursesQueryResultItem(result, view=view))
185    except ParseError:
186        view.flash('Search string not allowed.')
187        return
188    return hitlist
Note: See TracBrowser for help on using the repository browser.