B
    *mfx                 @   s  d Z dZdZdZ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ZddlZddlZddlZddlmZmZmZmZ ddlmZ dd	lmZ ddlZyddlZW n ek
r   ddlZY nX dd
lmZmZ ddl m!Z!m"Z"m#Z#m$Z$ ddl%m&Z' e(e)fZ*e(Z+dd Z,dd Z-dZ.dZ/dZ0dZ1dZ2dZ3dZ4dZ5dZ6G dd de7Z8G dd de8Z9G dd de8e:Z;G dd de8Z<G d d! d!e8Z=G d"d# d#e8Z>G d$d% d%e?Z@G d&d' d'e?ZAG d(d) d)e?ZBd*d+ ZCd,d- ZDdddi di d.dddd/dddfd0d1ZEd2d3 ZFeFe/ZGeFe0ZHeFe1ZIeFe2ZJeFe3ZKeFe4ZLeFe5ZMeFe6ZN[FG d4d5 d5eOZPd6d7 ZQd8d9 ZRdJd;d<ZSdKd=d>ZTdLd?d@ZUdAdB ZVdCdD ZWe/e2e3e4e1e0e5e6fZXdEZYeR ZZda[dFZ\e]dGdH e^eej_e\eej_dIe\eeee`e\fD dZadS )Mz
urlfetch
~~~~~~~~~~

An easy to use HTTP client based on httplib.

:copyright: (c) 2011-2020 by Yue Du.
:license: BSD 2-clause License, see LICENSE for more details.
z2.0.1zYue Du <ifduyue@gmail.com>z#https://github.com/ifduyue/urlfetchzBSD 2-Clause License    N)basenamedirnameabspathjoin)partial)BytesIO)HTTPConnectionHTTPSConnection)parse_qs	urlencodeurlspliturljoinc             C   s
   |  dS )Nzlatin-1)encode)s r   K/home/ankuromar296_gmail_com/.local/lib/python3.7/site-packages/urlfetch.py<lambda>%       r   c             C   s   | S )Nr   )r   r   r   r   r   &   r   )requestfetchSessiongetheadputpostdeleteoptionstracepatchUrlfetchExceptionContentLimitExceededURLErrorContentDecodingErrorTooManyRedirectsGETPOSTPUTDELETEHEADOPTIONSTRACEPATCHc               @   s   e Zd ZdZdS )r   zBBase exception. All exceptions and errors will subclass from this.N)__name__
__module____qualname____doc__r   r   r   r   r   E   s   r   c               @   s   e Zd ZdZdS )r    z#Content length is beyond the limit.N)r,   r-   r.   r/   r   r   r   r   r    I   s   r    c               @   s   e Zd ZdZdS )r!   z"Error parsing or handling the URL.N)r,   r-   r.   r/   r   r   r   r   r!   M   s   r!   c               @   s   e Zd ZdZdS )r"   zFailed to decode the content.N)r,   r-   r.   r/   r   r   r   r   r"   Q   s   r"   c               @   s   e Zd ZdZdS )r#   zToo many redirects.N)r,   r-   r.   r/   r   r   r   r   r#   U   s   r#   c               @   s   e Zd ZdZdS )TimeoutzRequest timed out.N)r,   r-   r.   r/   r   r   r   r   r0   Y   s   r0   c               @   sB   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S )cached_propertyzCached property.

    A property that is only computed once per instance and then replaces
    itself with an ordinary attribute. Deleting the attribute resets the
    property.
    Nc             C   s2   || _ || _|| _|p|j| _|j| _|j| _d S )N)_cached_property__get_cached_property__set_cached_property__delr/   r,   r-   )selffgetfsetfdeldocr   r   r   __init__e   s    zcached_property.__init__c             C   sH   |d kr| S y|j | j S  tk
rB   | | }|j | j< |S X d S )N)__dict__r,   KeyErrorr2   )r5   instanceownervaluer   r   r   __get__m   s    zcached_property.__get__c             C   s2   |d kr| S | j d k	r"|  ||}||j| j< d S )N)r3   r;   r,   )r5   r=   r?   r   r   r   __set__w   s
    
