o
    óT·jöG  ã                   @   sˆ  d dl mZmZ d dlmZ d dlmZ d dlmZ d dl	m
Z
mZmZmZmZmZ d dlmZ d dlZd dlmZmZmZ d	d
lmZ d	dlmZmZmZ d	dlmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+ eG dd„ dƒƒZ,eG dd„ dƒƒZ-eG dd„ dƒƒZ.G dd„ de/eƒZ0G dd„ de/eƒZ1dede/defdd„Z2G dd„ dƒZ3G dd„ dƒZ4G d d!„ d!ƒZ5G d"d#„ d#ƒZ6dS )$é    )Ú	dataclassÚasdict)ÚEnum)Úchain)Úunescape)ÚListÚDictÚIteratorÚIterableÚPatternÚOptional)ÚElementTreeN)Ú	HTTPErrorÚSessionÚResponseé   )ÚProxyConfig)Ú	WATCH_URLÚINNERTUBE_CONTEXTÚINNERTUBE_API_URL)ÚVideoUnavailableÚYouTubeRequestFailedÚNoTranscriptFoundÚTranscriptsDisabledÚNotTranslatableÚTranslationLanguageNotAvailableÚFailedToCreateConsentCookieÚInvalidVideoIdÚ	IpBlockedÚRequestBlockedÚAgeRestrictedÚVideoUnplayableÚYouTubeDataUnparsableÚPoTokenRequiredc                   @   s(   e Zd ZU eed< eed< 	 eed< dS )ÚFetchedTranscriptSnippetÚtextÚstartÚdurationN)Ú__name__Ú
__module__Ú__qualname__ÚstrÚ__annotations__Úfloat© r.   r.   úf/home/dinkstrade/pdmp-scanner/venv/lib/python3.10/site-packages/youtube_transcript_api/_transcripts.pyr$   "   s   
 r$   c                   @   s~   e Zd ZU dZee ed< eed< eed< eed< eed< de	e fdd	„Z
defd
d„Zdefdd„Zdee fdd„ZdS )ÚFetchedTranscriptz�
    Represents a fetched transcript. This object is iterable, which allows you to
    iterate over the transcript snippets.
    ÚsnippetsÚvideo_idÚlanguageÚlanguage_codeÚis_generatedÚreturnc                 C   ó
   t | jƒS ©N)Úiterr1   ©Úselfr.   r.   r/   Ú__iter__>   ó   
zFetchedTranscript.__iter__c                 C   s
   | j | S r8   )r1   )r;   Úindexr.   r.   r/   Ú__getitem__A   r=   zFetchedTranscript.__getitem__c                 C   r7   r8   )Úlenr1   r:   r.   r.   r/   Ú__len__D   r=   zFetchedTranscript.__len__c                 C   s   dd„ | D ƒS )Nc                 S   s   g | ]}t |ƒ‘qS r.   )r   )Ú.0Úsnippetr.   r.   r/   Ú
<listcomp>H   s    z1FetchedTranscript.to_raw_data.<locals>.<listcomp>r.   r:   r.   r.   r/   Úto_raw_dataG   s   zFetchedTranscript.to_raw_dataN)r(   r)   r*   Ú__doc__r   r$   r,   r+   Úboolr	   r<   r?   ÚintrA   r   rE   r.   r.   r.   r/   r0   1   s   
 r0   c                   @   s   e Zd ZU eed< eed< dS )Ú_TranslationLanguager3   r4   N)r(   r)   r*   r+   r,   r.   r.   r.   r/   rI   K   s   
 rI   c                   @   ó   e Zd ZdZdZdZdS )Ú_PlayabilityStatusÚOKÚERRORÚLOGIN_REQUIREDN)r(   r)   r*   rL   rM   rN   r.   r.   r.   r/   rK   Q   ó    rK   c                   @   rJ   )Ú_PlayabilityFailedReasonu%   Sign in to confirm youâ€™re not a botz/This video may be inappropriate for some users.zThis video is unavailableN)r(   r)   r*   ÚBOT_DETECTEDÚAGE_RESTRICTEDÚVIDEO_UNAVAILABLEr.   r.   r.   r/   rP   W   rO   rP   Úresponser2   r6   c              
   C   sD   z| j dkr
