source: main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/applicants/applicant.py @ 7002

Last change on this file since 7002 was 7002, checked in by uli, 13 years ago

Throw in the complete mess of last 2 weeks. External file storage now works basically (tests pass), although there are lots of things still to remove, finetune, document, etc.

File size: 6.8 KB
Line 
1##
2## applicants.py
3## Login : <uli@pu.smp.net>
4## Started on  Fri Jul 16 11:46:55 2010 Uli Fouquet
5## $Id$
6##
7## Copyright (C) 2010 Uli Fouquet & Henrik Bettermann
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22import os
23import grok
24from grok import index
25from zope.component import getUtility
26from zope.component.interfaces import IFactory
27from zope.interface import implementedBy
28from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
29from waeup.sirp.interfaces import IObjectHistory, IExtFileStore
30from waeup.sirp.app import University
31from waeup.sirp.applicants.interfaces import (
32    IResultEntry, IApplicant, IApplicantEdit, default_passport_image,
33    )
34from waeup.sirp.image import WAeUPImageFile
35from waeup.sirp.utils.helpers import attrs_to_fields
36
37def get_regno_or_ac(context):
38    reg_no = getattr(context, 'reg_no', None)
39    if reg_no is None:
40        return getattr(context, 'access_code', None)
41    return reg_no
42
43class ResultEntry(grok.Context):
44    grok.implements(IResultEntry)
45
46    def __init__(self, subject=None, score=None):
47        self.subject = subject
48        self.score = score
49
50class Applicant(grok.Model):
51    grok.implements(IApplicant,IApplicantEdit)
52    grok.provides(IApplicant)
53
54    def __init__(self):
55        super(Applicant, self).__init__()
56        IWorkflowInfo(self).fireTransition('init')
57        self.application_date = None
58        return
59
60    #def getApplicantsRootLogger(self):
61    #    return grok.getSite()['applicants'].logger
62
63    def loggerInfo(self, ob_class, comment=None):
64        target = self.__name__
65        return grok.getSite()['applicants'].logger_info(ob_class,target,comment)
66
67    @property
68    def state(self):
69        state = IWorkflowState(self).getState()
70        return state
71
72    @property
73    def history(self):
74        history = IObjectHistory(self)
75        return history
76
77# Set all attributes of Applicant required in IApplicant as field
78# properties. Doing this, we do not have to set initial attributes
79# ourselves and as a bonus we get free validation when an attribute is
80# set.
81Applicant = attrs_to_fields(Applicant)
82
83class ApplicantCatalog(grok.Indexes):
84    """A catalog indexing :class:`Applicant` instances in the ZODB.
85    """
86    grok.site(University)
87    grok.name('applicants_catalog')
88    grok.context(IApplicant)
89
90    access_code = index.Field(attribute='access_code')
91
92#class ApplicantTraverser(grok.Traverser):
93#    """Get image of the context applicant.
94#
95#    Each applicant can provide a passport photograph which will be
96#    returned by this traverser if:
97#
98#    - we request the exact filename of the picture or
99#
100#    - ask for a picture named 'passport.jpg'.
101#
102#    If no picture was stored yet, we get a placeholder image when
103#    asking for `passport.jpg`.
104#
105#    If none of the above applies, we return ``None``, most probably
106#    resulting a :exc:`NotFound` exception.
107#
108#    """
109#    grok.context(IApplicant)
110#    def traverse(self, name):
111#        if name != 'passport.jpg':
112#            return
113#        marked_filename = '__img_appl__%s.jpg' % (
114#            get_regno_or_ac(self.context))
115#        image = getUtility(IExtFileStore).getFile(marked_filename)
116#        if image is None:
117#            # Return placeholder
118#            from waeup.sirp.applicants.interfaces import IMAGE_PATH
119#            return open(os.path.join(IMAGE_PATH, 'placeholder_m.jpg'), 'rb')
120#            pass
121#        return image #WAeUPImageFile(marked_filename, image.read())
122#        if not hasattr(self.context, 'passport'):
123#            return None
124#        passport_filename = getattr(self.context.passport, 'filename', None)
125#        if name == passport_filename:
126#            return self.context.passport
127#        if name == 'passport.jpg':
128#            if self.context.passport is not None:
129#                return self.context.passport
130#        return
131
132class ApplicantFactory(grok.GlobalUtility):
133    """A factory for applicants.
134    """
135    grok.implements(IFactory)
136    grok.name(u'waeup.Applicant')
137    title = u"Create a new applicant.",
138    description = u"This factory instantiates new applicant instances."
139
140    def __call__(self, *args, **kw):
141        return Applicant()
142
143    def getInterfaces(self):
144        return implementedBy(Applicant)
145
146from waeup.sirp.interfaces import IFileStoreHandler, IFileStoreNameChooser
147from waeup.sirp.imagestorage import DefaultFileStoreHandler
148
149APPLICANT_IMAGE_STORE_NAME = 'img-applicant'
150
151class ApplicantImageNameChooser(grok.Adapter):
152    grok.context(IApplicant)
153    grok.implements(IFileStoreNameChooser)
154
155    def checkName(self, name=None):
156        return name == self.chooseName(name, self.context)
157
158    def chooseName(self, name=None):
159        parent_name = getattr(
160            getattr(self.context, '__parent__', None),
161            '__name__', '_default')
162        marked_filename = '__%s__%s/%s.jpg' % (
163            APPLICANT_IMAGE_STORE_NAME,
164            parent_name, get_regno_or_ac(self.context))
165        return marked_filename
166
167
168class ApplicantImageStoreHandler(DefaultFileStoreHandler, grok.GlobalUtility):
169    """Applicant specific image handling.
170
171    This handler knows in which path in a filestore to store applicant
172    images and how to turn this kind of data into some (browsable)
173    file object.
174
175    It is called from the global file storage, when it wants to
176    get/store a file with a file id starting with
177    ``__img-applicant__`` (the marker string for applicant images).
178
179    Like each other file store handler it does not handle the files
180    really (this is done by the global file store) but only computes
181    paths and things like this.
182    """
183    grok.implements(IFileStoreHandler)
184    grok.name(APPLICANT_IMAGE_STORE_NAME)
185
186    def pathFromFileID(self, store, root, file_id):
187        """All applicants images are filed in directory ``applicants``.
188        """
189        marker, filename, basename, ext = store.extractMarker(file_id)
190        return os.path.join(root, 'applicants', filename)
191
192    def createFile(self, store, root, filename, file_id, file):
193        """Create a browsable file-like object.
194        """
195        # possible other actions: check for jpeg format
196        path = self.pathFromFileID(store, root, file_id)
197        return file, path, WAeUPImageFile(filename, file_id)
Note: See TracBrowser for help on using the repository browser.