U
    $PfIp                     @   s   d dl m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
 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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# ddl$m%Z% G dd deZ&G dd de&eZ'G dd de&Z(dS )    )unicode_literalsN)sha1)powsqrtfloor   )InfoExtractor)VRVIE   )compat_b64decodecompat_etree_Elementcompat_etree_fromstring
compat_strcompat_urllib_parse_urlencodecompat_urllib_requestcompat_urlparse)ExtractorErrorbytes_to_intlistextract_attributesfloat_or_noneintlist_to_bytesint_or_nonelowercase_escapemerge_dicts
remove_endsanitized_Requesturlencode_postdata
xpath_text)aes_cbc_decryptc                   @   s>   e Zd ZdZdZdZdddZdd Zd	d
 Ze	dd Z
dS )CrunchyrollBaseIEz!https://www.crunchyroll.com/login
login_formcrunchyrollNc                 C   s<   |pi }d| |d< t |d}| jd||d|ddidS )	NZRpcApirequtf-8z https://www.crunchyroll.com/xml/FContent-Type!application/x-www-form-urlencoded)fataldataheaders)r   encodeZ_download_xml)selfmethodvideo_idnoter'    r.   D/tmp/pip-unpacked-wheel-7zdooeg3/youtube_dl/extractor/crunchyroll.py_call_rpc_api-   s        zCrunchyrollBaseIE._call_rpc_apic           
      C   s   |   \}}|d krd S | | jd d}dd }||r<d S | jd| j |ddd}t|d}|sn| j}n|d	st	| j|}| 
| j|}|||d
 | j|d ddt|ddid}||rd S | jd|dd d}	|	rtd|	 ddtdd S )NzDownloading login pagec                 S   s   d| kS )Nzhref="/logout"r.   )webpager.   r.   r/   	is_logged?   s    z+CrunchyrollBaseIE._login.<locals>.is_loggedz)(?P<form><form[^>]+?id=(["\'])%s\2[^>]*>)z
login formform)groupactionhttp)zlogin_form[name]zlogin_form[password]z
Logging inzWrong login infor$   r%   )r'   r(   z2(?s)<ul[^>]+class=["']messages["'][^>]*>(.+?)</ul>zerror messagedefaultzUnable to login: %sTexpectedzUnable to log in)Z_get_login_info_download_webpage
_LOGIN_URL_search_regex_LOGIN_FORMr   get
startswithr   urljoinZ_form_hidden_inputsupdater   _html_search_regexr   )
r*   usernamepasswordZ
login_pager2   Zlogin_form_strZpost_urlr    responseerrorr.   r.   r/   _login7   s\        
     zCrunchyrollBaseIE._loginc                 C   s   |    d S )N)rH   r*   r.   r.   r/   _real_initializeh   s    z"CrunchyrollBaseIE._real_initializec                 C   s8   t | }t |j}dg|d< t |jt|ddS )N1Z	skip_wallT)query)r   urlparseparse_qsrL   
urlunparse_replacer   )url
parsed_urlqsr.   r.   r/   _add_skip_wallk   s    

