a
    hC                     @   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Z	ddl
mZ ddlmZmZ ddlmZmZ G dd deZG d	d
 d
eZG dd deZG dd dZdS )    N   )InfoExtractor   )ExtractorErrorint_or_none)	get_firsttraverse_objc                   @   s   e Zd ZdZdZddddddd	d
ddd	ddiddddddddddiddddddddddddd	ddiddgZd Zd!d" Zd#d$ Zd%d& Z	d S )'GoPlayIEzChttps?://(www\.)?goplay\.be/video/([^/?#]+/[^/?#]+/|)(?P<id>[^/#]+)Zgoplayzhttps://www.goplay.be/video/de-slimste-mens-ter-wereld/de-slimste-mens-ter-wereld-s22/de-slimste-mens-ter-wereld-s22-aflevering-1z$2baa4560-87a0-421b-bffc-359914e3c387mp4z/De Slimste Mens ter Wereld - S22 - Aflevering 1zJre:In aflevering 1 nemen Daan Alferink, Tess Elst en Xander De Rycke .{66}zDe Slimste Mens ter WereldzWordt aangekondigd   r   z	Season 22)	idexttitledescriptionseriesepisodeseason_numberepisode_numberseasonZskip_downloadTz1This video is only available for registered users)url	info_dictparamsskipz https://www.goplay.be/video/1917z$40cac41d-8d29-4ef5-aa11-75047b9f0907Z1917zHre:Op het hoogtepunt van de Eerste Wereldoorlog krijgen twee jonge .{94})r   r   r   r   zNhttps://www.goplay.be/video/de-mol/de-mol-s11/de-mol-s11-aflevering-1#autoplayz$ecb79672-92b9-4cd9-a0d7-e2f0250681eezDe Mol - S11 - Aflevering 1zNre:Tien kandidaten beginnen aan hun verovering van Amerika en ontmoeten .{102}z	Episode 1zDe Mol   z	Season 11)	r   r   r   r   r   r   r   r   r   Nc                 C   s.   |    t| ddd}|j||d\| _}d S )Nzeu-west-1_dViSsKM5YZ6s1h851s8uplco5h6mqh1jac8m)iepool_id	client_id)usernamepassword)Zreport_loginAwsIdpauthenticate	_id_token)selfr   r   Zaws_ r$   L/mnt/pikpak/tmp/myenv/lib/python3.9/site-packages/yt_dlp/extractor/goplay.py_perform_login@   s    zGoPlayIE._perform_loginc                 C   s   | j s| jddd S )Nr   )method)r!   Zraise_login_requiredr"   r$   r$   r%   _real_initializeE   s    zGoPlayIE._real_initializec                    s  |   }|  |}| ||}t| fdd}|d t|dthfdtjhfd}t|ddkrt|d	d
d	thfD ]~}t|dfddtf}|sq|t|dt	hf}	|
t|dthft|dt	hf|	| jd|	 d|ddd dd  qq|| jd dd| j i|  d}
d|
v rP| j|
d d ddd\}}nzd|
vrbtd|
d d  }|
d d! }| jd"| d#| d$d%d&d'id(}| |d) }d*d+ |D }| |\}}|
||d, |S )-Nc                    s   | dv o|d t j jkS )N)videometapath)urllibparseurlparser,   )kv)r   r$   r%   <lambda>O       z(GoPlayIE._real_extract.<locals>.<lambda>uuidr   r   )r   r   )programsubtypeZmovie.Z	playlistsZvideosc                    s   |d  kS )NZvideoIdr$   )r#   r1   )video_idr$   r%   r2   Y   r3   r   ZepisodeTitleZepisodeNumberz
^(.+)? - Sz - r   )default)r   r   r   r   z.https://api.goplay.be/web/v1/videos/long-form/AuthorizationzBearer )headersZmanifestUrlsZhlsr
   ZHLS)r   Zm3u8_idZssaizexpecting Google SSAI streamZcontentSourceIDZvideoIDz-https://dai.google.com/ondemand/dash/content/z/vid/z/streamss   {"api-key":"null"}zcontent-typezapplication/json)datar:   Zstream_manifestc                 S   s   g | ]}d |d vr|qS )z-ad-r   r$   ).0pr$   r$   r%   
<listcomp>   r3   z*GoPlayIE._real_extract.<locals>.<listcomp>)r   formats	subtitles)Z	_match_idZ_download_webpageZ_search_nextjs_v13_datar   r   strstripdictanyr   updateZ_search_regexget_download_jsonr!   Zgeo_verification_headersZ#_extract_m3u8_formats_and_subtitlesr   Z_extract_mpd_periodsZ_merge_mpd_periods)r"   r   Z
display_idZwebpageZnextjs_datar+   r   Zseason_dataZepisode_datar   apir?   r@   Zssai_content_source_idZssai_video_idZdaiZperiodsr$   )r   r7   r%   _real_extractI   sp    




