+
    i                     X   R t ^ RIt^ RIt^ RIt^ RIt^ RIHtHt ^ RIHt ^ RI	H
t
Ht ]P                  ! 4       R,          R,          s^t^t\        R,          sR tR	 R
 ltR R lt]3R R llt]3R R lltR R lt]3R R lltR R ltR tR R ltR R ltR R ltR R ltR# ) z'Caching utilities for last30days skill.N)datetimetimezone)Path)AnyOptionalz.cache
last30daysmodel_selection.jsonc                 x   \         P                  P                  R4      p V '       d   \        V 4      s\        R,          s \        P                  RRR7       R#   \         dU    \        \        P                  ! 4       4      R,          R,          s\        R,          s\        P                  RRR7        R# i ; i)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    Q/Users/bowang/.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B98B9c          
      T    V ^8  d   QhR\         R\         R\         R\         R\         /# )   topic	from_dateto_datesourcesreturnstr)formats   "r   __annotate__r$   !   s/     > > > >s >S >S >    c                    V  RV RV RV 2p\         P                  ! VP                  4       4      P                  4       R,          # )z+Generate a cache key from query parameters.|:N   N)hashlibsha256encode	hexdigest)r   r   r   r   key_datas   &&&& r   get_cache_keyr.   !   sB    )AgYay9H>>(//+,668==r%   c                0    V ^8  d   QhR\         R\        /# )r   	cache_keyr    )r"   r   )r#   s   "r   r$   r$   '   s     + +c +d +r%   c                "    \         V  R2,          # )zGet path to cache file.z.json)r   )r0   s   &r   get_cache_pathr2   '   s    )E***r%   c                <    V ^8  d   QhR\         R\        R\        /# )r   
cache_path	ttl_hoursr    )r   intbool)r#   s   "r   r$   r$   ,   s!      t  D r%   c                b   V P                  4       '       g   R#  V P                  4       p\        P                  ! VP                  \
        P                  R7      p\        P                  ! \
        P                  4      pWC,
          P                  4       R,          pWQ8  #   \         d     R# i ; i)z-Check if cache file exists and is within TTL.Ftz  
existsstatr   fromtimestampst_mtimer   utcnowtotal_secondsOSError)r4   r5   r>   mtimerB   	age_hourss   &&    r   is_cache_validrG   ,   s     &&t}}Fll8<<([//1D8	$$ s   BB B.-B.c                R    V ^8  d   QhR\         R\        R\        \        ,          /# r   r0   r5   r    )r"   r6   r   dict)r#   s   "r   r$   r$   ;   s%      # # htn r%   c                   \        V 4      p\        W!4      '       g   R#  \        VR4      ;_uu_ 4       p\        P                  ! V4      uuRRR4       #   + '       g   i     R# ; i  \        P
                  \        3 d     R# i ; i)zLoad data from cache if valid.Nr)r2   rG   openjsonloadJSONDecodeErrorrD   )r0   r5   r4   fs   &&  r   
load_cacherR   ;   sd    	*J*00*c""a99Q< #"""  '* s.   A) A

A) A&	 A) &A) )BBc                F    V ^8  d   QhR\         R\        \        ,          /# )r   r4   r    )r   r   float)r#   s   "r   r$   r$   I   s     
 
D 
Xe_ 
r%   c                Z   V P                  4       '       g   R#  V P                  4       p\        P                  ! VP                  \
        P                  R7      p\        P                  ! \
        P                  4      pW2,
          P                  4       R,          #   \         d     R# i ; i)zGet age of cache file in hours.Nr9   r;   r<   )r4   r>   rE   rB   s   &   r   get_cache_age_hoursrV   I   sy     &&t}}Fll8<<(**,t33 s   B B B*)B*c                <    V ^8  d   QhR\         R\        R\        /# rI   )r"   r6   tuple)r#   s   "r   r$   r$   V   s!      3 3 u r%   c                2   \        V 4      p\        W!4      '       g   R# \        V4      p \        VR4      ;_uu_ 4       p\        P
                  ! V4      V3uuRRR4       #   + '       g   i     R# ; i  \        P                  \        3 d    Ru # i ; i)zhLoad data from cache with age info.

