
    Zf!                    <   d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	m
Z
mZmZ ddlmZ ddlmZmZ ddlZddlmZ  ej*                  e      Zda ed	      Zej4                  d
k\  rddZnej6                  ZddZddZ G d d      ZddZddZ ddZ!y)zHelpers.    )annotationsN)CallableHashableIterable)Path)TypeVarcast)FileLockFT)   	   c                 ,    t        j                  | ddiS )zUse argument only available in newer Python.

        In this file, MD5 is only used for cache location, not security.
        usedforsecurityF)hashlibmd5)argss    0lib/python3.12/site-packages/tldextract/cache.pyr   r      s    
 {{D8%88    c                    	 ddl m}  d| z   }t        j                  j                  t        j                        }t        t        j                  j                  d            j                         dd }dj                  t        j                  dd	 D cg c]  }t        |       c}      }||||g}d
j                  |      }|S # t        $ r d} Y w xY wc c}w )zGenerate an identifier unique to the python version, tldextract version, and python instance.

    This will prevent interference between virtualenvs and issues that might arise when installing
    a new version of tldextract
    r   )versiondevztldextract-utf-8N   .__)tldextract._versionr   ImportErrorospathbasenamesysprefixr   encode	hexdigestjoinversion_infostr)r   tldextract_versionpython_env_namepython_binary_path_short_hashvpython_versionidentifier_partspkg_identifiers           r   get_pkg_unique_identifierr0   (   s    / '0gg&&szz2O$'

(9(9'(B$C$M$M$OPRQR$S!XXs/?/?/DE!s1vEFN%	 YY/0N!   Fs   C CCCc                    t         j                  j                  dd      } | | S t        j                  dd      }|-t        j                  dd      }|rt	        t        |d            }|t	        t        |dt                           S t	        t        t         j                  j                  t              d            S )zGet a cache dir that we have permission to write to.

    Try to follow the XDG standard, but if that doesn't work fallback to the package directory
    http://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
    TLDEXTRACT_CACHENXDG_CACHE_HOMEHOMEz.cachezpython-tldextractz.suffix_cache)
r   environgetgetenvr(   r   r0   r    dirname__file__)	cache_dirxdg_cache_home	user_homes      r   get_cache_dirr=   C   s     

148IYY/6NIIfd+	 i!:;N!!46O6QR
 	

 tBGGOOH-?@@r   c                      e Zd ZdZd
ddZddZ	 	 	 	 	 	 	 	 ddZddZ	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 	 	 ddZ		 	 	 	 	 	 	 	 ddZ
y	)	DiskCachez0Disk _cache that only works for jsonable values.c                    t        |      | _        t        j                  j	                  t        |      xs d      | _        || _        d| _        y)z.Construct a disk cache in the given directory. z.tldextract.jsonN)	boolenabledr   r    
expanduserr(   r:   lock_timeoutfile_ext)selfr:   rE   s      r   __init__zDiskCache.__init___   s=    I++C	N,@bA( +r   c                   | j                   st        d      | j                  ||      }t        j                  j                  |      st        d|z   dz   t        |      z         	 t        |      5 }t        j                  |      cddd       S # 1 sw Y   yxY w# t        t        f$ r:}t        j                  d||       t        d|z   dz   t        |      z         dd}~ww xY w)z%Retrieve a value from the disk cache.zCache is disabledznamespace: z key: Nz#error reading TLD cache file %s: %s)rC   KeyError_key_to_cachefile_pathr   r    isfilerepropenjsonloadOSError
ValueErrorLOGerror)rG   	namespacekeycache_filepath
cache_fileexcs         r   r6   zDiskCache.geth   s    ||.//44YDww~~n-=94x?$s)KLL	Wn% -yy,- - -$ 	WII;^SQ=94x?$s)KLRVV	Ws6   'B 2B	B BB B C&,5C!!C&c                @   | j                   sy| j                  ||      }	 t        |       t        |d      5 }t	        j
                  ||       ddd       y# 1 sw Y   yxY w# t        $ r0}t        s t        j                  d||||       daY d}~yY d}~yd}~ww xY w)zSet a value in the disk cache.Nwunable to cache %s.%s in %s. This could refresh the Public Suffix List over HTTP every app startup. Construct your `TLDExtract` with a writable `cache_dir` or set `cache_dir=None` to silence this warning. %sT)
