<commit_before># django imports
import hashlib

from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.cache import cache
from django.db.models.signals import post_save, m2m_changed, post_delete
from django.db.models.signals import pre_save
from django.db.models.signals import pre_delete

# lfs imports
from lfs.caching.utils import clear_cache, invalidate_cache_group_id
from lfs.cart.models import Cart
from lfs.catalog.models import Category
from lfs.catalog.models import Product
from lfs.catalog.models import StaticBlock
from lfs.core.models import Shop
from lfs.core.signals import cart_changed
from lfs.core.signals import product_changed
from lfs.core.signals import category_changed
from lfs.core.signals import shop_changed
from lfs.core.signals import topseller_changed
from lfs.core.signals import manufacturer_changed
from lfs.criteria.models import CountryCriterion
from lfs.customer_tax.models import CustomerTax
from lfs.marketing.models import Topseller
from lfs.order.models import OrderItem
from lfs.page.models import Page
from lfs.shipping.models import ShippingMethod
from lfs.tax.models import Tax

# reviews imports
from reviews.signals import review_added


# Shop
def shop_changed_listener(sender, **kwargs):
    clear_cache()
shop_changed.connect(shop_changed_listener)


# Cart
def cart_changed_listener(sender, **kwargs):
    update_cart_cache(sender)
cart_changed.connect(cart_changed_listener)


def cart_deleted_listener(sender, instance, **kwargs):
    update_cart_cache(instance)
pre_delete.connect(cart_deleted_listener, sender=Cart)


# Category
def category_deleted_listener(sender, instance, **kwargs):
    update_category_cache(instance)
pre_delete.connect(category_deleted_listener, sender=Category)


def category_saved_listener(sender, instance, **kwargs):
    update_category_cache(instance)
pre_save.connect(category_saved_listener, sender=Category)


def category_changed_listener(sender, **kwargs):
    update_category_cache(sender)
category_changed.connect(category_changed_listener)


def product_categories_changed_listener(sender, **kwargs):
    instance = kwargs['instance']
    reverse = kwargs['reverse']
    pk_set = kwargs['pk_set']

    if reverse:
        product = instance
        cache_key = "%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, True)
        cache.delete(cache_key)
        cache_key = "%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, False)
        cache.delete(cache_key)
    else:
        if pk_set:
            for product in Product.objects.filter(pk__in=pk_set):
                cache_key = "%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, True)
                cache.delete(cache_key)
                cache_key = "%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, False)
                cache.delete(cache_key)
m2m_changed.connect(product_categories_changed_listener, sender=Category.products.through)


