o
    i                     @   s   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	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 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dS )    N   )InfoExtractor   )ExtractorErrorISO639Utilsdetermine_extfilter_dictfloat_or_noneint_or_nonejoin_nonemptymake_archive_idparse_codecsparse_iso8601parse_qssmuggle_urlunified_timestampunsmuggle_urlurl_or_noneurljoinvariadic)requiretraverse_objc                   @   sp   e Zd ZdgZdZi Zdd ZdddZdd	 Zd
d Z	e
dd Zdd ZdddZdddZe
dd ZdS )	ZDFBaseIEDE)zdfz	api-tokenc                 C   s   | j s| j | jj| jdi i t| j dthfddtt k r;| j | 	dd dd | jj
g | j| j R   | j d  d	| j d
  S )Ndefaultexpiresr   r   z0https://zdf-prod-futura.zdf.de/mediathekV2/tokenzDownloading API tokenzFailed to download API tokentype token)_token_cacheupdatecacheload_TOKEN_CACHE_PARAMSr   r
   inttime_download_jsonstore)self r+   H/home/ubuntu/.local/lib/python3.10/site-packages/yt_dlp/extractor/zdf.py_get_api_token"   s   "
zZDFBaseIE._get_api_tokenNc                 C   s(   | j ||d| d| td|idS )NDownloading Failed to download Api-Auth)headers)r(   r   )r*   urlvideo_iditem	api_tokenr+   r+   r,   	_call_api1   s   
zZDFBaseIE._call_apic                 C   sB   |rt |ts	d S td|}|rt|dt|d S d S )Nz(?P<width>\d+):(?P<height>\d+)widthheight)
isinstancestrrematchr&   group)r*   aspect_ratiomobjr+   r+   r,   _parse_aspect_ratio6   s   $zZDFBaseIE._parse_aspect_ratioc                 C   s(   t |dd dthfdthfdfpd S )Nc                 S      |d S )NanchorOffsetr+   _vr+   r+   r,   <lambda>=       z-ZDFBaseIE._extract_chapters.<locals>.<lambda>rB   anchorLabel)
start_timetitle)r   r	   r:   )r*   datar+   r+   r,   _extract_chapters<   s   

zZDFBaseIE._extract_chaptersc                 C   sb   t  }i }| D ]'}t|d}|r||v rq|| |dp"d}||g d|i q|S )Nurilanguagedeur2   )setr   getadd
setdefaultappend)src	seen_urls	subtitlescaptionsubtitle_urllangr+   r+   r,   _extract_subtitlesB   s   
zZDFBaseIE._extract_subtitlesc                 C   s   t ||ddS )Nz
{playerId}android_native_6)r   replace)r*   api_base_urltemplater+   r+   r,   _expand_ptmd_templateQ   s   zZDFBaseIE._expand_ptmd_templatec                 C   s  d }d }g g }}t  }	t|D ][}
t|
i \}
}|ddk}| |
|d|}|dp6| jd|
dd d}|s=|s=|}|sLt|dd	d
tddhf}|t|ddthf7 }t|ddddthfD ]}t|ddthfD ]}t|dddd fD ]}|d }||	v rqz|		| t
|}|dkr| j||dddd}nM|dv rt|d}|r|rt|| nd }d|it|d||t|d td!|d"t| jd#|d$d dd%g}n| jd&| d'|d( g }|d)}|D ]w}t|d*p|d*pd+ }|d,d-k}|i |t|d. |od/t| o!||o%d0|d1d2d3|r1d4nd5||r>|d1d6ksF|sH|d7krHd8n|d9krT|d:krTd;n|d9kr[d<n|d:krbd=nd5d> qqzqnqbq|pq|||| |d?S )@Nvod_media_typeDGSz	PTMD databasenamez/vod/ptmd/[^/?#]+/(\w+)z
content IDr   
attributesdurationvaluei  )scalecaptions.priorityListformitaeten	qualitiesaudiotracksc                 S      t |d S )NrM   r   rC   r+   r+   r,   rF   q       z)ZDFBaseIE._extract_ptmd.<locals>.<lambda>rM   m3u8mp4hlsF)m3u8_idfatal)rr   webmhighestVerticalResolutionr2   	mimeCodecfilesizehttpr   z_(\d+)k_tbr)r8   r7   ry   	format_idr{   z Skipping unsupported extension "")r3   classrN    vcodecnoner|   dgszGerman Sign Languageformat_notez, delimAudiodeskriptionadirO   main
      r   )r|   r   
