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

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

Backup internationalization work in progress.

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