zcached_property.__set__c             C   sN   |d kr| S y|j | j}W n tk
r2   Y nX | jd k	rJ| || d S )N)r;   popr,   r<   r4   )r5   r=   r?   r   r   r   
__delete__~   s    
zcached_property.__delete__c             C   s   |  | j|| jS )N)	__class__r2   r4   )r5   r7   r   r   r   setter   s    zcached_property.setterc             C   s   |  | j| j|S )N)rD   r2   r3   )r5   r8   r   r   r   deleter   s    zcached_property.deleter)NNNN)
r,   r-   r.   r/   r:   r@   rA   rC   rE   rF   r   r   r   r   r1   ]   s   

r1   c               @   s   e Zd ZdZdd Zd&ddZdd Zd	d
 ZeZdd Z	dd Z
edd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Zedd  Zd!d" Zd#d$ Zd%S )'Responsea  A Response object.

    >>> import urlfetch
    >>> response = urlfetch.get("http://docs.python.org/")
    >>> response.total_time
    0.033042049407959
    >>> response.status, response.reason, response.version
    (200, 'OK', 10)
    >>> type(response.body), len(response.body)
    (<type 'str'>, 8719)
    >>> type(response.text), len(response.text)
    (<type 'unicode'>, 8719)
    >>> response.getheader('server')
    'Apache/2.2.16 (Debian)'
    >>> response.getheaders()
    [
        ('content-length', '8719'),
        ('x-cache', 'MISS from localhost'),
        ('accept-ranges', 'bytes'),
        ('vary', 'Accept-Encoding'),
        ('server', 'Apache/2.2.16 (Debian)'),
        ('last-modified', 'Tue, 26 Jun 2012 19:23:18 GMT'),
        ('connection', 'close'),
        ('etag', '"13cc5e4-220f-4c36507ded580"'),
        ('date', 'Wed, 27 Jun 2012 06:50:30 GMT'),
        ('content-type', 'text/html'),
        ('x-cache-lookup', 'MISS from localhost:8080')
    ]
    >>> response.headers
    {
        'content-length': '8719',
        'x-cache': 'MISS from localhost',
        'accept-ranges': 'bytes',
        'vary': 'Accept-Encoding',
        'server': 'Apache/2.2.16 (Debian)',
        'last-modified': 'Tue, 26 Jun 2012 19:23:18 GMT',
        'connection': 'close',
        'etag': '"13cc5e4-220f-4c36507ded580"',
        'date': 'Wed, 27 Jun 2012 06:50:30 GMT',
        'content-type': 'text/html',
        'x-cache-lookup': 'MISS from localhost:8080'
    }

    :raises: :class:`ContentLimitExceeded`
    c             K   s   x|D ]}t | |||  qW || _|j| _|j| _|j| _|j| _|j| _|dd | _|j	| _	|j
| _
| 	dd | _d | _yt|ddpd | _W n   d | _Y nX t| 	dd}| jr|| jkr|   td| j d S )N
total_timezcontent-encodinglength_limitr   zContent-Lengthz$Content length is more than %d bytes)setattr_rmsgstatusstatus_codereasonversionrB   rH   	getheader
getheaders_content_encoding_decoderintr   rI   closer    )r5   rkwargskcontent_lengthr   r   r   r:      s,    
zResponse.__init__   c             C   s   | j |S )zRead content (for streaming and large files)

        :arg int chunk_size: size of chunk, default is 65536, i.e. 64KiB.
        )rK   read)r5   
chunk_sizer   r   r   r\      s    zResponse.readc             C   s   | S )Nr   )r5   r   r   r   __iter__   s    zResponse.__iter__c          
   C   s  |   }|s,| jr&| j }d | _|S tn| j}|dkr| js|dkr\tdtj | _n>t | _y| j|S  tj	k
r   ttj | _Y nX y| j|S  t
tj	fk
r } z|   t|W d d }~X Y nX | r|   td| |S d S )N)gzipdeflater_      zUnknown encoding: %s)r\   rT   flushStopIterationrS   zlibdecompressobj	MAX_WBITS
decompresserrorIOErrorrV   r"   )r5   chunkZceer   r   r   __next__   s4    