preferencerN   language_preference)idre   formatsrW   )rP   r   r   rQ   r6   _search_regexr   r	   dictrR   r   _extract_m3u8_formatsr
   roundr   r   report_warningr   
short2longlowerrT   r[   )r*   	ptmd_urlsr3   r5   r>   
content_idre   r   src_captionsrV   ptmd_urlsmuggled_datais_dgsptmdrc   streamqualityvariant
format_urlextfmtsr8   r7   f_classff_langis_audio_onlyr+   r+   r,   _extract_ptmdT   s   








3zZDFBaseIE._extract_ptmdc                 C   s^   |s|sJ d| j d|d| d| ||rt| nd t|  d|r(dnd ddS )	Nz One of query or body is requiredzhttps://api.zdf.de/graphqlr.   r/   Tzapplication/json)r0   zApollo-Require-PreflightzContent-Type)queryrK   r1   )r(   jsondumpsencoder   r-   )r*   item_id	data_descr   bodyr+   r+   r,   _download_graphql   s   
zZDFBaseIE._download_graphqlc                 C   s    dd t | tjhdd fD S )Nc              	   S   sT   g | ]&\}}t |||d krdnddttdt |dthfdthfdqS )originalr   r   )r   r2   r   z+(?P<width>\d+|auto)[Xx](?P<height>\d+|auto)r7   r8   )r7   r8   )r:   r   r;   searchr
   ).0r|   r2   r+   r+   r,   
