from django.utils import timezone from django.db import models from ..models import AnalysisCache import hashlib import logging logger = logging.getLogger(__name__) class CacheService: """ Service for handling analysis result caching operations. This service provides methods for generating cache keys, retrieving cached results, and storing new results in the cache. """ def generate_hash(self, prompt, dealer_id, language): """ Generate a unique hash for the prompt, dealer, and language combination. :param prompt: The user's prompt text :type prompt: str :param dealer_id: The dealer's ID :type dealer_id: int :param language: The language code :type language: str :return: MD5 hash string :rtype: str """ cache_key = f"{prompt}:{dealer_id or 'all'}:{language}" return hashlib.md5(cache_key.encode()).hexdigest() def get_cached_result(self, prompt_hash, user, dealer_id): """ Retrieve a cached result if available and not expired. :param prompt_hash: The hash key for the cache entry :type prompt_hash: str :param user: The user making the request :type user: User :param dealer_id: The dealer's ID :type dealer_id: int :return: Cached result or None if not found :rtype: dict or None """ try: cache_entry = AnalysisCache.objects.filter( prompt_hash=prompt_hash, dealer_id=dealer_id, expires_at__gt=timezone.now() ).first() # If user is authenticated, also check user-specific cache if user and user.is_authenticated: user_cache = AnalysisCache.objects.filter( prompt_hash=prompt_hash, user=user, expires_at__gt=timezone.now() ).first() # User-specific cache takes precedence if user_cache: return user_cache.result return cache_entry.result if cache_entry else None except Exception as e: logger.warning(f"Error retrieving cache: {str(e)}") return None def cache_result(self, prompt_hash, result, user, dealer_id, duration=3600): """ Store a result in the cache. :param prompt_hash: The hash key for the cache entry :type prompt_hash: str :param result: The result to cache :type result: dict :param user: The user making the request :type user: User :param dealer_id: The dealer's ID :type dealer_id: int :param duration: Cache duration in seconds :type duration: int :return: None """ try: # Calculate expiration time expires_at = timezone.now() + timezone.timedelta(seconds=duration) # Create or update cache entry AnalysisCache.objects.update_or_create( prompt_hash=prompt_hash, user=user if user and user.is_authenticated else None, dealer_id=dealer_id, defaults={ 'result': result, 'expires_at': expires_at } ) except Exception as e: logger.warning(f"Error caching result: {str(e)}")