rC   rK   	_make_dirrN   rO   dumprQ   _DID_LOG_UNABLE_TO_CACHErS   warning)rG   rU   rV   valuerW   rX   ioes          r   setzDiskCache.setw   s     ||44YD	0n%nc* -j		%,- - - 	0+G "	 ,0( ,	0s4   A$ AA$ A!A$ !A$ $	B-!BBc           
        t        j                  | j                        D ]p  \  }}}|D ]e  }|j                  | j                        s|j                  | j                  dz         s=	 t        j
                  t        t        ||                   g r y# t        $ r Y vt        $ r(}|j                  t        j                  k7  r Y d}~d}~ww xY w)zClear the disk cache..lockN)r   walkr:   endswithrF   unlinkr(   r   FileNotFoundErrorrQ   errnoENOENT)rG   root_filesfilenamerY   s         r   clearzDiskCache.clear   s     ggdnn5 	"ND!U! "$$T]]3x7H7HMMG+8"		#d4&:";<"	" - " " 994! 5"s   '(B	CC'C

Cc                    t        t        | j                  |            }t        |      }t        t        ||| j                  z               }|S )N)r(   r   r:   _make_cache_keyrF   )rG   rU   rV   namespace_path
hashed_key
cache_paths         r   rK   z DiskCache._key_to_cachefile_path   sC     T$..)<=$S)
nj4==.HIJ
r   c                B   | j                   s |di |S |j                         D ci c]  \  }}||v s|| }}}| j                  ||      }|dz   }		 t        |       t        |	| j                        5  	 t        t        | j                  ||            }|cddd       S c c}}w # t        $ r3}
t
        st        j                  d||||
       da |di |cY d}
~
S d}
~
ww xY w# t        $ r  |di |}| j                  |||       Y ww xY w# 1 sw Y   yxY w)	!Get a url but cache the response.re   r\   TNtimeout)rU   rV   )rU   rV   ra    )rC   itemsrK   r]   rQ   r_   rS   r`   r
   rE   r	   r   r6   rJ   rc   )rG   funcrU   kwargshashed_argnameskr,   key_argsrW   	lock_pathrb   results               r   run_and_cachezDiskCache.run_and_cache   s6    ||>&>!%+\\^LTQqO7KAqDLL44YI"W,		"n%$ i):):; 	JaI8!LM
 	 	- M
  	"+G "	 ,0(>&>!	"(  J9(&IJ	 	sX   B%B%B+ 7D9!C*D+	C'4(C"C'"C'*%DDDDDc                >    | j                  t        d|||ddg      S )rw   urls)sessionurlry   r   )r|   rU   r}   r~   )r   
_fetch_url)rG   r   r   ry   s       r   cached_fetch_urlzDiskCache.cached_fetch_url   s1     !!&swG"G	 " 
 	
r   N)   )r:   z
str | NonerE   int)rU   r(   rV   str | dict[str, Hashable]returnobject)rU   r(   rV   r   ra   r   r   None)r   r   )rU   r(   rV   r   r   r(   )
r|   zCallable[..., T]rU   r(   r}   zdict[str, Hashable]r~   zIterable[str]r   r   )r   requests.Sessionr   r(   ry   zfloat | int | Noner   r(   )__name__
__module____qualname____doc__rH   r6   rc   rp   rK   r   r   rz   r   r   r?   r?   \   s    :+W00#<0EK0	08""#<	(( ( $	(
 '( 
(T	
'	
.1	
<N	
		
r   r?   c                    | j                  ||      }|j                          |j                  }t        |t              st	        |d      }|S )Nrx   r   )r6   raise_for_statustext
isinstancer(   )r   r   ry   responser   s        r   r   r      sD    {{3{0H==DdC 4!Kr   c                h    t        |       }t        |j                  d            j                         S )Nutf8)rM   r   r$   r%   )inputsrV   s     r   rr   rr      s(    
v,Cszz&!",,..r   c                L   t         j                  j                  t         j                  j                  |             s4	 t        j                  t         j                  j                  |              yy# t
        $ r(}|j                  t        j                  k7  r Y d}~yd}~ww xY w)z-Make a directory if it doesn't already exist.N)r   r    existsr8   makedirsrQ   rj   EEXIST)ro   rY   s     r   r]   r]      sl    77>>"''//(34	KK12 5  	yyELL( )	s   2A2 2	B#;BB#)r   bytesr   zhashlib._Hash)r   r(   )r   r   r   r(   ry   z
int | Noner   r(   )r   r   r   r(   )ro   r(   r   r   )"r   
__future__r   rj   r   rO   loggingr   r"   collections.abcr   r   r   pathlibr   typingr   r	   requestsfilelockr
   	getLoggerr   rS   r_   r   r'   r   r0   r=   r?   r   rr   r]   rz   r   r   <module>r      s     "     	 
 8 8 
  g!  CLv9 ++C6A2E
 E
P/
r   