<listcomp>   s    z1ZDFBaseIE._extract_thumbnails.<locals>.<listcomp>c                 S   rn   )Nr   ro   rC   r+   r+   r,   rF      rp   z/ZDFBaseIE._extract_thumbnails.<locals>.<lambda>)r   r   items)sourcer+   r+   r,   _extract_thumbnails   s   zZDFBaseIE._extract_thumbnailsN)NN)__name__
__module____qualname___GEO_COUNTRIESr%   r!   r-   r6   r@   rL   staticmethodr[   r`   r   r   r   r+   r+   r+   r,   r      s    



Tr   c                       sB  e Zd Zg dZdZddddddd	dd
dddgddddddddd	dd
dddgdddidddddddd	dd
dddgdddidddddddddddddd d!d"d#d$gd%d&d'ddddddddddd d!d"d#d$gd%ddidd(ddddddddddd d!d"d#d$gd%ddidd)d*i d+d,d-dd.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIgd&dJdKdLddMdNdOdPdQdRd=d?dSdTdUdVdWgd%d&dXdYi d+dZd-dd.d[d0d\d2d]d4d^d6d_d8d9d:d;d<d`d>dad@dbdBdcdDdddFdedHdfgd&dgdhdiddjdkdldmdndodpgdq	d&drdsi d+dtd-dd.dud0dvd2dwd4dxd6dyd8dzd:d{d<d`d>dad@d|dBd}dDd~dFdedHdgd&dddddddddzd{dddgdd&ddddddddddddddddddddddddddddddgZdZ fddZdd Zdd Z	  Z
S )ZDFIE)zFhttps?://(?:www\.)?zdf\.de/(?:video|play)/(?:[^/?#]+/)*(?P<id>[^/?#]+)z=https?://(?:www\.)?zdf\.de/(?:[^/?#]+/)*(?P<id>[^/?#]+)\.htmlzKhttps?://(?:www\.)?(?:zdfheute|logo)\.de/(?:[^/?#]+/)*(?P<id>[^/?#]+)\.htmlr   zrhttps://www.zdf.de/video/dokus/sylt---deutschlands-edles-nordlicht-movie-100/sylt-deutschlands-edles-nordlicht-100%sylt-deutschlands-edles-nordlicht-100rr   #Sylt - Deutschlands edles Nordlicht$md5:35407b810c2e1e33efbe15ef6e4c06c3     P@8re:https://www\.zdf\.de/assets/sylt-118~original\?cb=\d+-sylt---deutschlands-edles-nordlicht-movie-1009`20210204zdf 210402_1915_sendung_dokr   r   rJ   descriptionre   	thumbnailseries	series_id	timestampupload_date_old_archive_ids)r2   	info_dictzqhttps://www.zdf.de/play/dokus/sylt---deutschlands-edles-nordlicht-movie-100/sylt-deutschlands-edles-nordlicht-100skip_downloadT)r2   r   paramszbhttps://www.zdf.de/dokumentation/dokumentation-sonstige/sylt-deutschlands-edles-nordlicht-100.htmlzhttps://www.zdf.de/video/dokus/collection-index-page-ard-collection-ard-dxjuomfyzdpzag93ojy2mzhhmmq3mzk2ztq4nda-132/page-video-ard-gelb-vom-hellen-glanz-zu-finsteren-abgruenden-102 84980c1a0148da6cd94de58333d7e1eez@page-video-ard-gelb-vom-hellen-glanz-zu-finsteren-abgruenden-102u.   Gelb: Vom hellen Glanz zu finsteren Abgründenz$md5:9aad4806b4c8ea152ab21e70c9d516beg     @zkre:https://www\.zdf\.de/assets/image-ard-gelb-vom-hellen-glanz-zu-finsteren-abgruenden-102~original\?cb=\d+zDie Magie der FarbenzTcollection-index-page-ard-collection-ard-dxjuomfyzdpzag93ojy2mzhhmmq3mzk2ztq4nda-132zSeason 2023i  z	Episode 5r   ihd20230801z>zdf video_ard_dXJuOmFyZDpwdWJsaWNhdGlvbjo0YTYyOTJjM2Q0ZThlNmY1)r   r   rJ   r   re   r   r   r   seasonseason_numberepisodeepisode_numberr   r   r   )r2   md5r   zhttps://www.zdf.de/play/dokus/collection-index-page-ard-collection-ard-dxjuomfyzdpzag93ojy2mzhhmmq3mzk2ztq4nda-132/page-video-ard-gelb-vom-hellen-glanz-zu-finsteren-abgruenden-102zhttps://www.zdf.de/dokus/collection-index-page-ard-collection-ard-dxjuomfyzdpzag93ojy2mzhhmmq3mzk2ztq4nda-132/page-video-ard-gelb-vom-hellen-glanz-zu-finsteren-abgruenden-102.htmlzThttps://www.zdf.de/video/magazine/heute-journal-104/heute-journal-vom-19-12-2021-100 6ada39465497a84fb98d48ffff69e7b7r   z heute-journal-vom-19-12-2021-100r   rJ   zheute journal vom 19.12.2021r   z$md5:02504cf3b03777ff32fcc927d260c5ddre   g     @r   zjhttps://epg-image.zdf.de/fotobase-webdelivery/images/273e5545-16e7-4ca3-898e-52fe9e06d964?layout=1920x1080chapterszcount:11r   heute journalr   heute-journal-104r   zSeason 2021r   i  r   zEpisode 370r   ir  r   i̙ar   20211219r   zzdf 211219_sendung_hjoz]https://www.zdf.de/video/serien/funk-collection-funk-11790-1596/funk-alles-ist-verzaubert-102 57af4423db0455a3975d2dc4578536bczfunk-alles-ist-verzaubert-102zAlles ist verzaubertz0Die Neue an der Schule verdreht Ismail den Kopf.g     @zTre:https://www\.zdf\.de/assets/teaser-funk-alles-ist-verzaubert-102~original\?cb=\d+DRUCKzfunk-collection-funk-11790-1596z
Episode 502   i0|a20211029zzdf video_funk_1770473zWhttps://www.zdfheute.de/video/heute-journal/heute-journal-vom-19-dezember-2025-100.html 47af8c2cfa30abf74501170f62754c63z&heute-journal-vom-19-dezember-2025-100z#heute journal vom 19. Dezember 2025z$md5:fd0dfbce0783486db839ff9140a8074bg     Л@zjhttps://epg-image.zdf.de/fotobase-webdelivery/images/273e5545-16e7-4ca3-898e-52fe9e06d964?layout=2400x1350zcount:10zSeason 2025i  zEpisode 365m  iмEi20251219zzdf 251219_2200_sendung_hjozhhttps://www.zdf.de/nachrichten/politik/deutschland/koalitionsverhandlungen-spd-cdu-csu-dobrindt-100.html c3a78514dd993a5781aa3afe50db51e2z0koalitionsverhandlungen-spd-cdu-csu-dobrindt-100u(   Dobrindt schließt Steuererhöhungen ausz$md5:9a117646d7b8df6bc902eb543a9c9023iE  zTre:https://www\.zdfheute\.de/assets/dobrindt-csu-berlin-direkt-100~1920x1080\?cb=\d+ig20250330zzdf 250330_clip_2_bdi)	r   r   rJ   r   re   r   r   r   r   z>https://www.logo.de/logo-vom-freitag-19-dezember-2025-102.html cfb1a0988b1249f052a437a55851134bz%logo-vom-freitag-19-dezember-2025-102z$logo! vom Freitag, 19. Dezember 2025z$md5:971428cb563e924c153580f23870c613g     ~@z[re:https://www\.zdf\.de/assets/iran-rote-erde-sendung-19-dezember-2025-100~original\?cb=\d+zcount:7zlogo!zlogo-154zEpisode 382i~  i|Eizzdf 251219_1925_sendung_logzIhttps://www.logo.de/kinderreporter-vivaan-trifft-alina-grijseels-100.html 094cea026babb67aa25fd0108400bc12z0kinderreporter-vivaan-trifft-alina-grijseels-100z*Vivaan trifft Handballerin Alina Grijseelsz$md5:9572e7f4340dda823ea4091a76624da6g     d@zJre:https://www\.zdf\.de/assets/vivaan-alina-grijseels-100~original\?cb=\d+iFi20251220z%zdf 251219_kr_alina_grijseels_neu_logz^https://www.zdf.de/politik/phoenix-sendungen/wohin-fuehrt-der-protest-in-der-pandemie-100.html)r2   only_matchingz@https://www.zdf.de/dokumentation/ab-18/10-wochen-sommer-102.htmlzOhttps://www.zdf.de/politik/phoenix-sendungen/die-gesten-der-maechtigen-100.htmlz>https://www.zdf.de/filme/filme-sonstige/der-hauptmann-112.htmlz8https://www.zdf.de/wissen/nano/nano-21-mai-2019-102.htmlzYhttps://www.zdf.de/service-und-hilfe/die-neue-zdf-mediathek/zdfmediathek-trailer-100.htmlz\https://www.zdf.de/filme/taunuskrimi/die-lebenden-und-die-toten-1---ein-taunuskrimi-100.htmlzqhttps://www.zdf.de/dokumentation/planet-e/planet-e-uebersichtsseite-weitere-dokumentationen-von-planet-e-100.htmlzVhttps://www.zdf.de/arte/todliche-flucht/page-video-artede-toedliche-flucht-16-100.htmlzShttps://www.zdf.de/dokumentation/terra-x/unser-gruener-planet-wuesten-doku-100.htmla$  
query VideoByCanonical($canonical: String!) {
  videoByCanonical(canonical: $canonical) {
    canonical
    title
    leadParagraph
    editorialDate
    teaser {
      description
      image {
        list
      }
    }
    episodeInfo {
      episodeNumber
      seasonNumber
    }
    smartCollection {
      canonical
      title
    }
    currentMedia {
      nodes {
        ptmdTemplate
        ... on VodMedia {
          duration
          aspectRatio
          streamAnchorTags {
            nodes {
              anchorOffset
              anchorLabel
            }
          }
          vodMediaType
          label
        }
        ... on LiveMedia {
          start
          stop
          encryption
          liveMediaType
          label
        }
        id
      }
    }
  }
}
    c                    s0   t  j|i |}|d}t| |g|d< |S )Nr   r   )superr   popr   )r*   argskwargs	ptmd_dataold_archive_id	__class__r+   r,   r     s   
