o
    ȷen                     @   s  d 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
mZmZmZmZmZmZmZmZ eeZdZdZeedZdd	 Zd
d Z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#e#e j$%  e#e j&%  e#e j'%  e#e j(%  dS )zt
Django-environ allows you to utilize 12factor inspired environment
variables to configure your Django application.
    N   )jsonurlparseliburlparse
urlunparseParseResultparse_qsunquote_plusDJANGO_POSTGRESREDIS_DRIVERImproperlyConfigured
basestringz0.4.54joke2k.c                 C   s$   zt | W S  ty   |  Y S w N)astliteral_eval
ValueError)value r   F/var/www/ideatree/venv/lib/python3.10/site-packages/environ/environ.py_cast   s
   r   c                 C   s   t | dr|  rt| S | S )Nisdigit)hasattrr   intvr   r   r   	_cast_int!      r   c                 C   s   t | tr	t| S | S r   )
isinstancestrr	   r   r   r   r   _cast_urlstr$   s   r!   c                   @   s   e Zd Zdd ZdS )NoValuec                 C   s   d | jjS )Nz<{0}>)format	__class____name__selfr   r   r   __repr__*   s   zNoValue.__repr__N)r%   
__module____qualname__r(   r   r   r   r   r"   (   s    r"   c                
   @   sX  e Zd ZdZejZe ZdZ	e
ZdZi dededededd	d
dddddddddddddddddddddZg dZdZd d!d"d#d$d%eeed&	Zg d'Zd(Zd)d)d)d)d*d+d,d-d.Zd/d0gZd1Zd2d3d4d5d6d7d8Zd9d: Zd;ed<fd=d>Zd?d@ Zed<fdAdBZefdCdDZedEfdFdGZefdHdIZefdJdKZ efdLdMZ!efdNdOZ"d;efdPdQZ#d;efdRdSZ$e%efdTdUZ%efdVdWZ&eed;fdXdYZ'e'Z(eed;fdZd[Z)e)Z*eed;fd\d]Z+e+Z,eed;fd^d_Z-efd`daZ.d;ed<fdbdcZ/e0ddde Z1e0dpdfdgZ2e0dpdhdiZ3e0dpdjdkZ4e0dpdldmZ5e0dpdndoZ6d;S )qEnva  Provide scheme-based lookups of environment variables so that each
    caller doesn't have to pass in `cast` and `default` parameters.

    Usage:::

        env = Env(MAIL_ENABLED=bool, SMTP_LOGIN=(str, 'DEFAULT'))
        if env('MAIL_ENABLED'):
            ...
    )trueonokyyes1DATABASE_URLpostgres
postgresqlpsqlpgsqlpostgisz&django.contrib.gis.db.backends.postgismysqlzdjango.db.backends.mysqlmysql2zmysql-connectorzmysql.connector.djangomysqlgisz$django.contrib.gis.db.backends.mysqlmssqlzsql_server.pyodbcoraclezdjango.db.backends.oraclepyodbcredshiftdjango_redshift_backend
spatialitez)django.contrib.gis.db.backends.spatialitesqlitezdjango.db.backends.sqlite3ldapzldapdb.backends.ldap)CONN_MAX_AGEATOMIC_REQUESTS
AUTOCOMMITDISABLE_SERVER_SIDE_CURSORS	CACHE_URLz+django.core.cache.backends.db.DatabaseCachez+django.core.cache.backends.dummy.DummyCachez3django.core.cache.backends.filebased.FileBasedCachez-django.core.cache.backends.locmem.LocMemCachez3django.core.cache.backends.memcached.MemcachedCachez1django.core.cache.backends.memcached.PyLibMCCache)	dbcache
dummycache	filecachelocmemcachememcache
pymemcache
rediscacheredisrediss)TIMEOUT
KEY_PREFIXVERSIONKEY_FUNCTIONBINARY	EMAIL_URLz+django.core.mail.backends.smtp.EmailBackendz.django.core.mail.backends.console.EmailBackendz0django.core.mail.backends.filebased.EmailBackendz-django.core.mail.backends.locmem.EmailBackendz,django.core.mail.backends.dummy.EmailBackend)smtpsmtpssmtp+tlssmtp+sslconsolemailfilemail
memorymail	dummymailEMAIL_USE_TLSEMAIL_USE_SSL
SEARCH_URLzAhaystack.backends.elasticsearch_backend.ElasticsearchSearchEnginezChaystack.backends.elasticsearch2_backend.Elasticsearch2SearchEnginez)haystack.backends.solr_backend.SolrEnginez-haystack.backends.whoosh_backend.WhooshEnginez-haystack.backends.xapian_backend.XapianEnginez-haystack.backends.simple_backend.SimpleEngine)elasticsearchelasticsearch2solrwhooshxapiansimplec                 K   s   d| _ || _d S )NT)
smart_castscheme)r'   ri   r   r   r   __init__x   s   
zEnv.__init__NFc                 C   s   | j ||||dS )Ncastdefaultparse_default	get_value)r'   varrl   rm   rn   r   r   r   __call__|   s   zEnv.__call__c                 C   s
   || j v S r   )ENVIRON)r'   rq   r   r   r   __contains__      
