U
    $Pff                     @   s4  d dl m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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 G dd	 d	eZG d
d deZdd ZG dd deZ G dd deZ!G dd de!Z"G dd de!Z#G dd de!Z$G dd deZ%G dd deZ&dS )    )unicode_literalsN   )InfoExtractor   )compat_parse_qs
compat_strcompat_urlparsecompat_urllib_parse_urlencodecompat_urllib_parse_urlparse)
clean_htmldict_getExtractorErrorfloat_or_noneint_or_noneparse_durationparse_iso8601	qualitiestry_getunified_timestampupdate_url_queryurl_or_noneurljoinc                
   @   st   e Zd ZdZdZdZdZdZdZdZ	dd	d
ddddddd	Z
dd Zdd Zdd Zd ddZd!ddZdd ZdS )"TwitchBaseIEz&https?://(?:(?:www|go|m)\.)?twitch\.tvzhttps://api.twitch.tvzhttps://usher.ttvnw.netzhttps://www.twitch.tv/loginz https://passport.twitch.tv/loginZkimne78kx3ncx6brgo4mv6wki5h1koZtwitchZ@27111f1b382effad0b6def325caef1909c733fe6a4fbabf54f8d491ef2cf2f14Z@a937f1d22e269e39a03b509f65a7490f9fc247d7f83d6ac1421523e3b68042cbZ@b73ad2bfaecfd30a9e6c28fada15bd97032c83ec77a0440766a56fe0bd632777Z@07e3691a1bad77a36aba590c351180439a40baefc1c275356f40fc7082419a84Z@1c719a40e481453e5c48d9bb585d971b8b372f8ebb105b17076722264dfa5b3eZ@e1edae8122517d013405f237ffcc124515dc6ded82480a88daef69c83b53ac01Z@36b89d2507fce29e5ca551df756d27c1cfe079e2609642b4390aa4c35796eb11Z@3006e77e51b128d838fa4e835723ca4dc9a05c5efd4466c1085215c6e437e65cZ@226edb3e692509f727fd56821f5653c05740242c82b0388883e0c0e75dcbf687)	CollectionSideBarFilterableVideoTower_VideosClipsCards__UserChannelCollectionsContentStreamMetadataComscoreStreamingQueryVideoAccessToken_ClipVideoPreviewOverlayVideoMetadatac                 C   s   |    d S N)_login)self r%   ?/tmp/pip-unpacked-wheel-7zdooeg3/youtube_dl/extractor/twitch.py_real_initialize9   s    zTwitchBaseIE._real_initializec                    s     \}}|d krd S dd   fdd}jd d\}}d|krV t| |||d||jd\}}|szd S td	|d k	rd
}|||d|dd d S )Nc                 S   s   t d|  ddd S )Nz Unable to login. Twitch said: %sTexpected)r   )messager%   r%   r&   failA   s     z!TwitchBaseIE._login.<locals>.failc                    s    | }|| | }jd| djdd}t||}|ddd}j|d |t|	 |dd	}t
|d
}	|	r~ |	 d|ddkrdS t||dp|d }
j|
d d|dS )Nz&<form[^>]+action=(["\'])(?P<url>.+?)\1zpost urlurl)defaultgroupzhttps://www.twitch.tvtext/plain;charset=UTF-8)ZRefererZOriginContent-Typei  )dataheadersZexpected_status)errorZerror_descriptionZ
error_codezAuthenticated successfullyr*    )NNredirectZredirect_pathzDownloading login redirect page)r2   )Z_hidden_inputsupdategeturlZ_search_regex_LOGIN_POST_URLr   _download_jsonjsondumpsencoder   get_download_webpage_handle)pageZurlhnoter1   formpage_urlZpost_urlr2   responser3   Zredirect_urlr+   r$   r%   r&   
login_stepE   sL    

   
    
  z'TwitchBaseIE._login.<locals>.login_stepzDownloading login pageZblacklist_messagez