z CrunchyrollBaseIE._add_skip_wall)NN)__name__
__module____qualname__r<   r>   Z_NETRC_MACHINEr0   rH   rJ   staticmethodrT   r.   r.   r.   r/   r   (   s   

1r   c                       sp  e Zd ZdZdZddddddd	d
ddddidddddddddddddidddddeedddddddidd d!deedd"d#d$ed%d&d'd(d)ddidd*dd+d,dd+d-d.deed/d0d1d2ddidd3d4dd5d6d7d8d9ddiddd:d;deed<d=d>d?d@dA	ddiddBdd+dCdd+gZdDdEdFdGdHZ fdIdJZdKdL Z	dMdN Z
dOdP ZdQdR ZdSdT ZdUdV Z  ZS )WCrunchyrollIEr!   zhttps?://(?:(?P<prefix>www|m)\.)?(?P<url>crunchyroll\.(?:com|fr)/(?:media(?:-|/\?id=)|(?:[^/]*/){1,2}[^/?&]*?)(?P<video_id>[0-9]+))(?:[/?&]|$)zhhttp://www.crunchyroll.com/wanna-be-the-strongest-in-the-world/episode-1-an-idol-wrestler-is-born-645513Z645513mp4uK   Wanna be the Strongest in the World Episode 1 – An Idol-Wrestler is Born!z$md5:2d17137920c64f2f49981a7797d275efzre:^https?://.*\.jpg$z%Yomiuri Telecasting Corporation (YTV)Z20131013zre:(?!.*&amp))idexttitledescription	thumbnailuploaderupload_daterQ   Zskip_downloadTz
Video gone)rQ   	info_dictparamsskipz7http://www.crunchyroll.com/media-589804/culture-japan-1Z589804flvu;   Culture Japan Episode 1 – Rebuilding Japan after the 3.11z$md5:2fbc01f90b87e8e9137296f37b461c12zDanny Choo NetworkZ20120213)r[   r\   r]   r^   r_   r`   ra   z~http://www.crunchyroll.com/rezero-starting-life-in-another-world-/episode-5-the-morning-of-our-promise-is-still-distant-702409Z702409zRe:Zero Partnersi%WZ20160501)r[   r\   r]   r^   r_   r`   	timestampra   )rQ   rb   rc   zhttp://www.crunchyroll.com/konosuba-gods-blessing-on-this-wonderful-world/episode-1-give-me-deliverance-from-this-judicial-injustice-727589Z727589zKadokawa Pictures Inc.iT
vXZ20170111z3KONOSUBA -God's blessing on this wonderful world! 2r
   z1Give Me Deliverance From This Judicial Injustice!r   )r[   r\   r]   r^   r_   r`   rf   ra   seriesseasonseason_numberepisodeepisode_numberzLhttp://www.crunchyroll.fr/girl-friend-beta/episode-11-goodbye-la-mode-661697rQ   Zonly_matchingz]http://www.crunchyroll.com/cosplay-complex-ova/episode-1-the-birth-of-the-cosplay-club-565617zIhttp://www.crunchyroll.com/11eyes/episode-1-piros-jszaka-red-night-535080Z535080zMarvelous AQL Inc.iJZ20091014)r[   r\   r]   r^   r`   rf   ra   zZhttp://www.crunchyroll.com/hakuoki-reimeiroku/episode-1-dawn-of-the-divine-warriors-606899Z606899u<   Hakuoki Reimeiroku Episode 1 – Dawn of the Divine Warriorsz^Ryunosuke was left to die, but Serizawa-san asked him a simple question "Do you want to live?"zGeneon EntertainmentZ20120717)r[   r\   r]   r^   r`   ra   zRhttp://www.crunchyroll.com/nyarko-san-another-crawling-chaos/episode-1-test-590532Z590532zTV TOKYOiTOZ20120305z"Nyarko-san: Another Crawling ChaoszHaiyoru! Nyaruani (ONA))	r[   r\   r]   r^   r`   rf   ra   rg   rh   z'http://www.crunchyroll.com/media-723735zchttps://www.crunchyroll.com/en-gb/mob-psycho-100/episode-2-urban-legends-encountering-rumors-780921)Z60106)Z61rm   )Z62rm   )80Z108)Z360Z480Z720Z1080c                    s<   t |tjr|nt|}|dd tt| j|f||S )NzAccept-Language*)
isinstancer   Requestr   
add_headersuperr   r;   )r*   Zurl_or_requestargskwargsrequest	__class__r.   r/   r;   
  s
    	zCrunchyrollIE._download_webpagec                    sV   t t|}t t|}t|}dd   fdd}||}tt|||}t|S )Nc                    sR   t |}t| D ]}||d |d   q|dd  }t t fdd|}|S )Nr
   c                    s   |   d S )N!   r.   )xmodulor.   r/   <lambda>"      zMCrunchyrollIE._decrypt_subtitles.<locals>.obfuscate_key_aux.<locals>.<lambda>)listrangeappendmap)countr~   startoutput_r.   r}   r/   obfuscate_key_aux  s    z;CrunchyrollIE._decrypt_subtitles.<locals>.obfuscate_key_auxc                    sz   t ttddtd }|| A d> }| |A }||d? A |A }t ddd}tt|t|d	 	 }|d
gd  S )Nr
      g@         a   )r   r
   asciir      )