zGoPlayIE._real_extract)
__name__
__module____qualname__Z
_VALID_URLZ_NETRC_MACHINEZ_TESTSr!   r&   r)   rI   r$   r$   r$   r%   r	      sX   *r	   c                   @   s   e Zd ZdZdS )InvalidLoginExceptionz# The login credentials are invalid NrJ   rK   rL   __doc__r$   r$   r$   r%   rM      s   rM   c                   @   s   e Zd ZdZdS )AuthenticationExceptionz' Something went wrong while logging in NrN   r$   r$   r$   r%   rP      s   rP   c                   @   s   e Zd Z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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$S )%r   z AWS Identity Provider c                 C   s   || _ || _d| jvrtd|| _| jdd | _d| j d| _d| _d| _t	dd	| _
| | j| _| | j| _| | d
| j d | j | _|  | _|  | _dS )aM  
        :param InfoExtrator ie: The extractor that instantiated this class.
        :param str pool_id:     The AWS user pool to connect to (format: <region>_<poolid>).
                                E.g.: eu-west-1_aLkOfYN3T
        :param str client_id:   The client application ID (the ID of the application connecting)
        r#   z4Invalid pool_id format. Should be <region>_<poolid>.r   zhttps://cognito-idp.z.amazonaws.com/A   FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF2zCaldera Derived Keyutf-8000N)r   r   
ValueErrorr   splitregionr   Zn_hexZg_hex	bytearray	info_bits_AwsIdp__hex_to_longbig_ng_AwsIdp__hex_hashr0    _AwsIdp__generate_random_small_asmall_a_value_AwsIdp__calculate_alarge_a_value)r"   r   r   r   r$   r$   r%   __init__   s     
"
zAwsIdp.__init__c                 C   s   |  |}t| }dddd}| jj| jd||ddd}|d	}|d
dkrbt|d | 	||}t| }	ddd}
| jj| jd|	|
ddd}d|v rt
|d |d d |d d fS )z, Authenticate with a username and password. z.AWSCognitoIdentityProviderService.InitiateAuthidentityzapplication/x-amz-json-1.1)X-Amz-TargetzAccept-EncodingContent-TypeNzAuthenticating usernamezInvalid username)r;   r:   ZnoteZerrnoteZChallengeParametersChallengeNamePASSWORD_VERIFIERmessagez8AWSCognitoIdentityProviderService.RespondToAuthChallenge)rd   re   zAuthenticating passwordzInvalid passwordZAuthenticationResultZIdTokenZRefreshToken)#_AwsIdp__get_authentication_requestjsondumpsencoder   rG   r   rF   rP   '_AwsIdp__get_challenge_response_requestrM   )r"   r   r   Zauth_data_dictZ	auth_dataZauth_headersZauth_response_jsonchallenge_parametersZchallenge_requestZchallenge_dataZchallenge_headersr$   r$   r%   r       s6    





zAwsIdp.authenticatec                 C   s   ||  | jdd| jdS )z

        :param str username:    The username to use

        :return: A full Authorization request.
        :rtype: dict
        )USERNAMEZSRP_AZUSER_SRP_AUTH)ZAuthParametersZAuthFlowClientId)_AwsIdp__long_to_hexra   r   )r"   r   r$   r$   r%   Z__get_authentication_request   s    

z#AwsIdp.__get_authentication_requestc                 C   s   |d }|d }|d }|d }|d }|   }| ||| ||}	t|}
t| jdd dt|d t|
 t|d }tj	|	|t
jd	}t| d}||||d
d| jdS )aH   Create a Challenge Response Request object.

        :param dict[str,str|imt] challenge_parameters:  The parameters for the challenge.
        :param str password:                            The password.

        :return: A valid and full request data object to use as a response for a challenge.
        :rtype: dict
        ro   ZUSER_ID_FOR_SRPZSRP_BZSALTZSECRET_BLOCKr#   r   rR   )	digestmod)ro   	TIMESTAMPZPASSWORD_CLAIM_SECRET_BLOCKZPASSWORD_CLAIM_SIGNATURErg   )ZChallengeResponsesrf   rp   )_AwsIdp__get_current_timestamp"_AwsIdp__get_hkdf_key_for_passwordrZ   base64standard_b64decoderX   r   rV   hmacnewhashlibsha256standard_b64encodedigestdecoder   )r"   rn   r   Zuser_idZuser_id_for_srpZsrp_bsaltZsecret_block	timestampZhkdfZsecret_block_bytesmsgZhmac_objZsignature_stringr$   r$   r%   Z __get_challenge_response_request   s>    	
z'AwsIdp.__get_challenge_response_requestc              
   C   s   |  | j|}|dkrtdd| jdd ||}| | }| | 	| 