t|ƒ‚|  ¡  | W S  ty! } zt||ƒ‚d }~ww )Ni­  )Ústatus_coder   Úraise_for_statusr   r   )rT   r2   Úerrorr.   r.   r/   Ú_raise_http_errors]   s   

€ÿrX   c                   @   s|   e Zd Zdededededededee fdd	„Zddede	fdd„Z
defdd„Zedefdd„ƒZdedd fdd„ZdS )Ú
TranscriptÚhttp_clientr2   Úurlr3   r4   r5   Útranslation_languagesc                 C   s>   || _ || _|| _|| _|| _|| _|| _dd„ |D ƒ| _dS )z�
        You probably don't want to initialize this directly. Usually you'll access Transcript objects using a
        TranscriptList.
        c                 S   s   i | ]}|j |j“qS r.   )r4   r3   ©rB   Útranslation_languager.   r.   r/   Ú
<dictcomp>}   s    ÿÿz'Transcript.__init__.<locals>.<dictcomp>N)Ú_http_clientr2   Ú_urlr3   r4   r5   r\   Ú_translation_languages_dict)r;   rZ   r2   r[   r3   r4   r5   r\   r.   r.   r/   Ú__init__h   s   þzTranscript.__init__FÚpreserve_formattingr6   c                 C   sV   d| j v r
t| jƒ‚| j | j ¡}t|d� t|| jƒj¡}t	|| j| j
| j| jd�S )zƒ
        Loads the actual transcript data.
        :param preserve_formatting: whether to keep select HTML text formatting
        z&exp=xpe)rd   )r1   r2   r3   r4   r5   )ra   r#   r2   r`   ÚgetÚ_TranscriptParserÚparserX   r%   r0   r3   r4   r5   )r;   rd   rT   r1   r.   r.   r/   Úfetch‚   s   


ÿûzTranscript.fetchc                 C   s"   dj | j| j| jrdd�S dd�S )Nz7{language_code} ("{language}"){translation_description}z[TRANSLATABLE]Ú )r3   r4   Útranslation_description)Úformatr3   r4   Úis_translatabler:   r.   r.   r/   Ú__str__•   s   ýýzTranscript.__str__c                 C   s   t | jƒdkS )Nr   )r@   r\   r:   r.   r.   r/   rl   œ   s   zTranscript.is_translatablec                 C   sN   | j st| jƒ‚|| jvrt| jƒ‚t| j| jdj| j|d�| j| |dg ƒS )Nz{url}&tlang={language_code})r[   r4   T)	rl   r   r2   rb   r   rY   r`   rk   ra   )r;   r4   r.   r.   r/   Ú	translate    s   


ÿ÷zTranscript.translateN©F)r(   r)   r*   r   r+   rG   r   rI   rc   r0   rh   rm   Úpropertyrl   rn   r.   r.   r.   r/   rY   g   s*    þýüûúù
ørY   c                	   @   sú   e Zd ZdZdedeeef deeef dee fdd„Z	e
deded	ed
d fdd„ƒZd
ee fdd„Zdee d
efdd„Zdee d
efdd„Zdee d
efdd„Zdee deeeef  d
efdd„Zd
efdd„Zdee d
efdd„ZdS )ÚTranscriptListzê
    This object represents a list of transcripts. It can be iterated over to list all transcripts which are available
    for a given YouTube video. Also, it provides functionality to search for a transcript in a given language.
    r2   Úmanually_created_transcriptsÚgenerated_transcriptsr\   c                 C   s   || _ || _|| _|| _dS )aÚ  
        The constructor is only for internal use. Use the static build method instead.

        :param video_id: the id of the video this TranscriptList is for
        :param manually_created_transcripts: dict mapping language codes to the manually created transcripts
        :param generated_transcripts: dict mapping language codes to the generated transcripts
        :param translation_languages: list of languages which can be used for translatable languages
        N)r2   Ú_manually_created_transcriptsÚ_generated_transcriptsÚ_translation_languages)r;   r2   rr   rs   r\   r.   r.   r/   rc   º   s   
