# Path: invenio_files_rest/errors.py
# class BucketLockedError(InvalidOperationError):
#     """Exception raised when a bucket is locked."""
# 
#     code = 403
#     description = "Bucket is locked for modifications."
# 
# class FileInstanceAlreadySetError(InvalidOperationError):
#     """Exception raised when file instance already set on object."""
# 
# class FileInstanceUnreadableError(InvalidOperationError):
#     """Exception raised when trying to get an unreadable file."""
# 
#     code = 503
#     description = "File storage is offline."
# 
# class FileSizeError(StorageError):
#     """Exception raised when a file larger than allowed."""
# 
#     code = 400
# 
# class InvalidKeyError(InvalidOperationError):
#     """Invalid key."""
# 
#     code = 400
#     description = "Filename is too long."
# 
# class InvalidOperationError(FilesException):
#     """Exception raised when an invalid operation is performed."""
# 
#     code = 403
# 
# class MultipartAlreadyCompleted(MultipartException):
#     """Exception raised when multipart object is already completed."""
# 
#     code = 403
#     description = "Multipart upload is already completed."
# 
# class MultipartInvalidChunkSize(MultipartException):
#     """Exception raised when multipart object is already completed."""
# 
#     code = 400
#     description = "Invalid part size."
# 
# class MultipartInvalidPartNumber(MultipartException):
#     """Exception raised when multipart object is already completed."""
# 
#     code = 400
#     description = "Invalid part number."
# 
# class MultipartInvalidSize(MultipartException):
#     """Exception raised when multipart object is already completed."""
# 
#     code = 400
#     description = "Invalid file size."
# 
# class MultipartMissingParts(MultipartException):
#     """Exception raised when multipart object is already completed."""
# 
#     code = 400
#     description = "Not all parts have been uploaded."
# 
# class MultipartNotCompleted(MultipartException):
#     """Exception raised when multipart object is not already completed."""
# 
#     code = 400
#     description = "Multipart upload is already completed."
# 
# Path: invenio_files_rest/proxies.py

# 
# Path: invenio_files_rest/utils.py
# def guess_mimetype(filename):
#     """Map extra mimetype with the encoding provided.
# 
#     :returns: The extra mimetype.
#     """
#     m, encoding = mimetypes.guess_type(filename)
#     if encoding:
#         m = ENCODING_MIMETYPES.get(encoding, None)
#     return m or 'application/octet-stream'


import re
import sys
import uuid
from datetime import datetime
from flask import current_app
from functools import wraps
from invenio_db import db
from os.path import basename
from sqlalchemy.dialects import mysql
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import validates
from sqlalchemy.orm.exc import MultipleResultsFound
from sqlalchemy_utils.types import UUIDType
from .errors import BucketLockedError, FileInstanceAlreadySetError, \
    FileInstanceUnreadableError, FileSizeError, InvalidKeyError, \
    InvalidOperationError, MultipartAlreadyCompleted, \
    MultipartInvalidChunkSize, MultipartInvalidPartNumber, \
    MultipartInvalidSize, MultipartMissingParts, MultipartNotCompleted
from .proxies import current_files_rest
from .utils import guess_mimetype
        with db.session.begin_nested():
            if self.file_id:
                self.bucket.size -= self.file.size
            self.query.filter_by(
                bucket_id=self.bucket_id,
                key=self.key,
                version_id=self.version_id,
            ).delete()

        return self

    @classmethod
    def create(cls, bucket, key, _file_id=None, stream=None, mimetype=None,
               version_id=None, **kwargs):
        """Create a new object in a bucket.

        The created object is by default created as a delete marker. You must
        use ``set_contents()`` or ``set_location()`` in order to change this.

        :param bucket: The bucket (instance or id) to create the object in.
        :param key: Key of object.
        :param _file_id: For internal use.
        :param stream: File-like stream object. Used to set content of object
            immediately after being created.
        :param mimetype: MIME type of the file object if it is known.
        :param kwargs: Keyword arguments passed to ``Object.set_contents()``.
        """
        bucket = as_bucket(bucket)

        if bucket.locked:

