U
    y^q                     @   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 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_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
remove_endsanitized_Requestunified_strdate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   encode_download_xml)selfmethodvideo_idnoter&    r.   SC:\Users\TaGoRe\Desktop\beinconnect-dl\binaries\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)_get_login_info_download_webpage
_LOGIN_URL_search_regex_LOGIN_FORMr   get
startswithr   urljoin_form_hidden_inputsupdater   _html_search_regexr   )
r*   usernamepassword
login_pager2   Zlogin_form_strpost_urlr   responseerrorr.   r.   r/   _login6   s\        
     zCrunchyrollBaseIE._loginc                 C   s   |    d S )N)rL   r*   r.   r.   r/   _real_initializeg   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_qsrP   
urlunparse_replacer   )url
parsed_urlqsr.   r.   r/   _add_skip_wallj   s    

z CrunchyrollBaseIE._add_skip_wall)NN)__name__
__module____qualname__r=   r?   _NETRC_MACHINEr0   rL   rN   staticmethodrX   r.   r.   r.   r/   r   '   s   

1r   c                       sd  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id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)d*d+ddidd,dd-d.dd-d/d0dd1d2d3d4d5ddidd6d7dd8d9d:d;d5ddidd<d=dd>d?dd@dAdBdCddiddDdd-dEdd-gZdFdGdHdIdJZ fdKdLZdMdN ZdOdP Z	dQdR Z
dSdT ZdUdV ZdWdX Z  ZS )Y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_daterU   skip_downloadT)rU   	info_dictparamsz7http://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`   ra   rb   rc   rd   re   rf   z
Video gone)rU   rh   ri   skipz~http://www.crunchyroll.com/rezero-starting-life-in-another-world-/episode-5-the-morning-of-our-promise-is-still-distant-702409Z702409ub   Re:ZERO -Starting Life in Another World- Episode 5 – The Morning of Our Promise Is Still Distantz$md5:97664de1ab24bbf77a9c01918cb7dca9zTV TOKYOZ20160508zhttp://www.crunchyroll.com/konosuba-gods-blessing-on-this-wonderful-world/episode-1-give-me-deliverance-from-this-judicial-injustice-727589Z727589us   KONOSUBA -God's blessing on this wonderful world! 2 Episode 1 – Give Me Deliverance From This Judicial Injustice!z$md5:cbcf05e528124b0f3a0a419fc805ea7dzKadokawa Pictures Inc.20170118z1KONOSUBA -God's blessing on this wonderful world!z3KONOSUBA -God's blessing on this wonderful world! 2r
   z1Give Me Deliverance From This Judicial Injustice!r   )r`   ra   rb   rc   rd   re   rf   seriesseasonseason_numberepisodeepisode_numberzLhttp://www.crunchyroll.fr/girl-friend-beta/episode-11-goodbye-la-mode-661697rU   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535080u/   11eyes Episode 1 – Red Night ~ Piros éjszakazUKakeru and Yuka are thrown into an alternate nightmarish world they call "Red Night".zMarvelous AQL Inc.Z20091021)r`   ra   rb   rc   re   rf   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20120717zRhttp://www.crunchyroll.com/nyarko-san-another-crawling-chaos/episode-1-test-590532Z590532u*   Haiyoru! Nyaruani (ONA) Episode 1 – Testz5Mahiro and Nyaruko talk about official certification.Z20120305z"Nyarko-san: Another Crawling ChaoszHaiyoru! Nyaruani (ONA))r`   ra   rb   rc   re   rf   rm   rn   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61rt   )Z62rt   )80Z108)Z360Z480720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*   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   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_srt-  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0rO   z-1r.   )ZstrvalueZassvaluer.   r.   r/   ass_bool:  s    z9CrunchyrollIE._convert_subtitles_to_ass.<locals>.ass_boolz[Script Info]
