Changeset 12421
- Timestamp:
- 8 Jan 2015, 11:59:47 (10 years ago)
- Location:
- main/waeup.kofa/trunk/src/waeup/kofa/students
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py
r12104 r12421 281 281 """ 282 282 # XXX: fix circular import problem 283 from waeup.kofa.students. viewlets import FileManager283 from waeup.kofa.students.fileviewlets import FileManager 284 284 from waeup.kofa.browser import DEFAULT_IMAGE_PATH 285 285 style = getSampleStyleSheet() -
main/waeup.kofa/trunk/src/waeup/kofa/students/viewlets.py
r12393 r12421 16 16 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 17 ## 18 import os19 18 import grok 20 19 from zope.component import getUtility 21 20 from zope.interface import Interface 22 21 from zope.i18n import translate 23 from waeup.kofa.interfaces import ( 24 IKofaObject, IExtFileStore, IFileStoreNameChooser) 22 from waeup.kofa.interfaces import IExtFileStore, IKofaObject 25 23 from waeup.kofa.interfaces import MessageFactory as _ 26 from waeup.kofa.utils.helpers import string_from_bytes, file_size27 from waeup.kofa.browser import DEFAULT_IMAGE_PATH28 24 from waeup.kofa.browser.viewlets import ( 29 25 PrimaryNavTab, ManageActionButton, AddActionButton) 30 from waeup.kofa.browser.layout import ( 31 default_primary_nav_template, default_filedisplay_template, 32 default_fileupload_template) 26 from waeup.kofa.browser.layout import default_primary_nav_template 33 27 from waeup.kofa.students.workflow import ( 34 28 ADMITTED, PAID, REQUESTED, RETURNING, CLEARED, REGISTERED, 35 29 VALIDATED, GRADUATED, TRANSCRIPT) 36 30 from waeup.kofa.students.browser import ( 37 StudentClearanceManageFormPage, 38 StudentBaseManageFormPage, StudentFilesUploadPage, 39 ExportPDFClearanceSlipPage, StudentsContainerPage, 31 StudentsContainerPage, 40 32 StudentsContainerManagePage, StudentBaseDisplayFormPage, 41 33 StudentClearanceDisplayFormPage, StudentPersonalDisplayFormPage, … … 50 42 IStudentPaymentsContainer, IStudentsUtils 51 43 ) 52 from waeup.kofa.utils.helpers import get_fileformat53 44 54 45 grok.context(IKofaObject) # Make IKofaObject the default context 55 46 grok.templatedir('browser_templates') 56 47 57 ALLOWED_FILE_EXTENSIONS = ('jpg', 'png', 'pdf', 'tif', 'fpm')58 48 59 49 class StudentManageSidebar(grok.ViewletManager): … … 804 794 ] 805 795 return targets 806 807 def handle_file_delete(context, view, download_name):808 """Handle deletion of student file.809 810 """811 store = getUtility(IExtFileStore)812 store.deleteFileByContext(context, attr=download_name)813 context.writeLogMessage(view, 'deleted: %s' % download_name)814 view.flash(_('${a} deleted.', mapping = {'a':download_name}))815 return816 817 def handle_file_upload(upload, context, view, max_size, download_name=None):818 """Handle upload of student file.819 820 Returns `True` in case of success or `False`.821 822 Please note that file pointer passed in (`upload`) most probably823 points to end of file when leaving this function.824 """825 # Check some file requirements first826 size = file_size(upload)827 if size > max_size:828 view.flash(_('Uploaded file is too big.'), type="danger")829 return False830 upload.seek(0) # file pointer moved when determining size831 dummy,ext = os.path.splitext(upload.filename)832 # fpm files are expected to be fingerprint minutiae, file833 # format is not yet checked834 if ext == '.fpm':835 file_format = 'fpm'836 else:837 file_format = get_fileformat(None, upload.read(512))838 upload.seek(0) # same here839 if file_format is None:840 view.flash(_('Could not determine file type.'), type="danger")841 return False842 basename, expected_ext = os.path.splitext(download_name)843 if expected_ext:844 if '.' + file_format != expected_ext:845 view.flash(_('${a} file format expected.',846 mapping = {'a':expected_ext[1:]}), type="danger")847 return False848 else:849 if not file_format in ALLOWED_FILE_EXTENSIONS:850 view.flash(851 _('Only the following extensions are allowed: ${a}',852 mapping = {'a':', '.join(ALLOWED_FILE_EXTENSIONS)}),853 type="danger")854 return False855 download_name += '.' + file_format856 store = getUtility(IExtFileStore)857 file_id = IFileStoreNameChooser(context).chooseName(attr=download_name)858 store.createFile(file_id, upload)859 context.writeLogMessage(view, 'uploaded: %s (%s)' % (860 download_name,upload.filename))861 view.flash(_('File ${a} uploaded.', mapping = {'a':download_name}))862 return True863 864 class FileManager(grok.ViewletManager):865 """Viewlet manager for uploading files, preferably scanned images.866 """867 grok.name('files')868 869 class FileDisplay(grok.Viewlet):870 """Base file display viewlet.871 """872 grok.baseclass()873 grok.context(IStudent)874 grok.viewletmanager(FileManager)875 grok.view(StudentClearanceDisplayFormPage)876 template = default_filedisplay_template877 grok.order(1)878 grok.require('waeup.viewStudent')879 label = _(u'File')880 title = _(u'Scan')881 download_name = u'filename.jpg'882 883 @property884 def file_exists(self):885 image = getUtility(IExtFileStore).getFileByContext(886 self.context, attr=self.download_name)887 if image:888 return True889 else:890 return False891 892 class FileUpload(FileDisplay):893 """Base upload viewlet.894 """895 grok.baseclass()896 grok.context(IStudent)897 grok.viewletmanager(FileManager)898 grok.view(StudentClearanceManageFormPage)899 template = default_fileupload_template900 grok.require('waeup.uploadStudentFile')901 tab_redirect = '#tab2-top'902 mus = 1024 * 150903 upload_button =_('Upload selected file')904 delete_button = _('Delete')905 906 @property907 def show_viewlet(self):908 students_utils = getUtility(IStudentsUtils)909 if self.__name__ in students_utils.SKIP_UPLOAD_VIEWLETS:910 return False911 return True912 913 @property914 def input_name(self):915 return "%s" % self.__name__916 917 def update(self):918 self.max_upload_size = string_from_bytes(self.mus)919 delete_button = self.request.form.get(920 'delete_%s' % self.input_name, None)921 upload_button = self.request.form.get(922 'upload_%s' % self.input_name, None)923 if delete_button:924 handle_file_delete(925 context=self.context, view=self.view,926 download_name=self.download_name)927 self.view.redirect(928 self.view.url(929 self.context, self.view.__name__) + self.tab_redirect)930 return931 if upload_button:932 upload = self.request.form.get(self.input_name, None)933 if upload:934 # We got a fresh upload935 handle_file_upload(upload,936 self.context, self.view, self.mus, self.download_name)937 self.view.redirect(938 self.view.url(939 self.context, self.view.__name__) + self.tab_redirect)940 else:941 self.view.flash(_('No local file selected.'), type="danger")942 self.view.redirect(943 self.view.url(944 self.context, self.view.__name__) + self.tab_redirect)945 return946 947 class PassportDisplay(FileDisplay):948 """Passport display viewlet.949 """950 grok.order(1)951 grok.context(IStudent)952 grok.view(StudentBaseDisplayFormPage)953 grok.require('waeup.viewStudent')954 grok.template('imagedisplay')955 label = _(u'Passport Picture')956 download_name = u'passport.jpg'957 958 class PassportUploadManage(FileUpload):959 """Passport upload viewlet for officers.960 """961 grok.order(1)962 grok.context(IStudent)963 grok.view(StudentBaseManageFormPage)964 grok.require('waeup.manageStudent')965 grok.template('imageupload')966 label = _(u'Passport Picture (jpg only)')967 mus = 1024 * 50968 download_name = u'passport.jpg'969 tab_redirect = '#tab2'970 971 class PassportUploadEdit(PassportUploadManage):972 """Passport upload viewlet for students.973 """974 grok.view(StudentFilesUploadPage)975 grok.require('waeup.uploadStudentFile')976 977 class BirthCertificateDisplay(FileDisplay):978 """Birth Certificate display viewlet.979 """980 grok.order(1)981 label = _(u'Birth Certificate')982 title = _(u'Birth Certificate Scan')983 download_name = u'birth_certificate'984 985 class BirthCertificateSlip(BirthCertificateDisplay):986 grok.view(ExportPDFClearanceSlipPage)987 988 class BirthCertificateUpload(FileUpload):989 """Birth Certificate upload viewlet.990 """991 grok.order(1)992 label = _(u'Birth Certificate')993 title = _(u'Birth Certificate Scan')994 mus = 1024 * 150995 download_name = u'birth_certificate'996 tab_redirect = '#tab2-top'997 998 class Image(grok.View):999 """Renders images for students.1000 """1001 grok.baseclass()1002 grok.name('none.jpg')1003 grok.context(IStudent)1004 grok.require('waeup.viewStudent')1005 download_name = u'none.jpg'1006 1007 def render(self):1008 # A filename chooser turns a context into a filename suitable1009 # for file storage.1010 image = getUtility(IExtFileStore).getFileByContext(1011 self.context, attr=self.download_name)1012 if image is None:1013 # show placeholder image1014 self.response.setHeader('Content-Type', 'image/jpeg')1015 return open(DEFAULT_IMAGE_PATH, 'rb').read()1016 dummy,ext = os.path.splitext(image.name)1017 if ext == '.jpg':1018 self.response.setHeader('Content-Type', 'image/jpeg')1019 elif ext == '.fpm':1020 self.response.setHeader('Content-Type', 'application/binary')1021 elif ext == '.png':1022 self.response.setHeader('Content-Type', 'image/png')1023 elif ext == '.pdf':1024 self.response.setHeader('Content-Type', 'application/pdf')1025 elif ext == '.tif':1026 self.response.setHeader('Content-Type', 'image/tiff')1027 return image1028 1029 class Passport(Image):1030 """Renders jpeg passport picture.1031 """1032 grok.name('passport.jpg')1033 download_name = u'passport.jpg'1034 grok.context(IStudent)1035 1036 class ApplicationSlipImage(Image):1037 """Renders application slip scan.1038 """1039 grok.name('application_slip')1040 download_name = u'application_slip'1041 1042 class BirthCertificateImage(Image):1043 """Renders birth certificate scan.1044 """1045 grok.name('birth_certificate')1046 download_name = u'birth_certificate'
Note: See TracChangeset for help on using the changeset viewer.