Source code for superdjango.storage.utils

# Imports

from django.conf import settings
from myninjas.utils import File
import os
from PIL import Image
from unidecode import unidecode
from .constants import ALLOWED_CHARACTERS

# Exports

__all__ = (
    "generate_thumbnail",
    "get_unique_file_name",
    "get_upload_to",
    "remove_non_ascii",
    "sanitize",
)

# Constants

UPLOAD_DIR = getattr(settings, "SUPERDJANGO_UPLOAD_DIR", "uploads")

# Functions


[docs]def generate_thumbnail(path, height=200, prefix=None, suffix="thumbnail", width=200): """Generate a thumbnail for the given image file. :param path: The path to the image file. :type path: str :param height: The height of the thumbnail image. :type height: int :param prefix: The prefix of the new thumbnail file. The width and height will be added to the prefix in the form of ``prefix-WxH-file.extension``. :type prefix: str :param suffix: The suffix of the new thumbnail file. The width and height will be added to the suffix in the form of ``file-suffix-WxH.extension``. :type suffix: str :param width: The width of the thumbnail image. :type width: int :rtype: str :returns: The path of the thumbnail file relative to ``MEDIA_ROOT``. .. note:: Either the prefix or suffix is used in the new file name, but not both. """ file = File(path) a = list() if prefix is not None: a.append(prefix) a.append("%sx%s" % (width, height)) a.append("%s%s" % (file.name, file.extension)) else: a.append(file.name) a.append(suffix) a.append("%sx%s%s" % (width, height, file.extension)) new_file_name = "-".join(a) new_path = os.path.join(file.directory, new_file_name) image = Image.open(path) image.thumbnail((width, height)) image.save(new_path) partial = new_path.replace(settings.MEDIA_ROOT, "") if partial.startswith("/"): partial = partial[1:] return partial
[docs]def get_unique_file_name(file_name): """Given a file name to be uploaded, get a unique name if the file already exists. :param file_name: The name of the file to be checked. :type file_name: str :rtype: str """ # First, clean up the name. file_name = sanitize(file_name) # The name is unique if the file doesn't already exist. path = os.path.join(settings.MEDIA_ROOT, UPLOAD_DIR, file_name) if not os.path.exists(path): return file_name # Now find a unique name. suffix = 1 while True: file_name = "%s-%s" % (suffix, file_name) path = os.path.join(settings.MEDIA_ROOT, UPLOAD_DIR, file_name) if not os.path.exists(path): return file_name
[docs]def get_upload_to(instance, filename): """Get the path to upload a content file. :param instance: The model instance. :param filename: The name of the file. :type filename: str :rtype: str .. important:: The model instance must implement a ``get_upload_to()`` method. This allows the actual work of acquiring the upload path to be performed on the model where the file is defined. .. code-block:: python from superdjango.storage import import get_upload_to, remove_non_ascii class Document(models.Model): file = models.FileField( _("file"), help_text=_("Select the file to upload."), upload_to=get_upload_to ) def get_upload_to(self, filename): file_name = self.file.field.storage.get_valid_name(filename) file_name = remove_non_ascii(file_name) directory_name = "documents" path = os.path.join(directory_name, file_name) return path """ return instance.get_upload_to(filename)
[docs]def remove_non_ascii(text): """Replace non-ASCII characters with ASCII characters. :param text: The string that should have non-ASCII characters removed. :type text: str :rtype: str """ return unidecode(str(text))
[docs]def sanitize(file_name): """Make sure a given file name has no spaces or special characters. :param file_name: The file name to be sanitized. Do NOT include the path. :type file_name: str :rtype: str """ file_name = remove_non_ascii(file_name) file_name = file_name.replace(" ", "-") a = list() for c in file_name: if c not in ALLOWED_CHARACTERS: continue a.append(c) return ''.join(a)