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

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

Extend certificates_catalog and let's search for certificates too.

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