# Manufacturer
def manufacturer_changed_listener(sender, **kwargs):
    # filtered lists of products assigned to manufacturer used at manufacturer page
    cache.delete("%s-manufacturer-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, sender.slug))
    # list of all manufacturer products
    cache.delete("%s-manufacturer-all-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, sender.pk))
    # if manufacturer assignment was changed then product navigation might be different too
    invalidate_cache_group_id('product_navigation')
manufacturer_changed.connect(manufacturer_changed_listener)


# OrderItem
def order_item_listener(sender, instance, **kwargs):
    """Deletes topseller after an OrderItem has been updated. Topseller are
    calculated automatically on base of OrderItems, hence we have to take of
    that.
    """
    cache.delete("%s-topseller" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
    try:
        for category in instance.product.get_categories(with_parents=True):
            cache.delete("%s-topseller-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, category.id))
    except:
        pass  # fail silently
pre_delete.connect(order_item_listener, sender=OrderItem)
post_save.connect(order_item_listener, sender=OrderItem)


# Page
def page_saved_listener(sender, instance, **kwargs):
    cache.delete("%s-page-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))
    cache.delete("%s-pages" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
post_save.connect(page_saved_listener, sender=Page)


# Product
def product_changed_listener(sender, **kwargs):
    update_product_cache(sender)
product_changed.connect(product_changed_listener)


def product_saved_listener(sender, instance, **kwargs):
    # update_product_cache(instance)
    update_category_cache(instance)
post_save.connect(product_saved_listener, sender=Product)


def product_pre_saved_listener(sender, instance, **kwargs):
    """ If product slug was changed we should have cleared slug based product cache"""
    # check if product already exists in database
    if instance.pk:
        if instance.is_variant():
            parent = instance.parent
        else:
            parent = instance

        cache_key = "%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id)
        cache.delete(cache_key)
        cache_key_hash = hashlib.md5(cache_key).hexdigest()
        cache.delete(cache_key_hash)

        old_product = Product.objects.get(pk=parent.pk)
        cache_key = "%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, old_product.slug)
        cache.delete(cache_key)
        cache_key_hash = hashlib.md5(cache_key).hexdigest()
        cache.delete(cache_key_hash)

pre_save.connect(product_pre_saved_listener, sender=Product)


# Shipping Method
def shipping_method_saved_listener(sender, instance, **kwargs):
    cache.delete("%s-shipping-delivery-time" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
    cache.delete("%s-shipping-delivery-time-cart" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
    cache.delete("all_active_shipping_methods")
post_save.connect(shipping_method_saved_listener, sender=ShippingMethod)


def shipping_method_deleted_listener(sender, instance, **kwargs):
    cache.delete("all_active_shipping_methods")
post_delete.connect(shipping_method_deleted_listener, sender=ShippingMethod)


# Shop<commit_msg>second fix to cache cleanup on product save<commit_after># django imports
import hashlib

from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.cache import cache
from django.db.models.signals import post_save, m2m_changed, post_delete
from django.db.models.signals import pre_save
from django.db.models.signals import pre_delete

# lfs imports
from lfs.caching.utils import clear_cache, invalidate_cache_group_id
from lfs.cart.models import Cart
from lfs.catalog.models import Category
from lfs.catalog.models import Product
from lfs.catalog.models import StaticBlock
from lfs.core.models import Shop
from lfs.core.signals import cart_changed
from lfs.core.signals import product_changed
from lfs.core.signals import category_changed
from lfs.core.signals import shop_changed
from lfs.core.signals import topseller_changed
from lfs.core.signals import manufacturer_changed
from lfs.criteria.models import CountryCriterion
from lfs.customer_tax.models import CustomerTax
from lfs.marketing.models import Topseller
from lfs.order.models import OrderItem
from lfs.page.models import Page
from lfs.shipping.models import ShippingMethod
from lfs.tax.models import Tax

# reviews imports
from reviews.signals import review_added


# Shop
def shop_changed_listener(sender, **kwargs):
    clear_cache()
shop_changed.connect(shop_changed_listener)


# Cart
def cart_changed_listener(sender, **kwargs):
    update_cart_cache(sender)
cart_changed.connect(cart_changed_listener)


def cart_deleted_listener(sender, instance, **kwargs):
    update_cart_cache(instance)
pre_delete.connect(cart_deleted_listener, sender=Cart)


# Category
def category_deleted_listener(sender, instance, **kwargs):
    update_category_cache(instance)
pre_delete.connect(category_deleted_listener, sender=Category)


def category_saved_listener(sender, instance, **kwargs):
    update_category_cache(instance)
pre_save.connect(category_saved_listener, sender=Category)


def category_changed_listener(sender, **kwargs):
    update_category_cache(sender)
category_changed.connect(category_changed_listener)


def product_categories_changed_listener(sender, **kwargs):
    instance = kwargs['instance']
    reverse = kwargs['reverse']
    pk_set = kwargs['pk_set']

    if reverse:
        product = instance
        cache_key = "%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, True)
        cache.delete(cache_key)
        cache_key = "%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, False)
        cache.delete(cache_key)
    else:
        if pk_set:
            for product in Product.objects.filter(pk__in=pk_set):
                cache_key = "%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, True)
                cache.delete(cache_key)
                cache_key = "%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, False)
                cache.delete(cache_key)
m2m_changed.connect(product_categories_changed_listener, sender=Category.products.through)


# Manufacturer
def manufacturer_changed_listener(sender, **kwargs):
    # filtered lists of products assigned to manufacturer used at manufacturer page
    cache.delete("%s-manufacturer-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, sender.slug))
    # list of all manufacturer products
    cache.delete("%s-manufacturer-all-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, sender.pk))
    # if manufacturer assignment was changed then product navigation might be different too
    invalidate_cache_group_id('product_navigation')
manufacturer_changed.connect(manufacturer_changed_listener)


# OrderItem
def order_item_listener(sender, instance, **kwargs):
    """Deletes topseller after an OrderItem has been updated. Topseller are
    calculated automatically on base of OrderItems, hence we have to take of
    that.
    """
    cache.delete("%s-topseller" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
    try:
        for category in instance.product.get_categories(with_parents=True):
            cache.delete("%s-topseller-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, category.id))
    except:
        pass  # fail silently
pre_delete.connect(order_item_listener, sender=OrderItem)
post_save.connect(order_item_listener, sender=OrderItem)


# Page
def page_saved_listener(sender, instance, **kwargs):
    cache.delete("%s-page-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))
    cache.delete("%s-pages" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
post_save.connect(page_saved_listener, sender=Page)


# Product
def product_changed_listener(sender, **kwargs):
    update_product_cache(sender)
product_changed.connect(product_changed_listener)


def product_saved_listener(sender, instance, **kwargs):
    # update_product_cache(instance)
    update_category_cache(instance)
post_save.connect(product_saved_listener, sender=Product)


def product_pre_saved_listener(sender, instance, **kwargs):
    """ If product slug was changed we should have cleared slug based product cache"""
    # check if product already exists in database
    if instance.pk:
        if instance.is_variant():
            parent = instance.parent
        else:
            parent = instance

        cache_key = "%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id)
        cache.delete(cache_key)
        cache_key_hash = hashlib.md5(cache_key).hexdigest()
        cache.delete(cache_key_hash)

        try:
            old_product = Product.objects.get(pk=parent.pk)
        except Product.DoesNotExist:
            pass
        else:
            cache_key = "%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, old_product.slug)
            cache.delete(cache_key)
            cache_key_hash = hashlib.md5(cache_key).hexdigest()
            cache.delete(cache_key_hash)

pre_save.connect(product_pre_saved_listener, sender=Product)


# Shipping Method
def shipping_method_saved_listener(sender, instance, **kwargs):
    cache.delete("%s-shipping-delivery-time" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
    cache.delete("%s-shipping-delivery-time-cart" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
    cache.delete("all_active_shipping_methods")
post_save.connect(shipping_method_saved_listener, sender=ShippingMethod)


def shipping_method_deleted_listener(sender, instance, **kwargs):
    cache.delete("all_active_shipping_methods")
post_delete.connect(shipping_method_deleted_listener, sender=ShippingMethod)


# Shop
{'fraction_non_alphanumeric': 0.09011650335622251, 'fraction_numerical': 0.0006172363243576885, 'mean_word_length': 4.96228150873965, 'pattern_counts': {'":': 0, '<': 3, '<?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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1647708', 'n_tokens_mistral': 3881, 'n_tokens_neox': 3836, 'n_words': 785}