
    ?i              
          d Z ddlZddlZddlZddlZddlmZmZ ddlmZ ddl	m
Z
mZ  ej                         dz  dz  adZd	Zt        d
z  ad Zdededededef
dZdedefdZefdededefdZefdededee   fdZdedee   fdZefdededefdZdedefdZd ZdefdZ defdZ!dedee   fd Z"ded!efd"Z#y)#z'Caching utilities for last30days skill.    N)datetimetimezone)Path)AnyOptionalz.cache
last30days      model_selection.jsonc                  B   t         j                  j                  d      } | rt        |       at        dz  a	 t        j                  dd       y# t        $ rF t        t        j                               dz  dz  at        dz  at        j                  dd       Y yw xY w)zJEnsure cache directory exists. Supports env override and sandbox fallback.LAST30DAYS_CACHE_DIRr   T)parentsexist_okr   cacheN)
osenvirongetr   	CACHE_DIRMODEL_CACHE_FILEmkdirPermissionErrortempfile
gettempdir)env_dirs    P/home/ubuntu/.openclaw/workspace/skills/last30days-official/scripts/lib/cache.pyensure_cache_dirr      s     jjnn34GM	$'==5t4 5,,./,>H	$'==t45s   A ABBtopic	from_dateto_datesourcesreturnc                     |  d| d| d| }t        j                  |j                               j                         dd S )z+Generate a cache key from query parameters.|N   )hashlibsha256encode	hexdigest)r   r   r   r    key_datas        r   get_cache_keyr*   !   sD    )AgYay9H>>(//+,668"==    	cache_keyc                     t         |  dz  S )zGet path to cache file.z.json)r   )r,   s    r   get_cache_pathr.   '   s    )E***r+   
cache_path	ttl_hoursc                 >   | j                         sy	 | j                         }t        j                  |j                  t
        j                        }t        j                  t
        j                        }||z
  j                         dz  }||k  S # t        $ r Y yw xY w)z-Check if cache file exists and is within TTL.Ftz  
existsstatr   fromtimestampst_mtimer   utcnowtotal_secondsOSError)r/   r0   r7   mtimer;   	age_hourss         r   is_cache_validr@   ,   s     &&t}}Fll8<<(5[//1D8	9$$ s   A<B 	BBc                     t        |       }t        ||      sy	 t        |d      5 }t        j                  |      cddd       S # 1 sw Y   yxY w# t        j
                  t        f$ r Y yw xY w)zLoad data from cache if valid.Nr)r.   r@   openjsonloadJSONDecodeErrorr=   )r,   r0   r/   fs       r   
load_cacherH   ;   sf    	*J*i0*c" 	 a99Q<	  	  	   '* s-   A A	A A
A A A-,A-c                 4   | j                         sy	 | j                         }t        j                  |j                  t
        j                        }t        j                  t
        j                        }||z
  j                         dz  S # t        $ r Y yw xY w)zGet age of cache file in hours.Nr2   r4   r5   )r/   r7   r>   r;   s       r   get_cache_age_hoursrJ   I   sx     &&t}}Fll8<<(e**,t33 s   A7B 	BBc                     t        |       }t        ||      syt        |      }	 t        |d      5 }t	        j
                  |      |fcddd       S # 1 sw Y   yxY w# t        j                  t        f$ r Y yw xY w)ztLoad data from cache with age info.

    Returns:
        Tuple of (data, age_hours) or (None, None) if invalid
    )NNrB   N)r.   r@   rJ   rC   rD   rE   rF   r=   )r,   r0   r/   agerG   s        r   load_cache_with_agerM   V   sw      	*J*i0
j
)C*c" 	%a99Q<$	% 	% 	%  '* s.   A A	A AA A A:9A:datac                     t                t        |       }	 t        |d      5 }t        j                  ||       ddd       y# 1 sw Y   yxY w# t
        $ r Y yw xY w)zSave data to cache.wN)r   r.   rC   rD   dumpr=   )r,   rN   r/   rG   s       r   
save_cacherR   j   sW    	*J*c" 	aIIdA	 	 	 s-   A AA AA A 	AAc                      t         j                         r,t         j                  d      D ]  } 	 | j                           yy# t        $ r Y #w xY w)zClear all cache files.z*.jsonN)r   r6   globunlinkr=   rG   s    r   clear_cacherW   v   sM    ) 	A
	   s   A	AAc                      t        t        t        dz        si S 	 t        t        d      5 } t	        j
                  |       cddd       S # 1 sw Y   yxY w# t        j                  t        f$ r i cY S w xY w)zLoad model selection cache.r	   rB   N)r@   r   MODEL_CACHE_TTL_DAYSrC   rD   rE   rF   r=   rV   s    r   load_model_cacherZ      sh    *,@2,EF	"C( 	 A99Q<	  	  	   '* 	s.   A A
 	A 
AA A A43A4c                     t                	 t        t        d      5 }t        j                  | |       ddd       y# 1 sw Y   yxY w# t
        $ r Y yw xY w)zSave model selection cache.rP   N)r   rC   r   rD   rQ   r=   )rN   rG   s     r   save_model_cacher\      sN    "C( 	AIIdA	 	 	 s+   A <A AA A 	AAproviderc                 8    t               }|j                  |       S )z*Get cached model selection for a provider.)rZ   r   )r]   r   s     r   get_cached_modelr_      s    E99Xr+   modelc                     t               }||| <   t        j                  t        j                        j                         |d<   t        |       y)z%Cache model selection for a provider.
updated_atN)rZ   r   r;   r   r:   	isoformatr\   )r]   r`   r   s      r   set_cached_modelrd      s;    EE(O",,x||4>>@E,Ur+   )$__doc__r%   rD   r   r   r   r   pathlibr   typingr   r   homer   DEFAULT_TTL_HOURSrY   r   r   strr*   r.   intboolr@   dictrH   floatrJ   tuplerM   rR   rW   rZ   r\   r_   rd    r+   r   <module>rq      sa   -   	  '   DIIK("\1	  55 5 > > >s >S >S >+c +d +
 7H t  D  1B # # htn 
D 
Xe_ 
 :K 3 3 u (	# 	T 		$ 	4 s x} s 3 r+   