Logging in)usernamepassword	client_idz$(?i)<form[^>]+id="two-factor-submit"ztwo-factor authentication tokenzSubmitting TFA tokentrue)Zauthy_tokenZremember_2fa)Z_get_login_infor>   _LOGIN_FORM_URLr   
_CLIENT_IDresearchZ_get_tfa_info)r$   rF   rG   rE   Z
login_pagehandleZredirect_pageZ	tfa_tokenr%   rD   r&   r#   <   s:    !    
zTwitchBaseIE._loginc              	   C   sh   zt dd |D }d|d< W n: tk
rX   |D ] }d|d kr2|ddd q2Y nX | | d S )	Nc                 s   s   | ]}|d  dkr|V  qdS )	format_idSourceNr%   ).0fr%   r%   r&   	<genexpr>   s      z.TwitchBaseIE._prefer_source.<locals>.<genexpr>
   qualityz	/chunked/r,   rP   )rU   Zformat_note)nextStopIterationr6   _sort_formats)r$   formatssourcerR   r%   r%   r&   _prefer_source   s    zTwitchBaseIE._prefer_sourceTc                 C   sN   d| j d}| dd}|r.d|j |d< | jd||t| ||dS )	Nr/   )r0   z	Client-IDzhttps://gql.twitch.tvz
auth-tokenzOAuth Authorizationzhttps://gql.twitch.tv/gql)r1   r2   fatal)rK   Z_get_cookiesr=   valuer9   r:   r;   r<   )r$   video_idopsr@   r]   r2   Zgql_authr%   r%   r&   _download_base_gql   s       zTwitchBaseIE._download_base_gqlc                 C   s4   |D ] }dd| j |d  di|d< q| |||S )NZpersistedQueryr   operationName)versionZ
sha256Hash
extensions)_OPERATION_HASHESra   )r$   r_   r`   r@   r]   opr%   r%   r&   _download_gql   s    
zTwitchBaseIE._download_gqlc                 C   s4   d| }dd|||f i}|  ||d| d | S )Nz%sPlaybackAccessTokenquerya?  {
              %s(
                %s: "%s",
                params: {
                  platform: "web",
                  playerBackend: "mediaplayer",
                  playerType: "site"
                }
              )
              {
                value
                signature
              }
            }z#Downloading %s access token GraphQLr1   )ra   )r$   r_   Z
token_kind
param_namemethodr`   r%   r%   r&   _download_access_token   s      z#TwitchBaseIE._download_access_tokenN)T)T)__name__
__module____qualname__Z_VALID_URL_BASEZ	_API_BASE_USHER_BASErJ   r8   rK   Z_NETRC_MACHINEre   r'   r#   r[   ra   rg   rk   r%   r%   r%   r&   r   #   s.   D


r   c                   @   s   e Zd ZdZdZddddddd	d
ddeddddiddddddddddded
ddiddddddddd ddd!ddd"ddgZd#d$ Zed%d& Z	ed'd( Z
d)d* Zd+S ),TwitchVodIEz
twitch:voda(  (?x)
                    https?://
                        (?:
                            (?:(?:www|go|m)\.)?twitch\.tv/(?:[^/]+/v(?:ideo)?|videos)/|
                            player\.twitch\.tv/\?.*?\bvideo=v?
                        )
                        (?P<id>\d+)
                    z0http://www.twitch.tv/riotgames/v/6528877?t=5m10sZv6528877mp4zLCK Summer Split - Week 6 Day 1zre:^https?://.*\.jpg$i8C  iV_UZ20150624z
Riot GamesZ	riotgamesi6  )idexttitle	thumbnailduration	timestampupload_dateuploaderuploader_id
view_count
start_timeskip_downloadTr,   	info_dictparamsz(http://www.twitch.tv/belkao_o/v/11230755Z	v11230755Untitled Broadcastif  iUZ20150816ZBelkAO_oZbelkao_o)
rr   rs   rt   ru   rv   rw   rx   ry   rz   r{   zHTTP Error 404: Not Found)r,   r   r   skipz/http://player.twitch.tv/?t=5m10s&video=v6528877r,   Zonly_matchingz$https://www.twitch.tv/videos/6528877z+https://m.twitch.tv/beagsandjam/v/247478721z2https://www.twitch.tv/northernlion/video/291940395z)https://player.twitch.tv/?video=480452374c                 C   sR   |  |dd|ddgdd d }|d}|d krFtd	| d
d| ||S )Nr!   r4   )channelLoginZvideoIDrb   	variablesz#Downloading stream metadata GraphQLr   r1   videozVideo %s does not existTr(   )rg   r=   r   _extract_info_gql)r$   item_idr1   r   r%   r%   r&   _download_info   s(    	
 zTwitchVodIE._download_infoc           	      C   s   |  d}|dkrd}n|dkr&d}nd }d}t|}g }|  d}t|tr| D ]4\}}t|}|slqV||krvqV||||d qV| d	 |  d
