Changeset 7097 for main/waeup.sirp/trunk/src/waeup/sirp/students
- Timestamp:
- 12 Nov 2011, 22:30:27 (13 years ago)
- Location:
- main/waeup.sirp/trunk/src/waeup/sirp/students
- Files:
-
- 4 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.sirp/trunk/src/waeup/sirp/students/browser.py
r7068 r7097 470 470 title = 'Clearance Data' 471 471 pnav = 4 472 files_changed = [] 472 473 473 474 form_fields['date_of_birth'].custom_widget = FriendlyDateWidget('le-year') -
main/waeup.sirp/trunk/src/waeup/sirp/students/student.py
r7062 r7097 17 17 Container for the various objects owned by students. 18 18 """ 19 import os 19 20 import grok 20 21 from grok import index … … 23 24 from hurry.workflow.interfaces import IWorkflowState, IWorkflowInfo 24 25 from zope.securitypolicy.interfaces import IPrincipalRoleManager 25 from waeup.sirp.interfaces import IObjectHistory, IUserAccount 26 from waeup.sirp.interfaces import ( 27 IObjectHistory, IUserAccount, IFileStoreNameChooser, IFileStoreHandler) 28 from waeup.sirp.image import WAeUPImageFile 29 from waeup.sirp.imagestorage import DefaultFileStoreHandler 26 30 from waeup.sirp.students.interfaces import ( 27 31 IStudent, IStudentNavigation, IStudentClearanceEdit, … … 136 140 user, target, comment)) 137 141 return 142 143 #: The file id marker for student files 144 STUDENT_FILE_STORE_NAME = 'file-student' 145 146 class StudentFileNameChooser(grok.Adapter): 147 """A file id chooser for :class:`Applicant` objects. 148 149 `context` is an :class:`Applicant` instance. 150 151 The :class:`ApplicantImageNameChooser` can build/check file ids 152 for :class:`Applicant` objects suitable for use with 153 :class:`ExtFileStore` instances. The delivered file_id contains 154 the file id marker for :class:`Applicant` object and the 155 registration number or access code of the context applicant. Also 156 the name of the connected applicant container will be part of the 157 generated file id. 158 159 This chooser is registered as an adapter providing 160 :class:`waeup.sirp.interfaces.IFileStoreNameChooser`. 161 162 File store name choosers like this one are only convenience 163 components to ease the task of creating file ids for applicant 164 objects. You are nevertheless encouraged to use them instead of 165 manually setting up filenames for applicants. 166 167 .. seealso:: :mod:`waeup.sirp.imagestorage` 168 169 """ 170 grok.context(IStudent) 171 grok.implements(IFileStoreNameChooser) 172 173 def checkName(self, name=None, attr=None): 174 """Check whether the given name is a valid file id for the context. 175 176 Returns ``True`` only if `name` equals the result of 177 :meth:`chooseName`. 178 179 """ 180 return name == self.chooseName() 181 182 def chooseName(self, name=None, attr=None): 183 """Get a valid file id for student context. 184 185 *Example:* 186 187 For a student with student id ``'A123456'`` and 188 with attr ``'nice_image'`` stored in 189 the students container this chooser would create: 190 191 ``'__file-student__students/A/A123456/nice_image_A123456.jpg'`` 192 193 meaning that the nice image of this applicant would be 194 stored in the site-wide file storage in path: 195 196 ``students/A/A123456/nice_image_A123456.jpg`` 197 198 """ 199 first_character = self.context.student_id[0] 200 marked_filename = '__%s__%s/%s/%s_%s.jpg' % ( 201 STUDENT_FILE_STORE_NAME, first_character, 202 self.context.student_id, attr, self.context.student_id) 203 return marked_filename 204 205 206 class StudentFileStoreHandler(DefaultFileStoreHandler, grok.GlobalUtility): 207 """Student specific file handling. 208 209 This handler knows in which path in a filestore to store student 210 files and how to turn this kind of data into some (browsable) 211 file object. 212 213 It is called from the global file storage, when it wants to 214 get/store a file with a file id starting with 215 ``__file-student__`` (the marker string for student files). 216 217 Like each other file store handler it does not handle the files 218 really (this is done by the global file store) but only computes 219 paths and things like this. 220 """ 221 grok.implements(IFileStoreHandler) 222 grok.name(STUDENT_FILE_STORE_NAME) 223 224 def pathFromFileID(self, store, root, file_id): 225 """All applicants images are filed in directory ``applicants``. 226 """ 227 marker, filename, basename, ext = store.extractMarker(file_id) 228 return os.path.join(root, 'students', filename) 229 230 def createFile(self, store, root, filename, file_id, file): 231 """Create a browsable file-like object. 232 """ 233 # possible other actions: check for jpeg format 234 path = self.pathFromFileID(store, root, file_id) 235 return file, path, WAeUPImageFile(filename, file_id) -
main/waeup.sirp/trunk/src/waeup/sirp/students/viewlets.py
r6687 r7097 1 1 import grok 2 from zope.component import getUtility 2 3 from zope.interface import Interface 3 from waeup.sirp.interfaces import IWAeUPObject 4 from waeup.sirp.interfaces import ( 5 IWAeUPObject, IExtFileStore, IFileStoreNameChooser) 6 from waeup.sirp.utils.helpers import string_from_bytes, file_size 7 from waeup.sirp.browser import DEFAULT_IMAGE_PATH 8 from waeup.sirp.students.browser import ( 9 StudentClearanceDisplayFormPage, StudentClearanceManageFormPage) 4 10 5 11 grok.context(IWAeUPObject) # Make IWAeUPObject the default context … … 190 196 rel_link = '/students/%s' % self.request.principal.id 191 197 return self.view.application_url() + rel_link 198 199 def handle_img_upload(upload, context, view, max_size, attr=None): 200 """Handle upload of applicant image. 201 202 Returns `True` in case of success or `False`. 203 204 Please note that file pointer passed in (`upload`) most probably 205 points to end of file when leaving this function. 206 """ 207 size = file_size(upload) 208 if size > max_size: 209 view.flash('Uploaded image is too big!') 210 return False 211 upload.seek(0) # file pointer moved when determining size 212 store = getUtility(IExtFileStore) 213 file_id = IFileStoreNameChooser(context).chooseName(attr=attr) 214 store.createFile(file_id, upload) 215 return True 216 217 class FileManager(grok.ViewletManager): 218 """Viewlet manager for uploading files, preferably scanned images. 219 """ 220 grok.name('files') 221 222 class FileDisplay(grok.Viewlet): 223 """Base file display viewlet. 224 """ 225 grok.baseclass() 226 grok.viewletmanager(FileManager) 227 grok.view(StudentClearanceDisplayFormPage) 228 grok.template('filedisplay') 229 grok.order(1) 230 grok.require('waeup.viewStudent') 231 label = u'Some Text:' 232 img_src = u'filename.jpg' 233 attr = None 234 235 class FileUpload(FileDisplay): 236 """Base upload viewlet. 237 """ 238 grok.baseclass() 239 grok.viewletmanager(FileManager) 240 grok.view(StudentClearanceManageFormPage) 241 grok.template('fileupload') 242 grok.require('waeup.manageStudents') 243 mus = 1024 * 150 244 input_name = u'form.filename' 245 246 def update(self): 247 self.max_upload_size = string_from_bytes(self.mus) 248 upload = self.request.form.get(self.input_name, None) 249 if upload: 250 # We got a fresh upload 251 file_changed = handle_img_upload( 252 upload, self.context, self.view, self.mus, self.attr) 253 if file_changed is False: # False is not None! 254 self.redirect(self.view.url(self.context)) 255 return # error during image upload. Ignore other values 256 else: 257 self.view.files_changed += self.img_src 258 return 259 260 class BirthCertificateDisplay(FileDisplay): 261 """Birth Certificate upload viewlet. 262 """ 263 grok.order(1) 264 label = u'Birth Certificate:' 265 img_src = u'birth_certificate.jpg' 266 attr = u'birth_certificate' 267 268 class BirthCertificateUpload(FileUpload): 269 """Birth Certificate upload viewlet. 270 """ 271 grok.order(1) 272 label = u'Birth Certificate:' 273 mus = 1024 * 150 274 img_src = u'birth_certificate.jpg' 275 input_name = u'form.birth_certificate' 276 attr = u'birth_certificate' 277 278 class Image(grok.View): 279 """Renders image for students. 280 """ 281 grok.name('none.jpg') 282 grok.view(StudentClearanceManageFormPage) 283 grok.require('waeup.viewStudent') 284 grok.baseclass() 285 attr = None 286 287 def render(self): 288 # A filename chooser turns a context into a filename suitable 289 # for file storage. 290 image = getUtility(IExtFileStore).getFileByContext( 291 self.context, attr=self.attr) 292 self.response.setHeader( 293 'Content-Type', 'image/jpeg') 294 if image is None: 295 # show placeholder image 296 return open(DEFAULT_IMAGE_PATH, 'rb').read() 297 return image 298 299 class BirthCertificateImage(Image): 300 """Renders birth certificate. 301 """ 302 grok.name('birth_certificate.jpg') 303 attr = u'birth_certificate'
Note: See TracChangeset for help on using the changeset viewer.