zResponse.__next__c             C   s   | S )Nr   )r5   r   r   r   	__enter__  s    zResponse.__enter__c             C   s   |    dS )NF)rV   )r5   exc_typeexc_valexc_tbr   r   r   __exit__  s    zResponse.__exit__c             K   s   | |f|S )zRMake an :class:`~urlfetch.Response` object from a httplib response
        object.r   )cls
connectionrX   r   r   r   from_httplib"  s    zResponse.from_httplibc             C   s`   g }d}xH| D ]@}| | |t|7 }| jr|| jkr|   td| j qW td|S )zfResponse body.

        :raises: :class:`ContentLimitExceeded`, :class:`ContentDecodingError`
        r   z$Content length is more than %d bytes )appendlenrI   rV   r    br   )r5   contentlengthrj   r   r   r   body(  s    

zResponse.bodyc             C   s   | j S )N)r{   )r5   r   r   r   ry   =  s    zResponse.contentc             C   s
   t | jS )zResponse body in unicode.)mb_codery   )r5   r   r   r   textA  s    zResponse.textc          
   C   s<   yt | jS  tk
r6 } zt|W dd}~X Y nX dS )zTLoad response body as json.

        :raises: :class:`ContentDecodingError`
        N)jsonloadsr}   	Exceptionr"   )r5   rk   r   r   r   r~   F  s    zResponse.jsonc             C   s   t dd |  D S )a  Response headers.

        Response headers is a dict with all keys in lower case.

        >>> import urlfetch
        >>> response = urlfetch.get("http://docs.python.org/")
        >>> response.headers
        {
            'content-length': '8719',
            'x-cache': 'MISS from localhost',
            'accept-ranges': 'bytes',
            'vary': 'Accept-Encoding',
            'server': 'Apache/2.2.16 (Debian)',
            'last-modified': 'Tue, 26 Jun 2012 19:23:18 GMT',
            'connection': 'close',
            'etag': '"13cc5e4-220f-4c36507ded580"',
            'date': 'Wed, 27 Jun 2012 06:50:30 GMT',
            'content-type': 'text/html',
            'x-cache-lookup': 'MISS from localhost:8080'
        }
        c             s   s   | ]\}}|  |fV  qd S )N)lower).0rY   vr   r   r   	<genexpr>h  s    z#Response.headers.<locals>.<genexpr>)dictrR   )r5   r   r   r   headersQ  s    zResponse.headersc             C   s&   t | d}tdd | D S )zCookies in dictz
set-cookiec             s   s   | ]}|j |jfV  qd S )N)keyr?   )r   ir   r   r   r   n  s    z#Response.cookies.<locals>.<genexpr>)CookieSimpleCookierQ   r   values)r5   cr   r   r   cookiesj  s    zResponse.cookiesc             C   s   d dd | j D S )zCookie stringz; c             s   s   | ]\}}d ||f V  qdS )z%s=%sNr   )r   rY   r   r   r   r   r   s  s    z(Response.cookiestring.<locals>.<genexpr>)r   r   items)r5   r   r   r   cookiestringp  s    zResponse.cookiestringc       
   
   C   s   g }|  d}|s|S x|dD ]}y|dd\}}W n tk
rX   |d }}Y nX i }|d|d< xP|dD ]B}y|d\}}	W n tk
r   P Y nX |	d	||d	< qxW || q"W |S )
z"Links parsed from HTTP Link headerlink,;   ru   z<> '"url=z '")rQ   split
ValueErrorstriprv   )
r5   retZ
linkheaderr   r   paramsr   paramrY   r   r   r   r   linksu  s&    
zResponse.linksc             C   s   | j   dS )zClose the connection.N)rK   rV   )r5   r   r   r   rV     s    zResponse.closec             C   s   |    d S )N)rV   )r5   r   r   r   __del__  s    zResponse.__del__N)r[   )r,   r-   r.   r/   r:   r\   r^   rl   nextrm   rq   classmethodrt   r1   r{   propertyry   r}   r~   r   r   r   r   rV   r   r   r   r   r   rG      s&   -+
 rG   c               @   s   e Zd ZdZi i dfddZdd Zdd Zd'd
