コード例 #1
0
ファイル: api.py プロジェクト: hfeeki/transifex
    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)

                try:
                    sf.update_props()
                    sf.file_check()
                    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, (FileCheckError, ParseError)):
                        #FIXME: Custom Exception should use an extra attr for
                        # localized string.
                        message = e.message
                    else:
                        #TODO Send email to admins
                        message = _("A strange error happened:") + e.message
                        logger.error(str(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)