Exemple #1
0
    def post(self, request, *args, **kwargs):

        metadata = self.get_metadata(request)

        metadata["filename"] = self.validate_filename(metadata)

        message_id = request.META.get("HTTP_MESSAGE_ID")
        if message_id:
            metadata["message_id"] = base64.b64decode(message_id)

        if (settings.TUS_EXISTING_FILE == "error"
                and settings.TUS_FILE_NAME_FORMAT == "keep"
                and TusFile.check_existing_file(metadata.get("filename"))):
            return TusResponse(status=409,
                               reason="File with same name already exists")

        file_size = int(request.META.get(
            "HTTP_UPLOAD_LENGTH", "0"))  # TODO: check min max upload size

        tus_file = TusFile.create_initial_file(metadata, file_size)

        return TusResponse(
            status=201,
            extra_headers={
                "Location":
                "{}{}".format(request.build_absolute_uri(),
                              tus_file.resource_id)
            },
        )
Exemple #2
0
    def rename(self):

        setting = settings.TUS_FILE_NAME_FORMAT

        if setting == "keep":
            if TusFile.check_existing_file(self.filename):
                return TusResponse(status=409,
                                   reason="File with same name already exists")
        if setting == "replace":
            TusFile.remove_existing_file(self.filename)
        elif setting == "random":
            self.filename = FilenameGenerator(
                self.filename).create_random_name()
        elif setting == "random-suffix":
            self.filename = FilenameGenerator(
                self.filename).create_random_suffix_name()
        elif setting == "increment":
            self.filename = FilenameGenerator(
                self.filename).create_incremented_name()
        else:
            return TusResponse(
                status=409,
                reason="Incorrect TUS_FILE_NAME_FORMAT setting: %s" %
                (setting),
            )

        os.rename(self.get_path(),
                  os.path.join(settings.TUS_DESTINATION_DIR, self.filename))

        return TusResponse(status=200)
Exemple #3
0
    def patch(self, request, resource_id, *args, **kwargs):

        tus_file = TusFile(str(resource_id))
        chunk = TusChunk(request)

        if not tus_file.is_valid():
            return TusResponse(status=410)

        if chunk.offset != tus_file.offset:
            return TusResponse(status=409)

        if chunk.offset > tus_file.file_size:
            return TusResponse(status=413)

        tus_file.write_chunk(chunk=chunk)

        if tus_file.is_complete():
            # file transfer complete, rename from resource id to actual filename
            response = tus_file.rename()
            if response.status_code != 200:
                return response

            tus_file.clean()

            self.send_signal(tus_file)
            self.finished()

        return TusResponse(status=204,
                           extra_headers={"Upload-Offset": tus_file.offset})
Exemple #4
0
    def head(self, request, resource_id):

        resource_id = str(resource_id)

        offset = cache.get("tus-uploads/{}/offset".format(resource_id))
        file_size = cache.get("tus-uploads/{}/file_size".format(resource_id))

        if offset is None:
            return TusResponse(status=404)

        return TusResponse(status=200,
                           extra_headers={
                               'Upload-Offset': offset,
                               'Upload-Length': file_size
                           })
Exemple #5
0
    def write_chunk(self, chunk):
        try:
            with open(self.get_path(), "r+b") as f:
                f.seek(chunk.offset)
                f.write(chunk.content)
            self.offset = cache.incr(
                "tus-uploads/{}/offset".format(self.resource_id),
                chunk.chunk_size)

        except IOError:
            logger.error(
                "patch",
                extra={
                    "request": chunk.META,
                    "tus": {
                        "resource_id": self.resource_id,
                        "filename": self.filename,
                        "file_size": self.file_size,
                        "metadata": self.metadata,
                        "offset": self.offset,
                        "upload_file_path": self.get_path(),
                    },
                },
            )
            return TusResponse(status=500)
Exemple #6
0
 def write_init_file(self):
     try:
         with open(self.get_path(), 'wb') as f:
             f.seek(self.file_size - 1)
             f.write(b'\0')
     except IOError as e:
         error_message = "Unable to create file: {}".format(e)
         logger.error(error_message, exc_info=True)
         return TusResponse(status=500, reason=error_message)
Exemple #7
0
    def head(self, request, resource_id):

        tus_file = TusFile.get_tusfile_or_404(str(resource_id))

        return TusResponse(status=200,
                           extra_headers={
                               'Upload-Offset': tus_file.offset,
                               'Upload-Length': tus_file.file_size
                           })
Exemple #8
0
    def dispatch(self, *args, **kwargs):

        if not self.request.META.get("HTTP_TUS_RESUMABLE"):
            return TusResponse(status=405, content="Method Not Allowed")

        override_method = self.request.META.get("HTTP_X_HTTP_METHOD_OVERRIDE")
        if override_method:
            self.request.method = override_method

        return super(TusUpload, self).dispatch(*args, **kwargs)
Exemple #9
0
    def write_init_file(self):
        os.makedirs(settings.TUS_DESTINATION_DIR, exist_ok=True)
        os.makedirs(settings.TUS_UPLOAD_DIR, exist_ok=True)

        try:
            with open(self.get_path(), "wb") as f:
                f.seek(self.file_size - 1)
                f.write(b"\0")
        except IOError as e:
            error_message = "Unable to create file: {}".format(e)
            logger.error(error_message, exc_info=True)
            return TusResponse(status=500, reason=error_message)
Exemple #10
0
    def rename(self):

        setting = settings.TUS_FILE_NAME_FORMAT

        if setting == 'keep':
            if self.check_existing_file(self.filename):
                return TusResponse(status=409, reason="File with same name already exists")
        elif setting == 'random':
            self.filename = FilenameGenerator(self.filename).create_random_name()
        elif setting == 'random-suffix':
            self.filename = FilenameGenerator(self.filename).create_random_suffix_name()
        elif setting == 'increment':
            self.filename = FilenameGenerator(self.filename).create_incremented_name()
        else:
            return ValueError()

        os.rename(self.get_path(), os.path.join(settings.TUS_DESTINATION_DIR, self.filename))
Exemple #11
0
 def get_tusfile_or_404(resource_id):
     if TusFile.resource_exists(str(resource_id)):
         return TusFile(resource_id)
     else:
         raise TusResponse(status=404)
Exemple #12
0
 def options(self, request, *args, **kwargs):
     return TusResponse(status=204)