dZdd Ze	dd Z
e
j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S )(r   a  A session object.

    :class:`urlfetch.Session` can hold common headers and cookies.
    Every request issued by a :class:`urlfetch.Session` object will bring u
    these headers and cookies.

    :class:`urlfetch.Session` plays a role in handling cookies, just like a
    cookiejar.

    :arg dict headers: Init headers.
    :arg dict cookies: Init cookies.
    :arg tuple auth: (username, password) for basic authentication.
    Nc             C   sZ   |  | _|  | _|rVt|ttfrVdt| }t|d}d|	d | jd< dS )z(Init a :class:`~urlfetch.Session` objectz%s:%szutf-8zBasic AuthorizationN)
copyr   r   
isinstancelisttuplebase64	b64encoder   decode)r5   r   r   authr   r   r   r:     s    

zSession.__init__c             C   s   || j |< dS )z!Add an header to default headers.N)r   )r5   headerr?   r   r   r   	putheader  s    zSession.putheaderc             C   s   | j |S )z&Remove an header from default headers.)r   rB   )r5   r   r   r   r   	popheader  s    zSession.popheaderru   c             C   s   || j |< dS )z!Add an cookie to default cookies.N)r   )r5   r   r?   r   r   r   	putcookie  s    zSession.putcookiec             C   s   | j |S )z&Remove an cookie from default cookies.)r   rB   )r5   r   r   r   r   	popcookie  s    zSession.popcookiec             C   s   d dd | j D S )zCookie string.

        It's assignalbe, and will change :attr:`~.Session.cookies`
        correspondingly.

        >>> s = Session()
        >>> s.cookiestring = 'foo=bar; 1=2'
        >>> s.cookies
        {'1': '2', 'foo': 'bar'}
        z; c             s   s   | ]\}}d ||f V  qdS )z%s=%sNr   )r   rY   r   r   r   r   r     s    z'Session.cookiestring.<locals>.<genexpr>)r   r   r   )r5   r   r   r   r     s    zSession.cookiestringc             C   s*   t |}dd | D }t|| _dS )z"Cookie string setterc             S   s   g | ]}|j |jfqS r   )r   r?   )r   r   r   r   r   
<listcomp>  s    z(Session.cookiestring.<locals>.<listcomp>N)r   r   r   r   r   )r5   r?   r   scr   r   r   r     s    
c             C   s   | j  | j d}|S )N)r   r   )r   r   r   )r5   sessionr   r   r   snapshot  s    zSession.snapshotc             O   sP   | j  }| jr| j|d< ||di  ||d< t||}| j|j |S )zIssue a request.r   r   )r   r   r   updater   r   r   )r5   argsrX   r   rW   r   r   r   r     s    


zSession.requestc             O   sF   | dd}| di }|r*t|ttfs.|r:| j||S | j ||S )zFetch an URLdataNfiles)r   r   
basestringr   r   )r5   r   rX   r   r   r   r   r   r     s
    zSession.fetchc             O   s   d|d< | j ||S )zIssue a get request.r$   method)r   )r5   r   rX   r   r   r   r     s    zSession.getc             O   s   t |d< | j||S )zIssue a post request.r   )r%   r   )r5   r   rX   r   r   r   r     s    zSession.postc             O   s   t |d< | j||S )zIssue a put request.r   )r&   r   )r5   r   rX   r   r   r   r     s    zSession.putc             O   s   t |d< | j||S )zIssue a delete request.r   )r'   r   )r5   r   rX   r   r   r   r     s    zSession.deletec             O   s   t |d< | j||S )zIssue a head request.r   )r(   r   )r5   r   rX   r   r   r   r     s    zSession.headc             O   s   t |d< | j||S )zIssue a options request.r   )r)   r   )r5   r   rX   r   r   r   r     s    zSession.optionsc             O   s   t |d< | j||S )zIssue a trace request.r   )r*   r   )r5   r   rX   r   r   r   r     s    zSession.tracec             O   s   t |d< | j||S )zIssue a patch request.r   )r+   r   )r5   r   rX   r   r   r   r     s    zSession.patch)ru   )r,   r-   r.   r/   r:   r   r   r   r   r   r   rE   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s&   
	r   c              O   sB   | dd}| di }|r*t|ttfs.|r8t| |S t | |S )zfetch an URL.

    :func:`~urlfetch.fetch` is a wrapper of :func:`~urlfetch.request`.
    It calls :func:`~urlfetch.get` by default. If one of parameter ``data``
    or parameter ``files`` is supplied, :func:`~urlfetch.post` is called.
    r   Nr   )r   r   r   r   r   )r   rX   r   r   r   r   r   r     s
    