zEnv.__contains__c                 C   s$   | j |t|d}|r|ddS |S )z
        :rtype: str
        rl   rm   z\n
)rp   r    replace)r'   rq   rm   	multiliner   r   r   r   r       s   zEnv.strc                 C      | j |t|dS )z3Helper for python2
        :rtype: unicode
        rv   )rp   r    r'   rq   rm   r   r   r   unicode      zEnv.unicodeutf8c                 C   s   | j |td|S )z
        :rtype: bytes
        )rl   )rp   r    encode)r'   rq   rm   encodingr   r   r   bytes   s   z	Env.bytesc                 C   rz   )z
        :rtype: bool
        rv   )rp   boolr{   r   r   r   r      r}   zEnv.boolc                 C   rz   )z
        :rtype: int
        rv   )rp   r   r{   r   r   r   r      r}   zEnv.intc                 C   rz   )z
        :rtype: float
        rv   )rp   floatr{   r   r   r   r      r}   z	Env.floatc                 C   s   | j |tj|dS )z'
        :returns: Json parsed
        rv   )rp   r   loadsr{   r   r   r   r         zEnv.jsonc                 C   s    | j ||s
t|dS |g|dS )z
        :rtype: list
        rv   )rp   listr'   rq   rl   rm   r   r   r   r          zEnv.listc                 C   s    | j ||s
t|dS |f|dS )z
        :rtype: tuple
        rv   )rp   tupler   r   r   r   r      r   z	Env.tuplec                 C   s   | j |||dS )z
        :rtype: dict
        rv   ro   r   r   r   r   dict   r}   zEnv.dictc                 C   s   | j |t|ddS )z.
        :rtype: urlparse.ParseResult
        Trk   )rp   r   r{   r   r   r   url   r   zEnv.urlc                 C      | j | j||d|dS )zWReturns a config dictionary, defaulting to DATABASE_URL.

        :rtype: dict
        rm   engine)db_url_configrp   r'   rq   rm   r   r   r   r   db_url      z
Env.db_urlc                 C   r   )zTReturns a config dictionary, defaulting to CACHE_URL.

        :rtype: dict
        r   backend)cache_url_configr   r'   rq   rm   r   r   r   r   	cache_url   r   zEnv.cache_urlc                 C   r   )zTReturns a config dictionary, defaulting to EMAIL_URL.

        :rtype: dict
        r   r   )email_url_configr   r   r   r   r   	email_url   r   zEnv.email_urlc                 C   r   )zUReturns a config dictionary, defaulting to SEARCH_URL.

        :rtype: dict
        r   r   )search_url_configr   r   r   r   r   