intr   r   r   r   r   r   strr)   digest)keyZnum1Znum2Znum3Znum4prefixZshaHashr   r.   r/   obfuscate_key%  s    z7CrunchyrollIE._decrypt_subtitles.<locals>.obfuscate_key)r   r   r   r   r   zlib
decompress)r*   r'   ivr[   r   r   Zdecrypted_datar.   r   r/   _decrypt_subtitles  s    	
z CrunchyrollIE._decrypt_subtitlesc                 C   sl   d}t |ddD ]R\}}|jd dd}|jd dd}|jd d	d
}|d||||f 7 }q|S )N ./events/eventr   r   .,endtextz\N
z%d
%s --> %s
%s

)	enumeratefindallattribreplace)r*   sub_rootr   ieventr   r   r   r.   r.   r/   _convert_subtitles_to_srt4  s    z'CrunchyrollIE._convert_subtitles_to_srtc                 C   s   d}dd }d}|d|j d  7 }|d7 }|d|j d	  7 }|d
|j d  7 }|d|j d  7 }|d7 }|dD ]}|d|j d  7 }|d|j d  7 }|d|j d  7 }|d|j d  7 }|d|j d  7 }|d|j d  7 }|d|j d  7 }|d||j d  7 }|d||j d  7 }|d||j d  7 }|d||j d  7 }|d|j d  7 }|d|j d  7 }|d|j d  7 }|d|j d   7 }|d|j d!  7 }|d|j d"  7 }|d|j d#  7 }|d|j d$  7 }|d|j d%  7 }|d|j d&  7 }|d|j d'  7 }|d|j d(  7 }|d)7 }qr|d*7 }|d+D ]}|d,7 }|d|j d-  7 }|d|j d.  7 }|d|j d/  7 }|d|j d  7 }|d|j d%  7 }|d|j d&  7 }|d|j d'  7 }|d|j d0  7 }|d|j d1  7 }|d)7 }qB|S )2Nr   c                 S   s   d}| dkrd}|S )N0rK   z-1r.   )ZstrvalueZassvaluer.   r.   r/   ass_boolA  s    z9CrunchyrollIE._convert_subtitles_to_ass.<locals>.ass_boolz[Script Info]
z
Title: %s
r]   zScriptType: v4.00+
zWrapStyle: %s
Z
wrap_stylezPlayResX: %s
Z
play_res_xzPlayResY: %s
Z
play_res_yz
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
z./styles/stylezStyle: namer   Z	font_nameZ	font_sizeZprimary_colourZsecondary_colourZoutline_colourZback_colourZboldZitalicZ	underlineZ	strikeoutZscale_xZscale_yspacingZangleZborder_styleoutlineZshadow	alignmentZmargin_lZmargin_rZmargin_vencodingr   zZ
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
r   zDialogue: 0r   r   styleZeffectr   )r   r   )r*   r   r   r   r   r   r.   r.   r/   _convert_subtitles_to_ass>  s`    
z'CrunchyrollIE._convert_subtitles_to_assc                 C   s(   t |}d| |dd| |dgS )NZsrt)r\   r'   ass)r   r   r   )r*   subtitler   r.   r.   r/   _extract_subtitles~  s    z CrunchyrollIE._extract_subtitlesc                 C   s   i }t d|D ]\}}| jd|d| d|id}t|ts>q|d}t|dd}t|d	d
}	|r|r|	snq| |	||d}
| j	d|
ddd}|sq| 
|
||< q|S )Nz&\bssid=([0-9]+)"[^>]+?\btitle="([^"]+)ZSubtitle_GetXmlzDownloading subtitles for Zsubtitle_script_idr'   r[   r   zsubtitle ivr'   zsubtitle datar#   zlang_code=["\']([^"\']+)Zsubtitle_lang_codeFr&   )rer   r0   rp   r   r?   r   r   decoder=   r   )r*   r,   r1   	subtitlesZsub_idZsub_nameZsub_docZsidr   r'   r   Z	lang_coder.   r.   r/   _get_subtitles  s.      

zCrunchyrollIE._get_subtitlesc           5      C   sX  t | j|}|d}|ddkrD| ||d}| d|d}nd|d }| j| |||  d	}| jd
|ddd}|rt	|t 
d|}|rt|d}|ddkrt	d|d  ddd|kr|   | | jd|ddd|}	|	dpi }
| jd|dd dd}| jd|d d d}|sFt d!d| |}t d"d#|}| | jd$| |d%dd|pv|
d%}|rt|d&d'}| jd(d)g|d*d+d}g }|	d,g D ]}|d-}|d.}| |d||d/||}|D ]J}|sd0|d1< d2}||kr|d07 }||kr.|d07 }|r||d3< q|| q|sg }t d4|D ]:\}}t|}|d5}|rd6|krqd|| qd|sd7D ]}t ||}|r qʐq|s| j }g }|D ]}| j| \}}|d8 }g } | jd9|d:| ||||d;d<}!t|!trL|!d=}"|"d k	rL| |" | jd>|d?| |||d@d<}"t|"tr| |" | D ]N}"t|"dA}#|#|krq||# t|"dB}$|$sq|$ dCr|| j!|$|dDdEdFd+dG qt|"dH}%|%s q|"dI}&|t"t|&dJt"t|&dKdL}'dM|%krt dNdO|%# }%t$%|%}(t$&|(j'dPdQt(|(j)dR|$*dSdT f dU})| +|)||r|',dV| |)dW ||' q|',dX| |%|$dYdZ ||' qq| -|d[ | jd\|d]d^|id_}&i }*|	d`g D ]B}+|+d},|,s$q|*.|+ddag |,|+d/dbdc q|*sb| /||}*| jdd|ded+df}-d  }. }/ }0 }1}2t|&trt|&dg}.t|&dh}/t"t|&di}0t0|
djdk}1t|&dl}2|/s|
dm}/|0st"|
di}0|2s|
dni d}2t"| jdo|dpd d}3| j1||i d}4t2||||1|2||-|.|3|/|0|*|dq|4S )rNr,   r   mzDownloading mobile webpagez'<link rel="canonical" href="([^"]+)" />webpage_urlzhttp://www.rQ   r(   z1<div class="showmedia-trailer-notice">(.+?)</div>ztrailer-noticer   r7   z>Page\.messaging_box_controller\.addItems\(\[(?P<msg>{.+?})\]\)msgtyperG   zcrunchyroll returned error: %smessage_bodyTr9   z:To view this, please log in to verify you are 18 or older.z#vilos\.config\.media\s*=\s*({.+?});zvilos mediaz{}metadatazP(?:vilos\.config\.player\.language|LOCALE)\s*=\s*(["\'])(?P<lang>(?:(?!\1).)+)\1languagelang)r8   r4   )z(?s)<h1[^>]*>((?:(?!<h1).)*?<(?:span[^>]+itemprop=["\']title["\']|meta[^>]+itemprop=["\']position["\'])[^>]*>(?:(?!<h1).)+?)</h1>z#<title>(.+?),\s+-\s+.+? Crunchyrollvideo_titlez	^Watch\s+z {2,} zC<script[^>]*>\s*.+?\[media_id=%s\].+?({.+?"description"\s*:.+?})\);r^   z\r\nr   z/<a[^>]+href="/publisher/[^"]+"[^>]*>([^<]+)</a>z6<div>\s*Publisher:\s*<span>\s*(.+?)\s*</span>\s*</div>video_uploaderFZstreams
audio_langhardsub_langformatr   
preferencer   language_preferencez7(<a[^>]+token=["\']showmedia\.([0-9]{3,4})p["\'][^>]+>)hrefz
/freetrial)z$token=["\']showmedia\.([0-9]{3,4})p"zshowmedia\.([0-9]{3,4})ppZVideoPlayer_GetStandardConfigzDownloading media info for %s)media_idvideo_formatZvideo_qualityZcurrent_pager   z./{default}preload/stream_infoZVideoEncode_GetStreamInfozDownloading stream info for %s)r   r   Zvideo_encode_qualityz./video_encode_idz./filer6   rZ   Zm3u8_nativeZhls)Zentry_protocolZm3u8_idr&   z./hostz
./metadataz./heightz./width)r   heightwidthz.fplive.net/z
^rtmpe?://zhttp://zv.lvlt.crcdn.netz%s/%s/:ry   )netlocpathzhttp-)	format_idrQ   zrtmp-re   )r   rQ   Z	play_pathr\   )r   r   r   r   ZtbrZfpsZVideoPlayer_GetMediaMetadatazDownloading media infor   )r-   r'   r   ZenUSr   )rQ   r\   zB(?s)<h\d[^>]+\bid=["\']showmedia_about_episode_num[^>]+>(.+?)</h\drg   r   Zseries_titleZepisode_titlerk   durationi  Zepisode_image_urlr]   r_   zU(?s)<h\d[^>]+id=["\']showmedia_about_episode_num[^>]+>.+?</h\d>\s*<h4>\s*Season (\d+)zseason number)r[   r]   r^   r   r_   r`   rg   rh   ri   rj   rk   r   formats)3r   match
_VALID_URLr4   r;   r=   rT   geo_verification_headersrC   r   searchjsonloadsr?   Zraise_login_requiredZ_parse_jsonsubZ_og_search_descriptionr   r   Z_extract_vrv_formatsextendr   r   r   _FORMAT_IDSkeysr0   rp   r   findr   r@   Z_extract_m3u8_formatsr   stripr   rM   rO   rP   r   r   splitZ_is_valid_urlrB   Z_sort_formats
setdefaultZextract_subtitlesr   Z_search_json_ldr   )5r*   rQ   Zmobjr,   Zmobile_webpager   r1   Znote_mr   ZmediaZmedia_metadatar   r   Zvideo_descriptionr   r   streamr   r   Zvrv_formatsfr   Zavailable_fmtsafmtattrsr   r   Zvideo_encode_idsZstream_qualityZstream_formatr   Zstream_infosZ
streamdataZstream_infoZvideo_encode_idZ
video_fileZ	video_urlr   format_infoZparsed_video_urlZdirect_video_urlr   r   Zsubtitle_urlrg   rh   rj   rk   r   r_   ri   infor.   r.   r/   _real_extract  s   
              

   





 


 





    




  

  



  zCrunchyrollIE._real_extract)rU   rV   rW   IE_NAMEr   r   _TESTSr   r;   r   r   r   r   r   r   __classcell__r.   r.   rw   r/   rY   y   s       
    	
