HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/unlimited-leads/leads_venv/lib/python3.12/site-packages/storages/utils.py
import os
import pathlib
import posixpath

from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.files.utils import FileProxyMixin
from django.utils.encoding import force_bytes


def to_bytes(content):
    """Wrap Django's force_bytes to pass through bytearrays."""
    if isinstance(content, bytearray):
        return content

    return force_bytes(content)


def setting(name, default=None):
    """
    Helper function to get a Django setting by name. If setting doesn't exists
    it will return a default.

    :param name: Name of setting
    :type name: str
    :param default: Value if setting is unfound
    :returns: Setting's value
    """
    return getattr(settings, name, default)


def clean_name(name):
    """
    Normalize the name.

    Includes cleaning up Windows style paths, ensuring an ending trailing slash,
    and coercing from pathlib.PurePath.
    """
    if isinstance(name, pathlib.PurePath):
        name = str(name)

    # Normalize Windows style paths
    clean_name = posixpath.normpath(name).replace("\\", "/")

    # os.path.normpath() can strip trailing slashes so we implement
    # a workaround here.
    if name.endswith("/") and not clean_name.endswith("/"):
        # Add a trailing slash as it was stripped.
        clean_name += "/"

    # Given an empty string, os.path.normpath() will return ., which we don't want
    if clean_name == ".":
        clean_name = ""

    return clean_name


def safe_join(base, *paths):
    """
    A version of django.utils._os.safe_join for S3 paths.

    Joins one or more path components to the base path component
    intelligently. Returns a normalized version of the final path.

    The final path must be located inside of the base path component
    (otherwise a ValueError is raised).

    Paths outside the base path indicate a possible security
    sensitive operation.
    """
    base_path = base
    base_path = base_path.rstrip("/")
    paths = list(paths)

    final_path = base_path + "/"
    for path in paths:
        _final_path = posixpath.normpath(posixpath.join(final_path, path))
        # posixpath.normpath() strips the trailing /. Add it back.
        if path.endswith("/") or _final_path + "/" == final_path:
            _final_path += "/"
        final_path = _final_path
    if final_path == base_path:
        final_path += "/"

    # Ensure final_path starts with base_path and that the next character after
    # the base path is /.
    base_path_len = len(base_path)
    if not final_path.startswith(base_path) or final_path[base_path_len] != "/":
        raise ValueError(
            "the joined path is located outside of the base path component"
        )

    return final_path.lstrip("/")


def check_location(storage):
    if storage.location.startswith("/"):
        correct = storage.location.lstrip("/")
        raise ImproperlyConfigured(
            (
                "{}.location cannot begin with a leading slash. Found '{}'. Use '{}' "
                "instead."
            ).format(
                storage.__class__.__name__,
                storage.location,
                correct,
            )
        )


def lookup_env(names):
    """
    Look up for names in environment. Returns the first element
    found.
    """
    for name in names:
        value = os.environ.get(name)
        if value:
            return value


def is_seekable(file_object):
    return not hasattr(file_object, "seekable") or file_object.seekable()


class ReadBytesWrapper(FileProxyMixin):
    """
    A wrapper for a file-like object, that makes read() always returns bytes.
    """

    def __init__(self, file, encoding=None):
        """
        :param file: The file-like object to wrap.
        :param encoding: Specify the encoding to use when file.read() returns strings.
            If not provided will default to file.encoding, of if that's not available,
            to utf-8.
        """
        self.file = file
        self._encoding = encoding or getattr(file, "encoding", None) or "utf-8"

    def read(self, *args, **kwargs):
        content = self.file.read(*args, **kwargs)

        if not isinstance(content, bytes):
            content = content.encode(self._encoding)
        return content

    def close(self):
        self.file.close()

    def readable(self):
        return True