zTranscriptList.__init__rZ   Úcaptions_jsonr6   c                 C   s¬   dd„ |  dg ¡D ƒ}i }i }|d D ];}|  dd¡dkr |}n|}t| ||d  d	d¡|d
 d d d |d |  dd¡dk|  dd¡rG|ng ƒ||d < qt||||ƒS )a]  
        Factory method for TranscriptList.

        :param http_client: http client which is used to make the transcript retrieving http calls
        :param video_id: the id of the video this TranscriptList is for
        :param captions_json: the JSON parsed from the YouTube pages static HTML
        :return: the created TranscriptList
        c                 S   s,   g | ]}t |d  d d d |d d�‘qS )ÚlanguageNameÚrunsr   r%   ÚlanguageCode©r3   r4   )rI   r]   r.   r.   r/   rD   Ú   s    üþÿz(TranscriptList.build.<locals>.<listcomp>ÚtranslationLanguagesÚcaptionTracksÚkindri   ÚasrÚbaseUrlz	&fmt=srv3Únamery   r   r%   rz   ÚisTranslatableF)re   rY   Úreplacerq   )rZ   r2   rw   r\   rr   rs   ÚcaptionÚtranscript_dictr.   r.   r/   ÚbuildÎ   s0   
ûù
üzTranscriptList.buildc                 C   s   t | j ¡ | j ¡ ƒS r8   )r   rt   Úvaluesru   r:   r.   r.   r/   r<   ü   s   þzTranscriptList.__iter__Úlanguage_codesc                 C   s   |   || j| jg¡S )a>  
        Finds a transcript for a given language code. Manually created transcripts are returned first and only if none
        are found, generated transcripts are used. If you only want generated transcripts use
        `find_manually_created_transcript` instead.

        :param language_codes: A list of language codes in a descending priority. For example, if this is set to
        ['de', 'en'] it will first try to fetch the german transcript (de) and then fetch the english transcript (en) if
        it fails to do so.
        :return: the found Transcript
        )Ú_find_transcriptrt   ru   ©r;   rˆ   r.   r.   r/   Úfind_transcript  s   
þzTranscriptList.find_transcriptc                 C   ó   |   || jg¡S )a„  
        Finds an automatically generated transcript for a given language code.

        :param language_codes: A list of language codes in a descending priority. For example, if this is set to
        ['de', 'en'] it will first try to fetch the german transcript (de) and then fetch the english transcript (en) if
        it fails to do so.
        :return: the found Transcript
        )r‰   ru   rŠ   r.   r.   r/   Úfind_generated_transcript  s   	z(TranscriptList.find_generated_transcriptc                 C   rŒ   )a|  
        Finds a manually created transcript for a given language code.

        :param language_codes: A list of language codes in a descending priority. For example, if this is set to
        ['de', 'en'] it will first try to fetch the german transcript (de) and then fetch the english transcript (en) if
        it fails to do so.
        :return: the found Transcript
        )r‰   rt   rŠ   r.   r.   r/   Ú find_manually_created_transcript  s   ÿz/TranscriptList.find_manually_created_transcriptÚtranscript_dictsc                 C   s:   |D ]}|D ]}||v r||     S qqt | j|| ƒ‚r8   )r   r2   )r;   rˆ   r�   r4   r…   r.   r.   r/   r‰   ,  s   ÿÿzTranscriptList._find_transcriptc                 C   sR   dj | j|  dd„ | j ¡ D ƒ¡|  dd„ | j ¡ D ƒ¡|  dd„ | jD ƒ¡d�S )Na  For this video ({video_id}) transcripts are available in the following languages:

(MANUALLY CREATED)
{available_manually_created_transcript_languages}

(GENERATED)
{available_generated_transcripts}

(TRANSLATION LANGUAGES)
{available_translation_languages}c                 s   ó   � | ]}t |ƒV  qd S r8   ©r+   ©rB   Ú
transcriptr.   r.   r/   Ú	<genexpr>C  s
   € ÿ