@
rY   c                   @   sJ   e Zd ZdZdZddddddd	d
ddddddddgZdd ZdS )CrunchyrollShowPlaylistIEzcrunchyroll:playlistzhttps?://(?:(?P<prefix>www|m)\.)?(?P<url>crunchyroll\.com/(?!(?:news|anime-news|library|forum|launchcalendar|lineup|store|comics|freetrial|login|media-\d+))(?P<id>[\w\-]+))/?(?:\?|$)zPhttp://www.crunchyroll.com/a-bridge-to-the-starry-skies-hoshizora-e-kakaru-hashiz5a-bridge-to-the-starry-skies-hoshizora-e-kakaru-hashiz7A Bridge to the Starry Skies - Hoshizora e Kakaru Hashi)r[   r]      )rQ   rb   playlist_countz.http://www.crunchyroll.com/cosplay-complex-ovazcosplay-complex-ovazCosplay Complex OVAr   ZGeorestricted)rQ   rb   r   rd   z<http://www.crunchyroll.com/ladies-versus-butlers?skip_wall=1Trl   c                    sh     |} j ||  d} jd|d d}td|} fdd|D }|  d|||dS )	Nr   r   r7   zB(?s)<li id="showview_videos_media_(\d+)"[^>]+>.*?<a href="([^"]+)"c                    s"   g | ]\}}  d | d|qS )zhttp://www.crunchyroll.comZCrunchyroll)Z
url_result).0Zep_ideprI   r.   r/   
<listcomp>  s   z;CrunchyrollShowPlaylistIE._real_extract.<locals>.<listcomp>Zplaylist)_typer[   r]   entries)Z	_match_idr;   rT   r   Z_html_search_metar   r   reverse)r*   rQ   Zshow_idr1   r]   Zepisode_pathsr   r.   rI   r/   r     s(    
 
z'CrunchyrollShowPlaylistIE._real_extractN)rU   rV   rW   r   r   r   r   r.   r.   r.   r/   r   ~  s(   	r   ))
__future__r   r   r   r   hashlibr   mathr   r   r   commonr   Zvrvr	   compatr   r   r   r   r   r   r   utilsr   r   r   r   r   r   r   r   r   r   r   r   Zaesr   r   rY   r   r.   r.   r.   r/   <module>   s"   $	8Q    	