zZDFIE._extract_ptmdc           	   
   C   s   | j d| |ddd}|d }t|dthttdhf}g }t|dtjhd	fD ]#\}}t|d
thf}|s8q)|||t|	dt|	dd q)d|it|ddt
hfddt
hfdthtfdd| jhfd| |||  d|iS )Nz4https://zdf-prod-futura.zdf.de/mediathekV2/document/zDownloading fallback metadataz$Failed to download fallback metadata)noteerrnotedocument)streamApiUrlAndroid)streamsr   r   zPTMD URL
teaserBild.r2   r7   r8   )r2   r   r7   r8   
thumbnailstitelbeschreibung))r   date)metaeditorialDaterh   )rJ   r   r   rW   r   )r(   r   r   anyr   r   r   rT   r
   rQ   r:   r   r[   r   r-   )	r*   document_idvideor   r   r   thumbnail_keyr   thumbnail_urlr+   r+   r,   _extract_fallback  sH   



zZDFIE._extract_fallbackc           	      C   s8  |  |}| j|dd| jd|iddd d }|s| |S d }g }t|dd	d
d fD ]'}| d|d }|d }rEt|d|i}|| |sT| 	|d}q-i t|dt
hfdtt
hfdthfddd| jhfddthfddthfddt
hfddt
hfdd	ddd	| jhfd	| |||  |d|iS )Nzvideo metadataVideoByCanonical	canonical)operationNamer   	variables)r   rK   videoByCanonicalcurrentMedianodesc                 S   rA   )NptmdTemplater+   rC   r+   r+   r,   rF   K  rG   z%ZDFIE._real_extract.<locals>.<lambda>zhttps://api.zdf.der  vodMediaTypera   aspectRatiorJ   leadParagraph)teaserr   r   r  imagelistepisodeInfoepisodeNumberseasonNumbersmartCollectionr   streamAnchorTags)	rJ   r   r   r   r   r   r   r   r   r   )	_match_idr   _GRAPHQL_QUERYr  r   r`   rQ   r   rT   r@   r:   r  r   r   r
   rL   r   r-   )	r*   r2   r3   
