U
    H4fL                     @   s   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Zd dlmZ d dl	Z	d dl
Z
zd dlZW n ek
rx   dZY nX eeZG dd dZG dd deZG dd deZG d	d
 d
eZdd Zdd ZdS )    N)contextmanagerc                   @   s    e Zd ZdZdd Zdd ZdS )Basez Base class for caching backends.c                 C   s
   t  d S NNotImplementedErrorselfurlcontent r   ./tmp/pip-unpacked-wheel-04z2hmy8/zeep/cache.pyadd   s    zBase.addc                 C   s
   t  d S r   r   )r   r	   r   r   r   get   s    zBase.getN)__name__
__module____qualname____doc__r   r   r   r   r   r   r      s   r   c                   @   s,   e Zd ZdZdd Zdd Zedd ZdS )	VersionedCacheBasezuVersioned base class for caching backends.
    Note when subclassing a version class attribute must be provided.
    c                 C   s   t |}| j| S )zHelper function for encoding cacheable content as base64.
        :param data: Content to be encoded.
        :rtype: bytes
        )base64	b64encode_version_stringr   datar   r   r   _encode_data'   s    
zVersionedCacheBase._encode_datac                 C   s(   | | jr$t|t| jd S dS )z~Helper function for decoding base64 cached content.
        :param data: Content to be decoded.
        :rtype: bytes
        N)
startswithr   r   	b64decodelenr   r   r   r   _decode_data/   s    zVersionedCacheBase._decode_datac                 C   s0   t | dddk	stdd| j }t|dS )z]Expose the version prefix to be used in content serialization.
        :rtype: bytes
        _versionNzJA version must be provided in order to use the VersionedCacheBase backend.z	$ZEEP:%s$ascii)getattrAssertionErrorr   bytesencode)r   prefixr   r   r   r   7   s    
z"VersionedCacheBase._version_stringN)r   r   r   r   r   r   propertyr   r   r   r   r   r   "   s
   r   c                   @   s.   e Zd ZdZi Zd
ddZdd Zdd Zd	S )InMemoryCachezDSimple in-memory caching using dict lookup with support for timeouts  c                 C   s
   || _ d S r   )_timeout)r   timeoutr   r   r   __init__K   s    zInMemoryCache.__init__c                 C   sF   t d| t|ttfs.tdt|jt	j	
 |f| j|< d S )NCaching contents of %sz'a bytes-like object is required, not {})loggerdebug
isinstancestrr"   	TypeErrorformattyper   datetimeutcnow_cacher   r   r   r   r   N   s    zInMemoryCache.addc                 C   sT   z| j | \}}W n tk
r&   Y nX t|| jsDtd| |S td| d S )NCache HIT for %sCache MISS for %s)r5   KeyError_is_expiredr(   r,   r-   )r   r	   createdr
   r   r   r   r   V   s    zInMemoryCache.getN)r'   )r   r   r   r   r5   r*   r   r   r   r   r   r   r&   C   s   
r&   c                   @   s:   e Zd ZdZdZdddZedd Zd	d
 Zdd Z	dS )SqliteCachez7Cache contents via a sqlite database on the filesystem.1Nr'   c              	   C   sr   t d krtd|dkr tdt | _|| _|r8|nt | _| 	  }|
 }|d |  W 5 Q R X d S )Nz.sqlite3 module is required for the SqliteCachez:memory:zkThe SqliteCache doesn't support :memory: since it is not thread-safe. Please use zeep.cache.InMemoryCache()z
                    CREATE TABLE IF NOT EXISTS request
                    (created timestamp, url text, content text)
                )sqlite3RuntimeError
ValueError	threadingRLock_lockr(   _get_default_cache_path_db_pathdb_connectioncursorexecutecommit)r   pathr)   connrF   r   r   r   r*   h   s    

zSqliteCache.__init__c              	   c   s6   | j & tj| jtjd}|V  |  W 5 Q R X d S )N)Zdetect_types)rB   r=   connectrD   ZPARSE_DECLTYPESclose)r   
connectionr   r   r   rE      s     zSqliteCache.db_connectionc              	   C   sd   t d| | |}|  <}| }|d|f |dtj ||f |  W 5 Q R X d S )Nr+   z!DELETE FROM request WHERE url = ?z<INSERT INTO request (created, url, content) VALUES (?, ?, ?))	r,   r-   r   rE   rF   rG   r3   r4   rH   )r   r	   r
   r   rJ   rF   r   r   r   r      s    

zSqliteCache.addc              	   C   st   |   $}| }|d|f | }W 5 Q R X |rd|d \}}t|| jsdtd| | |S td| d S )Nz0SELECT created, content FROM request WHERE url=?r   r6   r7   )	rE   rF   rG   Zfetchallr9   r(   r,   r-   r   )r   r	   rJ   rF   Zrowsr:   r   r   r   r   r      s    

zSqliteCache.get)Nr'   )
r   r   r   r   r   r*   r   rE   r   r   r   r   r   r   r;   c   s   

r;   c                 C   sF   |dkrdS t j  jtjd}| jtjd}|t j|d7 }||kS )z&Return boolean if the value is expiredNF)tzinfo)seconds)r3   r4   replacepytzutc	timedelta)valuer)   nowZmax_ager   r   r   r9      s    r9   c               
   C   sh   t dd} zt|  W n> tk
rX } z |jtjkrFtj| rFn W 5 d }~X Y nX tj	| dS )NZzeepFzcache.db)
platformdirsuser_cache_dirosmakedirsOSErrorerrnoEEXISTrI   isdirjoin)rI   excr   r   r   rC      s    rC   )r   r3   r[   loggingrX   r@   typing
contextlibr   rV   rQ   r=   ImportError	getLoggerr   r,   r   r   r&   r;   r9   rC   r   r   r   r   <module>   s(   


! D