
    FEi                     >   U d Z ddlZddlZddlZddlmZ ddlmZmZmZm	Z	m
Z
mZmZmZ ddlmZ  ededef         Z ed	      Z G d
 dee         Z edd      Zeed<   defdZddZde
eef   fdZdeddfdZdefdZdedefdZddedeegef   fdZy)zUtility functions for trendspy.    N)datetime)CallableAnyTypeVarcastDictOptionalTupleGeneric)wrapsF.)boundTc                       e Zd ZdZddedefdZdedee	   fdZ
dede	dd	fd
ZdefdZddZdeeef   fdZedefd       Zej&                  dedd	fd       Zy	)TTLCachea  
    Thread-safe TTL (Time-To-Live) cache for storing temporary data.

    Features:
    - Automatic expiration based on TTL
    - Thread-safe operations
    - Maximum size limit with LRU-style eviction
    - Cache statistics (hits, misses)

    Example:
        >>> cache = TTLCache(ttl=300, max_size=100)  # 5 min TTL, max 100 items
        >>> cache.set('US', trends_data)
        >>> data = cache.get('US')  # Returns data if not expired
        >>> cache.clear()  # Clear all cached data
    ttlmax_sizec                 |    i | _         || _        || _        t        j                         | _        d| _        d| _        y)z
        Initialize TTL cache.

        Args:
            ttl: Time-to-live in seconds (default: 300 = 5 minutes)
            max_size: Maximum number of items to cache (default: 256)
        r   N)_cache_ttl	_max_size	threadingRLock_lock_hits_misses)selfr   r   s      [/home/sietch6/trending-topics-pipeline/venv/lib/python3.12/site-packages/trendspyg/utils.py__init__zTTLCache.__init__    s5     35	!__&

    keyreturnc                 :   | j                   5  || j                  v rV| j                  |   \  }}t        j                         |k  r | xj                  dz  c_        |cddd       S | j                  |= | xj                  dz  c_        	 ddd       y# 1 sw Y   yxY w)z
        Get value from cache if exists and not expired.

        Args:
            key: Cache key

        Returns:
            Cached value or None if not found/expired
           N)r   r   timer   r   )r   r!   valueexpirys       r   getzTTLCache.get/   s     ZZ 
	dkk! $C 0v99;'JJ!OJ 
	 
	 C(LLAL
	 
	 
	s   AB%#BBr&   Nc                    | j                   5  t        | j                        | j                  k\  rk|| j                  vr]| j	                          t        | j                        | j                  k\  r+t        t        | j                              }| j                  |= t        j                         | j                  z   }||f| j                  |<   ddd       y# 1 sw Y   yxY w)zz
        Set value in cache with TTL.

        Args:
            key: Cache key
            value: Value to cache
        N)	r   lenr   r   _evict_expirednextiterr%   r   )r   r!   r&   
oldest_keyr'   s        r   setzTTLCache.setE   s     ZZ 
	/4;;4>>1c6L##%t{{#t~~5!%d4;;&7!8JJ/YY[499,F %vDKK
	/ 
	/ 
	/s   C CCc                     t        j                          }| j                  j                         D cg c]  \  }\  }}||k\  s| }}}}|D ]  }| j                  |=  t        |      S c c}}}w )z;Remove all expired entries. Returns count of evicted items.)r%   r   itemsr*   )r   nowk_expexpired_keysr!   s          r   r+   zTTLCache._evict_expiredY   sj    iik-1[[->->-@OOka!SC3JOO 	!CC 	!<   Ps   A+A+c                     | j                   5  | j                  j                          d| _        d| _        ddd       y# 1 sw Y   yxY w)zClear all cached data.r   N)r   r   clearr   r   r   s    r   r8   zTTLCache.cleara   s<    ZZ 	KKDJDL	 	 	s	   )?Ac                 :   | j                   5  | j                  | j                  z   }|dkD  r| j                  |z  dz  nd}| j                  | j                  t        | j                        | j
                  | j                  |dddcddd       S # 1 sw Y   yxY w)zl
        Get cache statistics.

        Returns:
            Dict with hits, misses, size, hit_rate
        r   d           z.1f%)hitsmissessizer   r   hit_rateN)r   r   r   r*   r   r   r   )r   totalrA   s      r   statszTTLCache.statsh   s     ZZ 
	JJ-E5:QY

U*S0CH

,,DKK( NNyy'nA.
	 
	 
	s   A:BBc                     | j                   S )zGet current TTL value.r   r9   s    r   r   zTTLCache.ttl{   s     yyr    c                     || _         y)z4Set new TTL value (doesn't affect existing entries).NrE   )r   r&   s     r   r   zTTLCache.ttl   s     	r    )     r@   r"   N)__name__
__module____qualname____doc__floatintr   strr	   r   r(   r/   r+   r8   r   r   rC   propertyr   setter r    r   r   r      s     E S s x{ ,/s /1 / /(! !tCH~ & U   	ZZ 4  r    r   rG   rH   )r   r   
_rss_cacher"   c                      t         S )z"Get the global RSS cache instance.)rT   rS   r    r   get_rss_cacherV      s    r    c                  ,    t         j                          y)zClear the global RSS cache.N)rT   r8   rS   r    r   clear_rss_cacherX      s    r    c                  *    t         j                         S )z(Get statistics for the global RSS cache.)rT   rC   rS   r    r   get_rss_cache_statsrZ      s    r    r   c                     | t         _        y)zq
    Set the TTL for the global RSS cache.

    Args:
        ttl: New TTL in seconds (0 to disable caching)
    N)rT   r   )r   s    r   set_rss_cache_ttlr\      s     JNr    c                  H    t        j                         j                  d      S )z0Get current timestamp in YYYYMMDD-HHMMSS format.z%Y%m%d-%H%M%S)r   r2   strftimerS   r    r   get_timestampr_      s    <<>""?33r    	directoryc                 4    t        j                  | d       | S )z.Ensure directory exists, create if it doesn't.T)exist_ok)osmakedirs)r`   s    r   
ensure_dirre      s    KK	D)r    delayc                 ,     dt         dt         f fd}|S )zSimple rate limiting decorator.funcr"   c                 ~     dgt               dt        dt        dt        f fd       }t        t        |      S )Nr<   argskwargsr"   c                      t        j                          d   z
  }|k  rt        j                  |z
          | i |}t        j                          d<   |S )Nr   )r%   sleep)rj   rk   elapsedresultrf   rh   last_calleds       r   wrapperz.rate_limit.<locals>.decorator.<locals>.wrapper   sQ    iikKN2G

57?+4*6*F!YY[KNMr    )r   r   r   r   )rh   rq   rp   rf   s   ` @r   	decoratorzrate_limit.<locals>.decorator   sD    e	t	3 	# 	# 	 
	 Awr    )r   )rf   rr   s   ` r   
rate_limitrs      s       a   r    rI   )g      ?)rM   rc   r%   r   r   typingr   r   r   r   r   r	   r
   r   	functoolsr   r   r   r   rT   __annotations__rV   rX   rP   rZ   rN   r\   r_   re   rs   rS   r    r   <module>rw      s    % 	    O O O  CxS)*CLtwqz tp  EC8
H 8x 

T#s(^ 
5 T 4s 4
# # e hsAv&6 r    