Returns:
    Tuple of (data, age_hours) or (None, None) if invalid
NrL   )NN)r2   rG   rV   rM   rN   rO   rP   rD   )r0   r5   r4   agerQ   s   &&   r   load_cache_with_ager[   V   s{      	*J*00
j
)C*c""a99Q<$ #"""  '* s.   A6 A"
A6 "A3	-A6 3A6 6BBc                0    V ^8  d   QhR\         R\        /# )r   r0   data)r"   rJ   )r#   s   "r   r$   r$   j   s     	 	# 	T 	r%   c                    \        4        \        V 4      p \        VR4      ;_uu_ 4       p\        P                  ! W4       RRR4       R#   + '       g   i     R# ; i  \
         d     R# i ; i)zSave data to cache.wN)r   r2   rM   rN   dumprD   )r0   r]   r4   rQ   s   &&  r   
save_cachera   j   sR    	*J*c""aIId #""" s.   A  AA  A	A  A   A/.A/c                     \         P                  4       '       d0   \         P                  R4       F  p  V P                  4        K  	  R# R#   \         d     K*  i ; i)zClear all cache files.z*.jsonN)r   r=   globunlinkrD   rQ   s    r   clear_cacherf   v   sK    )A
 *   s   AAAc                $    V ^8  d   QhR\         /# )r   r    rJ   )r#   s   "r   r$   r$      s     	 	$ 	r%   c                 *   \        \        \        ^,          4      '       g   / #  \        \        R4      ;_uu_ 4       p \        P
                  ! V 4      uuRRR4       #   + '       g   i     R# ; i  \        P                  \        3 d    / u # i ; i)zLoad model selection cache.rL   N)rG   r   MODEL_CACHE_TTL_DAYSrM   rN   rO   rP   rD   re   s    r   load_model_cacherk      sh    *,@2,EFF	"C((A99Q< )(((  '* 	s.   A2 A
A2 A/	)A2 /A2 2BBc                $    V ^8  d   QhR\         /# )r   r]   rh   )r#   s   "r   r$   r$      s      4 r%   c                    \        4         \        \        R4      ;_uu_ 4       p\        P                  ! W4       RRR4       R#   + '       g   i     R# ; i  \
         d     R# i ; i)zSave model selection cache.r_   N)r   rM   r   rN   r`   rD   )r]   rQ   s   & r   save_model_cachern      sI    "C((AIId )((( s-   A AA A	A A A('A(c                F    V ^8  d   QhR\         R\        \         ,          /# )r   providerr    )r"   r   )r#   s   "r   r$   r$      s      s x} r%   c                8    \        4       pVP                  V 4      # )z*Get cached model selection for a provider.)rk   r   )rp   r   s   & r   get_cached_modelrr      s    E99Xr%   c                0    V ^8  d   QhR\         R\         /# )r   rp   modelr!   )r#   s   "r   r$   r$      s      s 3 r%   c                    \        4       pWV &   \        P                  ! \        P                  4      P                  4       VR&   \        V4       R# )z%Cache model selection for a provider.
updated_atN)rk   r   rB   r   rA   	isoformatrn   )rp   rt   r   s   && r   set_cached_modelrx      s9    E(O",,x||4>>@E,Ur%   )__doc__r)   rN   r   r   r   r   pathlibr   typingr   r   homer   DEFAULT_TTL_HOURSrj   r   r   r.   r2   rG   rR   rV   r[   ra   rf   rk   rn   rr   rx    r%   r   <module>r      s    -   	  '   IIK("\1	  55 5 >+
 7H  1B 
 :K (		r%   