o
    i*D                     @   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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 ))GoPlayIEzplay.tvzPLAY (formerly goplay.be)zAhttps?://(www\.)?play\.tv/video/([^/?#]+/[^/?#]+/|)(?P<id>[^/#]+)goplayzhttps://www.play.tv/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seasonskip_downloadTz1This video is only available for registered users)url	info_dictparamsskipzhttps://www.play.tv/video/1917z$40cac41d-8d29-4ef5-aa11-75047b9f09071917zHre:Op het hoogtepunt van de Eerste Wereldoorlog krijgen twee jonge .{94})r   r   r   r   zLhttps://www.play.tv/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_dViSsKM5Y6s1h851s8uplco5h6mqh1jac8m)iepool_id	client_id)usernamepassword)report_loginAwsIdpauthenticate	_id_token)selfr!   r"   aws_ r*   K/home/ubuntu/.local/lib/python3.10/site-packages/yt_dlp/extractor/goplay.py_perform_loginB   s   zGoPlayIE._perform_loginc                 C   s   | j s	| jddd S )Nr"   )method)r&   raise_login_requiredr'   r*   r*   r+   _real_initializeG   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r|t|d	d
d	thfD ]=}t|dfddtf}|sOq>t|dt	hf}	|
t|dthft|dt	hf|	| jd|	 d|ddd dd  | jd dd| j i|  d}
d|
v r| j|
d d ddd\}}n<d|
vrt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urlparser3   )kv)r   r*   r+   <lambda>Q   s    z(GoPlayIE._real_extract.<locals>.<lambda>uuidr   r   )r   r   )programsubtypemovie.	playlistsvideosc                    s   |d  kS )NvideoIdr*   )r)   r8   )video_idr*   r+   r9   [   s    r   episodeTitleepisodeNumberz
^(.+)? - Sz - r   )default)r   r   r   r   z,https://api.play.tv/web/v1/videos/long-form/AuthorizationzBearer )headersmanifestUrlshlsr   HLS)r   m3u8_idssaizexpecting Google SSAI streamcontentSourceIDvideoIDz-https://dai.google.com/ondemand/dash/content/z/vid/z/streamss   {"api-key":"null"}zcontent-typezapplication/json)datarF   stream_manifestc                 S   s   g | ]
}d |d vr|qS )z-ad-r   r*   ).0pr*   r*   r+   
<listcomp>   s    z*GoPlayIE._real_extract.<locals>.<listcomp>)r   formats	subtitles)	_match_id_download_webpage_search_nextjs_v13_datar   r   strstripdictanyr   update_search_regexget_download_jsonr&   geo_verification_headers#_extract_m3u8_formats_and_subtitlesr   _extract_mpd_periods_merge_mpd_periods)r'   r   
display_idwebpagenextjs_datar2   r   season_dataepisode_datar   apirS   rT   ssai_content_source_idssai_video_iddaiperiodsr*   )r   rA   r+   _real_extractK   sp   


