1 from __future__ 
import unicode_literals
 
   5 from .common 
import InfoExtractor
 
  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 
= url_or_none(caption
.get('fileUrl')) 
  73                 if not subtitle_url 
or not subtitle_url
.startswith('http'): 
  75                 lang 
= caption
.get('fileLang', 'en') 
  76                 ext 
= determine_ext(subtitle_url
) 
  77                 subtitles
.setdefault(lang
, []).append({ 
  79                     'ext': 'ttml' if ext 
== 'xml' else ext
, 
  84             'display_id': display_id
, 
  86             'description': description
, 
  89             'season_number': season_number
, 
  90             'episode_number': episode_number
, 
  92             'age_limit': age_limit
, 
  94             'subtitles': subtitles
, 
  98 class DiscoveryGoIE(DiscoveryGoBaseIE
): 
  99     _VALID_URL 
= DiscoveryGoBaseIE
._VALID
_URL
_TEMPLATE 
% r
'(?:[^/]+/)+' 
 100     _GEO_COUNTRIES 
= ['US'] 
 102         'url': 'https://www.discoverygo.com/bering-sea-gold/reaper-madness/', 
 104             'id': '58c167d86b66d12f2addeb01', 
 106             'title': 'Reaper Madness', 
 107             'description': 'md5:09f2c625c99afb8946ed4fb7865f6e78', 
 109             'series': 'Bering Sea Gold', 
 116     def _real_extract(self
, url
): 
 117         display_id 
= self
._match
_id
(url
) 
 119         webpage 
= self
._download
_webpage
(url
, display_id
) 
 121         container 
= extract_attributes( 
 123                 r
'(<div[^>]+class=["\']video
-player
-container
[^
>]+>)', 
 124                 webpage, 'video container
')) 
 126         video = self._parse_json( 
 127             container.get('data
-video
') or container.get('data
-json
'), 
 130         stream = video.get('stream
') 
 132         return self._extract_video_info(video, stream, display_id) 
 135 class DiscoveryGoPlaylistIE(DiscoveryGoBaseIE): 
 136     _VALID_URL = DiscoveryGoBaseIE._VALID_URL_TEMPLATE % '' 
 138         'url
': 'https
://www
.discoverygo
.com
/bering
-sea
-gold
/', 
 140             'id': 'bering
-sea
-gold
', 
 141             'title
': 'Bering Sea Gold
', 
 142             'description
': 'md5
:cc5c6489835949043c0cc3ad66c2fa0e
', 
 144         'playlist_mincount
': 6, 
 148     def suitable(cls, url): 
 149         return False if DiscoveryGoIE.suitable(url) else super( 
 150             DiscoveryGoPlaylistIE, cls).suitable(url) 
 152     def _real_extract(self, url): 
 153         display_id = self._match_id(url) 
 155         webpage = self._download_webpage(url, display_id) 
 158         for mobj in re.finditer(r'data
-json
=(["\'])(?P<json>{.+?})\1', webpage): 
 159             data = self._parse_json( 
 160                 mobj.group('json'), display_id, 
 161                 transform_source=unescapeHTML, fatal=False) 
 162             if not isinstance(data, dict) or data.get('type') != 'episode': 
 164             episode_url = data.get('socialUrl') 
 167             entries.append(self.url_result( 
 168                 episode_url, ie=DiscoveryGoIE.ie_key(), 
 169                 video_id=data.get('id'))) 
 171         return self.playlist_result( 
 173             remove_end(self._og_search_title( 
 174                 webpage, fatal=False), ' | Discovery GO'), 
 175             self._og_search_description(webpage))