U
    g                     @  s   d dl mZ d dlZd dlmZ d dlmZ d dlmZ ddl	m
Z
mZ ddlmZ d	d
lmZ d	dlmZmZ d	dlmZ edddG dd dZG dd de
eZeedd ZdS )    )annotationsN)ABC)	dataclass)Any   )RequestHandlerregister_preference)UnsupportedRequest   )NoneType)classpropertyjoin_nonempty)std_headersT)orderfrozenc                   @  sr   e Zd ZU dZdZded< dZded< dZded< dZded< dd	 Z	d d
ddZ
dd Zedd
ddZdS )ImpersonateTargeta<  
    A target for browser impersonation.

    Parameters:
    @param client: the client to impersonate
    @param version: the client version to impersonate
    @param os: the client OS to impersonate
    @param os_version: the client OS version to impersonate

    Note: None is used to indicate to match any.

    Nz
str | Noneclientversionos
os_versionc                 C  s,   | j r| jstd| jr(| js(tdd S )Nz$client is required if version is setz#os is required if os_version is set)r   r   
ValueErrorr   r   self r   A/tmp/pip-unpacked-wheel-q5ljy6pj/yt_dlp/networking/impersonate.py__post_init__"   s    zImpersonateTarget.__post_init__targetc                 C  s   t |tsdS | jd ks.|jd ks.| j|jko| jd ksN|jd ksN| j|jko| jd ksn|jd ksn| j|jko| jd kp|jd kp| j|jkS )NF)
isinstancer   r   r   r   r   r   r   r   r   r   __contains__(   s    
 zImpersonateTarget.__contains__c                 C  s(   t | j| j dt | j| j dS )N:)r   r   r   r   r   rstripr   r   r   r   __str__2   s    zImpersonateTarget.__str__strc                 C  s.   t d|}|s td| d| f | S )Nze(?:(?P<client>[^:-]+)(?:-(?P<version>[^:-]+))?)?(?::(?:(?P<os>[^:-]+)(?:-(?P<os_version>[^:-]+))?)?)?zInvalid impersonate target "")re	fullmatchr   	groupdict)clsr   Zmobjr   r   r   from_str5   s    zImpersonateTarget.from_str)__name__
__module____qualname____doc__r   __annotations__r   r   r   r   r    r#   classmethodr*   r   r   r   r   r      s   

r   c                      s   e Zd ZU dZi Zded< dddd fddZdd	d
dZ fddZ fddZ	dd	ddZ
eddddZdd	ddZdd Zdd Z  ZS )ImpersonateRequestHandlera<  
    Base class for request handlers that support browser impersonation.

    This provides a method for checking the validity of the impersonate extension,
    which can be used in _check_extensions.

    Impersonate targets consist of a client, version, os and os_ver.
    See the ImpersonateTarget class for more details.

    The following may be defined:
     - `_SUPPORTED_IMPERSONATE_TARGET_MAP`: a dict mapping supported targets to custom object.
                Any Request with an impersonate target not in this list will raise an UnsupportedRequest.
                Set to None to disable this check.
                Note: Entries are in order of preference

    Parameters:
    @param impersonate: the default impersonate target to use for requests.
                        Set to None to disable impersonation.
    zdict[ImpersonateTarget, Any]!_SUPPORTED_IMPERSONATE_TARGET_MAPN)impersonater   c                  s   t  jf | || _d S N)super__init__r3   )r   r3   kwargs	__class__r   r   r6   S   s    z"ImpersonateRequestHandler.__init__r   c                 C  s@   t |ttfst|d ks | js$d S | |s<td| d S )Nz Unsupported impersonate target: )r   r   r   AssertionErrorsupported_targetsis_supported_targetr	   r   r   r   r   _check_impersonate_targetW   s
    
z3ImpersonateRequestHandler._check_impersonate_targetc                   s(   t  | d|kr$| |d d S )Nr3   )r5   _check_extensionsr=   get)r   
extensionsr8   r   r   r>   ^   s    z+ImpersonateRequestHandler._check_extensionsc                   s   t  | | | j d S r4   )r5   	_validater=   r3   r   requestr8   r   r   rA   c   s    z#ImpersonateRequestHandler._validatezImpersonateTarget | Nonec                 C  sP   |dkrdS | j D ]8}||kr| jrB| j| j d| d|  |  S qdS )z'Resolve a target to a supported target.Nz: resolved impersonate target z to )r;   verboseZ_loggerstdoutZRH_NAME)r   r   Zsupported_targetr   r   r   _resolve_targetg   s    
z)ImpersonateRequestHandler._resolve_targetztuple[ImpersonateTarget, ...])returnc                 C  s   t | j S r4   )tupler2   keys)r)   r   r   r   r;   r   s    z+ImpersonateRequestHandler.supported_targetsc                 C  s   t |tst| |d k	S r4   )r   r   r:   rF   r   r   r   r   r<   v   s    z-ImpersonateRequestHandler.is_supported_targetc                 C  s   |  |jdp| jS )z(Get the requested target for the requestr3   )rF   r@   r?   r3   rB   r   r   r   _get_request_targetz   s    z-ImpersonateRequestHandler._get_request_targetc                 C  sH   |  |j}| |d k	rDt D ] \}}|||kr"|| q"|S r4   )Z_merge_headersheadersrJ   r   itemsr?   pop)r   rC   rK   kvr   r   r   _get_impersonate_headers~   s    z2ImpersonateRequestHandler._get_impersonate_headers)r+   r,   r-   r.   r2   r/   r6   r=   r>   rA   rF   r   r;   r<   rJ   rP   __classcell__r   r   r8   r   r1   =   s   
r1   c                 C  s   |j ds| jrdS dS )Nr3   i  r   )r@   r?   r3   )ZrhrC   r   r   r   impersonate_preference   s    rR   )
__future__r   r&   abcr   Zdataclassesr   typingr   commonr   r   
exceptionsr	   Zcompat.typesr   utilsr   r   Zutils.networkingr   r   r1   rR   r   r   r   r   <module>   s   
-L