pd|  dt|  d||  di  d|  di  dt|  dt|  d|d
S )NstatusZ	recordingTZrecordedF)smallmediumZlargepreview)r,   Z
preferenceZ_idrt   r   descriptionlengthchannelZdisplay_namenameZrecorded_atviews)
rr   rt   r   rv   
thumbnailsry   rz   rw   r{   is_live)	r=   r   
isinstancedictitemsr   appendr   r   )	infor   r   Z
_QUALITIESZquality_keyr   r   thumbnail_idthumbnail_urlr%   r%   r&   _extract_info  s@    



zTwitchVodIE._extract_infoc                 C   s   |  dp|}|d dkr"d| }t|  d}|rNdD ]}|d| d}q8||  d	p\d
|  dt|  d|t| dd tt| dd tt|  dt|  dd	S )Nrr   r   vzv%spreviewThumbnailURL)widthheightz{%s}0rt   r   r   lengthSecondsc                 S   s   | d d S )NownerdisplayNamer%   xr%   r%   r&   <lambda>C      z/TwitchVodIE._extract_info_gql.<locals>.<lambda>c                 S   s   | d d S )Nr   loginr%   r   r%   r%   r&   r   D  r   ZpublishedAt	viewCount)	rr   rt   r   rv   ru   ry   rz   rw   r{   )r=   r   replacer   r   r   r   )r   r   vod_idru   pr%   r%   r&   r   3  s"    zTwitchVodIE._extract_info_gqlc                 C   s   |  |}| |}| |dd}| jd| j|tddddd|d |d df |d	d
d}| | ||d< t|}t|j	}d|krt
|d d |d< |dd k	rdtd| d| jiddgi|d< |S )Nr   rr   z%s/vod/%s.m3u8?%srI   	twitchwebr^   	signature)allow_sourceallow_audio_onlyallow_spectreplayerplaylist_include_framerateZnauthZnauthsigrq   Zm3u8_native)Zentry_protocolrY   tr   r|   rw   Zrechatz+https://api.twitch.tv/v5/videos/%s/commentsrH   r:   )r,   rs   Z	subtitles)	_match_idr   rk   _extract_m3u8_formatsro   r	   r[   r
   r   rh   r   r=   r   rK   )r$   r,   r   r   access_tokenrY   
parsed_urlrh   r%   r%   r&   _real_extractI  sN    

   

 
zTwitchVodIE._real_extractN)rl   rm   rn   IE_NAME
_VALID_URLint_TESTSr   staticmethodr   r   r   r%   r%   r%   r&   rp      st   
  8
