
    V|hF                        S SK r SSKJr  SSKJrJrJrJrJrJ	r	J
r
JrJrJr  SSKJrJr   " S S\5      r " S	 S
\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      rg)    N   )InfoExtractor   )
UnsupportedErrorbool_or_nonedetermine_extint_or_none
js_to_jsonparse_qsstr_or_nonetry_getunified_timestampurl_or_none)subs_list_to_dicttraverse_objc                   L    \ rS rSrS
S jrSS jrS
S jrS
S jrS rS
S jr	S	r
g)RutubeBaseIE   Nc                 L    U(       d  0 nSUS'   U R                  SU S3USSUS9$ )Njsonformatzhttps://rutube.ru/api/video//zDownloading video JSONzUnable to download video JSONquery)_download_jsonselfvideo_idr   s      Q/home/james-whalen/.local/lib/python3.13/site-packages/yt_dlp/extractor/rutube.py_download_api_infoRutubeBaseIE._download_api_info   sB    E h""*8*A6.+5 # : 	:    c                    U(       a  US   OUR                  S5      nUR                  S5      nUb	  USL a  SOSn[        US 5      n[        US 5      nUR                  S5      n[        UR                  S	5      5      n	U(       a  UR                  S
5      =(       d    UOUS
   UUUR                  S5      U	[        US 5      U(       a  [        U5      OS [	        UR                  S5      5      U(       a  U/OS U[        UR                  S5      5      [        UR                  S5      5      [        UR                  S5      5      U R                  X5      S.$ )Ntitleis_adultT   r   c                     U S   S   $ )Nauthorid xs    r   <lambda>,RutubeBaseIE._extract_info.<locals>.<lambda>'   s    q{4/@r"   c                     U S   S   $ )Ncategorynamer*   r+   s    r   r-   r.   (   s    AjM&,Ar"   descriptiondurationr)   thumbnail_urlc                     U S   S   $ )Nr(   r1   r*   r+   s    r   r-   r.   2   s    8V1Dr"   
created_tshitscomments_countis_livestream)r)   r$   r2   	thumbnailr3   uploaderuploader_id	timestamp
categories	age_limit
view_countcomment_countis_livechapters)getr   r	   strr   r   "_extract_chapters_from_description)
r   videor   require_titler$   r?   r<   r0   r2   r3   s
             r   _extract_infoRutubeBaseIE._extract_info    s%   "/gUYYw5GIIj)	 '4/QIe%@A5"ABii.uyy45 2:%))D/-XuT{&?3 'DE/:3{+*599\+BC(08*d"%eii&78(3C)DE#EIIo$>???V
 	
r"   c                 @    U R                  U R                  XS9U5      $ Nr   )rI   r    r   s      r   _download_and_extract_info'RutubeBaseIE._download_and_extract_info=   s*    !!##H#:HF 	Fr"   c           	      j    U(       d  0 nSUS'   U R                  SU S3USSU R                  5       US9$ )Nr   r   z#https://rutube.ru/api/play/options/r   zDownloading options JSONzUnable to download options JSON)headersr   )r   geo_verification_headersr   s      r   _download_api_options"RutubeBaseIE._download_api_optionsA   sP    E h""1(1=0-1135	 # B 	Br"   c                 \   / n0 nUS   R                  5        H  u  pV[        U5      nUS:X  a6  U R                  XbSUSS9u  pUR                  U5        U R	                  XS9  ML  US:X  a"  UR                  U R                  XbUSS95        Mt  UR                  UUS	.5        M     [        US
SSS[        145       H7  n
U R                  XSSSS9u  pUR                  U5        U R	                  XS9  M9     U R	                  [        USSSSS[        14S.[        [        SS9145      US9  X44$ )Nvideo_balancerm3u8mp4F)m3u8_idfatal)targetf4m)f4m_idrY   )url	format_idlive_streamshls.r]   )rY   rX   captionscodefile	langTitle)r)   r]   r1   ru)lang)itemsr   #_extract_m3u8_formats_and_subtitlesextend_merge_subtitles_extract_f4m_formatsappendr   r   rE   allr   )r   optionsr   formats	subtitlesr^   
format_urlextfmtssubshls_urls              r   _extract_formats_and_subtitles+RutubeBaseIE._extract_formats_and_subtitlesK   s   	%,-=%>%D%D%F!I
+Cf}!EE%% F Q
t$%%d%=t88%  9  I J %!*   &G $GneS%R]Q^-_`GAA5u B FJDNN4 !!$!9	 a
 	l7Z 3%(G
 "-.	50 1 :C	 	 	D
 !!r"   c                 @    U R                  U R                  XS9U5      $ rL   )rv   rR   r   s      r   +_download_and_extract_formats_and_subtitles8RutubeBaseIE._download_and_extract_formats_and_subtitlesi   s*    22&&x&=xI 	Ir"   r*   N)NT)__name__
__module____qualname____firstlineno__r    rI   rM   rR   rv   ry   __static_attributes__r*   r"   r   r   r      s#    :
:FB"<Ir"   r   c                   r   \ rS rSrSrSrSrS/rSSSS	S
SSSSSS\SS// S.SS0S.SSS.SSS.SSS.SSS.SSSSS S!S"S#S$S%S\S&S'// S.SS0S.S(S)SS*S+/S,SS-SS.S/\S0S1S2S3.SS0S.S4S5SS6/S7SS8SS9S:\S;\	S<S=.S>S?.S@SASSS7SB/ SCSDSESFS\SGSH/SI.SS0S.SJSS.SKSS./r
SLSMSSNSSO// SPSQSSRSSSTSU\SV.SS0S./rSW rSXrgY)ZRutubeIEn   rutubezRutube videoszXhttps?://rutube\.ru/(?:(?:live/)?video(?:/private)?|(?:play/)?embed)/(?P<id>[\da-z]{32})zZ<iframe[^>]+?src=(["\'])(?P<url>(?:https?:)?//rutube\.ru/(?:play/)?embed/[\da-z]{32}.*?)\1z9https://rutube.ru/video/3eac3b4561676c17df9132a9a1e62e3e/ 3eac3b4561676c17df9132a9a1e62e3erW   u>   Раненный кенгуру забежал в аптекуzhttp://www.ntdtv.ru Q   
NTDRussian29790i2^R20131016r   5re:https?://pic\.rutubelist\.ru/video/.+\.(?:jpg|png)u   Новости и СМИ)r)   rr   r$   r2   r3   r;   r<   r=   upload_dater?   r@   r:   r>   rC   skip_downloadrV   r]   	info_dictparamsz=https://rutube.ru/play/embed/a10e53b86e8f349080f718582ce4c661Tr]   only_matchingz8https://rutube.ru/embed/a10e53b86e8f349080f718582ce4c661zDhttps://rutube.ru/video/3eac3b4561676c17df9132a9a1e62e3e/?pl_id=4252zHhttps://rutube.ru/video/10b3a03fc01d5bbcc632a2f3514e8aab/?pl_type=sourcezZhttps://rutube.ru/video/private/884fb55f07a97ab673c7d654553e0f48/?p=x2QojCumHTS3rsKHWXN8Lg 884fb55f07a97ab673c7d654553e0f48u   Яцуноками, Nioh2uE   Nioh2: финал сражения с боссом Яцуноками   mexus24222106i	c20221210zJhttps://pic.rutubelist.ru/video/f2/d4/f2d42b54be0a6e69c1c22539e3152156.jpgu   Видеоигрыz9https://rutube.ru/video/c65b465ad0c98c89f3b25cb03dcc87c6/ c65b465ad0c98c89f3b25cb03dcc87c6zcount:4u6   Бизнес и предпринимательствоz$md5:252feac1305257d8c1bab215cedde75di  23491359i1Tc20230223u   Бизнес с нуля: найм сотрудников. Интервью с директором строительной компании #1u   Стас Быков)r)   rr   rC   r>   r2   r:   r3   r?   r<   r=   r@   r   r$   r;   z>https://rutube.ru/live/video/c58f502c7bb34a8fcdd976b221fca292/ c58f502c7bb34a8fcdd976b221fca292u   Телепередачи rB   23460655i]b20220519u   Первый канал)r)   rr   r>   r2   r:   live_statusr?   r<   r=   r@   r   r$   r;   zInvalid URL)r]   r   skipz>https://rutube.ru/play/embed/03a9cb54bac3376af4c5cb0f18444e01/ 03a9cb54bac3376af4c5cb0f18444e01uY   Церемония начала торгов акциями ПАО «ЕвроТранс»20240829i%  u&   MOEX - Московская биржаiĘf38420507u   Интервью)r)   rr   r?   r2   r$   rC   r   r3   r;   r=   r:   r@   r<   r>   z9https://rutube.ru/video/5ab908fccfac5bb43ef2b1e4182256b0/zFhttps://rutube.ru/live/video/private/c58f502c7bb34a8fcdd976b221fca292/z%https://novate.ru/blogs/170625/73644/ b0c96c75a4e5b274721bbced6ed8fb64u   Где в России находится единственная в своем роде скальная торпедная батареяu
   Наукаz$md5:2ed82e6b81958a43da6fb4d56f949e1f   iNh20250615Novate24044809)r)   rr   r$   r?   r>   rC   r2   r3   r:   r=   r   r;   r<   r@   c                     U R                  U5      n[        U5      nU R                  X#5      nU R                  X#5      u  pV0 UEUUS.E$ )N)ro   rp   )	_match_idr   rM   ry   )r   r]   r   r   inforo   rp   s          r   _real_extractRutubeIE._real_extract   sY    >>#&..x?!MMh^

"
 	
r"   r*   N)r|   r}   r~   r   IE_NAMEIE_DESC
_VALID_URL_EMBED_REGEXintrE   _TESTS_WEBPAGE_TESTSr   r   r*   r"   r   r   r   n   s)   GGlJqrL K4U1$"#%Q56
  #F+%( O J V Z l40b%#%e/0
  #F+%( K4!STAQ%#% h-
  #F+%( P456Q$%#%1
 #& P4p%@#Q%-.
  #F+%( K X[pFd 74 d'.AQ#% %
  #F+% N*	
r"   r   c                   h    \ rS rSrSrSrSrSSSSS	S
SSSS/ S\SS/S.SS0S.SSS.SSS./rS r	Sr
g)RutubeEmbedIEi  zrutube:embedzRutube embedded videoszBhttps?://rutube\.ru/(?:video|play)/embed/(?P<id>[0-9]+)(?:[?#/]|$)z;https://rutube.ru/video/embed/6722881?vk_puid37=&vk_puid38= a10e53b86e8f349080f718582ce4c661rW   i6R20131223297833zsubziro89 ILyaud   Мистический городок Эйри в Индиан 5 серия озвучка subziro89r   is  z$md5:a5acea57bbc3ccdc3cacd1f11a014b5br   u   Сериалы)r)   rr   r=   r   r<   r;   r$   r?   r3   rC   r2   r@   r:   r>   r   rV   r   z$https://rutube.ru/play/embed/8083783Tr   z>https://rutube.ru/play/embed/10631925?p=IbAigKqWd1do4mjaM5XLIQc                     U R                  U5      n[        U5      nU R                  X#5      nUS   nU R                  XE5      u  pgU R	                  XS5      nUR                  SUUS.5        U$ )Neffective_videoRutube)extractor_keyro   rp   )r   r   rR   rv   rM   update)	r   r]   embed_idr   rn   r   ro   rp   r   s	            r   r   RutubeEmbedIE._real_extract'  sz    >>#& ,,X=,-!@@S..x?%"
 	
 r"   r*   N)r|   r}   r~   r   r   r   r   r   r   r   r   r*   r"   r   r   r     s    G&GVJ M4#%#({AQ+,
  #F+%( 6
 P-F8r"   r   c                   ,    \ rS rSrS rS rS rS rSrg)RutubePlaylistBaseIEi8  c                 "    U R                   X!4-  $ r{   )_PAGE_TEMPLATE)r   page_numplaylist_idargskwargss        r   _next_page_url#RutubePlaylistBaseIE._next_page_url9  s    ""k%<<<r"   c              /   <  #    S n[         R                  " S5       H  nU R                  U=(       d    U R                  " XQ/UQ70 UD6USU 35      nUR	                  S5      nU(       a  [        U[        5      (       d    g U Ha  n[        UR	                  S5      5      n	U	(       d  M&  U R                  USS9n
U
R                  SU	[        R                  5       S.5        U
v   Mc     UR	                  S	5      nU(       a  UR	                  S
5      (       a  M    g    g 7f)Nr   zDownloading page results	video_urlF)rH   r]   )_typer]   ie_keynexthas_next)	itertoolscountr   r   rD   
isinstancelistr   rI   r   r   r   )r   r   r   r   next_page_urlpagenumpager   resultr   entrys              r   _entriesRutubePlaylistBaseIE._entries<  s     q)G&& ;!4!4";+/";39";0	:<D
 hhy)G*Wd";";!'

;(?@	 **6*G"$&oo/ 
  " !HHV,M (<(<1 *s   DDDc                 l    U R                  U R                  " U/UQ70 UD6XR                  S5      5      $ )Nplaylist_name)playlist_resultr   rD   )r   r   r   r   s       r   _extract_playlist&RutubePlaylistBaseIE._extract_playlistX  s7    ##MM+777O46 	6r"   c                 B    U R                  U R                  U5      5      $ r{   )r   r   )r   r]   s     r   r   "RutubePlaylistBaseIE._real_extract]  s    %%dnnS&9::r"   r*   N)	r|   r}   r~   r   r   r   r   r   r   r*   r"   r   r   r   8  s    =86
;r"   r   c                   6    \ rS rSrSrSrSrSSS0SS	./rS
rSr	g)RutubeTagsIEia  zrutube:tagszRutube tagsz*https?://rutube\.ru/tags/video/(?P<id>\d+)z"https://rutube.ru/tags/video/1800/r)   1800D   r]   r   playlist_mincountz8https://rutube.ru/api/tags/video/%s/?page=%s&format=jsonr*   N
r|   r}   r~   r   r   r   r   r   r   r   r*   r"   r   r   r   a  s7    GG>J3&
   F PNr"   r   c                   .    \ rS rSrSrSrSrSrSrS r	Sr
g	)
RutubeMovieIEip  zrutube:moviezRutube moviesz+https?://rutube\.ru/metainfo/tv/(?P<id>\d+)z1https://rutube.ru/api/metainfo/tv/%s/?format=jsonz>https://rutube.ru/api/metainfo/tv/%s/video?page=%s&format=jsonc                     U R                  U5      nU R                  U R                  U-  US5      nU R                  X#R	                  S5      S9$ )NzDownloading movie JSONr1   )r   )r   r   _MOVIE_TEMPLATEr   rD   )r   r]   movie_idmovies       r   r   RutubeMovieIE._real_extractx  sY    >>#&##  8+X$& %%IIf$5 & 7 	7r"   r*   N)r|   r}   r~   r   r   r   r   r   r   r   r   r*   r"   r   r   r   p  s     GG?JIOUN7r"   r   c                   6    \ rS rSrSrSrSrSSS0SS	./rS
rSr	g)RutubePersonIEi  zrutube:personzRutube person videosz,https?://rutube\.ru/video/person/(?P<id>\d+)z&https://rutube.ru/video/person/313878/r)   313878$   r   z:https://rutube.ru/api/video/person/%s/?page=%s&format=jsonr*   Nr   r*   r"   r   r   r     s7    G$G@J7(
   F RNr"   r   c                   6    \ rS rSrSrSrSrSSS0SS	./rS
rSr	g)RutubePlaylistIEi  zrutube:playlistzRutube playlistsz$https?://rutube\.ru/plst/(?P<id>\d+)zhttps://rutube.ru/plst/308547/r)   308547r   r   zChttps://rutube.ru/api/playlist/custom/%s/videos?page=%s&format=jsonr*   Nr   r*   r"   r   r   r     s7    G G8J/(
   F [Nr"   r   c                   l    \ rS rSrSrSrSrSSS0SS	.S
SS0SS	.SSS0SS	.SSS0SS	./rSrS r	S r
Srg)RutubeChannelIEi  zrutube:channelzRutube channelzehttps?://rutube\.ru/(?:channel/(?P<id>\d+)|u/(?P<slug>\w+))(?:/(?P<section>videos|shorts|playlists))?z(https://rutube.ru/channel/639184/videos/r)   639184_videos   r   z*https://rutube.ru/channel/25902603/shorts/25902603_shortsi  z#https://rutube.ru/channel/25902603/25902603i  z"https://rutube.ru/u/rutube/videos/23704195_videosq   zJhttps://rutube.ru/api/video/person/%s/?page=%s&format=json&origin__type=%sc                 N    SSSS.R                  U5      nU R                  X!U4-  $ )Nzrtb,rst,ifrm,rsparshortsr   )videosshortsN)rD   r   )r   r   r   sectionorigin_types        r   r   RutubeChannelIE._next_page_url  s8    )
 #g,	 	
 ""k[%IIIr"   c                 V   U R                  U5      R                  SSS5      u  p#nUS:X  a  [        U5      eU(       aK  U R                  X5      nU R	                  SUSU[
        S9n[        USS	S
 SS[        1[        1[        45      nU R                  X$S9nU(       a
  U SU 3US'   U$ )Nr)   slugr  	playlistszwindow\.reduxState\s*=zredux state)transform_sourceapiqueriesc                 $    U R                  S5      $ )NchannelIdBySlug)
startswith)k_s     r   r-   /RutubeChannelIE._real_extract.<locals>.<lambda>  s    q||<M/Nr"   data
channel_id)r  r  )_match_valid_urlgroupr   _download_webpage_search_jsonr
   r   r   r   anyr   )r   r]   r   r  r  webpageredux_stateplaylists           r   r   RutubeChannelIE._real_extract  s    %)%:%:3%?%E%EdFT]%^"7k!"3'',,S7G++)7M4Zd , fK&{y"Nsek]C5A BK ))+)G +}AgY7HTNr"   r*   N)r|   r}   r~   r   r   r   r   r   r   r   r   r   r*   r"   r   r   r     s    GGyJ9/
 ! <#
 ! 5*
 ! 4#
 !%F4 bNJr"   r   )r   commonr   utilsr   r   r   r	   r
   r   r   r   r   r   utils.traversalr   r   r   r   r   r   r   r   r   r   r   r*   r"   r   <module>r!     s     !  UI= UIpU
| U
p/L /d&;< &;RP' P7( 7"R) R[+ [6* 6r"   