1 from __future__ 
import unicode_literals
 
   5 from .common 
import InfoExtractor
 
   6 from ..compat 
import compat_str
 
  18 class DiscoveryGoBaseIE(InfoExtractor
): 
  19     _VALID_URL_TEMPLATE 
= r
'''(?x)https?://(?:www\.)?(?: 
  21             investigationdiscovery| 
  29         )go\.com/%s(?P<id>[^/?#&]+)''' 
  31     def _extract_video_info(self
, video
, stream
, display_id
): 
  35             if video
.get('authenticated') is True: 
  37                     'This video is only available via cable service provider subscription that' 
  38                     ' is not currently supported. You may want to use --cookies.', expected
=True) 
  40                 raise ExtractorError('Unable to find stream') 
  41         STREAM_URL_SUFFIX 
= 'streamUrl' 
  43         for stream_kind 
in ('', 'hds'): 
  44             suffix 
= STREAM_URL_SUFFIX
.capitalize() if stream_kind 
else STREAM_URL_SUFFIX
 
  45             stream_url 
= stream
.get('%s%s' % (stream_kind
, suffix
)) 
  49                 formats
.extend(self
._extract
_m
3u8_formats
( 
  50                     stream_url
, display_id
, 'mp4', entry_protocol
='m3u8_native', 
  51                     m3u8_id
='hls', fatal
=False)) 
  52             elif stream_kind 
== 'hds': 
  53                 formats
.extend(self
._extract
_f
4m
_formats
( 
  54                     stream_url
, display_id
, f4m_id
=stream_kind
, fatal
=False)) 
  55         self
._sort
_formats
(formats
) 
  57         video_id 
= video
.get('id') or display_id
 
  58         description 
= video
.get('description', {}).get('detailed') 
  59         duration 
= int_or_none(video
.get('duration')) 
  61         series 
= video
.get('show', {}).get('name') 
  62         season_number 
= int_or_none(video
.get('season', {}).get('number')) 
  63         episode_number 
= int_or_none(video
.get('episodeNumber')) 
  65         tags 
= video
.get('tags') 
  66         age_limit 
= parse_age_limit(video
.get('parental', {}).get('rating')) 
  69         captions 
= stream
.get('captions') 
  70         if isinstance(captions
, list): 
  71             for caption 
in captions
: 
  72                 subtitle_url 
= caption
.get('fileUrl') 
  73                 if (not subtitle_url 
or not isinstance(subtitle_url
, compat_str
) or 
  74                         not subtitle_url
.startswith('http')): 
  76                 lang 
= caption
.get('fileLang', 'en') 
  77                 ext 
= determine_ext(subtitle_url
) 
  78                 subtitles
.setdefault(lang
, []).append({ 
  80                     'ext': 'ttml' if ext 
== 'xml' else ext
, 
  85             'display_id': display_id
, 
  87             'description': description
, 
  90             'season_number': season_number
, 
  91             'episode_number': episode_number
, 
  93             'age_limit': age_limit
, 
  95             'subtitles': subtitles
, 
  99 class DiscoveryGoIE(DiscoveryGoBaseIE
): 
 100     _VALID_URL 
= DiscoveryGoBaseIE
._VALID
_URL
_TEMPLATE 
% r
'(?:[^/]+/)+' 
 101     _GEO_COUNTRIES 
= ['US'] 
 103         'url': 'https://www.discoverygo.com/bering-sea-gold/reaper-madness/', 
 105             'id': '58c167d86b66d12f2addeb01', 
 107             'title': 'Reaper Madness', 
 108             'description': 'md5:09f2c625c99afb8946ed4fb7865f6e78', 
 110             'series': 'Bering Sea Gold', 
 117     def _real_extract(self
, url
): 
 118         display_id 
= self
._match
_id
(url
) 
 120         webpage 
= self
._download
_webpage
(url
, display_id
) 
 122         container 
= extract_attributes( 
 124                 r
'(<div[^>]+class=["\']video
-player
-container
[^
>]+>)', 
 125                 webpage, 'video container
')) 
 127         video = self._parse_json( 
 128             container.get('data
-video
') or container.get('data
-json
'), 
 131         stream = video.get('stream
') 
 133         return self._extract_video_info(video, stream, display_id) 
 136 class DiscoveryGoPlaylistIE(DiscoveryGoBaseIE): 
 137     _VALID_URL = DiscoveryGoBaseIE._VALID_URL_TEMPLATE % '' 
 139         'url
': 'https
://www
.discoverygo
.com
/bering
-sea
-gold
/', 
 141             'id': 'bering
-sea
-gold
', 
 142             'title
': 'Bering Sea Gold
', 
 143             'description
': 'md5
:cc5c6489835949043c0cc3ad66c2fa0e
', 
 145         'playlist_mincount
': 6, 
 149     def suitable(cls, url): 
 150         return False if DiscoveryGoIE.suitable(url) else super( 
 151             DiscoveryGoPlaylistIE, cls).suitable(url) 
 153     def _real_extract(self, url): 
 154         display_id = self._match_id(url) 
 156         webpage = self._download_webpage(url, display_id) 
 159         for mobj in re.finditer(r'data
-json
=(["\'])(?P<json>{.+?})\1', webpage): 
 160             data = self._parse_json( 
 161                 mobj.group('json'), display_id, 
 162                 transform_source=unescapeHTML, fatal=False) 
 163             if not isinstance(data, dict) or data.get('type') != 'episode': 
 165             episode_url = data.get('socialUrl') 
 168             entries.append(self.url_result( 
 169                 episode_url, ie=DiscoveryGoIE.ie_key(), 
 170                 video_id=data.get('id'))) 
 172         return self.playlist_result( 
 174             remove_end(self._og_search_title( 
 175                 webpage, fatal=False), ' | Discovery GO'), 
 176             self._og_search_description(webpage))