U
    g@                     @   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m	Z	 ddl
mZ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traverse_objunescapeHTMLc                   @   s   e Zd ZdZdZddddddd	d
dddddddd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 )&GoPlayIEzGhttps?://(www\.)?goplay\.be/video/([^/]+/[^/]+/|)(?P<display_id>[^/#]+)Zgoplayzjhttps://www.goplay.be/video/de-container-cup/de-container-cup-s3/de-container-cup-s3-aflevering-2#autoplayz$9c4214b8-e55d-4e4b-a446-f015f6c6f811mp4zS3 - Aflevering 2zDe Container CupzSeason 3   z	Episode 2r   )idexttitleseriesseasonseason_numberepisodeepisode_numberz1This video is only available for registered users)url	info_dictskipzNhttps://www.goplay.be/video/a-family-for-thr-holidays-s1-aflevering-1#autoplayz$74e3ed07-748c-49e4-85a0-393a93337dbfzA Family for the Holidays)r   r   r   zNhttps://www.goplay.be/video/de-mol/de-mol-s11/de-mol-s11-aflevering-1#autoplayz$03eb8f2f-153e-41cb-9805-0d3a29dab656zS11 - Aflevering 1z	Episode 1zDe Mol   r   z	Season 11)r   r   r   r   r   r   r   r   Zskip_downloadT)r   r   paramsr   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"   ;/tmp/pip-unpacked-wheel-q5ljy6pj/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_initializeD   s    zGoPlayIE._real_initializec                    s  |   dd\ }|  |}| d|d}| t||d}|d}|rl|d }d|di}nLt|d	d
d fddfdd}	|	d }|	dt|	d|	d|	dd}| jd| |dd| j	 i| 
 d}
d|
kr| j|
d d |ddd\}}nzd|
krtd|
d d  }|
d d! }| jd"| d#| d$|d%d&d'id(}| |d) |}d*d+ |D }| |\}}||||d, |S )-Nr   
display_idz<div\s+data-hero="([^"]+)"
video_datadatamovieZ	videoUuidr   Z	playlists.Zepisodesc                    s   |d d  kS )NZpageInfor   r"   )r!   vr   r"   r#   <lambda>U       z(GoPlayIE._real_extract.<locals>.<lambda>F)get_allZepisodeTitle)programr   ZseasonNumberZepisodeNumber)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)r*   r3   Zstream_manifestc                 S   s   g | ]}d |d kr|qS )z-ad-r   r"   ).0pr"   r"   r#   
<listcomp>x   s      z*GoPlayIE._real_extract.<locals>.<listcomp>)r   formats	subtitles)Z_match_valid_urlgroupZ_download_webpageZ_html_search_regexZ_parse_jsonr   getr   _download_jsonr   Zgeo_verification_headersZ#_extract_m3u8_formats_and_subtitlesr   Z_extract_mpd_periodsZ_merge_mpd_periodsupdate)r    r   r(   ZwebpageZvideo_data_jsonr)   r+   Zvideo_idr   r   apir7   r8   Zssai_content_source_idZssai_video_idZdaiZperiodsr"   r-   r#   _real_extractH   sh    
  


   
 zGoPlayIE._real_extract)
__name__
__module____qualname__Z
_VALID_URLZ_NETRC_MACHINEZ_TESTSr   r$   r'   r>   r"   r"   r"   r#   r      sR   
	 'r   c                   @   s   e Zd ZdZdS )InvalidLoginExceptionz# The login credentials are invalid Nr?   r@   rA   __doc__r"   r"   r"   r#   rB      s   rB   c                   @   s   e Zd ZdZdS )AuthenticationExceptionz' Something went wrong while logging in NrC   r"   r"   r"   r#   rE      s   rE   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k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_hashk _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|k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*   r3   ZnoteZerrnoteZChallengeParametersChallengeNamePASSWORD_VERIFIERmessagez8AWSCognitoIdentityProviderService.RespondToAuthChallenge)rZ   r[   zAuthenticating passwordzInvalid passwordZAuthenticationResultZIdTokenZRefreshToken)#_AwsIdp__get_authentication_requestjsondumpsencoder   r;   r   r:   rE   '_AwsIdp__get_challenge_response_requestrB   )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      sF    
    
    

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_hexrW   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
        re   ZUSER_ID_FOR_SRPZSRP_BZSALTZSECRET_BLOCKr!   r   rG   )	digestmod)re   	TIMESTAMPZPASSWORD_CLAIM_SECRET_BLOCKZPASSWORD_CLAIM_SIGNATUREr]   )ZChallengeResponsesr\   rf   )_AwsIdp__get_current_timestamp"_AwsIdp__get_hkdf_key_for_passwordrO   base64standard_b64decoderM   r   rK   hmacnewhashlibsha256standard_b64encodedigestdecoder   )r    rd   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_urW   rJ   formatr   rK   _AwsIdp__hash_sha256rb   rO   rR   _AwsIdp__pad_hexpowrQ   rP   rS   rU   _AwsIdp__compute_hkdfrM   fromhexrg   )r    r   r   Zserver_b_valueru   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   rG   N   )rn   ro   rp   rq   rs   rN   rM   chr)r    Zikmru   ZprkZinfo_bits_updateZ	hmac_hashr"   r"   r#   Z__compute_hkdf?  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
        )rR   r{   rO   )r    big_aZbig_bZ
u_hex_hashr"   r"   r#   Z__calculate_uL  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_randomrP   )r    Zrandom_long_intr"   r"   r#   Z__generate_random_small_aY  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|   rQ   rU   rP   rJ   )r    r   r"   r"   r#   Z__calculate_ab  s    zAwsIdp.__calculate_ac                 C   s   | dS )Nxr"   )Zlong_numr"   r"   r#   Z__long_to_hexo  s    zAwsIdp.__long_to_hexc                 C   s
   t | dS )Nr   )intZ
hex_stringr"   r"   r#   Z__hex_to_longs  s    zAwsIdp.__hex_to_longc                 C   s   t t| S N)r   rz   rM   r~   r   r"   r"   r#   Z
__hex_hashw  s    zAwsIdp.__hex_hashc                 C   s"   t |  }dt| d | S )zAuthenticationHelper.hash@   rI   )rp   rq   	hexdigestlen)bufrs   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k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   rI   r   Z89ABCDEFabcdefrH   )
isinstancestrr   rg   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   rO   )nbytesZ
random_hexr"   r"   r#   Z__get_random  s    zAwsIdp.__get_randomc                  C   sp   ddddddddd	d
dddg} dddddddg}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   )ry   rL   r   rK   r   r&   r"   r"   r#   __str__  s
      zAwsIdp.__str__N)r?   r@   rA   rD   rX   r   r_   rc   rk   r}   rx   rT   rV   staticmethodrg   rO   rR   rz   r{   r   rj   r   r"   r"   r"   r#   r      s2   0$-	






r   )rl   r   r   r   rp   rn   r`   r   commonr   utilsr   r   r   r   rB   rE   r   r"   r"   r"   r#   <module>   s   v