r   c       	   	   C   s   d}d}t || }t ||}|r|rddd |dddd	D }dd
d |dddd	D }|dd k	rt|d}|d | |d | kS ||kS n
| |S d S )Nz'(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3})z2(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3})(?=/(\d+))?ru   c             s   s   | ]}d  t|V  qdS )z{:08b}N)formatrU   )r   sectionr   r   r   r   -  s    z!match_no_proxy.<locals>.<genexpr>r            c             s   s   | ]}d  t|V  qdS )z{:08b}N)r   rU   )r   r   r   r   r   r   0  s      )rematchr   grouprU   endswith)	hostno_proxyZip_regexZno_proxy_ip_regexZip_matchZno_proxy_ip_matchZ	host_bitsZno_proxy_bitsZbit_match_countr   r   r   match_no_proxy&  s    
r   FTc       $   
      s|  fdd}d}|  }|tkr2tddt |r~t|trLt| |} n2t|tr~| d dkrv| d| krpd	nd7 } | |7 } t|  d
dt	| d d} d }|
dkr|rt
}
|
si }
t}|rtdptd}|r|d}|
|}|rt fdd|D sd}d|kr(dd|f }t|}|d rz|d rzd|d |d f }t|d}d|d |d< ||d |d |d  ||}n|| d  d  ||}|sڈ d rڈ d rڈ d  d f}|rt|ttfrdt| }t|d}d|d |d!< |r<t||\}}||d"< nt|trRt|d#}t|trl|sld$|d"< || t }y.|r| n d% }||||| | }W nX tjk
r } zt|W dd}~X Y n, t k
r } zt|W dd}~X Y nX t }|| } g }!t!j"|||	|!dd | | |d&}"x:|"j#d'krvd(|"j$krv|rv|"j%|"& |!'|"f t(|!|krt)d)|"j#d*kr|nd+}|"j$d( }#|#dd, d-krʈ d d. |# } n
t*| |#} t|   d |d/< |"j+|d0<  d }|
|}|r d tkrd}d|kr2dd|f }t|}|d r|d rd|d |d f }t|d}d|d |d< ||d |d |d  ||}n(d}|,dd || d  d  ||}y.|r| n d% }||||| | }W nX tjk
r& } zt|W dd}~X Y n, t k
rP } zt|W dd}~X Y nX t!j"|||	|!dd | | |d&}"q>W |"S )1a  request an URL

    :arg string url: URL to be fetched.
    :arg string method: (optional) HTTP method, one of ``GET``, ``DELETE``,
                        ``HEAD``, ``OPTIONS``, ``PUT``, ``POST``, ``TRACE``,
                        ``PATCH``. ``GET`` is the default.
    :arg dict/string params: (optional) Dict or string to attach to url as
                                querystring.
    :arg dict headers: (optional) HTTP request headers.
    :arg float timeout: (optional) Timeout in seconds
    :arg files: (optional) Files to be sended
    :arg randua: (optional) If ``True`` or ``path string``, use a random
                    user-agent in headers, instead of
                    ``'urlfetch/' + __version__``
    :arg tuple auth: (optional) (username, password) for basic authentication
    :arg int length_limit: (optional) If ``None``, no limits on content length,
                        if the limit reached raised exception 'Content length
                        is more than ...'
    :arg dict proxies: (optional) HTTP proxy, like {'http': '127.0.0.1:8888',
                                                 'https': '127.0.0.1:563'}
    :arg bool trust_env: (optional) If ``True``, urlfetch will get infomations
                        from env, such as HTTP_PROXY, HTTPS_PROXY
    :arg int max_redirects: (integer, optional) Max redirects allowed within a
                            request. Default is 0, which means redirects are
                            not allowed.
    :arg tuple source_address: (optional) A tuple of (host, port) to
                               specify the source_address to bind to. This
                               argument is ignored if you're using Python prior
                               to 2.7/3.2.
    :arg bool validate_certificate: (optional) If ``False``, urlfetch skips
                                all the necessary certificate and hostname checks
    :returns: A :class:`~urlfetch.Response` object
    :raises: :class:`URLError`, :class:`UrlfetchException`,
             :class:`TooManyRedirects`,
    c                sf   ||d}d} dkrt  }| dkr6t||f|}n,| dkrVt||fd|i|}ntd|  |S )z Return HTTP or HTTPS connection.)timeoutsource_addressNFhttphttpscontextzUnknown Connection Type: %s)ssl_create_unverified_contextr   r	   r!   )Z	conn_typer   portr   r   rX   ssl_contextconn)validate_certificater   r   make_connectionr  s    
