diff options
Diffstat (limited to 'youtube_dl/extractor/funimation.py')
| -rw-r--r-- | youtube_dl/extractor/funimation.py | 66 | 
1 files changed, 24 insertions, 42 deletions
| diff --git a/youtube_dl/extractor/funimation.py b/youtube_dl/extractor/funimation.py index e44a2a87f..8c37509ec 100644 --- a/youtube_dl/extractor/funimation.py +++ b/youtube_dl/extractor/funimation.py @@ -2,15 +2,11 @@  from __future__ import unicode_literals  from .common import InfoExtractor -from ..compat import ( -    compat_HTTPError, -    compat_urllib_parse_unquote_plus, -) +from ..compat import compat_HTTPError  from ..utils import (      determine_ext,      int_or_none,      js_to_json, -    sanitized_Request,      ExtractorError,      urlencode_postdata  ) @@ -20,6 +16,7 @@ class FunimationIE(InfoExtractor):      _VALID_URL = r'https?://(?:www\.)?funimation(?:\.com|now\.uk)/shows/[^/]+/(?P<id>[^/?#&]+)'      _NETRC_MACHINE = 'funimation' +    _TOKEN = None      _TESTS = [{          'url': 'https://www.funimation.com/shows/hacksign/role-play/', @@ -38,56 +35,38 @@ class FunimationIE(InfoExtractor):      }, {          'url': 'https://www.funimation.com/shows/attack-on-titan-junior-high/broadcast-dub-preview/',          'info_dict': { -            'id': '9635', +            'id': '210051',              'display_id': 'broadcast-dub-preview',              'ext': 'mp4',              'title': 'Attack on Titan: Junior High - Broadcast Dub Preview', -            'description': 'md5:f8ec49c0aff702a7832cd81b8a44f803',              'thumbnail': r're:https?://.*\.(?:jpg|png)',          }, -        'skip': 'Access without user interaction is forbidden by CloudFlare', +        'params': { +            # m3u8 download +            'skip_download': True, +        },      }, {          'url': 'https://www.funimationnow.uk/shows/puzzle-dragons-x/drop-impact/simulcast/',          'only_matching': True,      }] -    _LOGIN_URL = 'http://www.funimation.com/login' - -    def _extract_cloudflare_session_ua(self, url): -        ci_session_cookie = self._get_cookies(url).get('ci_session') -        if ci_session_cookie: -            ci_session = compat_urllib_parse_unquote_plus(ci_session_cookie.value) -            # ci_session is a string serialized by PHP function serialize() -            # This case is simple enough to use regular expressions only -            return self._search_regex( -                r'"user_agent";s:\d+:"([^"]+)"', ci_session, 'user agent', -                default=None) -      def _login(self):          (username, password) = self._get_login_info()          if username is None:              return -        data = urlencode_postdata({ -            'email_field': username, -            'password_field': password, -        }) -        user_agent = self._extract_cloudflare_session_ua(self._LOGIN_URL) -        if not user_agent: -            user_agent = 'Mozilla/5.0 (Windows NT 5.2; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0' -        login_request = sanitized_Request(self._LOGIN_URL, data, headers={ -            'User-Agent': user_agent, -            'Content-Type': 'application/x-www-form-urlencoded' -        }) -        login_page = self._download_webpage( -            login_request, None, 'Logging in as %s' % username) -        if any(p in login_page for p in ('funimation.com/logout', '>Log Out<')): -            return -        error = self._html_search_regex( -            r'(?s)<div[^>]+id=["\']errorMessages["\'][^>]*>(.+?)</div>', -            login_page, 'error messages', default=None) -        if error: -            raise ExtractorError('Unable to login: %s' % error, expected=True) -        raise ExtractorError('Unable to log in') +        try: +            data = self._download_json( +                'https://prod-api-funimationnow.dadcdigital.com/api/auth/login/', +                None, 'Logging in as %s' % username, data=urlencode_postdata({ +                    'username': username, +                    'password': password, +                })) +            self._TOKEN = data['token'] +        except ExtractorError as e: +            if isinstance(e.cause, compat_HTTPError) and e.cause.code == 401: +                error = self._parse_json(e.cause.read().decode(), None)['error'] +                raise ExtractorError(error, expected=True) +            raise      def _real_initialize(self):          self._login() @@ -125,9 +104,12 @@ class FunimationIE(InfoExtractor):          description = self._html_search_meta(['description', 'og:description'], webpage, fatal=True)          try: +            headers = {} +            if self._TOKEN: +                headers['Authorization'] = 'Token %s' % self._TOKEN              sources = self._download_json(                  'https://prod-api-funimationnow.dadcdigital.com/api/source/catalog/video/%s/signed/' % video_id, -                video_id)['items'] +                video_id, headers=headers)['items']          except ExtractorError as e:              if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403:                  error = self._parse_json(e.cause.read(), video_id)['errors'][0] | 