$
rp   c                 C   s^   t | tst| d}|s d S dt |d| | d| dt| dt| ddS )	Nrr   url_transparentzhttps://www.twitch.tv/videos/%srt   r   r   r   )_typeie_keyrr   r,   rt   ru   rv   r{   )r   r   AssertionErrorr=   rp   r   r   r   )noder_   r%   r%   r&   _make_video_results  s    
r   c                   @   s0   e Zd ZdZddddddgZdZd	d
 ZdS )TwitchCollectionIEz@https?://(?:(?:www|go|m)\.)?twitch\.tv/collections/(?P<id>[^/]+)z0https://www.twitch.tv/collections/wlDCoH0zEBZZbQZwlDCoH0zEBZZbQz'Overthrow Nook, capitalism for childrenrr   rt      r,   r   Zplaylist_mincountr   c           	      C   s   |  |}| || jd|idgdd d d }|d}g }|d d	 D ]<}t|ts\qL|d
}t|tsrqLt|}|rL|| qL| j|||dS )NZcollectionIDr   zDownloading collection GraphQLr   r1   
collectionrt   r   edgesr   Zplaylist_idZplaylist_title)	r   rg   _OPERATION_NAMEr=   r   r   r   r   playlist_result)	r$   r,   collection_idr   rt   entriesedger   r   r%   r%   r&   r     s<    




  z TwitchCollectionIE._real_extractN)rl   rm   rn   r   r   r   r   r%   r%   r%   r&   r     s   	r   c                   @   s   e Zd ZdZdd ZdS )TwitchPlaylistBaseIEd   c                 '   s"  d }| j |f| }d| j  tdD ]}| }| j|d< |rJ||d< | j|| j|dgd| j|f dd}|sz qt	| fd	d
t
}|s q|D ]h}	t|	tsq|	d| jkrq|	d}
t|
tsq|
d| jkrq| |
}|r|	d}|V  q|rt|ts( qq(d S )Nz%ssr   limitcursorr   zDownloading %ss GraphQL page %sFr]   c                    s   | d d d   d S )Nr   r1   userr   r%   r   Zentries_keyr%   r&   r     r   z/TwitchPlaylistBaseIE._entries.<locals>.<lambda>Z
__typenamer   )_make_variables_ENTRY_KIND	itertoolscountcopy_PAGE_LIMITrg   r   
_NODE_KINDr   listr   r   r=   
_EDGE_KIND_extract_entryr   )r$   channel_nameargsr   Zvariables_commonZpage_numr   r?   r   r   r   entryr%   r   r&   _entries  sR    

 
 




zTwitchPlaylistBaseIE._entriesN)rl   rm   rn   r   r   r%   r%   r%   r&   r     s   r   c                       s   e 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ddddddddddddddg	ZedddgZed d!Zed"d#ed$d%ed&d'ed(d)ed*Z	d+Z
e
d,d-Zd.Zd/Zd0Zd1Ze fd2d3Zed4d5 Zed6d7 Zd8d9 Z  ZS ):TwitchVideosIEzGhttps?://(?:(?:www|go|m)\.)?twitch\.tv/(?P<id>[^/]+)/(?:videos|profile)z0https://www.twitch.tv/spamfish/videos?filter=allspamfishz$spamfish - All Videos sorted by Dater   i  r   z;https://www.twitch.tv/spamfish/videos?filter=all&sort=viewsz'spamfish - All Videos sorted by Populari  z5https://www.twitch.tv/spamfish/videos?filter=archivesz)spamfish - Past Broadcasts sorted by Date   z7https://www.twitch.tv/spamfish/videos?filter=highlightsz$spamfish - Highlights sorted by Datei  z>https://www.twitch.tv/esl_csgo/videos?filter=uploads&sort=timeZesl_csgoz!esl_csgo - Uploads sorted by Date   z;https://www.twitch.tv/spamfish/videos?filter=past_premieresz(spamfish - Past Premieres sorted by Dater   z)https://www.twitch.tv/spamfish/videos/allTr   z'https://m.twitch.tv/spamfish/videos/allz%https://www.twitch.tv/spamfish/videos	BroadcasttypelabelNz
All VideosZARCHIVEzPast BroadcastsZ	HIGHLIGHTZ
HighlightsZUPLOADZUploadsZPAST_PREMIEREzPast Premieres)ZarchivesZ
highlightsZuploadsZpast_premieresallDateZPopular)timer   r   r   Z	VideoEdgeZVideoc                    s.   t  fddttfD rdS tt|  S )Nc                 3   s   | ]}|  V  qd S r"   suitablerQ   Zier,   r%   r&   rS   +  s     z*TwitchVideosIE.suitable.<locals>.<genexpr>F)anyTwitchVideosClipsIETwitchVideosCollectionsIEsuperr   r   clsr,   	__class__r   r&   r   (  s    zTwitchVideosIE.suitablec                 C   s   | ||  dS )N)ZchannelOwnerLoginZbroadcastTypeZ	videoSort)upper)r   Zbroadcast_typesortr%   r%   r&   r   0  s    zTwitchVideosIE._make_variablesc                 C   s   t | S r"   )r   )r   r%   r%   r&   r   8  s    zTwitchVideosIE._extract_entryc              
   C   s   |  |}tt|j}|ddgd }|ddgd }| j|| j}| j| 	||j
