<commit_before>from functools import wraps

from django.contrib.staticfiles.finders import find
from django.core.exceptions import ImproperlyConfigured

from sorl.thumbnail.engines.base import EngineBase as ThumbnailEngineBase

from ..conf import settings
from ..parsers import parse_geometry


def handle_padding(fn):
    @wraps(fn)
    def wrapped(self, image, geometry, options):
        watermark_before_padding = options.get(
            "watermark_before_padding", settings.THUMBNAIL_WATERMARK_BEFORE_PADDING
        )
        padding = False
        if watermark_before_padding:
            if options.get("padding") and self.get_image_size(image) != geometry:
                # remove padding option, add it later
                padding = options["padding"]
                options["padding"] = False

        image = fn(self, image, geometry, options)

        if watermark_before_padding:
            if padding and self.get_image_size(image) != geometry:
                # add padding after watermark
                options["padding"] = padding
                image = self.padding(image, geometry, options)
        return image

    return wrapped


class WatermarkEngineBase(ThumbnailEngineBase):
    """
    Extend sorl.thumbnail base engine to support watermarks.
    """

    name = "BaseEngine"

    @handle_padding
    def create(self, image, geometry, options):
        image = super(WatermarkEngineBase, self).create(image, geometry, options)
        if (
            settings.THUMBNAIL_WATERMARK_ALWAYS
            or "watermark" in options
            or "watermark_pos" in options
            or "watermark_size" in options
            or "watermark_alpha" in options
        ):
            image = self.watermark(image, options)
            # WORKAROUND: Forcefully convert JPGs to RGB.
            #             Pillow < 4.2 allowed this. Since then, one has to forcefully
            #             convert. Which makes sense as JPGs can't have an alpha
            #             channel.
            #             See #28 for details.
            if options.get("format", "").lower() == "jpeg" and image.mode == "RGBA":
                image = image.convert("RGB")
        return image

    def watermark(self, image, options):
        """
        Wrapper for ``_watermark``

        Takes care of all the options handling.
        """
        watermark_img = options.get("watermark", settings.THUMBNAIL_WATERMARK)

        if not watermark_img:
            raise AttributeError(
                "Trying to apply a watermark, "
                "however no THUMBNAIL_WATERMARK defined, "
                "and watermark not set on tag"
            )
        watermark_path = find(watermark_img)

        if "cropbox" not in options:
            options["cropbox"] = None
        if "watermark_alpha" not in options:
            options["watermark_alpha"] = settings.THUMBNAIL_WATERMARK_OPACITY
<commit_msg>better error messages. as suggested in !25<commit_after>import os
from functools import wraps

from django.contrib.staticfiles.finders import find
from django.core.exceptions import ImproperlyConfigured

from sorl.thumbnail.engines.base import EngineBase as ThumbnailEngineBase

from ..conf import settings
from ..parsers import parse_geometry


def handle_padding(fn):
    @wraps(fn)
    def wrapped(self, image, geometry, options):
        watermark_before_padding = options.get(
            "watermark_before_padding", settings.THUMBNAIL_WATERMARK_BEFORE_PADDING
        )
        padding = False
        if watermark_before_padding:
            if options.get("padding") and self.get_image_size(image) != geometry:
                # remove padding option, add it later
                padding = options["padding"]
                options["padding"] = False

        image = fn(self, image, geometry, options)

        if watermark_before_padding:
            if padding and self.get_image_size(image) != geometry:
                # add padding after watermark
                options["padding"] = padding
                image = self.padding(image, geometry, options)
        return image

    return wrapped


class WatermarkEngineBase(ThumbnailEngineBase):
    """
    Extend sorl.thumbnail base engine to support watermarks.
    """

    name = "BaseEngine"

    @handle_padding
    def create(self, image, geometry, options):
        image = super(WatermarkEngineBase, self).create(image, geometry, options)
        if (
            settings.THUMBNAIL_WATERMARK_ALWAYS
            or "watermark" in options
            or "watermark_pos" in options
            or "watermark_size" in options
            or "watermark_alpha" in options
        ):
            image = self.watermark(image, options)
            # WORKAROUND: Forcefully convert JPGs to RGB.
            #             Pillow < 4.2 allowed this. Since then, one has to forcefully
            #             convert. Which makes sense as JPGs can't have an alpha
            #             channel.
            #             See #28 for details.
            if options.get("format", "").lower() == "jpeg" and image.mode == "RGBA":
                image = image.convert("RGB")
        return image

    def watermark(self, image, options):
        """
        Wrapper for ``_watermark``

        Takes care of all the options handling.
        """
        watermark_img = options.get("watermark", settings.THUMBNAIL_WATERMARK)
        if not watermark_img:
            raise AttributeError("No THUMBNAIL_WATERMARK defined or set on tag.")
        if not os.path.isfile(watermark_img):
            raise RuntimeError("Set watermark does not point to a file.")
        watermark_path = find(watermark_img)

        if "cropbox" not in options:
            options["cropbox"] = None
        if "watermark_alpha" not in options:
            options["watermark_alpha"] = settings.THUMBNAIL_WATERMARK_OPACITY

{'fraction_non_alphanumeric': 0.07912572009488308, 'fraction_numerical': 0.0016943409013893595, 'mean_word_length': 2.161756829137654, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2248011', 'n_tokens_mistral': 1626, 'n_tokens_neox': 1589, 'n_words': 453}