video_datar>   r   noder   ra   r+   r+   r,   _real_extract>  sN   







zZDFIE._real_extract)r   r   r   
_VALID_URLIE_NAME_TESTSr  r   r  r  __classcell__r+   r+   r   r,   r      sT   	
	
	
    2%r   c                       s   e Zd ZdZdZddddddd	d
dddddd	e gddddddddddddgdddidddddddd	dd d!d"dd#d	d$d%d&d"dd'd(d)gZd*Ze	 fd+d,Z
d4d.d/Zd0d1 Zd2d3 Z  ZS )5ZDFChannelIEz2https?://www\.zdf\.de/(?:[^/?#]+/)*(?P<id>[^/?#]+)zzdf:channelz1https://www.zdf.de/sport/das-aktuelle-sportstudiozdas-aktuelle-sportstudio-220zdas aktuelle sportstudioz$md5:e46c785324238a03edcf8b301c5fd5dc)r   rJ   r      )r2   r   playlist_mincountz5https://www.zdf.de/sport/das-aktuelle-sportstudio-220zFhttps://www.zdf.de/dokus/sylt---deutschlands-edles-nordlicht-movie-100r   rr   r   r   r   r   r   r   r   r   r   r   T)add_ier2   r   r   z9https://www.zdf.de/gesellschaft/aktenzeichen-xy-ungeloestzaktenzeichen-xy-ungeloest-110u   Aktenzeichen XY... Ungelöstz$md5:b79ac0d64b979e53cbe510c0ca9cb7ber   z-https://www.zdf.de/magazine/heute-journal-104r   r   z$md5:6edad39189abf8431795d3d6d7f986b3in  z:https://www.zdf.de/magazine/heute-journal-104?staffel=2025zheute-journal-104-s2025zheute journal - Season 2025r   r   )r2   r   r&  playlist_maxcount   c                    s   t |rdS t |S )NF)r   suitabler   )clsr2   r   r+   r,   r*    s   zZDFChannelIE.suitableNc                 C   sT   | j |d| d| ddtt||| j|dtdddd	id
dd d S )Nzseason z page z JSONseasonByCanonical)seasonIndexr  episodesPageSizeepisodesAfterpersistedQueryr   @9412a0f4ac55dc37d46975d461ec64bfd14380d815df843a1492348f77b5c99aversion
sha256Hashr	  r
  