ÿz)TranscriptList.__str__.<locals>.<genexpr>c                 s   r�   r8   r‘   r’   r.   r.   r/   r”   G  s   € 
ÿc                 s   s"   � | ]}d j |j|jd�V  qdS )z{language_code} ("{language}")r{   N)rk   r3   r4   r]   r.   r.   r/   r”   J  s   € üþ
ÿ)r2   Ú/available_manually_created_transcript_languagesÚavailable_generated_transcriptsÚavailable_translation_languages)rk   r2   Ú_get_language_descriptionrt   r‡   ru   rv   r:   r.   r.   r/   rm   8  s   
þ
ÿ
ûïzTranscriptList.__str__Útranscript_stringsc                 C   s    d  dd„ |D ƒ¡}|r|S dS )NÚ
c                 s   s   � | ]	}d j |d�V  qdS )z - {transcript})r“   N)rk   r’   r.   r.   r/   r”   T  s
   € 
ÿ
ÿz;TranscriptList._get_language_description.<locals>.<genexpr>ÚNone)Újoin)r;   r™   Údescriptionr.   r.   r/   r˜   S  s   
þz(TranscriptList._get_language_descriptionN)r(   r)   r*   rF   r+   r   rY   r   rI   rc   Ústaticmethodr   r†   r	   r<   r
   r‹   r�   rŽ   r‰   rm   r˜   r.   r.   r.   r/   rq   ´   sL    þ
ý
ü
ûÿÿÿþ-ÿ
þþý
ürq   c                   @   sÞ   e Zd Zdedee fdd„Zdedefdd„Z	d ded
e
defdd„Zdededefdd„Zdededefdd„Zdededdfdd„Zdededdfdd„Zdedefdd„Zdedefdd„Zdededefdd„ZdS )!ÚTranscriptListFetcherrZ   Úproxy_configc                 C   s   || _ || _d S r8   )r`   Ú_proxy_config)r;   rZ   r    r.   r.   r/   rc   \  s   
zTranscriptListFetcher.__init__r2   r6   c                 C   s   t  | j||  |¡¡S r8   )rq   r†   r`   Ú_fetch_captions_json)r;   r2   r.   r.   r/   rh   `  s
   ýzTranscriptListFetcher.fetchr   Ú
try_numberc              
   C   s–   z|   |¡}|  ||¡}|  ||¡}|  ||¡W S  tyJ } z&| jd u r'dn| jj}|d |k r@| j||d d�W  Y d }~S | | j¡‚d }~ww )Nr   r   )r£   )	Ú_fetch_video_htmlÚ_extract_innertube_api_keyÚ_fetch_innertube_dataÚ_extract_captions_jsonr   r¡   Úretries_when_blockedr¢   Úwith_proxy_config)r;   r2   r£   ÚhtmlÚapi_keyÚinnertube_dataÚ	exceptionÚretriesr.   r.   r/   r¢   g  s   

ÿý€øz*TranscriptListFetcher._fetch_captions_jsonrª   c                 C   sF   d}t  ||¡}|rt| ¡ ƒdkr| d¡S d|v rt|ƒ‚t|ƒ‚)Nz)"INNERTUBE_API_KEY":\s*"([a-zA-Z0-9_-]+)"r   zclass="g-recaptcha")ÚreÚsearchr@   ÚgroupsÚgroupr   r"   )r;   rª   r2   ÚpatternÚmatchr.   r.   r/   r¥   w  s   
z0TranscriptListFetcher._extract_innertube_api_keyr¬   c                 C   s@   |   | d¡|¡ | di ¡ d¡}|d u sd|vrt|ƒ‚|S )NÚplayabilityStatusÚcaptionsÚplayerCaptionsTracklistRendererr}   )Ú_assert_playabilityre   r   )r;   r¬   r2   rw   r.   r.   r/   r§   €  s   ÿz,TranscriptListFetcher._extract_captions_jsonÚplayability_status_dataNc                 C   sÚ   |  d¡}|tjjkri|d urk|  d¡}|tjjkr.|tjjkr$t|ƒ‚|tjjkr.t	|ƒ‚|tj
jkrL|tjjkrL| d¡sD| d¡rHt|ƒ‚t|ƒ‚|  di ¡  di ¡  di ¡  dg ¡}t||d	d
„ |D ƒƒ‚d S d S )NÚstatusÚreasonzhttp://zhttps://ÚerrorScreenÚplayerErrorMessageRendererÚ	subreasonry   c                 S   s   g | ]}|  d d¡‘qS )r%   ri   )re   )rB   Úrunr.   r.   r/   rD   ¥  s    z=TranscriptListFetcher._assert_playability.<locals>.<listcomp>)re   rK   rL   ÚvaluerN   rP   rQ   r   rR   r    rM   rS   Ú
startswithr   r   r!   )r;   r¹   r2   Úplayability_statusr»   Ú
subreasonsr.   r.   r/   r¸   ‹  s0   


üÿêz)TranscriptListFetcher._assert_playabilityc                 C   s>   t  d|¡}|d u rt|ƒ‚| jjjdd| d¡ dd� d S )Nzname="v" value="(.*?)"ÚCONSENTzYES+r   z.youtube.com)Údomain)r¯   r°   r   r`   ÚcookiesÚsetr²   )r;   rª   r2   r´   r.   r.   r/   Ú_create_consent_cookie¨  s   
ÿz,TranscriptListFetcher._create_consent_cookiec                 C   s<   |   |¡}d|v r|  ||¡ |   |¡}d|v rt|ƒ‚|S )Nz&action="https://consent.youtube.com/s")Ú_fetch_htmlrÈ   r   )r;   r2   rª   r.   r.   r/   r¤   °  s   

