bravotv.py (3775B)
1 # coding: utf-8 2 from __future__ import unicode_literals 3 4 import re 5 6 from .adobepass import AdobePassIE 7 from ..utils import ( 8 smuggle_url, 9 update_url_query, 10 int_or_none, 11 ) 12 13 14 class BravoTVIE(AdobePassIE): 15 _VALID_URL = r'https?://(?:www\.)?(?P<req_id>bravotv|oxygen)\.com/(?:[^/]+/)+(?P<id>[^/?#]+)' 16 _TESTS = [{ 17 'url': 'https://www.bravotv.com/top-chef/season-16/episode-15/videos/the-top-chef-season-16-winner-is', 18 'md5': 'e34684cfea2a96cd2ee1ef3a60909de9', 19 'info_dict': { 20 'id': 'epL0pmK1kQlT', 21 'ext': 'mp4', 22 'title': 'The Top Chef Season 16 Winner Is...', 23 'description': 'Find out who takes the title of Top Chef!', 24 'uploader': 'NBCU-BRAV', 25 'upload_date': '20190314', 26 'timestamp': 1552591860, 27 } 28 }, { 29 'url': 'http://www.bravotv.com/below-deck/season-3/ep-14-reunion-part-1', 30 'only_matching': True, 31 }, { 32 'url': 'https://www.oxygen.com/in-ice-cold-blood/season-2/episode-16/videos/handling-the-horwitz-house-after-the-murder-season-2', 33 'only_matching': True, 34 }] 35 36 def _real_extract(self, url): 37 site, display_id = re.match(self._VALID_URL, url).groups() 38 webpage = self._download_webpage(url, display_id) 39 settings = self._parse_json(self._search_regex( 40 r'<script[^>]+data-drupal-selector="drupal-settings-json"[^>]*>({.+?})</script>', webpage, 'drupal settings'), 41 display_id) 42 info = {} 43 query = { 44 'mbr': 'true', 45 } 46 account_pid, release_pid = [None] * 2 47 tve = settings.get('ls_tve') 48 if tve: 49 query['manifest'] = 'm3u' 50 mobj = re.search(r'<[^>]+id="pdk-player"[^>]+data-url=["\']?(?:https?:)?//player\.theplatform\.com/p/([^/]+)/(?:[^/]+/)*select/([^?#&"\']+)', webpage) 51 if mobj: 52 account_pid, tp_path = mobj.groups() 53 release_pid = tp_path.strip('/').split('/')[-1] 54 else: 55 account_pid = 'HNK2IC' 56 tp_path = release_pid = tve['release_pid'] 57 if tve.get('entitlement') == 'auth': 58 adobe_pass = settings.get('tve_adobe_auth', {}) 59 if site == 'bravotv': 60 site = 'bravo' 61 resource = self._get_mvpd_resource( 62 adobe_pass.get('adobePassResourceId') or site, 63 tve['title'], release_pid, tve.get('rating')) 64 query['auth'] = self._extract_mvpd_auth( 65 url, release_pid, 66 adobe_pass.get('adobePassRequestorId') or site, resource) 67 else: 68 shared_playlist = settings['ls_playlist'] 69 account_pid = shared_playlist['account_pid'] 70 metadata = shared_playlist['video_metadata'][shared_playlist['default_clip']] 71 tp_path = release_pid = metadata.get('release_pid') 72 if not release_pid: 73 release_pid = metadata['guid'] 74 tp_path = 'media/guid/2140479951/' + release_pid 75 info.update({ 76 'title': metadata['title'], 77 'description': metadata.get('description'), 78 'season_number': int_or_none(metadata.get('season_num')), 79 'episode_number': int_or_none(metadata.get('episode_num')), 80 }) 81 query['switch'] = 'progressive' 82 info.update({ 83 '_type': 'url_transparent', 84 'id': release_pid, 85 'url': smuggle_url(update_url_query( 86 'http://link.theplatform.com/s/%s/%s' % (account_pid, tp_path), 87 query), {'force_smil_url': True}), 88 'ie_key': 'ThePlatform', 89 }) 90 return info