def setUp( self ): self.object_id = u"17" self.notebook_id = u"18" self.note_id = u"19" self.filename = u"foo.png" self.size_bytes = 2888 self.content_type = "image/png" self.delta = timedelta( seconds = 1 ) self.file = File.create( self.object_id, self.notebook_id, self.note_id, self.filename, self.size_bytes, self.content_type )
def upload(self, upload, notebook_id, note_id, x_progress_id, user_id): """ Upload a file from the client for attachment to a particular note. The x_progress_id must be provided as part of the query string, even if the other values are submitted as form data. @type upload: cgi.FieldStorage @param upload: file handle to uploaded file @type notebook_id: unicode @param notebook_id: id of the notebook that the upload is to @type note_id: unicode or NoneType @param note_id: id of the note that the upload is to (if any) @type x_progess_id: unicode @param x_progess_id: id of the file being uploaded @type user_id: unicode or NoneType @param user_id: id of current logged-in user (if any) @rtype: unicode @return: rendered HTML page @raise Access_error: the current user doesn't have access to the given notebook or note @raise Upload_error: the Content-Length header value is invalid """ global current_uploads, current_uploads_lock file_id = x_progress_id current_uploads_lock.acquire() try: uploaded_file = current_uploads.get(file_id) if not uploaded_file: return dict(script=general_error_script % u"Please select a file to upload.") del (current_uploads[file_id]) finally: current_uploads_lock.release() user = self.__database.load(User, user_id) notebook = self.__users.load_notebook(user_id, notebook_id, read_write=True) if not user or not notebook or notebook.read_write == Notebook.READ_WRITE_FOR_OWN_NOTES: uploaded_file.delete() return dict( script=general_error_script % u"Sorry, you don't have access to do that. Please make sure you're logged in as the correct user." ) content_type = upload.headers.get("content-type") # if we didn't receive all of the expected data, abort if uploaded_file.total_received_bytes < uploaded_file.content_length: uploaded_file.delete() return dict( script=general_error_script % u"The uploaded file was not fully received. Please try again or contact support." ) if uploaded_file.file_received_bytes == 0: uploaded_file.delete() return dict( script=general_error_script % u"The uploaded file was not received. Please make sure that the file exists." ) # if the uploaded file's size would put the user over quota, bail and inform the user rate_plan = self.__users.rate_plan(user.rate_plan) storage_quota_bytes = rate_plan.get(u"storage_quota_bytes") if storage_quota_bytes and user.storage_bytes + uploaded_file.total_received_bytes > storage_quota_bytes: uploaded_file.delete() return dict(script=quota_error_script) # record metadata on the upload in the database db_file = File.create(file_id, notebook_id, note_id, uploaded_file.filename, uploaded_file.file_received_bytes, content_type) self.__database.save(db_file, commit=False) self.__users.update_storage(user_id, commit=False) self.__database.commit() uploaded_file.close() return dict()
def upload( self, upload, notebook_id, note_id, x_progress_id, user_id ): """ Upload a file from the client for attachment to a particular note. The x_progress_id must be provided as part of the query string, even if the other values are submitted as form data. @type upload: cgi.FieldStorage @param upload: file handle to uploaded file @type notebook_id: unicode @param notebook_id: id of the notebook that the upload is to @type note_id: unicode or NoneType @param note_id: id of the note that the upload is to (if any) @type x_progess_id: unicode @param x_progess_id: id of the file being uploaded @type user_id: unicode or NoneType @param user_id: id of current logged-in user (if any) @rtype: unicode @return: rendered HTML page @raise Access_error: the current user doesn't have access to the given notebook or note @raise Upload_error: the Content-Length header value is invalid """ global current_uploads, current_uploads_lock file_id = x_progress_id current_uploads_lock.acquire() try: uploaded_file = current_uploads.get( file_id ) if not uploaded_file: return dict( script = general_error_script % u"Please select a file to upload." ) del( current_uploads[ file_id ] ) finally: current_uploads_lock.release() user = self.__database.load( User, user_id ) notebook = self.__users.load_notebook( user_id, notebook_id, read_write = True ) if not user or not notebook or notebook.read_write == Notebook.READ_WRITE_FOR_OWN_NOTES: uploaded_file.delete() return dict( script = general_error_script % u"Sorry, you don't have access to do that. Please make sure you're logged in as the correct user." ) content_type = upload.headers.get( "content-type" ) # if we didn't receive all of the expected data, abort if uploaded_file.total_received_bytes < uploaded_file.content_length: uploaded_file.delete() return dict( script = general_error_script % u"The uploaded file was not fully received. Please try again or contact support." ) if uploaded_file.file_received_bytes == 0: uploaded_file.delete() return dict( script = general_error_script % u"The uploaded file was not received. Please make sure that the file exists." ) # if the uploaded file's size would put the user over quota, bail and inform the user rate_plan = self.__users.rate_plan( user.rate_plan ) storage_quota_bytes = rate_plan.get( u"storage_quota_bytes" ) if storage_quota_bytes and user.storage_bytes + uploaded_file.total_received_bytes > storage_quota_bytes: uploaded_file.delete() return dict( script = quota_error_script ) # record metadata on the upload in the database db_file = File.create( file_id, notebook_id, note_id, uploaded_file.filename, uploaded_file.file_received_bytes, content_type ) self.__database.save( db_file, commit = False ) self.__users.update_storage( user_id, commit = False ) self.__database.commit() uploaded_file.close() return dict()