
    g,                         d dl Z d dlmZ d dlmZ d dlZd dlmZ d dlZd dlm	Z	 d dlm
Z
  e j                  e      Z e	j                         Zdddefd	Zdddefd
Zd Zd Zd Zd ZddZy)    N)minidom)BeautifulSoup)urllib3)lock)loggergetTc                    |rt        |      t        k7  r|g}t        t        j                  j
                        |d<   |d   s-t        j                  t        j                  j                         t        t        |j                               }	 |5  t        j                  d|j                         |         || fi |}ddd       |r%|r#j                   |vr	 |j#                          |S |S |rj#                          S # 1 sw Y   DxY w#  t        j                  d|j                           xY w# t        j                  j$                  $ r@}|d   rt        j&                  d       nt        j&                  d|       Y d}~yY d}~yd}~wt        j(                  $ r t        j&                  d       Y yt        j*                  $ r t        j&                  d       Y yt        j,                  $ r}|j.                  |j.                  j                   d	k\  rd
}	n|j.                  j                   dk\  rd}	nd}	t        j&                  d|j.                  j                   |	       t        j0                  r5t3        |j.                         nt        j&                  d       Y d}~yY d}~yY d}~yd}~wt        j4                  $ r }t        j&                  d|       Y d}~yd}~ww xY w)  
    Convenient wrapper for `requests.get', which will capture the exceptions
    and log them. On success, the Response object is returned. In case of a
    exception, None is returned.

    Additionally, there is support for rate limiting. To use this feature,
    supply a tuple of (lock, request_limit). The lock is used to make sure no
    other request with the same lock is executed. The request limit is the
    minimal time between two requests (and so 1/request_limit is the number of
    requests per seconds).
    verifyz Requesting URL via %s method: %sNz=Response status code %d is not white listed, raised exceptiona  Unable to connect to remote host because of a SSL error. It is likely that your system cannot verify the validityof the certificate. The remote certificate is either self-signed, or the remote server uses SNI. See the wiki for more information on this topic.zPSSL error raised during connection, with certificate verification turned off: %sMUnable to connect to remote host. Check if the remote host is up and running.z:Request timed out. The remote host did not respond timely.  zremote server error  zlocal client errorunknownz2Request raise HTTP error with status code %d (%s).zRequest raised HTTP error.zRequest raised exception: %s)typelistboolplexpyCONFIGVERIFY_SSL_CERTr   disable_warnings
exceptionsInsecureRequestWarninggetattrrequestslowerr   debugupperstatus_coderaise_for_statusSSLErrorerrorConnectionErrorTimeout	HTTPErrorresponseVERBOSEserver_messageRequestException)
urlmethod
auto_raisewhitelist_status_coder   kwargsrequest_methodr%   ecauses
             /opt/Tautulli/plexpy/request.pyrequest_responser2   #   sx    &;!<!D!6 7 FMM99:F8(  !3!3!J!JK Xv||~6N=8 	5LL2FLLNCI%c4V4H	5 !Z##+@@--/ x %%''	5 	5LL34<4H4HJ 
 '' 2(LL23 LL./02 23 ## '&	'  JH	J 7::!zz%%,-''3., "LLD

&&/
 ~~qzz*LL566 +  $$ 83Q778sy   D5 /D D5 D +D5 -D5 /D5 DD5 #D22D5 5K&1F+K&:'K&#K&5B,J00K&K!!K&c                    |rt        |      t        k7  r|g}t        t        j                  j
                        |d<   |d   s-t        j                  t        j                  j                         t        t        |j                               }d}dx}x}	}
	 |5   || fi |}ddd       |r"|r |j                  |vr$	 |j                          n|r|j                          |||
fS # 1 sw Y   DxY w#   xY w# t        j                  j                  $ r#}|d   rd}ndj!                  |      }Y d}~Rd}~wt        j"                  $ r d}Y lt        j$                  $ r d}Y t        j&                  $ r}|j(                  |j(                  j                  dk\  rdj!                  |	      }	n.|j(                  j                  d
k\  rdj!                  |	      }	nd}	dj!                  |	      }t        j*                  rt-        |j(                  d      }
nd}Y d}~;d}~wt        j.                  $ r}dj!                  |      }Y d}~hd}~ww xY w)r
   r   Nz8Unable to connect to remote host because of a SSL error.zeUnable to connect to remote host because of a SSL error, with certificate verification turned off: {}r   z%Request to the remote host timed out.r   zE[{e.response.status_code}] {e.response.reason} (remote server error).)r/   r   zD[{e.response.status_code}] {e.response.reason} (local client error).zUnknown HTTP error.zRequest raised a HTTP error: {}T)
return_msgz.Request raised a HTTP error: Unknown response.zRequest raised an exception: {})r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    formatr"   r#   r$   r%   r&   r'   r(   )r)   r*   r+   r,   r   r-   r.   r%   err_msghttp_errreq_msgr/   s               r1   request_response2r9      s$    &;!<!D!6 7 FMM99:F8(  !3!3!J!JK Xv||~6NH#''G'h0> 	5%c4V4H	5
 !Z##+@@--/ %%'J Wg%%c	5 	5 '' I(PG??Evay  ## ba :9 G::!zz%%,biilmin''3.ahhklhm 17>>xHG~~(E GG$$ >3::1=>sm   C8 
C&#C8 >C2 C8 &C/+C8 2C55C8 8ID33II#I5B!HI2I		Ic                 p    |j                  dd      }t        | fi |}|t        |j                  |      S y)zr
    Wrapper for `request_response', which will return a BeatifulSoup object if
    no exceptions are raised.
    parserhtml5libN)popr2   r   content)r)   r-   r;   r%   s       r1   request_soupr?      sA     ZZ*-F.v.HX--v66     c                 ^    t        | fi |}|t        j                  |j                        S y)zm
    Wrapper for `request_response', which will return a Minidom object if no
    exceptions are raised.
    N)r2   r   parseStringr>   r)   r-   r%   s      r1   request_minidomrD      s5      .v.H""8#3#344 r@   c                 ,   |j                  dd      }t        | fi |}|3	 |j                         }|r ||      st        j                  d       y|S y# t
        $ r5 t        j                  d       t        j                  rt        |       Y yY yw xY w)z
    Wrapper for `request_response', which will decode the response as JSON
    object and return the result, if no exceptions are raised.

    As an option, a validator callback can be given, which should return True
    if the result is valid.
    	validatorNzJSON validation result failedz#Response returned invalid JSON data)	r=   r2   jsonr   r!   
