tennistv.py (3945B)
1 # coding: utf-8 2 from __future__ import unicode_literals 3 4 import json 5 6 from .common import InfoExtractor 7 8 from ..utils import ( 9 ExtractorError, 10 unified_timestamp, 11 ) 12 13 14 class TennisTVIE(InfoExtractor): 15 _VALID_URL = r'https?://(?:www\.)?tennistv\.com/videos/(?P<id>[-a-z0-9]+)' 16 _TEST = { 17 'url': 'https://www.tennistv.com/videos/indian-wells-2018-verdasco-fritz', 18 'info_dict': { 19 'id': 'indian-wells-2018-verdasco-fritz', 20 'ext': 'mp4', 21 'title': 'Fernando Verdasco v Taylor Fritz', 22 'description': 're:^After his stunning victory.{174}$', 23 'thumbnail': 'https://atp-prod.akamaized.net/api/images/v1/images/112831/landscape/1242/0', 24 'timestamp': 1521017381, 25 'upload_date': '20180314', 26 }, 27 'params': { 28 'skip_download': True, 29 }, 30 'skip': 'Requires email and password of a subscribed account', 31 } 32 _NETRC_MACHINE = 'tennistv' 33 34 def _login(self): 35 username, password = self._get_login_info() 36 if not username or not password: 37 raise ExtractorError('No login info available, needed for using %s.' % self.IE_NAME, expected=True) 38 39 login_form = { 40 'Email': username, 41 'Password': password, 42 } 43 login_json = json.dumps(login_form).encode('utf-8') 44 headers = { 45 'content-type': 'application/json', 46 'Referer': 'https://www.tennistv.com/login', 47 'Origin': 'https://www.tennistv.com', 48 } 49 50 login_result = self._download_json( 51 'https://www.tennistv.com/api/users/v1/login', None, 52 note='Logging in', 53 errnote='Login failed (wrong password?)', 54 headers=headers, 55 data=login_json) 56 57 if login_result['error']['errorCode']: 58 raise ExtractorError('Login failed, %s said: %r' % (self.IE_NAME, login_result['error']['errorMessage'])) 59 60 if login_result['entitlement'] != 'SUBSCRIBED': 61 self.report_warning('%s may not be subscribed to %s.' % (username, self.IE_NAME)) 62 63 self._session_token = login_result['sessionToken'] 64 65 def _real_initialize(self): 66 self._login() 67 68 def _real_extract(self, url): 69 video_id = self._match_id(url) 70 webpage = self._download_webpage(url, video_id) 71 72 internal_id = self._search_regex(r'video=([0-9]+)', webpage, 'internal video id') 73 74 headers = { 75 'Origin': 'https://www.tennistv.com', 76 'authorization': 'ATP %s' % self._session_token, 77 'content-type': 'application/json', 78 'Referer': url, 79 } 80 check_data = { 81 'videoID': internal_id, 82 'VideoUrlType': 'HLSV3', 83 } 84 check_json = json.dumps(check_data).encode('utf-8') 85 check_result = self._download_json( 86 'https://www.tennistv.com/api/users/v1/entitlementchecknondiva', 87 video_id, note='Checking video authorization', headers=headers, data=check_json) 88 formats = self._extract_m3u8_formats(check_result['contentUrl'], video_id, ext='mp4') 89 90 vdata_url = 'https://www.tennistv.com/api/channels/v1/de/none/video/%s' % video_id 91 vdata = self._download_json(vdata_url, video_id) 92 93 timestamp = unified_timestamp(vdata['timestamp']) 94 thumbnail = vdata['video']['thumbnailUrl'] 95 description = vdata['displayText']['description'] 96 title = vdata['video']['title'] 97 98 series = vdata['tour'] 99 venue = vdata['displayText']['venue'] 100 round_str = vdata['seo']['round'] 101 102 return { 103 'id': video_id, 104 'title': title, 105 'description': description, 106 'formats': formats, 107 'thumbnail': thumbnail, 108 'timestamp': timestamp, 109 'series': series, 110 'season': venue, 111 'episode': round_str, 112 }