# 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
            writable=True,
            readable=False,
            size=0,
        )
        db.session.add(obj)
        return obj

    def delete(self):
        """Delete a file instance.

        The file instance can be deleted if it has no references from other
        objects. The caller is responsible to test if the file instance is
        writable and that the disk file can actually be removed.

        .. note::

           Normally you should use the Celery task to delete a file instance,
           as this method will not remove the file on disk.
        """
        self.query.filter_by(id=self.id).delete()
        return self

    def storage(self, **kwargs):
        """Get storage interface for object.

        Uses the applications storage factory to create a storage interface
        that can be used for this particular file instance.

        :returns: Storage interface.
        """

# 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

            writable=True,
            readable=False,
            size=0,
        )
        db.session.add(obj)
        return obj

    def delete(self):
        """Delete a file instance.

        The file instance can be deleted if it has no references from other
        objects. The caller is responsible to test if the file instance is
        writable and that the disk file can actually be removed.

        .. note::

           Normally you should use the Celery task to delete a file instance,
           as this method will not remove the file on disk.
        """
        self.query.filter_by(id=self.id).delete()
        return self

    def storage(self, **kwargs):
        """Get storage interface for object.

        Uses the applications storage factory to create a storage interface
        that can be used for this particular file instance.

        :returns: Storage interface.
        """

        return current_files_rest.storage_factory(fileinstance=self, **kwargs)