z request.<locals>.make_connectionFzMethod should be one of z, )?&r   r   z*/*z$gzip, deflate, compress, identity, *	http_host)AcceptzAccept-Encodingz
User-AgentHostschemeNr   ZNO_PROXYr   c             3   s   | ]}t  d  |V  qdS )r   N)r   )r   r   )
parsed_urlr   r   r     s    zrequest.<locals>.<genexpr>Tz://z%s://%sr   usernamepasswordz%s:%szutf-8zBasic zProxy-Authorizationr   r   r   zContent-Typer   z!application/x-www-form-urlencodeduri)
reqheadersrI   historyr   rH   
start_time)i-  i.  i/  i3  locationzmax_redirects exceededi3  r$   r   z//:r   ZReferer)-upperALLOWED_METHODSr   r   r   r   
url_concatr   	parse_urlrandom_useragentPROXIESPROXY_IGNORE_HOSTSosgetenvr   r   anyr   r   r   r   r   r   encode_multipartr   r   timer   getresponsesocketr   r0   r   rG   rt   rM   r   r{   rV   rv   rw   r#   r   r   rB   )$r   r   r   r   r   r   r   Zranduar   rI   proxies	trust_envmax_redirectsr   r   rX   r   Z	via_proxyr   r   Zignore_hostsr   proxyZparsed_proxyZ	proxyauthr   content_typer   request_urlresprk   end_timerH   r   responser   r   )r   r   r   r   <  s   6














r   c             C   s0   t t| d}d|   |_|  |_tj|_|S )N)r   zIssue a %s request)r   r   r   r/   r,   r-   )r   funcr   r   r   _partial_method5  s
    
r   c               @   s    e Zd ZdZdd Zdd ZdS )
ObjectDictz)Makes a dictionary behave like an object.c             C   s*   y| | S  t k
r$   t|Y nX d S )N)r<   AttributeError)r5   namer   r   r   __getattr__L  s    zObjectDict.__getattr__c             C   s   || |< d S )Nr   )r5   r   r?   r   r   r   __setattr__R  s    zObjectDict.__setattr__N)r,   r-   r.   r/   r   r   r   r   r   r   r   I  s   r   c             C   sD  yt | } W n tk
r    Y nX d| kr<| dd\}} nd}d|  } t| }t }||d< |j|d< |j|d< |j|d< |j|d	< |j|d
< |jr|d
  d|j 7  < |j	|d< |j
|d< |jdd}| |d< |d< y|j|d< W n tk
r   d|d< Y nX |d r4d|d |d f |d< n|d |d< |S )zReturn a dictionary of parsed url

    Including scheme, netloc, path, params, query, fragment, uri, username,
    password, host, port and http_host
    z://r   r   zhttp://r   netlocpathqueryfragmentr   r   r   r   idnazutf-8r   hostnamer   Nz%s:%dr   )unicodeUnicodeDecodeErrorr   r   r   r   r  r  r  r   r   r  r   r   r   r   )r   r   parsedrW   r   r   r   r   r   V  s<    







r   c              C   sH   i } t dpt d}t dp*t d}|r8|| d< |rD|| d< | S )zGet proxies from os.environ.
http_proxyZ
HTTP_PROXYhttps_proxyZHTTPS_PROXYr   r   )r   r   )r   r	  r
  r   r   r   get_proxies_from_environ  s    r  replacec             C   sp   t | tr$|dkr| S | j||dS x>dD ]6}y$| |} |dkrF| S | j||dS    Y q*X q*W t| |dS )zencoding/decoding helper.N)errors)zutf-8gb2312gbkgb18030big5)r   r  r   r   )r   Zcodingr  r   r   r   r   r|     s    



r|   c          	   C   s4  ddl }dt }t| tr"| g}ng }| r8tr8|t xH|D ]<} y*t| }t|j	rjt
| tjrjP W q>   Y q>X q>W |S t| d}|j}d}| }xtdD ]x}	||d|7 }||; }|| |  | }
|
s| |kr|d | }
|
 }
|
r|
d dkr|
S qW W dQ R X |S )a  Returns a User-Agent string randomly from file.

    :arg string filename: (Optional) Path to the file from which a random
        useragent is generated. By default it's ``True``, a file shipped
        with this module will be used.
    :returns: An user-agent string.
    r   Nzurlfetch/%srbr   #)random__version__r   r   UAFILErv   r   statS_ISREGst_modeaccessR_OKopenst_sizeRandomrangerandintseekreadlinetellr   )filenamer  Z
default_ua	filenamesstffilesizeposrW   r   liner   r   r   r     sB    






r   c             C   st   |s| S |r:| d dkr,| d| kr&dnd7 } | t |d S | d\} }}t|d}|| | d t |d S dS )am  Concatenate url and argument dictionary

    >>> url_concat("http://example.com/foo?a=b", dict(c="d"))
    'http://example.com/foo?a=b&c=d'

    :arg string url: URL being concat to.
    :arg dict args: Args being concat.
    :arg bool keep_existing: (Optional) Whether to keep the args which are
                            alreay in url, default is ``True``.
    r   )r   r   r   r   TN)r   	partitionr
   r   )r   r   Zkeep_existingseqr  r   r   r   r     s    

r   c              C   s   t dkrpda ytt } t d|  7 a W n tk
r<   Y nX ytt }t d| 7 a W n tk
rn   Y nX dt t jf S )zCGenerate a multipart boundry.

    :returns: A boundary string
    NZurlfetch.z%s.%s)	BOUNDARY_PREFIXreprr   getuidr   getpiduuiduuid4hex)uidpidr   r   r   choose_boundary  s    r7  c             C   s  t  }t }td| }tdd }t| trx|  D ]\}}t|tt	t
fsX|f}xr|D ]j}|| ||d|  |d t|trt|}t|tr||| n
|| |d q^W q:W x| D ]\}	}
t|
t	r|
\}}
n$t|
drt|
j}nd}td	t|
d
r0|
 }nt|
trB|
}nt|
}|| |r|||d|	|f  |d n||d|	  |d t|tr||| n
|| |d qW |td| d  d| }|| fS )zEncode multipart.

    :arg dict data: Data to be encoded
    :arg dict files: Files to be encoded
    :returns: Encoded binary string
    :raises: :class:`UrlfetchException`
    z--%s
zutf-8r   z+Content-Disposition: form-data; name="%s"
s   Content-Type: text/plain

s   
r   Nzfile must has filenamer\   z:Content-Disposition: form-data; name="%s"; filename="%s"
s*   Content-Type: application/octet-stream

z--z--
z multipart/form-data; boundary=%s)r   r7  rx   codecslookupr   r   r   r   r   setwriterU   strhasattrr   r   r   r\   r   getvalue)r   r   r{   boundaryZpart_boundarywriterr   r   r?   	fieldnamer'  r$  r   r   r   r   r     s^    














r   )z	127.0.0.1	localhostzurlfetch.useragents.listc             c   s   | ]}t j|r|V  qd S )N)r   r  isfile)r   r   r   r   r   r   Y  s   r   local)Nr  )T)T)br/   r  
__author____url____license__rd   r   sysr   r8  r2  r  r   r   r   os.pathr   r   r   r   Zpathjoin	functoolsr   ior   r   Z
simplejsonr~   ImportErrorhttp.clientr   r	   urllib.parser
   r   r   r   http.cookiesr   r   r<  bytesr   r  rx   u__all__r$   r%   r&   r'   r(   r)   r*   r+   ri   r   r    r   r!   r"   r#   r0   objectr1   rG   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r|   r   r   r7  r   r   r   r   r.  Z
UAFILENAMEr   r:  prefix__file__r  r   r   r   r   <module>   s   @8    k*

;
N