z'TranscriptListFetcher._fetch_video_htmlc                 C   s$   | j  tj|d�¡}tt||ƒjƒS )N)r2   )r`   re   r   rk   r   rX   r%   )r;   r2   rT   r.   r.   r/   rÉ   ¹  s   z!TranscriptListFetcher._fetch_htmlr«   c                 C   s0   | j jtj|d�t|dœd�}t||ƒ ¡ }|S )N)r«   )ÚcontextÚvideoId)Újson)r`   Úpostr   rk   r   rX   rÌ   )r;   r2   r«   rT   Údatar.   r.   r/   r¦   ½  s   
þþz+TranscriptListFetcher._fetch_innertube_data)r   )r(   r)   r*   r   r   r   rc   r+   rq   rh   rH   r   r¢   r¥   r§   r¸   rÈ   r¤   rÉ   r¦   r.   r.   r.   r/   rŸ   [  s    		rŸ   c                   @   sP   e Zd Zg d¢Zddefdd„Zdedee fdd„Zd	ede	e
 fd
d„ZdS )rf   )
ÚstrongÚemÚbÚiÚmarkÚsmallÚdelÚinsÚsubÚsupFrd   c                 C   s   |   |¡| _d S r8   )Ú_get_html_regexÚ_html_regex)r;   rd   r.   r.   r/   rc   ×  s   z_TranscriptParser.__init__r6   c                 C   s@   |rd  | j¡}d| d }t |tj¡}|S t dtj¡}|S )Nú|z<\/?(?!\/?(z
)\b).*?\b>z<[^>]*>)rœ   Ú_FORMATTING_TAGSr¯   ÚcompileÚ
IGNORECASE)r;   rd   Úformats_regexÚ
html_regexr.   r.   r/   rÙ   Ú  s   ÿz!_TranscriptParser._get_html_regexÚraw_datac                    s   ‡ fdd„t  |¡D ƒS )Nc              
      sN   g | ]#}|j d urtt ˆ jdt|j ƒ¡t|jd ƒt|j dd¡ƒd�‘qS )Nri   r&   Údurz0.0)r%   r&   r'   )	r%   r$   r¯   r×   rÚ   r   r-   Úattribre   )rB   Úxml_elementr:   r.   r/   rD   ä  s    
úýz+_TranscriptParser.parse.<locals>.<listcomp>)r   Ú
fromstring)r;   rá   r.   r:   r/   rg   ã  s   
úz_TranscriptParser.parseNro   )r(   r)   r*   rÜ   rG   rc   r   r+   rÙ   r   r$   rg   r.   r.   r.   r/   rf   É  s
    	rf   )7Údataclassesr   r   Úenumr   Ú	itertoolsr   rª   r   Útypingr   r   r	   r
   r   r   Ú
defusedxmlr   r¯   Úrequestsr   r   r   Úproxiesr   Ú	_settingsr   r   r   Ú_errorsr   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r0   rI   r+   rK   rP   rX   rY   rq   rŸ   rf   r.   r.   r.   r/   Ú<module>   s2     @
M (n