||d||j| j|| jf dS )Nfilterr   r   r   r   z%s - %s sorted by %sr   )r   r   parse_qsurlparserh   r=   _BROADCASTS_DEFAULT_BROADCASTr   r   r   r   
_SORTED_BY_DEFAULT_SORTED_BY)r$   r,   r   qsr   r   	broadcastr%   r%   r&   r   <  s    
zTwitchVideosIE._real_extract)rl   rm   rn   r   r   collections
namedtupler   r  r  r  r  r   r   r   r   classmethodr   r   r   r   r   __classcell__r%   r%   r   r&   r     s   




	;


r   c                   @   s   e Zd ZdZdddddddd	d
gZedddgZeddZeddeeddedddZ	dZ
dZdZdZdZedd Zedd Zdd  Zd!S )"r   z[https?://(?:(?:www|go|m)\.)?twitch\.tv/(?P<id>[^/]+)/(?:clips|videos/*?\?.*?\bfilter=clips)z<https://www.twitch.tv/vanillatv/clips?filter=clips&range=allZ	vanillatvzvanillatv - Clips Top Allr   r   r   z=https://www.twitch.tv/dota2ruhub/videos?filter=clips&range=7dTr   Clipr   r   Z	LAST_WEEKzTop 7DZLAST_DAYzTop 24HZ
LAST_MONTHzTop 30DZALL_TIMEzTop All)Z24hr7dZ30dr      r   clipZClipEdgec                 C   s   | d|idS )Nr   )r   Zcriteriar%   )r   r   r%   r%   r&   r   l  s
     z#TwitchVideosClipsIE._make_variablesc                 C   sx   t | tstt| d}|s$d S dt | d|| d| dt| dt| dt	| d| d	d

S )Nr,   r   rr   rt   thumbnailURLdurationSeconds	createdAtr   language)
r   r   rr   r,   rt   ru   rv   rw   r{   r  )
r   r   r   r   r=   TwitchClipsIEr   r   r   r   )r   Zclip_urlr%   r%   r&   r   u  s    z"TwitchVideosClipsIE._extract_entryc                 C   sb   |  |}tt|j}|ddgd }| j|| j}| j| 	||j
|d||jf dS )Nranger  r   z%s - Clips %sr   )r   r   r  r  rh   r=   _RANGE_DEFAULT_CLIPr   r   r   r   )r$   r,   r   r  r  r  r%   r%   r&   r     s    
z!TwitchVideosClipsIE._real_extractN)rl   rm   rn   r   r   r	  r
  r  r  r  r   r   r   r   r   r   r   r   r   r%   r%   r%   r&   r   J  s8   	