zGoPlayIE._real_extract)__name__
__module____qualname__IE_NAMEIE_DESC
_VALID_URL_NETRC_MACHINE_TESTSr&   r,   r0   rn   r*   r*   r*   r+   r	      s^    *r	   c                   @      e Zd ZdZdS )InvalidLoginExceptionz# The login credentials are invalid Nro   rp   rq   __doc__r*   r*   r*   r+   rx          rx   c                   @   rw   )AuthenticationExceptionz' Something went wrong while logging in Nry   r*   r*   r*   r+   r|      r{   r|   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/   FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF2zCaldera Derived Keyutf-8000N)r   r   
ValueErrorr    splitregionr   n_hexg_hex	bytearray	info_bits_AwsIdp__hex_to_longbig_ng_AwsIdp__hex_hashr7    _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r1t|d | 	||}t| }	ddd}
| jj| jd|	|
ddd}d|v rZt
|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)rN   rF   noteerrnoteChallengeParametersChallengeNamePASSWORD_VERIFIERmessagez8AWSCognitoIdentityProviderService.RespondToAuthChallenge)r   r   zAuthenticating passwordzInvalid passwordAuthenticationResultIdTokenRefreshToken)#_AwsIdp__get_authentication_requestjsondumpsencoder   r_   r   r^   r|   '_AwsIdp__get_challenge_response_requestrx   )r'   r!   r"   auth_data_dict	auth_dataauth_headersauth_response_jsonchallenge_parameterschallenge_requestchallenge_data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
        )USERNAMESRP_AUSER_SRP_AUTH)AuthParametersAuthFlowClientId)_AwsIdp__long_to_hexr   r    )r'   r!   r*   r*   r+   __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
        r   USER_ID_FOR_SRPSRP_BSALTSECRET_BLOCKr)   r   r   )	digestmod)r   	TIMESTAMPPASSWORD_CLAIM_SECRET_BLOCKPASSWORD_CLAIM_SIGNATUREr   )ChallengeResponsesr   r   )_AwsIdp__get_current_timestamp"_AwsIdp__get_hkdf_key_for_passwordr   base64standard_b64decoder   r   r   hmacnewhashlibsha256standard_b64encodedigestdecoder    )r'   r   r"   user_iduser_id_for_srpsrp_bsaltsecret_block	timestamphkdfsecret_block_bytesmsghmac_objsignature_stringr*   r*   r+    __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_ur   r   formatr   r   _AwsIdp__hash_sha256r   r   r   _AwsIdp__pad_hexpowr   r   r7   r   _AwsIdp__compute_hkdfr   fromhexr   )r'   r!   r"   server_b_valuer   u_valueusername_passwordusername_password_hashx_valueg_mod_pow_xn
int_value2s_valuer*   r*   r+   __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   r   N   )r   r   r   r   r   r   r   chr)r'   ikmr   prkinfo_bits_update	hmac_hashr*   r*   r+   __compute_hkdfJ  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   r   )r'   big_abig_b
u_hex_hashr*   r*   r+   __calculate_uW  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'   random_long_intr*   r*   r+   __generate_random_small_ad  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   r   )r'   r   r*   r*   r+   __calculate_am  s   zAwsIdp.__calculate_ac                 C   s   | dS )Nxr*   )long_numr*   r*   r+   __long_to_hexz  s   zAwsIdp.__long_to_hexc                 C   s
   t | dS )Nr   )int
hex_stringr*   r*   r+   __hex_to_long~  s   
zAwsIdp.__hex_to_longc                 C   s   t t| S N)r$   r   r   r   r   r*   r*   r+   
__hex_hash  s   zAwsIdp.__hex_hashc                 C   s"   t |  }dt| d | S )zAuthenticationHelper.hash@   r   )r   r   	hexdigestlen)bufr   r*   r*   r+   __hash_sha256  s   zAwsIdp.__hash_sha256c                 C   sR   t | tst| }n| }t|d dkrd| }|S |d dv r'd| }|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   r   r   89ABCDEFabcdefr   )
isinstancerX   r$   r   r   )long_inthash_strr*   r*   r+   	__pad_hex  s   



zAwsIdp.__pad_hexc                 C   s   t t| }t|S r   )binasciihexlifyosurandomr$   r   )nbytes
random_hexr*   r*   r+   __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daystime_nowformat_stringr*   r*   r+   __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   r   r   r   r    r/   r*   r*   r+   __str__  s   zAwsIdp.__str__N)ro   rp   rq   rz   r   r%   r   r   r   r   r   r   r   staticmethodr   r   r   r   r   r   r   r/  r*   r*   r*   r+   r$      s4    0$-	






r$   )r   r  r"  r!  r   r   r   r  urllib.parser4   commonr   utilsr   r   utils.traversalr   r   r	   rx   r|   r$   r*   r*   r*   r+   <module>   s      