z
Title: %s
rb   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_colourbolditalic	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_ass7  s`    
z'CrunchyrollIE._convert_subtitles_to_assc                 C   s(   t |}d| |dd| |dgS )Nsrt)ra   r&   ass)r   r   r   )r*   subtitler   r.   r.   r/   _extract_subtitlesw  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   ry   r   r@   r   r   decoder>   r   )r*   r,   r1   	subtitlesZsub_idZsub_nameZsub_docsidr   r&   r   	lang_coder.   r.   r/   _get_subtitles  s.      

zCrunchyrollIE._get_subtitlesc           5      C   sN  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}| d|d }t d!d"|}| | jd#| |d$dd|pX|
d$}|rvt|d%d&}| jd'd(g|d)d*t jd+}|rt|}| jd,d-g|d.d*d/}g }|	d0g D ]}|d1}|d2}| |d||d3||}|D ]J}|sd4|d5< d6}||kr&|d47 }||kr8|d47 }|r||d7< q|| q|sg }t d8|D ]:\}}t|}|d9}|rd:|krqn|| qn|sd;D ]}t ||}|r qԐq|s| j }g }|D ]}| j| \}}|d< } g }!| jd=|d>|  ||||d?d@}"t|"trV|"dA}#|#d k	rV|!|# | jdB|dC|  |||dDd@}#t|#tr|!|# |!D ]N}#t |#dE}$|$|krq||$ t |#dF}%|%sʐq|%!dGr|| j"|%|dHdIdJd*dK qt |#dL}&|&s
q|#dM}'| t#t |'dNt#t |'dOdP}(dQ|&krt dRdS|&$ }&t%&|&})t%'|)j(dTdUt)|)j*dV|%+dWdX f dY}*| ,|*|| r|(-dZ|  |*d[ ||( q|(-d\|  |&|%d]d^ ||( qq| .|d_ | jd`|dadb|idc}'i }+|	ddg D ]B},|,d}-|-s.q|+/|,ddeg |-|,d3dfdg q|+sl| 0||}+| jdh|did*d/}.d  }/ }0 }1 }2}3t|'trt |'dj}/t |'dk}0t#t |'dl}1t1|
dmdn}2t |'do}3|0s|
dp}0|1st#|
dl}1|3s|
dqi d}3t#| jdr|dsd d}4||||2|3|||.|/|4|0|1|+|dtS )uNr,   r   mzDownloading mobile webpagez'<link rel="canonical" href="([^"]+)" />webpage_urlzhttp://www.rU   r'   z1<div class="showmedia-trailer-notice">(.+?)</div>ztrailer-noticer   r7   z>Page\.messaging_box_controller\.addItems\(\[(?P<msg>{.+?})\]\)msgtyperK   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   zX(?s)<h1[^>]*>((?:(?!<h1).)*?<span[^>]+itemprop=["\']title["\'][^>]*>(?:(?!<h1).)+?)</h1>video_titlez {2,} zC<script[^>]*>\s*.+?\[media_id=%s\].+?({.+?"description"\s*:.+?})\);rc   z\r\nr   z,<div>Availability for free users:(.+?)</div>z.<div>[^<>]+<span>\s*(.+?\d{4})\s*</span></div>video_upload_dateF)r%   flagsz/<a[^>]+href="/publisher/[^"]+"[^>]*>([^<]+)</a>z6<div>\s*Publisher:\s*<span>\s*(.+?)\s*</span>\s*</div>video_uploaderr   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   r_   m3u8_nativehls)entry_protocolm3u8_idr%   z./hostz
./metadataz./heightz./width)r   heightwidthz.fplive.net/z
^rtmpe?://zhttp://zv.lvlt.crcdn.netz%s/%s/:r   )netlocpathzhttp-)	format_idrU   zrtmp-rj   )r   rU   	play_pathra   )r   r   r   r   tbrfpsZVideoPlayer_GetMediaMetadatazDownloading media infor   )r-   r&   r   ZenUSr   )rU   ra   zB(?s)<h\d[^>]+\bid=["\']showmedia_about_episode_num[^>]+>(.+?)</h\drm   series_titleepisode_titlerq   durationi  Zepisode_image_urlrb   rd   zU(?s)<h\d[^>]+id=["\']showmedia_about_episode_num[^>]+>.+?</h\d>\s*<h4>\s*Season (\d+)zseason number)r`   rb   rc   r   rd   re   rf   rm   rn   ro   rp   rq   r   formats)2r   match
_VALID_URLr4   r<   r>   rX   geo_verification_headersrE   r   searchjsonloadsr@   raise_login_required_parse_jsonsubr   r   DOTALLr   Z_extract_vrv_formatsextendr   r   r   _FORMAT_IDSkeysr0   ry   r   findr   rA   _extract_m3u8_formatsr   stripr   rQ   rS   rT   r   r   split_is_valid_urlrD   _sort_formats
setdefaultextract_subtitlesr   )5r*   rU   mobjr,   Zmobile_webpager   r1   Znote_mr   mediaZmedia_metadatar   r   video_descriptionr   r   r   streamr   r   Zvrv_formatsfr   Zavailable_fmtsafmtattrsr   r   Zvideo_encode_idsZstream_qualitystream_formatr   Zstream_infos
streamdatastream_infoZvideo_encode_id
video_file	video_urlr   format_infoZparsed_video_urlZdirect_video_urlr   r   subtitle_urlrm   rn   rp   rq   r   rd   ro   r.   r.   r/   _real_extract  s   
                

   





 


 





    




  

  



  zCrunchyrollIE._real_extract)rY   rZ   r[   IE_NAMEr   _TESTSr  r<   r   r   r   r   r   r  __classcell__r.   r.   r   r/   r^   x   s       
 
   
@
r^   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`   rb      )rU   rh   playlist_countz.http://www.crunchyroll.com/cosplay-complex-ovazcosplay-complex-ovazCosplay Complex OVAr   Georestricted)rU   rh   r"  rk   z<http://www.crunchyroll.com/ladies-versus-butlers?skip_wall=1Trr   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)
url_result).0ep_ideprM   r.   r/   
<listcomp>  s   z;CrunchyrollShowPlaylistIE._real_extract.<locals>.<listcomp>playlist)_typer`   rb   entries)	_match_idr<   rX   r   _html_search_metar   r   reverse)r*   rU   show_idr1   rb   Zepisode_pathsr+  r.   rM   r/   r    s(    
 
z'CrunchyrollShowPlaylistIE._real_extractN)rY   rZ   r[   r  r   r  r  r.   r.   r.   r/   r   x  s(   	r   )(
__future__r   r   r   r   hashlibr   mathr   r   r   commonr   vrvr	   compatr   r   r   r   r   r   utilsr   r   r   r   r   r   r   r   r   r   r   r   aesr   r   r^   r   r.   r.   r.   r/   <module>   s"    8Q    