def save(self, user=None, force_insert=False, force_update=False, commit=True): m = super(ResourceForm, self).save(commit=False) if commit: cleaned_data = self.cleaned_data file = None language = cleaned_data['source_language'] if cleaned_data.has_key('sourcefile'): file = cleaned_data['sourcefile'] if file: sf = StorageFile() sf.uuid = str(uuid4()) sf.name = file.name fh = open(sf.get_storage_path(), 'wb') file.seek(0) fh.write(file.read()) fh.flush() fh.close() sf.size = file.size sf.language = language sf.update_props() sf.save() parser = sf.find_parser() try: # Try to do an actual parsing to see if file is valid fhandler = parser(filename=sf.get_storage_path()) fhandler.set_language(language) fhandler.bind_resource(self.instance) fhandler.contents_check(fhandler.filename) fhandler.parse_file(is_source=True) fhandler.save2db(is_source=True, user=user) except: raise # Try to set the i18n type. Problem is that we only check # filename instead of mime type. we should probably update the # function to use python magic as well try: m.i18n_type = get_i18n_type_from_file(file.name) except: pass m.save() return m
def clean(self): """ Check if provided file is a valid file and can be handled by Transifex """ cleaned_data = self.cleaned_data file = None language = cleaned_data['source_language'] if cleaned_data.has_key('sourcefile'): file = cleaned_data['sourcefile'] if file: # Check if we can handle the file with an existing parser sf = StorageFile() sf.uuid = str(uuid4()) sf.name = file.name fh = open(sf.get_storage_path(), 'wb') file.seek(0) fh.write(file.read()) fh.flush() fh.close() sf.size = file.size sf.language = language try: sf.update_props() except (FileCheckError, ParseError), e: raise forms.ValidationError(e.message) sf.save() parser = sf.find_parser() if not parser: raise forms.ValidationError("File doesn't seem to be in a" " valid format.") try: # Try to do an actual parsing to see if file is valid fhandler = parser(filename=sf.get_storage_path()) fhandler.set_language(language) fhandler.contents_check(fhandler.filename) fhandler.parse_file(is_source=True) except Exception,e: sf.delete() raise forms.ValidationError("Could not import file: %s" % str(e))
def create(self, request, uuid=None, api_version=1): """ API call for uploading a file via POST or updating storage file attributes """ if request.user.is_anonymous(): return rc.FORBIDDEN if "application/json" in request.content_type: # Do API calls if "language" in request.data.keys() and uuid: # API call for changing language lang_code = request.data["language"] # TODO: Sanitize try: sf = StorageFile.objects.get(uuid=uuid) if lang_code == "": # Set to 'Not detected' sf.language = None else: sf.language = Language.objects.by_code_or_alias(lang_code) except StorageFile.DoesNotExist: return rc.NOT_FOUND # Translation file does not exist except Language.DoesNotExist: return rc.NOT_FOUND # Translation file not found sf.save() # Save the change logger.debug("Changed language of file %s (%s) to %s" % (sf.uuid, sf.name, lang_code)) return rc.ALL_OK return BAD_REQUEST("Unsupported request") # Unknown API call elif "multipart/form-data" in request.content_type: # Do file upload files = [] retval = None for name, submitted_file in request.FILES.items(): submitted_file = submitted_file sf = StorageFile() sf.name = str(submitted_file.name.encode("UTF-8")) sf.uuid = str(uuid4()) fh = open(sf.get_storage_path(), "wb") for chunk in submitted_file.chunks(): fh.write(chunk) fh.close() sf.size = os.path.getsize(sf.get_storage_path()) sf.user = request.user if "language" in request.data.keys(): lang_code = request.data["language"] try: sf.language = Language.objects.by_code_or_alias(lang_code) except Language.DoesNotExist: logger.error( "Weird! Selected language code (%s) does " "not match with any language in the database." % lang_code ) return BAD_REQUEST( "Selected language code (%s) does " "not match with any language in the database." % lang_code ) else: return BAD_REQUEST("Language for the file has not been specified.") try: sf.update_props() sf.save() logger.debug("Uploaded file %s (%s)" % (sf.uuid, sf.name)) files.append({"uuid": sf.uuid, "id": str(sf.id), "name": sf.name}) except UnicodeDecodeError, e: message = _( "The encoding of the uploaded file is not UTF-8. " "Currently, transifex supports only UTF-8" "encoded files. Please, visit" "http://help.transifex.net/user-guide/formats.html#encoding" "for further information." ) except Exception, e: if isinstance(e, UnicodeDecodeError): message = _( "The encoding of the uploaded file is not UTF-8. " "Currently, transifex supports only UTF-8" "encoded files. Please, visit" "http://help.transifex.net/user-guide/formats.html#encoding" "for further information." ) elif isinstance(e, (FileCheckError, ParseError)): # FIXME: Custom Exception should use an extra attr for # localized string. message = "%s" % e else: message = _("A strange error happened.") logger.error("Unhandled exception raised: %s" % e) # The object is not saved yet, but it removes file from # the filesystem sf.delete() # Delete possible uploaded files from the same request. # It allows multiple files per request, but if one fails, # the whole request must fail. StorageFile.objects.filter(id__in=[f["id"] for f in files]).delete() retval = dict(status="Error", message=message)