
    V|hS                         S SK r S SKrSSKJr  SSKJr  SSKJ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  S
r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      rg)    N   )Art19IE)InfoExtractor   )PATCHRequest)	HTTPError)
ExtractorErrorint_or_nonemake_archive_idparse_iso8601smuggle_urltry_callunsmuggle_urlupdate_url_queryurl_or_noneurljoin)traverse_objzEhttps?://(?:www\.|beta\.)?(?:watchnebula\.com|nebula\.app|nebula\.tv)c                   D    \ rS rSrSrS=rrS rS rS r	S r
S rS	 rS
rg)NebulaBaseIE   watchnebulaNc                     U R                  SS SS[        R                  " XS.5      R                  5       SS0S9n[        US[        145      U l        U R                  (       d  [	        S5      eg ! [         aI  n[        UR                  [        5      (       a$  UR                  R                  S:X  a
  [	        S	S
S9ee S nAff = f)Nzhttps://nebula.tv/auth/login/zLogging in to NebulazLogin failed)emailpasswordcontent-typeapplication/json)dataheadersi  z*Login failed: Invalid username or passwordT)expectedkeyzLogin failed: No token)_download_jsonjsondumpsencoder	   
isinstancecauser   statusr   str
_api_token)selfusernamer   responsees        Q/home/james-whalen/.local/lib/python3.13/site-packages/yt_dlp/extractor/nebula.py_perform_loginNebulaBaseIE._perform_login   s    		**/&ZZ( IJQQS');<	 + >H 'x%#@ !9::   	!''9--!''..C2G$%Q\`aa	s   :A1 1
C;AB??Cc                 *   U R                   (       a"  SU R                    3UR                  S0 5      S'    U R                  " U0 UD6$ ! [         a  n[	        UR
                  [        5      (       a  UR
                  R                  S;  a  e U R                  SUR
                  R                   35        U R                  5         U R                   (       a"  SU R                    3UR                  S0 5      S'   U R                  " U0 UD6s S nA$ S nAff = f)NzBearer r   Authorization)    zPReauthorizing with Nebula and retrying, because last API call resulted in error )
_token
setdefaultr!   r	   r%   r&   r   r'   	to_screen_real_initialize)r*   argskwargsr-   s       r.   	_call_apiNebulaBaseIE._call_api,   s    ;;BI$++@WFi,_=
	8&&777 	8aggy11QWW^^:5UNNbcdcjcjcqcqbrsu!!#{{FMdkk]D[!!)R0A&&777	8s   A 
DB6DDDc                    ^  T R                   (       d  [        U 4S j5      T l         T R                  SS T R                   (       a  SST R                    30OS SSS9S   T l        g )	Nc                  @   > T R                  S5      S   R                  $ )Nzhttps://nebula.tvznebula_auth.apiToken)_get_cookiesvaluer*   s   r.   <lambda>/NebulaBaseIE._real_initialize.<locals>.<lambda>>   s    ))*=>?UV\\    z2https://users.api.nebula.app/api/v1/authorization/r2   zToken zAuthorizing to NebularD   )r   noter   token)r)   r   r!   r5   rA   s   `r.   r8   NebulaBaseIE._real_initialize;   sb    &\^DO))@$EI___t.?&@AZ^(s * 4 5<=rD   c           
      @   S H?  n U R                  SUR                  S5      S    SU S3USU R                  SS	S
.S9u  pE  O   U R                  X5        WWS.$ ! [         a  n[	        UR
                  [        5      (       a*  UR
                  R                  S:X  a  U R                  5         U(       da  [	        UR
                  [        5      (       aB  UR
                  R                  S:X  a(  U R                  S5        U R                  5          S nAGM  e S nAff = f)N)FThttps://content.api.nebula.app/:r   s/z/manifest.m3u8mp4z23.10.0ios)rF   app_versionplatform)queryr3   r4   zPReauthorizing with Nebula and retrying, because fetching video resulted in error)formats	subtitles)#_extract_m3u8_formats_and_subtitlessplitr5   r	   r%   r&   r   r'   raise_login_requiredr7   r8   mark_watched)r*   
content_idslugretryfmtssubsr-   s          r.   _extract_formatsNebulaBaseIE._extract_formatsD   s   "E!EE5j6F6Fs6KA6N5OrR\Q]]kl%!%'0$)( F 
  #& 	*+d33 " aggy11aggnn6K--/AGGY!?!?AGGNNVYDYNN#uv))+s   ;A
D&B*DDDc                     [        US[        S5      14SS9nSUS   R                  S5      S   0[        USS	S
S[        14S[        14SSSSSSSSS[
        14S[        14SS 14S.5      EUUS.E$ )N)channel_slug
class_slughttps://nebula.tv/F)get_allidrJ   r   rX   titledescriptionpublished_atdurationr_   channel_titleimages	thumbnailsrcorderzype_idc                 T    U (       a   [        [        U 5      [        [        U 5      /$ S $ )N)r   NebulaIENebulaSubscriptionsIE)xs    r.   rB   6NebulaBaseIE._extract_video_metadata.<locals>.<lambda>o   s.    `aOHa0/BWYZ2[<] <lgk<lrD   )
display_idrd   re   	timestamprg   
channel_iduploader_idchanneluploaderseriescreatorrj   episode_number_old_archive_ids)channel_urluploader_url)r   r   	partitionr   r
   r   )r*   episoder}   s      r.   _extract_video_metadata$NebulaBaseIE._extract_video_metadata[   s    "4w?S7T6UV`eg '$-))#.q1
7$ ,,}o>'+7,-*+)*&U[MJ#*[M":%. 2l 1m %n% 
( ''+
 	
rD   c                     U R                  [        SUR                  S5      S    SU S35      USSS[        R                  " S	S
05      R                  5       SS0S9  g )NrI   rJ   r   rK   z
/progress/zMarking watchedzUnable to mark watchedF	completedTr   r   )fatalr   r   )r;   r   rT   r"   r#   r$   )r*   rW   rX   s      r.   _mark_watchedNebulaBaseIE._mark_watchedv   so    ::;K;KC;PQR;S:TTVWaVbblmn#%=U[$/0779#%78	 	 	:rD   )r)   r5   )__name__
__module____qualname____firstlineno___NETRC_MACHINEr5   r)   r/   r;   r8   r\   r   r   __static_attributes__ rD   r.   r   r      s/    "NFZ;8=4.
6:rD   r   c            	       @   \ rS rSrSr\ S3r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S_SS_S S!_S"S#S$/0ES%S&0S'.S(S)0 SS*_SS_S	S+_SS,_SS-_SS._SS/_SS0_SS/_SS0_SS/_SS1_SS/_SS2_SS3_SS3_S S!_S"S4S5/0ES%S&0S6.S7S80 SS9_SS_S	S:_SS;_SS<_SS=_SS>_SS?_SS>_SS?_SS@_SSA_SS@_SS>_SSB_S S!_SS>_S"SCSD/0ES%S&0S6.SESFSG.SH0 SSI_SS_SSJ_S	SK_SSL_SSM_SSN_SSO_SSP_SSO_SSP_SSQ_SSR_SSQ_SSO_S S!_SSO_S"SSST/0ES%S&0S'.SUSFSG./rSV rSWr	gX)Yro   ~   znebula:videoz/videos/(?P<id>[\w-]+)zEhttps://nebula.tv/videos/that-time-disney-remade-beauty-and-the-beastrc   z$84ed544d-4afd-4723-8cd5-2b95261f0abfextrL   rd   z,That Time Disney Remade Beauty and the Beastre   z$md5:2aae3c4cfc5ee09a1ecdff0909618cf4upload_date20180731rt   i_[rw   Lindsay Ellisru   lindsayellisrx   rv   r~   z(re:https://nebula\.(tv|app)/lindsayellisry   rs   z,that-time-disney-remade-beauty-and-the-beastr}   rz   rg   i  rj   z&re:https://\w+\.cloudfront\.net/[\w-]+r|   znebula 5c271b40b13fd613090034fdz,nebulasubscriptions 5c271b40b13fd613090034fdskip_downloadm3u8url	info_dictparamszWhttps://nebula.tv/videos/the-logistics-of-d-day-landing-craft-how-the-allies-got-ashore d05739cf6c38c09322422f696b569c23z$7e623145-1b44-4ca3-aa0b-ed25a247ea34z)Landing Craft - How The Allies Got AshorezMre:^In this episode we explore the unsung heroes of D-Day, the landing craft.20200327i,~~^u+   Real Engineering — The Logistics of D-Dayzd-dayz>the-logistics-of-d-day-landing-craft-how-the-allies-got-ashoreiI  zhttps://nebula.tv/d-dayznebula 5e7e78171aaf320001fbd6bez,nebulasubscriptions 5e7e78171aaf320001fbd6be)r   md5r   r   z1https://nebula.tv/videos/money-episode-1-the-draw ebe28a7ad822b9ee172387d860487868z$b96c5714-9e2b-4ec3-b3f1-20f6e89cc553zEpisode 1: The DrawuO   contains:There’s free money on offer… if the players can all work together.20200323ix^Tom Scott Presents: Moneytom-scott-presents-money*https://nebula.tv/tom-scott-presents-moneyi9  zmoney-episode-1-the-drawznebula 5e779ebdd157bc0001d1c75az,nebulasubscriptions 5e779ebdd157bc0001d1c75az7https://watchnebula.com/videos/money-episode-1-the-drawT)r   only_matchingzVhttps://nebula.tv/videos/tldrnewseu-did-the-us-really-blow-up-the-nordstream-pipelinesz$e389af9d-1dab-44f2-8788-ee24deb7ff0dz=tldrnewseu-did-the-us-really-blow-up-the-nordstream-pipelinesz3Did the US Really Blow Up the NordStream Pipelines?z$md5:b4e2a14e3ff08f546a3209c75261e78920230223i0czTLDR News EU
tldrnewseuz&re:https://nebula\.(tv|app)/tldrnewseui  znebula 63f64c74366fcd00017c1513z,nebulasubscriptions 63f64c74366fcd00017c1513z6https://beta.nebula.tv/videos/money-episode-1-the-drawc                     U R                  U5      n[        U0 5      u  pUR                  S5      (       a  US   USS.U R                  US   U5      E$ U R	                  SU 3USS9n0 U R                  U5      EU R                  US   U5      E$ )Nrc    rc   rs   rd   z.https://content.api.nebula.app/content/videos/zFetching video metadatarE   )	_match_idr   getr\   r;   r   )r*   r   rX   smuggled_datametadatas        r.   _real_extractNebulaIE._real_extract   s    ~~c"*33T""#D)" ''d(;TB	  >><TFC0 " 2
**84
##HTND9
 	
rD   r   N
r   r   r   r   IE_NAME_BASE_URL_RE
_VALID_URL_TESTSr   r   r   rD   r.   ro   ro   ~   s<   G!N"89JV
8
5
 C
 A	

 :
 
 
 .
 
 >
 G
 o
 H
 F
 
  !
" B#
$ !BDr s%
( #F+-0 i1
8
5
 @
 k	

 :
 
 D
 '
 E
 7
 C
 Z
 D
 
 4
  5!
" B#
$ !BDr s%
( #F+/2 C1
8
5
 *
 m	

 :
 
 2
 4
 3
 5
 H
 
 G
 1
 4
  B!
" 2#
$ !BDr s%
( #F+/2 I h
8
5
 Y
 J	

 A
 :
 
 ~
 ,
 
 <
 E
 
 D
 n
  B!
" ~#
$ !BDr s%
( #F+-0 HCdFL
rD   ro   c                       \ rS rSrSr\ S3r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#0 S$S_S%S&_S'S(_S)S_S*S+_S,S-_S.S/_S0S&_S1S2_S3S4_S5S6_S7S8_S9S:_S;S<_S=S>_S?S@_SASB_S"./rSC rSDr	gE)FNebulaClassIE   znebula:mediazI/(?!(?:myshows|library|videos)/)(?P<id>[\w-]+)/(?P<ep>[\w-]+)/?(?:$|[?#])z1https://nebula.tv/copyright-for-fun-and-profit/14z$d7432cdc-c608-474d-942c-f74345daed7brL   14.https://nebula.tv/copyright-for-fun-and-profit   zIhttps://dj423fildxgac.cloudfront.net/d533718d-9307-42d4-8fb0-e283285e99c9i  z
Episode 14zPhotos, Sculpture, and Video)
rc   r   rs   r}   r{   rj   r~   rg   r   rd   r   r   r   zPhttps://nebula.tv/extremitiespodcast/pyramiden-the-high-arctic-soviet-ghost-townmp3z$018f65f0-0033-4021-8f87-2d132beb19aaz$md5:05d2b23ab780c955e2511a2b9127acffz$335e8159-d663-491a-888f-1732285706aci03P_Extremities2020090320200902z,Pyramiden: The High-Arctic Soviet Ghost TowniF0]z:re:^https?://content\.production\.cdn\.art19\.com.*\.jpeg$g,}:(@i(P_20191016)r   rc   re   	series_idmodified_timestamp
episode_idry   modified_dater   rd   release_timestamprj   rg   rt   release_date)r   r   z2https://nebula.tv/thelayover/the-layover-episode-1r   rc   z$9d74a762-00bb-45a8-9e8d-9ed47c04a1d0r{   r   rj   r   20230304r   20230403ry   zThe Layoverr   r   iF:+drg   g	t@r   icdrd   u   The Layover — Episode 1r   z$874303a5-4900-4626-a4b6-2aacac34466ar   20230303r   z	Episode 1rt   iydre   z$md5:002cca89258e3bc7c268d5b8c24ba482c                 @   U R                  U5      R                  SS5      u  p#[        U0 5      u  pUR                  S5      (       a  US   USS.U R	                  US   U5      E$ U R                  SU SU S3USS	9nUR                  S
5      nUS:X  a(  0 U R                  U5      EU R	                  US   U5      E$ US:X  a  US   nU(       d&  UR                  S5      (       a  U R                  5         U R                  US   U5        [        R                  " U5      (       a  U R                  U[        5      $ [        US[        14S[        14S[        14S[        14S[        14S[         14S[        14S[        14SS[        14S.	5      $ [#        SU< 35      e)Nrc   epr   r   'https://content.api.nebula.app/content///?include=lessonszFetching class/podcast metadatar   typelessonpodcast_episodeepisode_urlpremiumrd   re   rf   rg   ru   rh   assetsregular)	rc   r   rd   re   rt   rg   ru   chnanelrj   zUnexpected content type )_match_valid_urlgroupr   r   r\   r;   r   rU   rV   r   suitable
url_resultr   r(   r   r   r
   r	   )r*   r   rX   r   r   r   content_typer   s           r.   r   NebulaClassIE._real_extract7  s   --c288tD*33T""#D)" ''d(;TB	  >>5dV1WIEVW8 " :  ||F+8#..x8''=  .."=1K8<<	#:#:))+htnd3,,{G<<cUm%}5!C5) -u5,}o>'+7+cU3+cU3&	K=A
+ 
 
 77GHIIrD   r   Nr   r   rD   r.   r   r      ss   G!N"klJB8K dL#3
 #F+  b8A?",@#'%C!+V"#&
( D
5
8
 a
 V	

 J
 Z
 m
 @
 !*
 

  
 0
 ?
 :
 {
  !
" A#
E7Fr(JrD   r   c                   @    \ rS rSrSr\ S3rSSSS0S./rS	 rS
 r	Sr
g)rp   ib  znebula:subscriptionsz2/(?P<id>myshows|library/latest-videos)/?(?:$|[?#])zhttps://nebula.tv/myshowsr   rc   myshows)r   playlist_mincountr   c           
   #   ^  #    [        SSSSS.5      n[        R                  " S5       H  nU R                  USSU 3S	9nUS
    HE  nU R	                  U5      nU R
                  " [        SUS    3SUS   05      [        4SS0UD6v   MG     UR                  S5      nU(       a  M    g    g 7f)Nz.https://content.api.nebula.app/video_episodes/true
engagementz-published_at)	followingincludeorderingr   r   zRetrieving subscriptions page r   resultshttps://nebula.tv/videos/rs   rc   url_transparentTnext)	r   	itertoolscountr;   r   r   r   ro   r   )r*   next_urlpage_numrw   r   r   s         r.   _generate_playlist_entries0NebulaSubscriptionsIE._generate_playlist_entriesm  s     #$T#'W
 
 "*Hnn),J8**U % WG"9-77@ook/0F/GH74=)'+,4XFJXNVX X .
 {{6*H8 +s   B"B-(B-c                 B    U R                  U R                  5       S5      $ )Nr   )playlist_resultr   )r*   r   s     r.   r   #NebulaSubscriptionsIE._real_extract  s    ##D$C$C$EyQQrD   r   N)r   r   r   r   r   r   r   r   r   r   r   r   rD   r.   rp   rp   b  s;    $G!N"TUJ*)
 F$RrD   rp   c            	           \ rS rSrSr\ S3r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SSSS.SS./rS  rS! r	S" r
S# rS$rg%)&NebulaChannelIEi  znebula:channelz5/(?!myshows|library|videos)(?P<id>[\w-]+)/?(?:$|[?#])r   r   r   z@Tom Scott hosts a series all about trust, negotiation and money.)rc   rd   re      )r   r   playlist_countzhttps://nebula.tv/lindsayellisr   r   zCEnjoy these hottest of takes on Disney, Transformers, and Musicals.r   )r   r   r   zhttps://nebula.tv/johnnyharrisjohnnyharriszJohnny Harrisz/I make videos about maps and many other things.Z   r   zcopyright-for-fun-and-profitzCopyright for Fun and Profitz$md5:6690248223eed044a9f11cd5a24f9742   z$https://nebula.tv/trussissuespodcasttrussissuespodcastzThe TLDR News Podcastz$md5:a08c4483bc0b705881d3e0199e721385P   c           
   #   x  #    SU S3n[         R                  " S5       H  nU R                  X2SU 3S9nUS    H]  nU R                  U5      nU R                  " [        UR                  S5      =(       d    SUS	    3S
US
   05      [        4SS0UD6v   M_     UR                  S5      nU(       a  M    g    g 7f)Nz.https://content.api.nebula.app/video_channels/z'/video_episodes/?ordering=-published_atr   zRetrieving channel page r   r   	share_urlr   rs   rc   r   Tr   )r   r   r;   r   r   r   r   ro   )r*   collection_idcollection_slugr   r   episodesr   r   s           r.   r   *NebulaChannelIE._generate_playlist_entries  s     CM?Ryz!*H~~hH`ai`jFk~lH#I.77@ookKK,d2KHUaLbKc0d74=)'+,4XFJXNVX X /
  ||F+H8 +s   B/B:5B:c           
   #      #    US    Hc  nU R                  U5      nU R                  " [        UR                  S5      =(       d    SUS    SUS    3SUS   05      [        4SS	0UD6v   Me     g 7f)
Nlessonsr   ra   r`   r   rX   rc   r   T)r   r   r   r   r   )r*   rw   r   r   s       r.   _generate_class_entries'NebulaChannelIE._generate_class_entries  s     i(F33F;H//+

;'k-?@V?WWXYabhYiXj+kvd|$#&'4XFJXNVX X )s   A.A0c              #     #    SU S3n[         R                  " S5       Ha  nU R                  X2SU 3S9n[        USS 45       H  nU R	                  US   [
        5      v   M      UR                  S	5      nU(       a  Ma    g    g 7f)
Nz0https://content.api.nebula.app/podcast_channels/z6/podcast_episodes/?ordering=-published_at&premium=truer   zRetrieving podcast page r   r   c                     [        US   5      $ )Nr   )r   )_vs     r.   rB   ;NebulaChannelIE._generate_podcast_entries.<locals>.<lambda>  s    ;WXYdWeKfrD   r   r   )r   r   r;   r   r   r   r   )r*   r   r   r   r   r   r   s          r.   _generate_podcast_entries)NebulaChannelIE._generate_podcast_entries  s     Em_  UK  L!*H~~hH`ai`jFk~lH'9>f2ghoogk&:MJJ i||F+H8 +s   A:B Bc                 |   U R                  U5      nU R                  SU S3USS9nUR                  S5      S:X  a  U R                  U5      nO@UR                  S5      S:X  a  U R	                  US   U5      nOU R                  US   U5      nU R                  UUUR                  S	5      UR                  S
5      S9$ )Nr   r   zRetrieving channelr   r   classpodcast_channelrc   rd   re   )entriesplaylist_idplaylist_titleplaylist_description)r   r;   r   r  r  r   r   )r*   r   r   rw   r  s        r.   r   NebulaChannelIE._real_extract  s    ..-..5o5FFWX"6 ! 8 ;;v')227;G[[ $5544WT]OTG55gdm_UG##'";;w/!(]!;	 $ = 	=rD   r   N)r   r   r   r   r   r   r   r   r   r  r  r   r   r   rD   r.   r   r     s    G!N"WXJ;,0]

  0 $`

  0 $L

   @03A

  6&,A

  A(FTX	=rD   r   )r   r"   art19r   commonr   
networkingr   networking.exceptionsr   utilsr	   r
   r   r   r   r   r   r   r   r   utils.traversalr   r   r   ro   r   rp   r   r   rD   r.   <module>r     s|       ! % -   +Wb:= b:Jz
| z
zdJL dJNRL RB]=l ]=rD   