ValueErrorr   r&   r'   )r)   r-   rF   r%   results        r1   request_jsonrJ      s     

;-I.v.H	)]]_F6!2<=   	)LL>? ~~x( 		)s   /A A 9BBc                 8    t        | fi |}||j                  S y)zL
    Wrapper for `request_response', which will return the raw content.
    N)r2   r>   rC   s      r1   request_contentrL     s*    
  .v.H r@   c                 ^   d}d| j                   j                  dd      v r	 t        | j                  d      }|rk|j                  d      }d}|D ])  }|j                  |      D ]  }|j                  d        + |r|j                  n|j                  }|j                         }|| j                  j                         }|rE	 |j                  dd	
      }t        |      dkD  r|dd dz   }|r|S t        j                  d|       yy# t        $ r d}Y w xY w# t        t        f$ r Y Tw xY w)a)  
    Extract server message from response and log in to logger with DEBUG level.

    Some servers return extra information in the result. Try to parse it for
    debugging purpose. Messages are limited to 150 characters, since it may
    return the whole page in case of normal web page URLs
    Nz	text/htmlzcontent-type r<   body)headerscriptfooternavinputtextareazutf-8replace)errors   z...z!Server responded with message: %s)headersr   r   r>   	Exceptionfindfind_allreplaceWithtextstripdecodeUnicodeDecodeErrorAttributeErrorlenr   r   )r%   r4   messagesoupelementselementtags          r1   r'   r'     sE    G h&&**>2>>	 !1!1:>D  ii'GQH# (==1 (COOB'(( '.gll499GmmoG ""((*	nnWYn?G
 w<#dsme+GN8'B )  	D	. #N3 		s#   D	 D 	DDD,+D,)F)collectionsxml.domr   bs4r   r   requests.packagesr   r   r   r   defaultdictintlast_requestsFakeLock	fake_lockr2   r9   r?   rD   rJ   rL   r'    r@   r1   <module>rs      s   $     %    ('',DMMO	 "'4+/iY8x #(D,0yQ&h
7	5)8 0Cr@   