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

Last change on this file since 6693 was 6447, checked in by Henrik Bettermann, 14 years ago

Implement search function for academic section. The courses_catalog and the certcourses_catalog are searched.

Remove search pages for students. Student search will be done in the upcoming student package.

File size: 4.6 KB
Line 
1"""Catalog and searching components for academics stuff.
2"""
3import grok
4from hurry.query import Eq, Text
5from hurry.query.query import Query
6from zope.catalog.interfaces import ICatalog
7from zope.component import getUtility
8from zope.component.interfaces import ComponentLookupError
9from zope.index.text.parsetree import ParseError
10from zope.intid import IIntIds
11#from waeup.sirp.catalog import QueryResultItem
12from waeup.sirp.index import UniqueField
13from waeup.sirp.interfaces import IUniversity, IQueryResultItem
14from waeup.sirp.university.interfaces import (
15    ICourse, ICertificateCourse, IDepartment,
16    ICertificate,
17    )
18
19class CourseIndexes(grok.Indexes):
20    """This catalog is needed for building sources.
21    """
22    grok.site(IUniversity)
23    grok.name('courses_catalog')
24    grok.context(ICourse)
25
26    code = UniqueField(attribute='code')
27    title = grok.index.Text(attribute='title')
28
29class CertificatesIndexes(grok.Indexes):
30    """This catalog is needed for building sources.
31    """
32    grok.site(IUniversity)
33    grok.name('certificates_catalog')
34    grok.context(ICertificate)
35
36    code = UniqueField(attribute='code')
37    application_category = grok.index.Field(attribute='application_category')
38
39class CertificateCoursesIndexes(grok.Indexes):
40    """This catalog is needed for automatic removal of certificate courses
41    and later for selection course tickets in the students section.
42    """
43    grok.site(IUniversity)
44    grok.name('certcourses_catalog')
45    grok.context(ICertificateCourse)
46
47    course_code = grok.index.Field(attribute='getCourseCode')
48
49@grok.subscribe(ICourse, grok.IObjectAddedEvent)
50def handleCourseAdd(obj, event):
51    """Index an added course with the local catalog.
52
53    Courses are not indexed automatically, as they are not a
54    dictionary subitem of the accompanied site object
55    (`IUniversity`). I.e. one cannot get them by asking for
56    ``app['FACCODE']['DEPTCODE']['COURSECODE']`` but one has to ask for
57    ``app.faculties['FACCODE']['DEPTCODE'].courses['COURSECODE']``.
58
59    Once, a course is indexed we can leave the further handling to
60    the default component architechture. At least removals will
61    be handled correctly then (and the course unindexed).
62    """
63    try:
64        cat = getUtility(ICatalog, name='courses_catalog')
65    except ComponentLookupError:
66        # catalog not available. This might happen during tests.
67        return
68    intids = getUtility(IIntIds)
69    index = cat['code']
70    index.index_doc(intids.getId(obj), obj)
71
72@grok.subscribe(ICourse, grok.IObjectAddedEvent)
73def handleCertificateAdd(obj, event):
74    """Index an added certificates with the local catalog.
75
76    See handleCourseAdd.
77    """
78    try:
79      cat = getUtility(ICatalog, name='certificates_catalog')
80    except ComponentLookupError:
81      # catalog not available. This might happen during tests.
82      return
83    intids = getUtility(IIntIds)
84    index = cat['code']
85    index.index_doc(intids.getId(obj), obj)
86
87@grok.subscribe(IDepartment, grok.IObjectRemovedEvent)
88def handleDepartmentRemoval(obj, event):
89    """Clear courses and certificates when a department is killed.
90    """
91    obj.courses.clear()
92    obj.certificates.clear()
93    return
94
95class CoursesQueryResultItem(object):
96    grok.implements(IQueryResultItem)
97
98    def __init__(self, context, view):
99        self.context = context
100        self.url = view.url(context)
101        self.title = context.title
102        self.code = context.code
103        self.type = 'Course'
104
105class CertificateCoursesQueryResultItem(object):
106    grok.implements(IQueryResultItem)
107
108    def __init__(self, context, view):
109        self.context = context
110        self.url = view.url(context)
111        self.title = context.course.title
112        self.code = context.getCourseCode
113        self.type = 'Course Referrer'
114
115def search(query=None, view=None):
116    if not query:
117        view.flash('Empty search string.')
118        return
119
120    hitlist = []
121    try:
122        results = Query().searchResults(
123            Eq(('courses_catalog', 'code'), query))
124        for result in results:
125            hitlist.append(CoursesQueryResultItem(result, view=view))
126        results = Query().searchResults(
127            Text(('courses_catalog', 'title'), query))
128        for result in results:
129            hitlist.append(CoursesQueryResultItem(result, view=view))
130
131        results = Query().searchResults(
132            Eq(('certcourses_catalog', 'course_code'), query))
133        for result in results:
134            hitlist.append(CertificateCoursesQueryResultItem(result, view=view))
135    except ParseError:
136        view.flash('Search string not allowed.')
137        return
138    return hitlist
Note: See TracBrowser for help on using the repository browser.