source: main/waeup.kofa/trunk/src/waeup/kofa/students/viewlets.py @ 9106

Last change on this file since 9106 was 9070, checked in by Henrik Bettermann, 12 years ago

Approve and Download buttons should always be the last buttons.

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