# Path: invenio_files_rest/errors.py
# class BucketLockedError(InvalidOperationError):
#     """Exception raised when a bucket is locked."""
# 
#     code = 403
#     description = "Bucket is locked for modifications."
# 
# class FileInstanceAlreadySetError(InvalidOperationError):
#     """Exception raised when file instance already set on object."""
# 
# class FileInstanceUnreadableError(InvalidOperationError):
#     """Exception raised when trying to get an unreadable file."""
# 
#     code = 503
#     description = "File storage is offline."
# 
# class FileSizeError(StorageError):
#     """Exception raised when a file larger than allowed."""
# 
#     code = 400
# 
# class InvalidKeyError(InvalidOperationError):
#     """Invalid key."""
# 
#     code = 400
#     description = "Filename is too long."
# 
# class InvalidOperationError(FilesException):
#     """Exception raised when an invalid operation is performed."""
# 
#     code = 403
# 
# class MultipartAlreadyCompleted(MultipartException):
#     """Exception raised when multipart object is already completed."""
# 
#     code = 403
#     description = "Multipart upload is already completed."
# 
# class MultipartInvalidChunkSize(MultipartException):
#     """Exception raised when multipart object is already completed."""
# 
#     code = 400
#     description = "Invalid part size."
# 
# class MultipartInvalidPartNumber(MultipartException):
#     """Exception raised when multipart object is already completed."""
# 
#     code = 400
#     description = "Invalid part number."
# 
# class MultipartInvalidSize(MultipartException):
#     """Exception raised when multipart object is already completed."""
# 
#     code = 400
#     description = "Invalid file size."
# 
# class MultipartMissingParts(MultipartException):
#     """Exception raised when multipart object is already completed."""
# 
#     code = 400
#     description = "Not all parts have been uploaded."
# 
# class MultipartNotCompleted(MultipartException):
#     """Exception raised when multipart object is not already completed."""
# 
#     code = 400
#     description = "Multipart upload is already completed."
# 
# Path: invenio_files_rest/proxies.py

# 
# Path: invenio_files_rest/utils.py
# def guess_mimetype(filename):
#     """Map extra mimetype with the encoding provided.
# 
#     :returns: The extra mimetype.
#     """
#     m, encoding = mimetypes.guess_type(filename)
#     if encoding:
#         m = ENCODING_MIMETYPES.get(encoding, None)
#     return m or 'application/octet-stream'


# Path: invenio_files_rest/models.py
import re
import sys
import uuid
from datetime import datetime
from flask import current_app
from functools import wraps
from invenio_db import db
from os.path import basename
from sqlalchemy.dialects import mysql
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import validates
from sqlalchemy.orm.exc import MultipleResultsFound
from sqlalchemy_utils.types import UUIDType
from .errors import BucketLockedError, FileInstanceAlreadySetError, \
    FileInstanceUnreadableError, FileSizeError, InvalidKeyError, \
    InvalidOperationError, MultipartAlreadyCompleted, \
    MultipartInvalidChunkSize, MultipartInvalidPartNumber, \
    MultipartInvalidSize, MultipartMissingParts, MultipartNotCompleted
from .proxies import current_files_rest
from .utils import guess_mimetype

        with db.session.begin_nested():
            if self.file_id:
                self.bucket.size -= self.file.size
            self.query.filter_by(
                bucket_id=self.bucket_id,
                key=self.key,
                version_id=self.version_id,
            ).delete()

        return self

    @classmethod
    def create(cls, bucket, key, _file_id=None, stream=None, mimetype=None,
               version_id=None, **kwargs):
        """Create a new object in a bucket.

        The created object is by default created as a delete marker. You must
        use ``set_contents()`` or ``set_location()`` in order to change this.

        :param bucket: The bucket (instance or id) to create the object in.
        :param key: Key of object.
        :param _file_id: For internal use.
        :param stream: File-like stream object. Used to set content of object
            immediately after being created.
        :param mimetype: MIME type of the file object if it is known.
        :param kwargs: Keyword arguments passed to ``Object.set_contents()``.
        """
        bucket = as_bucket(bucket)

        if bucket.locked:

            raise BucketLockedError()