sevenplus.py (3304B)
1 # coding: utf-8 2 from __future__ import unicode_literals 3 4 import re 5 6 from .brightcove import BrightcoveNewIE 7 from ..compat import ( 8 compat_HTTPError, 9 compat_str, 10 ) 11 from ..utils import ( 12 ExtractorError, 13 try_get, 14 update_url_query, 15 ) 16 17 18 class SevenPlusIE(BrightcoveNewIE): 19 IE_NAME = '7plus' 20 _VALID_URL = r'https?://(?:www\.)?7plus\.com\.au/(?P<path>[^?]+\?.*?\bepisode-id=(?P<id>[^&#]+))' 21 _TESTS = [{ 22 'url': 'https://7plus.com.au/MTYS?episode-id=MTYS7-003', 23 'info_dict': { 24 'id': 'MTYS7-003', 25 'ext': 'mp4', 26 'title': 'S7 E3 - Wind Surf', 27 'description': 'md5:29c6a69f21accda7601278f81b46483d', 28 'uploader_id': '5303576322001', 29 'upload_date': '20171201', 30 'timestamp': 1512106377, 31 'series': 'Mighty Ships', 32 'season_number': 7, 33 'episode_number': 3, 34 'episode': 'Wind Surf', 35 }, 36 'params': { 37 'format': 'bestvideo', 38 'skip_download': True, 39 } 40 }, { 41 'url': 'https://7plus.com.au/UUUU?episode-id=AUMS43-001', 42 'only_matching': True, 43 }] 44 45 def _real_extract(self, url): 46 path, episode_id = re.match(self._VALID_URL, url).groups() 47 48 try: 49 media = self._download_json( 50 'https://videoservice.swm.digital/playback', episode_id, query={ 51 'appId': '7plus', 52 'deviceType': 'web', 53 'platformType': 'web', 54 'accountId': 5303576322001, 55 'referenceId': 'ref:' + episode_id, 56 'deliveryId': 'csai', 57 'videoType': 'vod', 58 })['media'] 59 except ExtractorError as e: 60 if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403: 61 raise ExtractorError(self._parse_json( 62 e.cause.read().decode(), episode_id)[0]['error_code'], expected=True) 63 raise 64 65 for source in media.get('sources', {}): 66 src = source.get('src') 67 if not src: 68 continue 69 source['src'] = update_url_query(src, {'rule': ''}) 70 71 info = self._parse_brightcove_metadata(media, episode_id) 72 73 content = self._download_json( 74 'https://component-cdn.swm.digital/content/' + path, 75 episode_id, headers={ 76 'market-id': 4, 77 }, fatal=False) or {} 78 for item in content.get('items', {}): 79 if item.get('componentData', {}).get('componentType') == 'infoPanel': 80 for src_key, dst_key in [('title', 'title'), ('shortSynopsis', 'description')]: 81 value = item.get(src_key) 82 if value: 83 info[dst_key] = value 84 info['series'] = try_get( 85 item, lambda x: x['seriesLogo']['name'], compat_str) 86 mobj = re.search(r'^S(\d+)\s+E(\d+)\s+-\s+(.+)$', info['title']) 87 if mobj: 88 info.update({ 89 'season_number': int(mobj.group(1)), 90 'episode_number': int(mobj.group(2)), 91 'episode': mobj.group(3), 92 }) 93 94 return info