search_url   r   zEnv.search_urlc                 K   s   t | j||dfi |S )z
        :rtype: Path
        r   )Pathrp   )r'   rq   rm   kwargsr   r   r   path   s   zEnv.pathc           	      C   sL  t d||| || jv rJ| j| }zt|dk}W n ty'   d}Y nw |rF|s0|d }|| ju rEz|d }W n tyD   Y nw n|sJ|}z| j| }W n t	yj   || ju rfd|}t
||}Y nw t|dr|dr|d}| j|||d	}| jr|d
u r|d
urt|tst|}||ks|r|r| ||}|S )aP  Return value for given environment variable.

        :param var: Name of variable.
        :param cast: Type to cast return value as.
        :param default: If var not present in environ, return this instead.
        :param parse_default: force to parse default..

        :returns: Value from environment or default (if set)
        z,get '{0}' casted as '{1}' with default '{2}'   Fr   r   z Set the {0} environment variable
startswith$rv   N)loggerdebugr#   ri   len	TypeErrorNOTSET
IndexErrorrs   KeyErrorr   r   r   lstriprp   rh   r   r"   typeparse_value)	r'   rq   rl   rm   rn   var_infohas_defaultr   	error_msgr   r   r   rp      sN   





zEnv.get_valuec                    s   |du r|S |t u r%z	t|dk}W |S  ty$   |  jv }Y |S w t|tr=tt|d dd |dD }|S t|t	r]|
d
dd}t	t|d dd |D }|S t|tr|d	t|d
t|dt tt fdddd |dD }|S |tu rtdd |dD }|S |tu rdd |dD }|S |t	u r|
d
dd}t	dd |D }|S |tu rtdd|}td|}t|dkr|d }ndd|dd |d }t|}|S ||}|S )zParse and cast provided value

        :param value: Stringed value.
        :param cast: Type to cast return value as.

        :returns: Casted value
        Nr   c                 S      g | ]}|r|qS r   r   .0xr   r   r   
<listcomp>=      z#Env.parse_value.<locals>.<listcomp>,()c                 S   r   r   r   r   r   r   r   r   @  r   keyr   rl   c                    s(   | d   | d | d fS )Nr   r   )r   get)kvclskey_cast
value_castvalue_cast_by_keyr   r   <lambda>F  s   
z!Env.parse_value.<locals>.<lambda>c                 S      g | ]	}|r| d qS =splitr   valr   r   r   r   J      ;c                 S   r   r   r   r   r   r   r   r   M  r   c                 S   r   r   r   r   r   r   r   r   O  r   c                 S   r   r   r   r   r   r   r   r   R  r   z[^\d,\.] z[,\.]r   z{0}.{1})r   r   r   lowerBOOLEAN_TRUE_STRINGSr   r   mapr   r   stripr   r   r    r   resubr   r#   join)r   r   rl   r   	float_strpartsr   r   r   r   ,  s\   	&$
""