|| }t| j|| j}	|| j|	  }
t|
| j||  | j}| t| 
|t| 
| |S )ab   Calculates the final hkdf based on computed S value, and computed U value and the key.

        :param str username:        Username.
        :param str password:        Password.
        :param int server_b_value:  Server B value.
        :param int salt:            Generated salt.

        :return Computed HKDF value.
        :rtype: object
        r   zU cannot be zero.z{}{}:{}r#   r   )_AwsIdp__calculate_ura   rU   formatr   rV   _AwsIdp__hash_sha256rl   rZ   r]   _AwsIdp__pad_hexpowr\   r[   r0   r_   _AwsIdp__compute_hkdfrX   fromhexrq   )r"   r   r   Zserver_b_valuer   Zu_valueZusername_passwordZusername_password_hashZx_valueZg_mod_pow_xnZ
int_value2Zs_valuer$   r$   r%   Z__get_hkdf_key_for_password-  s    z"AwsIdp.__get_hkdf_key_for_passwordc                 C   sH   t ||tj }| jttdd }t ||tj }|dd S )z Standard hkdf algorithm

        :param {Buffer} ikm Input key material.
        :param {Buffer} salt Salt value.
        :return {Buffer} Strong key material.
        r   rR   N   )rx   ry   rz   r{   r}   rY   rX   chr)r"   Zikmr   ZprkZinfo_bits_updateZ	hmac_hashr$   r$   r%   Z__compute_hkdfH  s    zAwsIdp.__compute_hkdfc                 C   s$   |  | || | }| |S )z Calculate the client's value U which is the hash of A and B

        :param int big_a:   Large A value.
        :param int big_b:   Server B value.

        :return Computed U value.
        :rtype: int
        )r]   r   rZ   )r"   big_aZbig_bZ
u_hex_hashr$   r$   r%   Z__calculate_uU  s    
zAwsIdp.__calculate_uc                 C   s   |  d}|| j S )zo Helper function to generate a random big integer

        :return a random value.
        :rtype: int
           )_AwsIdp__get_randomr[   )r"   Zrandom_long_intr$   r$   r%   Z__generate_random_small_ab  s    
z AwsIdp.__generate_random_small_ac                 C   s,   t | j| j| j}|| j dkr(td|S )z Calculate the client's public value A = g^a%N with the generated random number a

        :return Computed large A.
        :rtype: int
        r   zSafety check for A failed)r   r\   r_   r[   rU   )r"   r   r$   r$   r%   Z__calculate_ak  s    zAwsIdp.__calculate_ac                 C   s   | dS )Nxr$   )Zlong_numr$   r$   r%   Z__long_to_hexx  s    zAwsIdp.__long_to_hexc                 C   s
   t | dS )Nr   )intZ
hex_stringr$   r$   r%   Z__hex_to_long|  s    zAwsIdp.__hex_to_longc                 C   s   t t| S N)r   r   rX   r   r   r$   r$   r%   Z
__hex_hash  s    zAwsIdp.__hex_hashc                 C   s"   t |  }dt| d | S )zAuthenticationHelper.hash@   rT   )rz   r{   	hexdigestlen)bufr}   r$   r$   r%   Z__hash_sha256  s    zAwsIdp.__hash_sha256c                 C   sP   t | tst| }n| }t|d dkr6d| }n|d dv rLd| }|S )z Converts a Long integer (or hex string) to hex format padded with zeroes for hashing

        :param int|str long_int:    Number or string to pad.

        :return Padded hex string.
        :rtype: str
        r   r   rT   r   Z89ABCDEFabcdefrS   )
isinstancerA   r   rq   r   )Zlong_intZhash_strr$   r$   r%   Z	__pad_hex  s    


zAwsIdp.__pad_hexc                 C   s   t t| }t|S r   )binasciihexlifyosurandomr   rZ   )nbytesZ
random_hexr$   r$   r%   Z__get_random  s    zAwsIdp.__get_randomc                  C   sP   g d} g d}t jt jj}||   d| |j  d|j d}||S )z Creates a timestamp with the correct English format.

        :return: timestamp in format 'Sun Jan 27 19:00:04 UTC 2019'
        :rtype: str
        )NJanFebMarAprMayJunJulAugSepOctNovDec)MonTueWedThuFriSatSun z %H:%M:%S UTC %Y)	dtdatetimenowtimezoneutcweekdaymonthdaystrftime)monthsdaysZtime_nowformat_stringr$   r$   r%   Z__get_current_timestamp  s
    
&zAwsIdp.__get_current_timestampc                 C   s   d | j| jdd | jS )Nz4AWS IDP Client for:
Region: {}
PoolId: {}
AppId:  {}r#   r   )r   rW   r   rV   r   r(   r$   r$   r%   __str__  s    zAwsIdp.__str__N)rJ   rK   rL   rO   rb   r    ri   rm   ru   r   r   r^   r`   staticmethodrq   rZ   r]   r   r   r   rt   r   r$   r$   r$   r%   r      s2   0$-	






r   )rv   r   r   r   rz   rx   rj   r   urllib.parser-   commonr   utilsr   r   Zutils.traversalr   r   r	   rM   rP   r   r$   r$   r$   r%   <module>   s    