r   c                   @   sT   e Zd ZdZddddddgZdZd	Zd
ZdZe	dd Z
e	dd Zdd ZdS )r   zWhttps?://(?:(?:www|go|m)\.)?twitch\.tv/(?P<id>[^/]+)/videos/*?\?.*?\bfilter=collectionsz8https://www.twitch.tv/spamfish/videos?filter=collectionsr   zspamfish - Collectionsr      r   r   r   ZCollectionsItemEdge
Collectionc                 C   s   d| iS )NZ
ownerLoginr%   )r   r%   r%   r&   r     s     z)TwitchVideosCollectionsIE._make_variablesc                 C   sj   t | tst| d}|s d S dt |d| | d| dt| dt| dt| dd		S )
Nrr   r   z$https://www.twitch.tv/collections/%srt   r  r   Z	updatedAtr   )	r   r   rr   r,   rt   ru   rv   rw   r{   )	r   r   r   r=   r   r   r   r   r   )r   r   r%   r%   r&   r     s    
z(TwitchVideosCollectionsIE._extract_entryc                 C   s$   |  |}| j| ||d| dS )Nz%s - Collectionsr   )r   r   r   )r$   r,   r   r%   r%   r&   r     s    
 z'TwitchVideosCollectionsIE._real_extractN)rl   rm   rn   r   r   r   r   r   r   r   r   r   r   r%   r%   r%   r&   r     s    


r   c                       sz   e Zd ZdZdZddddddd	d
dddeddd	iddd	ddd	ddd	ddd	dgZe fddZdd Z	  Z
S )TwitchStreamIEztwitch:streama  (?x)
                    https?://
                        (?:
                            (?:(?:www|go|m)\.)?twitch\.tv/|
                            player\.twitch\.tv/\?.*?\bchannel=
                        )
                        (?P<id>[^/#?]+)
                    zhttp://www.twitch.tv/shroomztvZ12772022048Z	shroomztvrq   z;re:^ShroomzTV [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$zGH1Z1 - lonewolfing with ShroomzTV | A3 Battle Royale later - @ShroomzTVTieTZ20150122Z	ShroomzTV)rr   
display_idrs   rt   r   r   rw   rx   ry   rz   r{   r}   r~   z+http://www.twitch.tv/miracle_doto#profile-0r   z)https://player.twitch.tv/?channel=lotsofszhttps://go.twitch.tv/foodzhttps://m.twitch.tv/foodc                    s6   t  fddttttttfD r&dS tt| 	 S )Nc                 3   s   | ]}|  V  qd S r"   r   r   r   r%   r&   rS     s     z*TwitchStreamIE.suitable.<locals>.<genexpr>F)
r   rp   r   r   r   r   r  r   r  r   r   r   r   r&   r     s    zTwitchStreamIE.suitablec                 C   s  |  | }| |dd|idd|dddddddd	d
|idgd}|d d d }|sntd| dd|d }|std| dd| |dd}|d }|dp|}dddtddddd|d d|dd	}	| j	d| j
|f |d|	d }
| |
 |d!}t|d"}t|d#d$ tp0i }|d%}t|d&d$ t}tt|d'd$ t}|ph|}|d(}|d)kr|d*| 7 }||| ||||||||