zEnv.parse_valuec                 C   s:  t || js|dkr| jd ddS t|}i }|jdd }t|ddd	 }|jdkrA|d
kr4d}|jrAt	j
d|j dd |jdkr[dj|j|jd}|jr[|dj|jd7 }||p`d
t|jpfd
t|jpld
|jppd
t|jpvd
d |jdkr|dr|dd\|d< |d< |jdkr|d
kr|d |d< d
|d< |jdkr|d s|d= nt|d |d< |jri }t|j D ]$\}}| | jv r|| t|d	 i q||t|d	 i q||d< |r||d< n|j|d< |d tjv r
tj|d  |d< |ddst	
d| i S |S )a  Pulled from DJ-Database-URL, parse an arbitrary Database URL.
        Support currently exists for PostgreSQL, PostGIS, MySQL, Oracle and SQLite.

        SQLite connects to file based databases. The same URL format is used, omitting the hostname,
        and using the "file" portion as the filename of the database.
        This has the effect of four slashes being present for an absolute file path:

        >>> from environ import Env
        >>> Env.db_url_config('sqlite:////full/path/to/your/file.sqlite')
        {'ENGINE': 'django.db.backends.sqlite3', 'HOST': '', 'NAME': '/full/path/to/your/file.sqlite', 'PASSWORD': '', 'PORT': '', 'USER': ''}
        >>> Env.db_url_config('postgres://uf07k1i6d8ia0v:wegauwhgeuioweg@ec2-107-21-253-135.compute-1.amazonaws.com:5431/d8r82722r2kuvn')
        {'ENGINE': 'django.db.backends.postgresql', 'HOST': 'ec2-107-21-253-135.compute-1.amazonaws.com', 'NAME': 'd8r82722r2kuvn', 'PASSWORD': 'wegauwhgeuioweg', 'PORT': 5431, 'USER': 'uf07k1i6d8ia0v'}

        zsqlite://:memory:rA   z:memory:)ENGINENAMEr   N?r   r   r   z9SQLite URL contains host component %r, it will be ignored   )
stacklevelrB   z{scheme}://{hostname})ri   hostnamez:{port})port)r   USERPASSWORDHOSTPORTr3   /r   r   r<   r   OPTIONSr   Fz#Engine not recognized from url: {0})r   	URL_CLASS
DB_SCHEMESr   r   r	   r   ri   netlocwarningswarnr#   r   r   updater!   usernamepasswordr   r   rsplitr    queryr   itemsupper_DB_BASE_OPTIONSr   r+   r   )r   r   r   configr   config_optionskr   r   r   r   r   a  sh   





zEnv.db_url_configc           
         s  t | jss
i S tj| jvrtdjjd}t	|dkr,|d }| jj |d}jdkrE|
djj i jrXjdv rX|
dd	j i n/jd
rjrijdd nd  fddjdD }t	|dkr|d n||d< jri }tj D ] \}}| t|d i}	| | jv r|
|	 q|
|	 q||d< |r||d< |S )z~Pulled from DJ-Cache-URL, parse an arbitrary Cache URL.

        :param url:
        :param backend:
        :return:
        zInvalid cache schema {}r   r   r   )BACKENDLOCATIONrJ   r   )rL   rM   zunix:rO   cacher   unixc                    s   g | ]} d  | j  qS )z://r   )r   locri   r   r   r   r     s    z(Env.cache_url_config.<locals>.<listcomp>r   r   )r   r   r   ri   CACHE_SCHEMESr   r#   r   r   r   r   r   r   r   rx   r   r   r   r   r   _CACHE_BASE_OPTIONS)
r   r   r   locationr   	locationsr   r   r   optr   r   r   r     sJ   


zEnv.cache_url_configc           	      C   s8  i }t || jst|n|}|jdd }t|ddd }||t|jt|j	|j
t|jd |r;||d< n|j| jvrHtd|j |j| jv rV| j|j |d< |jd	v r`d
|d< n	|jdkrid
|d< |jri }t|j D ] \}}| t|d i}| | jv r|| qu|| qu||d< |S )zParses an email URL.r   Nr   r   r   )EMAIL_FILE_PATHEMAIL_HOST_USEREMAIL_HOST_PASSWORD
EMAIL_HOST
EMAIL_PORTEMAIL_BACKENDzInvalid email schema %s)rX   rY   Tr_   rZ   r`   r   )r   r   r   r   r	   r   r   r!   r   r   r   r   r   ri   EMAIL_SCHEMESr   r   r   r   r   _EMAIL_BASE_OPTIONS)	r   r   r   r   r   r   r   r   r   r   r   r   r     s<   



zEnv.email_url_configc                 C   s  i }t || jst|n|}|jdd  }t|ddd }|j| jvr,td|j | j|j |d< i }|j	rst
|j	}d| v rO|d d d|d< d	| v ra| |d	 d t|d	< d
| v rs| |d
 d t|d
< |jdkrz|S |jdv rd| v r|d d |d< |dr|d d }|jdkrtd|dd  |f d |d< d| v r| |d d t|d< |S |jdv r|dd}t|dkrd|d d }|d }nd}|d }td|dd  |f d |d< d| v r| |d d t|d< ||d< |S d| |d< |jdkrAd| v r-|d d |d< d| v r@| |d d t|d< n|jdkrVd| v rV|d d |d< |r]||d< |S )Nr   r   r   r   zInvalid search schema %sr   EXCLUDED_INDEXESr   INCLUDE_SPELLING
BATCH_SIZErg   )rd   rb   rc   KWARGSr   r   rd   )http)r   r   r   URLrQ   )rb   rc   r   
INDEX_NAMEPATHre   STORAGE
POST_LIMITrf   FLAGS)r   r   r   r   r	   r   ri   SEARCH_SCHEMESr   r   r   keysr   r   r   endswithr   r   r   r   )r   r   r   r   r   paramsr   indexr   r   r   r   &  sj   




"
"zEnv.search_url_configc                 K   st  |du r%t  }tjtj|jjjd}tj	|s%t
d|  dS z#t|tr1t|ddn|}| }W d   n1 sBw   Y  W n tyY   t
d|  Y dS w td| | D ]A}td|}|r|d	 |d
 }}	td|	}
|
r|
d	}	td|	}|rtdd|d	}	| j|t|	 qf| D ]\}}| j|| qdS )a/  Read a .env file into os.environ.

        If not given a path to a dotenv path, does filthy magic stack backtracking
        to find manage.py and then find the dotenv.

        http://www.wellfireinteractive.com/blog/easier-12-factor-django/

        https://gist.github.com/bennylope/2999704
        Nz.envzU%s doesn't exist - if you're not configuring your environment separately, create one.zutf-8)r   zUError reading %s - if you're not configuring your environment separately, check this.z$Read environment variables from: {0}z'\A(?:export )?([A-Za-z_0-9]+\s*)=(.*)\Zr   r   z
\A'(.*)'\Zz
\A"(.*)"\Zz\\(.)z\1)sys	_getframeosr   r   dirnamef_backf_codeco_filenameexistsr   r   r   r   openreadIOErrorr   r   r#   
splitlinesr   matchgroupr   r   rs   
setdefaultr    r   )r   env_file	overridesframefcontentlinem1r   r   m2m3r   r   r   r   read_envp  sN   

zEnv.read_envr   )7r%   r)   r*   __doc__r  environrs   r"   r   r   r   r   DEFAULT_DATABASE_ENVr
   r   r   DEFAULT_CACHE_ENVr   r   r   DEFAULT_EMAIL_ENVr  r  DEFAULT_SEARCH_ENVr  rj   rr   rt   r    r|   r   r   r   r   r   r   r   r   r   r   dbr   r   r   emailr   r   rp   classmethodr   r   r   r   r   r/  r   r   r   r   r+   .   s    
	

		>
4\:,Ir+   c                       s   e Zd ZdZdd Zdd Zedd Zd) fd	d
	Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zed'd( Z  ZS )*r   a  Inspired to Django Two-scoops, handling File Paths in Settings.

        >>> from environ import Path
        >>> root = Path('/home')
        >>> root, root(), root('dev')
        (<Path:/home>, '/home', '/home/dev')
        >>> root == Path('/home')
        True
        >>> root in Path('/'), root not in Path('/other/path')
        (True, True)
        >>> root('dev', 'not_existing_dir', required=True)
        Traceback (most recent call last):
        environ.environ.ImproperlyConfigured: Create required path: /home/not_existing_dir
        >>> public = root.path('public')
        >>> public, public.root, public('styles')
        (<Path:/home/public>, '/home/public', '/home/public/styles')
        >>> assets, scripts = public.path('assets'), public.path('assets', 'scripts')
        >>> assets.root, scripts.root
        ('/home/public/assets', '/home/public/assets/scripts')
        >>> assets + 'styles', str(assets + 'styles'), ~assets
        (<Path:/home/public/assets/styles>, '/home/public/assets/styles', <Path:/home/public>)

    c                 O      | j | jg|R i |S )zCreate new Path based on self.root and provided paths.

        :param paths: List of sub paths
        :param kwargs: required=False
        :rtype: Path
        )r$   __root__r'   pathsr   r   r   r   r     s   z	Path.pathc                 O   s   t | |g|R i |S )zOpen a file.

        :param name: Filename appended to self.root
        :param args: passed to open()
        :param kwargs: passed to open()

        :rtype: file
        )r  )r'   nameargsr   r   r   r   file  s   	z	Path.filec                 C      | j S )zCurrent directory for this Pathr:  r&   r   r   r   root  s   z	Path.rootr   c                    sD   t t|   |ddrtj|}| j|g|R i || _d S )Nis_fileF)	superr   rj   r   r  r   r  _absolute_joinr:  )r'   startr<  r   r$   r   r   rj     s   zPath.__init__c                 O   r9  )zRetrieve the absolute path, with appended paths

        :param paths: List of sub path of self.root
        :param kwargs: required=False
        )rE  r:  r;  r   r   r   rr     s   zPath.__call__c                 C   s   | j |j kS r   rA  r'   otherr   r   r   __eq__     zPath.__eq__c                 C   s   |  | S r   )rJ  rH  r   r   r   __ne__  rK  zPath.__ne__c                 C   s   t | jt|t s|S |jS r   )r   r:  r   rH  r   r   r   __add__  r   zPath.__add__c                 C   sX   t |tr| d| S t |tr| j|rt| j|S tdj	t
| t
|d)Nz../zkunsupported operand type(s) for -: '{self}' and '{other}' unless value of {self} ends with value of {other}rH  )r   r   r   r   r:  r  r   rstripr   r#   r   rH  r   r   r   __sub__  s   

zPath.__sub__c                 C   s
   |  dS )Nz..r   r&   r   r   r   
__invert__  ru   zPath.__invert__c                 C   s,   | j }t|dkrtj|d}|j |S )Nr   r   )r:  r   r  r   r   r   )r'   item	base_pathr   r   r   rt     s   zPath.__contains__c                 C   s   d | jS )Nz
<Path:{0}>)r#   r:  r&   r   r   r   r(     rK  zPath.__repr__c                 C   r@  r   rA  r&   r   r   r   __str__  s   zPath.__str__c                 C      |   S r   rS  r&   r   r   r   __unicode__	     zPath.__unicode__c                 O      |   j|i |S r   )rS  __getitem__r'   r>  r   r   r   r   rY       zPath.__getitem__c                 C   rT  r   rU  r&   r   r   r   
__fspath__  rW  zPath.__fspath__c                 O   rX  r   )rS  rfindrZ  r   r   r   r]    r[  z
Path.rfindc                 O   rX  r   )rS  findrZ  r   r   r   r^    r[  z	Path.findc                 O   sF   t jt jj| g|R  }|ddr!t j|s!td||S )NrequiredFzCreate required path: {0})r  r   abspathr   r   r  r   r#   )baser<  r   absolute_pathr   r   r   rE    s   zPath._absolute_join)r   )r%   r)   r*   r0  r   r?  propertyrB  rj   rr   rJ  rL  rM  rO  rP  rt   r(   rS  rV  rY  r\  r]  r^  staticmethodrE  __classcell__r   r   rG  r   r     s.    	
	r   c                 C   s,   t tD ]}|drtt||  qd S )Nuses_)dirr   r   getattrappend)ri   methodr   r   r   register_scheme!  s
   
rk  c                 C   s   | D ]}t | qd S r   )rk  )schemesri   r   r   r   register_schemes'  s   
rm  ))r0  r   loggingr  r   r  r   compatr   r   r   r   r   r   r	   r
   r   r   r   	getLoggerr%   r   rS   
__author__r   r   __version__r   r   r!   objectr"   r+   r   rk  rm  r   r  r   r  r  r   r   r   r   <module>   s:    4

    v 