source: main/waeup.sirp/trunk/src/waeup/sirp/students/viewlets.py @ 7625

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

Move all action button viewlets from browser module to viewlets module.

  • Property svn:keywords set to Id
File size: 24.7 KB
RevLine 
[7191]1## $Id: viewlets.py 7591 2012-02-06 16:57:37Z 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##
[7106]18import os
[6642]19import grok
[7097]20from zope.component import getUtility
[6642]21from zope.interface import Interface
[7097]22from waeup.sirp.interfaces import (
[7321]23    ISIRPObject, IExtFileStore, IFileStoreNameChooser)
[7097]24from waeup.sirp.utils.helpers import string_from_bytes, file_size
25from waeup.sirp.browser import DEFAULT_IMAGE_PATH
[7591]26from waeup.sirp.browser.viewlets import (
27    PrimaryNavTab, ManageActionButton, AddActionButton)
[7243]28from waeup.sirp.browser.layout import default_primary_nav_template
[7591]29from waeup.sirp.students.workflow import (ADMITTED, PAID,
30    CLEARANCE, REQUESTED, RETURNING, CLEARED, REGISTERED, VALIDATED)
[7097]31from waeup.sirp.students.browser import (
[7591]32    StudentClearanceManageFormPage,
33    write_log_message, StudentBaseManageFormPage,
34    StudentFilesUploadPage, ExportPDFClearanceSlipPage, StudentsContainerPage,
35    StudentsContainerManagePage, StudentBaseDisplayFormPage,
36    StudentClearanceDisplayFormPage, StudentPersonalDisplayFormPage,
37    StudyCourseDisplayFormPage, StudyLevelDisplayFormPage,
38    CourseTicketDisplayFormPage, OnlinePaymentDisplayFormPage,
39    AccommodationManageFormPage, BedTicketDisplayFormPage,)
40from waeup.sirp.students.interfaces import (
41    IStudentsContainer, IStudent, IStudentClearance,
42    IStudentStudyCourse, IStudentAccommodation, IStudentStudyLevel,
43    ICourseTicket, IStudentOnlinePayment, IBedTicket,
44    )
[6642]45
[7321]46grok.context(ISIRPObject) # Make ISIRPObject the default context
[6687]47grok.templatedir('browser_templates')
[6642]48
[7123]49ALLOWED_FILE_EXTENSIONS = ('jpg', 'png', 'pdf', 'tif')
50
[6687]51class StudentManageSidebar(grok.ViewletManager):
52    grok.name('left_studentmanage')
[6642]53
[6687]54class StudentManageLink(grok.Viewlet):
[6660]55    """A link displayed in the student box which shows up for StudentNavigation
[6642]56    objects.
57
58    """
59    grok.baseclass()
[6687]60    grok.viewletmanager(StudentManageSidebar)
[7321]61    grok.context(ISIRPObject)
[6642]62    grok.view(Interface)
63    grok.order(5)
[6660]64    grok.require('waeup.viewStudent')
[6642]65
66    link = 'index'
67    text = u'Base Data'
68
69    def render(self):
70        url = self.view.url(self.context.getStudent(), self.link)
[7459]71        return u'<li><a href="%s">%s</a></li>' % (
[6642]72                url, self.text)
73
[7459]74class StudentManageApplicationLink(StudentManageLink):
[6687]75    grok.order(1)
[7351]76    link = 'application_slip'
77    text = u'Application Slip'
[7340]78
79    def render(self):
[7351]80        slip = getUtility(IExtFileStore).getFileByContext(
81            self.context.getStudent(), attr=self.link)
82        if slip:
83            url = self.view.url(self.context,self.link)
[7459]84            return u'<li><a href="%s">%s</a></li>' % (
[7340]85                    url, self.text)
86        return ''
87
[7459]88class StudentManageBaseLink(StudentManageLink):
89    grok.order(2)
90    link = 'index'
91    text = u'Base Data'
92
[6687]93class StudentManageClearanceLink(StudentManageLink):
[7340]94    grok.order(3)
[6687]95    link = 'view_clearance'
96    text = u'Clearance Data'
97
98class StudentManagePersonalLink(StudentManageLink):
[7340]99    grok.order(4)
[6687]100    link = 'view_personal'
101    text = u'Personal Data'
102
103class StudentManageStudyCourseLink(StudentManageLink):
[7340]104    grok.order(5)
[6687]105    link = 'studycourse'
106    text = u'Study Course'
107
108class StudentManagePaymentsLink(StudentManageLink):
[7340]109    grok.order(6)
[7181]110    grok.require('waeup.payStudent')
[6687]111    link = 'payments'
112    text = u'Payments'
113
114class StudentManageAccommodationLink(StudentManageLink):
[7340]115    grok.order(7)
[7181]116    grok.require('waeup.handleAccommodation')
[6687]117    link = 'accommodation'
[7459]118    text = u'Accommodation'
[6687]119
120class StudentManageHistoryLink(StudentManageLink):
[7340]121    grok.order(8)
[6687]122    link = 'history'
123    text = u'History'
124
[7591]125
126class StudentsContainerManageActionButton(ManageActionButton):
127    grok.order(1)
128    grok.context(IStudentsContainer)
129    grok.view(StudentsContainerPage)
130    grok.require('waeup.manageStudent')
131    text = 'Manage student section'
132
133class StudentsContainerAddActionButton(AddActionButton):
134    grok.order(1)
135    grok.context(IStudentsContainer)
136    grok.view(StudentsContainerManagePage)
137    grok.require('waeup.manageStudent')
138    text = 'Add student'
139    target = 'addstudent'
140
141class ContactActionButton(ManageActionButton):
142    grok.order(4)
143    grok.context(IStudent)
144    grok.view(StudentBaseDisplayFormPage)
145    grok.require('waeup.manageStudent')
146    icon = 'actionicon_mail.png'
147    text = 'Send email'
148    target = 'contactstudent'
149
150class StudentBaseManageActionButton(ManageActionButton):
151    grok.order(1)
152    grok.context(IStudent)
153    grok.view(StudentBaseDisplayFormPage)
154    grok.require('waeup.manageStudent')
155    text = 'Manage'
156    target = 'manage_base'
157
158class StudentClearanceManageActionButton(ManageActionButton):
159    grok.order(1)
160    grok.context(IStudent)
161    grok.view(StudentClearanceDisplayFormPage)
162    grok.require('waeup.manageStudent')
163    text = 'Manage'
164    target = 'edit_clearance'
165
166class StudentClearActionButton(ManageActionButton):
167    grok.order(2)
168    grok.context(IStudent)
169    grok.view(StudentClearanceDisplayFormPage)
170    grok.require('waeup.clearStudent')
171    text = 'Clear student'
172    target = 'clear'
173    icon = 'actionicon_accept.png'
174
175    @property
176    def target_url(self):
177        if self.context.state != REQUESTED:
178            return ''
179        return self.view.url(self.view.context, self.target)
180
181class StudentRejectClearanceActionButton(ManageActionButton):
182    grok.order(3)
183    grok.context(IStudent)
184    grok.view(StudentClearanceDisplayFormPage)
185    grok.require('waeup.clearStudent')
186    text = 'Reject clearance'
187    target = 'reject_clearance'
188    icon = 'actionicon_reject.png'
189
190    @property
191    def target_url(self):
192        if self.context.state not in (REQUESTED, CLEARED):
193            return ''
194        return self.view.url(self.view.context, self.target)
195
196class ClearanceSlipActionButton(ManageActionButton):
197    grok.order(4)
198    grok.context(IStudent)
199    grok.view(StudentClearanceDisplayFormPage)
200    grok.require('waeup.viewStudent')
201    icon = 'actionicon_pdf.png'
202    text = 'Download clearance slip'
203    target = 'clearance.pdf'
204
205class StudentPersonalEditActionButton(ManageActionButton):
206    grok.order(1)
207    grok.context(IStudent)
208    grok.view(StudentPersonalDisplayFormPage)
209    grok.require('waeup.viewStudent')
210    text = 'Edit'
211    target = 'edit_personal'
212
213class StudyCourseManageActionButton(ManageActionButton):
214    grok.order(1)
215    grok.context(IStudentStudyCourse)
216    grok.view(StudyCourseDisplayFormPage)
217    grok.require('waeup.manageStudent')
218    text = 'Manage'
219    target = 'manage'
220
221class CourseRegistrationSlipActionButton(ManageActionButton):
222    grok.order(1)
223    grok.context(IStudentStudyLevel)
224    grok.view(StudyLevelDisplayFormPage)
225    grok.require('waeup.viewStudent')
226    icon = 'actionicon_pdf.png'
227    text = 'Download course registration slip'
228    target = 'course_registration.pdf'
229
230class StudyLevelManageActionButton(ManageActionButton):
231    grok.order(2)
232    grok.context(IStudentStudyLevel)
233    grok.view(StudyLevelDisplayFormPage)
234    grok.require('waeup.manageStudent')
235    text = 'Manage'
236    target = 'manage'
237
238class StudentValidateCoursesActionButton(ManageActionButton):
239    grok.order(3)
240    grok.context(IStudentStudyLevel)
241    grok.view(StudyLevelDisplayFormPage)
242    grok.require('waeup.validateStudent')
243    text = 'Validate courses'
244    target = 'validate_courses'
245    icon = 'actionicon_accept.png'
246
247    @property
248    def target_url(self):
249        if self.context.getStudent().state != REGISTERED or \
250            str(self.context.__parent__.current_level) != self.context.__name__:
251            return ''
252        return self.view.url(self.view.context, self.target)
253
254class StudentRejectCoursesActionButton(ManageActionButton):
255    grok.order(4)
256    grok.context(IStudentStudyLevel)
257    grok.view(StudyLevelDisplayFormPage)
258    grok.require('waeup.validateStudent')
259    text = 'Reject courses'
260    target = 'reject_courses'
261    icon = 'actionicon_reject.png'
262
263    @property
264    def target_url(self):
265        if self.context.getStudent().state not in (VALIDATED, REGISTERED) or \
266            str(self.context.__parent__.current_level) != self.context.__name__:
267            return ''
268        return self.view.url(self.view.context, self.target)
269
270class CourseTicketManageActionButton(ManageActionButton):
271    grok.order(1)
272    grok.context(ICourseTicket)
273    grok.view(CourseTicketDisplayFormPage)
274    grok.require('waeup.manageStudent')
275    text = 'Manage'
276    target = 'manage'
277
278#class OnlinePaymentManageActionButton(ManageActionButton):
279#    grok.order(1)
280#    grok.context(IStudentPaymentsContainer)
281#    grok.view(PaymentsDisplayFormPage)
282#    grok.require('waeup.manageStudent')
283#    text = 'Manage payments'
284#    target = 'manage'
285
286class PaymentReceiptActionButton(ManageActionButton):
287    grok.order(1)
288    grok.context(IStudentOnlinePayment)
289    grok.view(OnlinePaymentDisplayFormPage)
290    grok.require('waeup.viewStudent')
291    icon = 'actionicon_pdf.png'
292    text = 'Download payment receipt'
293    target = 'payment_receipt.pdf'
294
295    @property
296    def target_url(self):
297        if self.context.p_state != 'paid':
298            return ''
299        return self.view.url(self.view.context, self.target)
300
301class RequestCallbackActionButton(ManageActionButton):
302    grok.order(2)
303    grok.context(IStudentOnlinePayment)
304    grok.view(OnlinePaymentDisplayFormPage)
305    grok.require('waeup.payStudent')
306    icon = 'actionicon_call.png'
307    text = 'Request callback'
308    target = 'callback'
309
310    @property
311    def target_url(self):
312        if self.context.p_state != 'unpaid':
313            return ''
314        return self.view.url(self.view.context, self.target)
315
316class AddBedTicketActionButton(ManageActionButton):
317    grok.order(1)
318    grok.context(IStudentAccommodation)
319    grok.view(AccommodationManageFormPage)
320    grok.require('waeup.handleAccommodation')
321    icon = 'actionicon_home.png'
322    text = 'Book accommodation'
323    target = 'add'
324
325class BedTicketSlipActionButton(ManageActionButton):
326    grok.order(1)
327    grok.context(IBedTicket)
328    grok.view(BedTicketDisplayFormPage)
329    grok.require('waeup.handleAccommodation')
330    icon = 'actionicon_pdf.png'
331    text = 'Download bed allocation slip'
332    target = 'bed_allocation.pdf'
333
334class RelocateStudentActionButton(ManageActionButton):
335    grok.order(2)
336    grok.context(IBedTicket)
337    grok.view(BedTicketDisplayFormPage)
338    grok.require('waeup.manageHostels')
339    icon = 'actionicon_reload.png'
340    text = 'Relocate student'
341    target = 'relocate'
342
343class StudentBaseActionButton(ManageActionButton):
344    grok.order(1)
345    grok.context(IStudent)
346    grok.view(StudentBaseDisplayFormPage)
347    grok.require('waeup.handleStudent')
348    text = 'Edit base data'
349    target = 'edit_base'
350
351class StudentPasswordActionButton(ManageActionButton):
352    grok.order(2)
353    grok.context(IStudent)
354    grok.view(StudentBaseDisplayFormPage)
355    grok.require('waeup.handleStudent')
356    icon = 'actionicon_key.png'
357    text = 'Change password'
358    target = 'change_password'
359
360class StudentPassportActionButton(ManageActionButton):
361    grok.order(3)
362    grok.context(IStudent)
363    grok.view(StudentBaseDisplayFormPage)
364    grok.require('waeup.handleStudent')
365    icon = 'actionicon_portrait.png'
366    text = 'Change portrait'
367    target = 'change_portrait'
368
369    @property
370    def target_url(self):
371        if self.context.state != 'admitted':
372            return ''
373        return self.view.url(self.view.context, self.target)
374
375class StudentClearanceStartActionButton(ManageActionButton):
376    grok.order(1)
377    grok.context(IStudent)
378    grok.view(StudentClearanceDisplayFormPage)
379    grok.require('waeup.handleStudent')
380    icon = 'actionicon_start.gif'
381    text = 'Start clearance'
382    target = 'start_clearance'
383
384    @property
385    def target_url(self):
386        if self.context.state != 'admitted':
387            return ''
388        return self.view.url(self.view.context, self.target)
389
390class StudentClearanceEditActionButton(ManageActionButton):
391    grok.order(1)
392    grok.context(IStudent)
393    grok.view(StudentClearanceDisplayFormPage)
394    grok.require('waeup.handleStudent')
395    text = 'Edit'
396    target = 'cedit'
397
398    @property
399    def target_url(self):
400        if self.context.clearance_locked:
401            return ''
402        return self.view.url(self.view.context, self.target)
403
404class CourseRegistrationStartActionButton(ManageActionButton):
405    grok.order(1)
406    grok.context(IStudentStudyCourse)
407    grok.view(StudyCourseDisplayFormPage)
408    grok.require('waeup.handleStudent')
409    icon = 'actionicon_start.gif'
410    text = 'Start course registration'
411    target = 'start_course_registration'
412
413    @property
414    def target_url(self):
415        if not self.context.getStudent().state in (CLEARED,RETURNING):
416            return ''
417        return self.view.url(self.view.context, self.target)
418
419class AddStudyLevelActionButton(AddActionButton):
420    grok.order(1)
421    grok.context(IStudentStudyCourse)
422    grok.view(StudyCourseDisplayFormPage)
423    grok.require('waeup.handleStudent')
424    text = 'Add course list'
425    target = 'add'
426
427    @property
428    def target_url(self):
429        student = self.view.context.getStudent()
430        condition1 = student.state != 'school fee paid'
431        condition2 = str(student['studycourse'].current_level) in \
432            self.view.context.keys()
433        if condition1 or condition2:
434            return ''
435        return self.view.url(self.view.context, self.target)
436
437class StudyLevelEditActionButton(ManageActionButton):
438    grok.order(1)
439    grok.context(IStudentStudyLevel)
440    grok.view(StudyLevelDisplayFormPage)
441    grok.require('waeup.handleStudent')
442    text = 'Add and remove courses'
443    target = 'edit'
444
445    @property
446    def target_url(self):
447        student = self.view.context.getStudent()
448        condition1 = student.state != 'school fee paid'
449        condition2 = student[
450            'studycourse'].current_level != self.view.context.level
451        if condition1 or condition2:
452            return ''
453        return self.view.url(self.view.context, self.target)
454
[7184]455class StudentsTab(PrimaryNavTab):
456    """Students tab in primary navigation.
457    """
458
[7321]459    grok.context(ISIRPObject)
[7184]460    grok.order(4)
[7240]461    grok.require('waeup.viewStudentsTab')
[7184]462
463    pnav = 4
464    tab_title = u'Students'
465
466    @property
467    def link_target(self):
468        return self.view.application_url('students')
469
[6687]470class PrimaryStudentNavManager(grok.ViewletManager):
471    """Viewlet manager for the primary navigation tab.
472    """
473    grok.name('primary_nav_student')
474
475class PrimaryStudentNavTab(grok.Viewlet):
476    """Base for primary student nav tabs.
477    """
478    grok.baseclass()
479    grok.viewletmanager(PrimaryStudentNavManager)
[7243]480    template = default_primary_nav_template
[6687]481    grok.order(1)
[7184]482    grok.require('waeup.Authenticated')
[6687]483    pnav = 0
484    tab_title = u'Some Text'
485
486    @property
487    def link_target(self):
488        return self.view.application_url()
489
490    @property
491    def active(self):
492        view_pnav = getattr(self.view, 'pnav', 0)
493        if view_pnav == self.pnav:
494            return 'active'
495        return ''
496
[7240]497class MyStudentDataTab(PrimaryStudentNavTab):
[7459]498    """MyData dropdown tab in primary navigation.
[6687]499    """
500    grok.order(3)
[7240]501    grok.require('waeup.viewMyStudentDataTab')
[7459]502    grok.template('mydatadropdowntabs')
[6687]503    pnav = 4
504    tab_title = u'My Data'
505
506    @property
[7459]507    def active(self):
508        view_pnav = getattr(self.view, 'pnav', 0)
509        if view_pnav == self.pnav:
510            return 'active dropdown'
511        return 'dropdown'
[7097]512
[7459]513    @property
514    def targets(self):
515        student_url = self.view.application_url() + (
516            '/students/%s' % self.request.principal.id)
517        #app_slip = getUtility(IExtFileStore).getFileByContext(
518        #    self.context.getStudent(), 'application_slip')
519        targets = []
520        #if app_slip:
521        #    targets = [{'url':student_url + '/application_slip', 'title':'Application Slip'},]
522        targets += [
523            {'url':student_url, 'title':'Base Data'},
524            {'url':student_url + '/view_clearance', 'title':'Clearance Data'},
525            {'url':student_url + '/view_personal', 'title':'Personal Data'},
526            {'url':student_url + '/studycourse', 'title':'Study Course'},
527            {'url':student_url + '/payments', 'title':'Payments'},
528            {'url':student_url + '/accommodation', 'title':'Accommodation Data'},
529            {'url':student_url + '/history', 'title':'History'},
530            ]
531        return targets
532
[7107]533def handle_file_delete(context, view, download_name):
534    """Handle deletion of student file.
535
536    """
537    store = getUtility(IExtFileStore)
538    store.deleteFileByContext(context, attr=download_name)
[7108]539    write_log_message(view, 'deleted: %s' % download_name)
[7123]540    view.flash('%s deleted.' % download_name)
[7107]541    return
542
[7106]543def handle_file_upload(upload, context, view, max_size, download_name=None):
544    """Handle upload of student file.
[7097]545
546    Returns `True` in case of success or `False`.
547
548    Please note that file pointer passed in (`upload`) most probably
549    points to end of file when leaving this function.
550    """
[7106]551    # Check some file requirements first
552    if upload.filename.count('.') == 0:
553        view.flash('File name has no extension.')
554        return False
555    if upload.filename.count('.') > 1:
556        view.flash('File name contains more than one dot.')
557        return False
558    basename, expected_ext = os.path.splitext(download_name)
559    dummy, ext = os.path.splitext(upload.filename)
560    ext.lower()
[7123]561    if expected_ext:
562        if ext != expected_ext:
563            view.flash('%s file extension expected.' %
564                expected_ext.replace('.',''))
565            return False
566    else:
567        if not ext.replace('.','') in ALLOWED_FILE_EXTENSIONS:
568            view.flash(
569                'Only the following extension are allowed: %s' %
570                ', '.join(ALLOWED_FILE_EXTENSIONS))
571            return False
572        download_name += ext
[7097]573    size = file_size(upload)
574    if size > max_size:
[7106]575        view.flash('Uploaded file is too big.')
[7097]576        return False
577    upload.seek(0) # file pointer moved when determining size
578    store = getUtility(IExtFileStore)
[7106]579    file_id = IFileStoreNameChooser(context).chooseName(attr=download_name)
[7097]580    store.createFile(file_id, upload)
[7108]581    write_log_message(view, 'uploaded: %s (%s)' % (download_name,upload.filename))
582    view.flash('File %s uploaded.' % download_name)
[7097]583    return True
584
585class FileManager(grok.ViewletManager):
586    """Viewlet manager for uploading files, preferably scanned images.
587    """
588    grok.name('files')
589
590class FileDisplay(grok.Viewlet):
591    """Base file display viewlet.
592    """
593    grok.baseclass()
[7100]594    grok.context(IStudentClearance)
[7097]595    grok.viewletmanager(FileManager)
596    grok.view(StudentClearanceDisplayFormPage)
597    grok.template('filedisplay')
598    grok.order(1)
599    grok.require('waeup.viewStudent')
[7319]600    label = u'File'
[7127]601    title = u'Scan'
[7106]602    download_name = u'filename.jpg'
[7097]603
[7107]604    @property
605    def file_exists(self):
606        image = getUtility(IExtFileStore).getFileByContext(
607            self.context, attr=self.download_name)
608        if image:
609            return True
610        else:
611            return False
612
[7097]613class FileUpload(FileDisplay):
614    """Base upload viewlet.
615    """
616    grok.baseclass()
[7100]617    grok.context(IStudentClearance)
[7097]618    grok.viewletmanager(FileManager)
619    grok.view(StudentClearanceManageFormPage)
620    grok.template('fileupload')
[7127]621    grok.require('waeup.uploadStudentFile')
[7491]622    tab_redirect = '?tab2'
[7097]623    mus = 1024 * 150
624
[7117]625    @property
626    def input_name(self):
627        return "%s" % self.__name__
628
[7097]629    def update(self):
630        self.max_upload_size = string_from_bytes(self.mus)
[7117]631        delete_button = self.request.form.get(
632            'delete_%s' % self.input_name, None)
633        upload_button = self.request.form.get(
634            'upload_%s' % self.input_name, None)
[7108]635        if delete_button:
[7107]636            handle_file_delete(
637                context=self.context, view=self.view,
638                download_name=self.download_name)
639            self.view.redirect(
[7134]640                self.view.url(
641                    self.context, self.view.__name__) + self.tab_redirect)
[7107]642            return
[7108]643        if upload_button:
644            upload = self.request.form.get(self.input_name, None)
645            if upload:
646                # We got a fresh upload
[7111]647                handle_file_upload(upload,
648                    self.context, self.view, self.mus, self.download_name)
649                self.view.redirect(
[7134]650                    self.view.url(
651                        self.context, self.view.__name__) + self.tab_redirect)
[7117]652            else:
653                self.view.flash('No local file selected.')
654                self.view.redirect(
[7134]655                    self.view.url(
656                        self.context, self.view.__name__) + self.tab_redirect)
[7097]657        return
658
[7112]659class PassportDisplay(FileDisplay):
660    """Passport display viewlet.
661    """
662    grok.order(1)
663    grok.context(IStudent)
664    grok.view(StudentBaseDisplayFormPage)
665    grok.require('waeup.viewStudent')
666    grok.template('imagedisplay')
[7319]667    label = u'Passport Picture'
[7112]668    download_name = u'passport.jpg'
669
670class PassportUploadManage(FileUpload):
671    """Passport upload viewlet for officers.
672    """
673    grok.order(1)
674    grok.context(IStudent)
675    grok.view(StudentBaseManageFormPage)
[7136]676    grok.require('waeup.manageStudent')
[7112]677    grok.template('imageupload')
[7319]678    label = u'Passport Picture (jpg only)'
[7112]679    mus = 1024 * 50
680    download_name = u'passport.jpg'
[7491]681    tab_redirect = '?tab2'
[7112]682
683class PassportUploadEdit(PassportUploadManage):
684    """Passport upload viewlet for students.
685    """
[7114]686    grok.view(StudentFilesUploadPage)
[7127]687    grok.require('waeup.uploadStudentFile')
[7112]688
[7097]689class BirthCertificateDisplay(FileDisplay):
[7112]690    """Birth Certificate display viewlet.
[7097]691    """
692    grok.order(1)
[7319]693    label = u'Birth Certificate'
[7127]694    title = u'Birth Certificate Scan'
[7123]695    download_name = u'birth_certificate'
[7097]696
[7280]697class BirthCertificateSlip(BirthCertificateDisplay):
698    grok.view(ExportPDFClearanceSlipPage)
699
[7127]700class BirthCertificateUpload(FileUpload):
[7097]701    """Birth Certificate upload viewlet.
702    """
703    grok.order(1)
[7319]704    label = u'Birth Certificate'
[7127]705    title = u'Birth Certificate Scan'
[7097]706    mus = 1024 * 150
[7123]707    download_name = u'birth_certificate'
[7491]708    tab_redirect = '?tab2'
[7097]709
[7111]710class AcceptanceLetterDisplay(FileDisplay):
[7112]711    """Acceptance Letter display viewlet.
[7111]712    """
713    grok.order(1)
[7319]714    label = u'Acceptance Letter'
[7127]715    title = u'Acceptance Letter Scan'
[7123]716    download_name = u'acceptance_letter'
[7111]717
[7280]718class AcceptanceLetterSlip(AcceptanceLetterDisplay):
719    grok.view(ExportPDFClearanceSlipPage)
720
[7127]721class AcceptanceLetterUpload(FileUpload):
[7111]722    """AcceptanceLetter upload viewlet.
723    """
[7112]724    grok.order(2)
[7319]725    label = u'Acceptance Letter'
[7127]726    title = u'Acceptance Letter Scan'
[7111]727    mus = 1024 * 150
[7123]728    download_name = u'acceptance_letter'
[7491]729    tab_redirect = '?tab2'
[7111]730
[7097]731class Image(grok.View):
[7351]732    """Renders images for students.
[7097]733    """
[7106]734    grok.baseclass()
[7097]735    grok.name('none.jpg')
[7112]736    grok.context(IStudentClearance)
[7097]737    grok.require('waeup.viewStudent')
[7106]738    download_name = u'none.jpg'
[7097]739
740    def render(self):
741        # A filename chooser turns a context into a filename suitable
742        # for file storage.
743        image = getUtility(IExtFileStore).getFileByContext(
[7106]744            self.context, attr=self.download_name)
[7097]745        if image is None:
746            # show placeholder image
[7123]747            self.response.setHeader('Content-Type', 'image/jpeg')
[7097]748            return open(DEFAULT_IMAGE_PATH, 'rb').read()
[7123]749        dummy,ext = os.path.splitext(image.name)
750        if ext == '.jpg':
751            self.response.setHeader('Content-Type', 'image/jpeg')
752        elif ext == '.png':
753            self.response.setHeader('Content-Type', 'image/png')
754        elif ext == '.pdf':
755            self.response.setHeader('Content-Type', 'application/pdf')
756        elif ext == '.tif':
757            self.response.setHeader('Content-Type', 'image/tiff')
[7097]758        return image
759
[7112]760class Passport(Image):
761    """Renders jpeg passport picture.
762    """
763    grok.name('passport.jpg')
764    download_name = u'passport.jpg'
765    grok.context(IStudent)
766
[7351]767class ApplicationSlipImage(Image):
768    """Renders application slip scan.
769    """
770    grok.name('application_slip')
771    download_name = u'application_slip'
772
[7097]773class BirthCertificateImage(Image):
[7351]774    """Renders birth certificate scan.
[7097]775    """
[7123]776    grok.name('birth_certificate')
777    download_name = u'birth_certificate'
[7111]778
779class AcceptanceLetterImage(Image):
[7351]780    """Renders acceptance letter scan.
[7111]781    """
[7123]782    grok.name('acceptance_letter')
783    download_name = u'acceptance_letter'
Note: See TracBrowser for help on using the repository browser.