extensionsr   rK   smartCollectionByCanonical)r   r   r   r   
_PAGE_SIZE)r*   playlist_idcanonical_id
season_idxr   page_numbercursorr+   r+   r,   _fetch_page  s*   zZDFChannelIE._fetch_pagec                 c   s
   t |D ]}\}}|d ur||krqd }tdD ]h}| ||||||}	t|	d}
t|
ddddd fD ]/}| j|d tfi t|d	thfd
dthfdtthfdt	hfddt
hfddt
hfdV  q5t|
dddthfppi }|dr{|ds} n|d }qqd S )Nr   )seasonsr  ..episodesr  c                 S   rn   )N
sharingUrlro   rC   r+   r+   r,   rF     rp   z'ZDFChannelIE._entries.<locals>.<lambda>rB  r  r  rJ   r  r   r  r  r  )r   rJ   r   r   r   r   r   pageInfohasNextPage	endCursor)	enumerate	itertoolscountr?  r   
url_resultr   r:   r  r   r
   r   rQ   )r*   r:  r;  season_numbersrequested_season_numberr<  r   r>  r=  pager  r   	page_infor+   r+   r,   _entries  s>   







zZDFChannelIE._entriesc           	      C   s^  |  |}| ||}| j| j|jddd}tt|ddthf}t||o)d| }| j	|ddt
|d	d
t
ddddiddd d }t|dthfpRi }t|ddddthf}| |oc|t|don|ds{| |d t|d S |d ur||vrtd| d| | |||||tt|dthf|od| ddt|dthfS )Nz
channel idr   )r=   staffelr   szsmart collection dataGetSmartCollectionByCanonicald   )r  videoPageSizer0  r   @cb49420e133bd668ad895a8cea0e65cba6aa11ac1cacb02341ff5cf32a17cd02r2  r5  r7  rK   r8  r  r@  .numberrB  r  zSeason z% was not found in the collection datarJ   z - r   infoText)r  _request_webpager   r   r2   r   r   r
   r   r   r   r   r   _yes_playlistr   rQ   rI  r   r   playlist_resultrN  r:   )	r*   r2   r;  urlhr   r:  collection_datar  rJ  r+   r+   r,   r    sR   
zZDFChannelIE._real_extractr   )r   r   r   r   r!  r   ie_keyr"  r9  classmethodr*  r?  rN  r  r#  r+   r+   r   r,   r$  e  s|    
A
r$  )rG  r   r;   r'   commonr   utilsr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   utils.traversalr   r   r   r   r$  r+   r+   r+   r,   <module>   s    L &   &