|d+kd,S )-Nr   r   r   r   r4   FT)r   ZclipSlugZisClipZisLiveZisVodOrCollectionZvodIDr    r   zDownloading stream GraphQLr   r1   r   z%s does not existr(   streamz%s is offlineZchannelNamer^   rr   rI   i@B i r   4r   zutf-8)	r   r   r   r   r   r   Zsegment_preferencesigtokenz%s/api/channel/hls/%s.m3u8rq   )rh   Zviewersr  c                 S   s   | d d d S )Nr   r1   r   r%   r   r%   r%   r&   r   6  r   z.TwitchStreamIE._real_extract.<locals>.<lambda>r   c                 S   s   | d d S )NZbroadcastSettingsrt   r%   r   r%   r%   r&   r   9  r   c                 S   s   | d d d d d S )Nr   r1   r   r  ZpreviewImageURLr%   r   r%   r%   r&   r   <  r   r   )Zrerunlivez (%s)r!  )rr   r  rt   r   ru   ry   rz   rw   r{   rY   r   )r   lowerrg   r   rk   r=   randomrandintr<   r   ro   r[   r   r   r   r   r   Z_live_title)r$   r,   r   Zgqlr   r  r   r   Z	stream_idrh   rY   r{   rw   Zsq_userry   r   ru   rt   Zstream_typer%   r%   r&   r     s       
  


   


zTwitchStreamIE._real_extract)rl   rm   rn   r   r   r   r   r  r   r   r  r%   r%   r   r&   r    sF   
 !r  c                   @   sf   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gZdd ZdS )r  ztwitch:clipsa-  (?x)
                    https?://
                        (?:
                            clips\.twitch\.tv/(?:embed\?.*?\bclip=|(?:[^/]+/)*)|
                            (?:(?:www|go|m)\.)?twitch\.tv/[^/]+/clip/
                        )
                        (?P<id>[^/?#&]+)
                    z0https://clips.twitch.tv/FaintLightGullWholeWheatZ 761769e1eafce0ffebfb4089cb3847cdZ42850523rq   z'EA Play 2016 Live from the Novo Theatrezre:^https?://.*\.jpgi]WZ20160612ZEAZstereotype_Z43566419)	rr   rs   rt   ru   rw   rx   creatorry   rz   )r,   md5r   z;https://clips.twitch.tv/rflegendary/UninterestedBeeDAESuppyTr   zDhttps://www.twitch.tv/sergeynixon/clip/StormyThankfulSproutFutureManzEhttps://clips.twitch.tv/embed?clip=InquisitiveBreakableYogurtJebaitedzChttps://m.twitch.tv/rossbroadcast/clip/ConfidentBraveHumanChefFrankzDhttps://go.twitch.tv/rossbroadcast/clip/ConfidentBraveHumanChefFrankc                 C   s  |  |}| |dd|idgdd d d }|s@tdd	d
|d d |d d d}| j|dd| iddd}|rt|dd tp|}g }|dg D ]X}t|tsqt|d}|sq|	t
|||dt|dt|dd q| | g }	dD ]d}
||
}|s q|
|d}td|}|r`|t|dt|dd  |		| q|d!p|||d"p||t|d#t|d$t|d%|	t|d&d tt|d'd tt|d(d td)
S )*Nr   Zslugr   z%Downloading clip access token GraphQLr   r1   r  z This clip is no longer availableTr(   ZplaybackAccessTokenr   r^   )r  r   rh   a  {
  clip(slug: "%s") {
    broadcaster {
      displayName
    }
    createdAt
    curator {
      displayName
      id
    }
    durationSeconds
    id
    tiny: thumbnailURL(width: 86, height: 45)
    small: thumbnailURL(width: 260, height: 147)
    medium: thumbnailURL(width: 480, height: 272)
    title
    videoQualities {
      frameRate
      quality
      sourceURL
    }
    viewCount
  }
}zDownloading clip GraphQLFr   c                 S   s   | d d S )Nr1   r  r%   r   r%   r%   r&   r     r   z-TwitchClipsIE._real_extract.<locals>.<lambda>ZvideoQualitiesZ	sourceURLrU   Z	frameRate)r,   rO   r   Zfps)Ztinyr   r   )rr   r,   z-(\d+)x(\d+)\.r   r   )r   r   rr   rt   r  r   r  c                 S   s   | d d S )NZbroadcasterr   r%   r   r%   r%   r&   r     r   c                 S   s   | d d S )Ncuratorr   r%   r   r%   r%   r&   r     r   c                 S   s   | d d S )Nr'  rr   r%   r   r%   r%   r&   r     r   )
rr   rt   rY   rv   r   rw   r   r%  ry   rz   )r   rg   r   ra   r   r   r=   r   r   r   r   r   rX   rL   rM   r6   r   r.   r   r   )r$   r,   r_   r  Zaccess_queryr1   rY   optionrZ   r   r   r   ZthumbZmobjr%   r%   r&   r   ~  s    
 	 

  



zTwitchClipsIE._real_extractN)rl   rm   rn   r   r   r   r   r%   r%   r%   r&   r  S  s@   
 r  )'
__future__r   r	  r   r:   r#  rL   commonr   compatr   r   r   r	   r
   utilsr   r   r   r   r   r   r   r   r   r   r   r   r   r   rp   r   r   r   r   r   r   r  r  r%   r%   r%   r&   <module>   s*   <  9%+vI1 