]>
Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/extractor/funimation.py
07d01caecfe6a1cc9bde8e23eb8d3955cdeda62c
   2 from __future__ 
import unicode_literals
 
   4 from .common 
import InfoExtractor
 
   5 from ..compat 
import compat_HTTPError
 
  15 class FunimationIE(InfoExtractor
): 
  16     _VALID_URL 
= r
'https?://(?:www\.)?funimation(?:\.com|now\.uk)/shows/[^/]+/(?P<id>[^/?#&]+)' 
  18     _NETRC_MACHINE 
= 'funimation' 
  22         'url': 'https://www.funimation.com/shows/hacksign/role-play/', 
  25             'display_id': 'role-play', 
  27             'title': '.hack//SIGN - Role Play', 
  28             'description': 'md5:b602bdc15eef4c9bbb201bb6e6a4a2dd', 
  29             'thumbnail': r
're:https?://.*\.jpg', 
  33             'skip_download': True, 
  36         'url': 'https://www.funimation.com/shows/attack-on-titan-junior-high/broadcast-dub-preview/', 
  39             'display_id': 'broadcast-dub-preview', 
  41             'title': 'Attack on Titan: Junior High - Broadcast Dub Preview', 
  42             'thumbnail': r
're:https?://.*\.(?:jpg|png)', 
  46             'skip_download': True, 
  49         'url': 'https://www.funimationnow.uk/shows/puzzle-dragons-x/drop-impact/simulcast/', 
  50         'only_matching': True, 
  54         username
, password 
= self
._get
_login
_info
() 
  58             data 
= self
._download
_json
( 
  59                 'https://prod-api-funimationnow.dadcdigital.com/api/auth/login/', 
  60                 None, 'Logging in', data
=urlencode_postdata({ 
  64             self
._TOKEN 
= data
['token'] 
  65         except ExtractorError 
as e
: 
  66             if isinstance(e
.cause
, compat_HTTPError
) and e
.cause
.code 
== 401: 
  67                 error 
= self
._parse
_json
(e
.cause
.read().decode(), None)['error'] 
  68                 raise ExtractorError(error
, expected
=True) 
  71     def _real_initialize(self
): 
  74     def _real_extract(self
, url
): 
  75         display_id 
= self
._match
_id
(url
) 
  76         webpage 
= self
._download
_webpage
(url
, display_id
) 
  78         def _search_kane(name
): 
  79             return self
._search
_regex
( 
  80                 r
"KANE_customdimensions\.%s\s*=\s*'([^']+)';" % name
, 
  81                 webpage
, name
, default
=None) 
  83         title_data 
= self
._parse
_json
(self
._search
_regex
( 
  84             r
'TITLE_DATA\s*=\s*({[^}]+})', 
  85             webpage
, 'title data', default
=''), 
  86             display_id
, js_to_json
, fatal
=False) or {} 
  88         video_id 
= title_data
.get('id') or self
._search
_regex
([ 
  89             r
"KANE_customdimensions.videoID\s*=\s*'(\d+)';", 
  90             r
'<iframe[^>]+src="/player/(\d+)"', 
  91         ], webpage
, 'video_id', default
=None) 
  93             player_url 
= self
._html
_search
_meta
([ 
  96                 'og:video:secure_url', 
  97             ], webpage
, fatal
=True) 
  98             video_id 
= self
._search
_regex
(r
'/player/(\d+)', player_url
, 'video id') 
 100         title 
= episode 
= title_data
.get('title') or _search_kane('videoTitle') or self
._og
_search
_title
(webpage
) 
 101         series 
= _search_kane('showName') 
 103             title 
= '%s - %s' % (series
, title
) 
 104         description 
= self
._html
_search
_meta
(['description', 'og:description'], webpage
, fatal
=True) 
 109                 headers
['Authorization'] = 'Token %s' % self
._TOKEN
 
 110             sources 
= self
._download
_json
( 
 111                 'https://prod-api-funimationnow.dadcdigital.com/api/source/catalog/video/%s/signed/' % video_id
, 
 112                 video_id
, headers
=headers
)['items'] 
 113         except ExtractorError 
as e
: 
 114             if isinstance(e
.cause
, compat_HTTPError
) and e
.cause
.code 
== 403: 
 115                 error 
= self
._parse
_json
(e
.cause
.read(), video_id
)['errors'][0] 
 116                 raise ExtractorError('%s said: %s' % ( 
 117                     self
.IE_NAME
, error
.get('detail') or error
.get('title')), expected
=True) 
 121         for source 
in sources
: 
 122             source_url 
= source
.get('src') 
 125             source_type 
= source
.get('videoType') or determine_ext(source_url
) 
 126             if source_type 
== 'm3u8': 
 127                 formats
.extend(self
._extract
_m
3u8_formats
( 
 128                     source_url
, video_id
, 'mp4', 
 129                     m3u8_id
='hls', fatal
=False)) 
 132                     'format_id': source_type
, 
 135         self
._sort
_formats
(formats
) 
 139             'display_id': display_id
, 
 141             'description': description
, 
 142             'thumbnail': self
._og
_search
_thumbnail
(webpage
), 
 144             'season_number': int_or_none(title_data
.get('seasonNum') or _search_kane('season')), 
 145             'episode_number': int_or_none(title_data
.get('episodeNum')), 
 147             'season_id': title_data
.get('seriesId'),