def get_play_token(self, locator, force=False): if settings.getInt(key='_drm_token_age') < int(time.time() - 50) and ( settings.getInt(key='_tokenrun') == 0 or settings.getInt(key='_tokenruntime') < int(time.time() - 30)): force = True if locator != settings.get(key='_drm_locator') or settings.getInt( key='_drm_token_age') < int(time.time() - 90) or force == True: settings.setInt(key='_tokenrun', value=1) settings.setInt(key='_tokenruntime', value=time.time()) data = self.download(url=settings.get(key='_token_url'), type="post", code=[200], data={"contentLocator": locator}, json_data=True, data_return=True, return_json=True, retry=True, check_data=False) if not data or not check_key(data, 'token'): settings.setInt(key="_tokenrun", value=0) return None settings.set(key='_drm_token', value=data['token']) settings.setInt(key='_drm_token_age', value=time.time()) settings.set(key='_drm_locator', value=locator) settings.setInt(key="_tokenrun", value=0) return data['token'] return settings.get(key='_drm_token')
def renew_epg(): if is_file_older_than_x_days( file=ADDON_PROFILE + "epg.xml", days=0.5) and (settings.getInt(key='_epgrun') == 0 or settings.getInt(key='_epgruntime') < (int(time.time()) - 300)): download_epg()
def _download_epg(**kwargs): _close() try: if settings.getInt('_epgrun') == 0 or settings.getInt( '_epgruntime') < (int(time.time()) - 300): download_epg() gui.notification(_.DONE_NOREBOOT) except: pass
def _reset(**kwargs): if not gui.yes_no(_.PLUGIN_RESET_YES_NO): return _close() try: xbmc.executeJSONRPC( '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":false}}}}' .format(ADDON_ID)) proxyport = settings.getInt(key='_proxyserver_port') shutil.rmtree(ADDON_PROFILE) settings.setInt(key='_proxyserver_port', value=proxyport) system, arch = get_system_arch() settings.set(key="_system", value=system) settings.set(key="_arch", value=arch) download_files() update_settings() change_icon() except: pass xbmc.executeJSONRPC( '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":true}}}}' .format(ADDON_ID)) gui.notification(_.PLUGIN_RESET_OK) signals.emit(signals.AFTER_RESET) gui.refresh()
def renew_epg(): md5JSON = load_file(file='md5.json', isJSON=True) if settings.getInt(key='_epgrun') == 0 or settings.getInt(key='_epgruntime') < (int(time.time()) - 300): try: if settings.getBool(key="minimalChannels"): if ADDON_ID == "plugin.video.ziggo" and settings.getBool(key='_base_v3') == True: key = 'epg.xml.v3.minimal.zip' else: key = 'epg.xml.minimal.zip' else: if ADDON_ID == "plugin.video.ziggo" and settings.getBool(key='_base_v3') == True: key = 'epg.xml.v3.zip' else: key = 'epg.xml.zip' if settings.get(key='_epg_md5') != md5JSON[key]: download_epg() except: download_epg()
def login(self, username, password, channels=False): settings.remove(key='_cookies') self._session = Session(cookies_key='_cookies') session_url = '{api_url}/USER/SESSIONS/'.format(api_url=settings.get(key='_api_url')) session_post_data = { "credentialsStdAuth": { 'username': username, 'password': password, 'remember': 'Y', 'deviceRegistrationData': { 'deviceId': settings.get(key='_devicekey'), 'accountDeviceIdType': 'DEVICEID', 'deviceType' : 'PCTV', 'vendor' : settings.get(key='_browser_name'), 'model' : settings.get(key='_browser_version'), 'deviceFirmVersion' : settings.get(key='_os_name'), 'appVersion' : settings.get(key='_os_version') } }, } resp = self._session.post(session_url, json=session_post_data) if resp.status_code != 200: gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE) self.clear_session() return try: data = resp.json() except: return if not data or not check_key(data, 'resultCode') or data['resultCode'] == 'KO': gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE) self.clear_session() return if channels == True or settings.getInt(key='_channels_age') < int(time.time() - 86400): self.get_channels_for_user() self.vod_subscription() if settings.getBool(key='save_password', default=False): set_credentials(username=username, password=password) else: set_credentials(username=username, password='') self.logged_in = True
def startHTTPServer(self): if self.isShutdown: return self.stopHTTPServer() try: self.HTTPServer = HTTPServer( self, ('', settings.getInt(key='_proxyserver_port'))) except IOError as e: pass threadStarting = threading.Thread(target=self.HTTPServer.serve_forever) threadStarting.start() self.HTTPServerThread = threadStarting
def login(self, username, password, channels=False): settings.remove(key='_access_token') user_agent = settings.get(key='_user_agent') HEADERS = { 'User-Agent': user_agent, 'X-Client-Id': settings.get(key='_client_id') + "||" + user_agent, 'X-OESP-Token': '', 'X-OESP-Username': username, } self._session = Session(headers=HEADERS) data = self.download(url=settings.get(key='_session_url'), type="post", code=[200], data={ "username": username, "password": password }, json_data=True, data_return=True, return_json=True, retry=True, check_data=False) if not data or not check_key(data, 'oespToken'): gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE) return settings.set(key='_access_token', value=data['oespToken']) self._session.headers.update({'X-OESP-Token': data['oespToken']}) if channels == True or settings.getInt( key='_channels_age') < int(time.time() - 86400): self.get_channels_for_user(location=data['locationId']) if settings.getBool(key='save_password', default=False): set_credentials(username=username, password=password) else: set_credentials(username=username, password='') self.logged_in = True
def startup(): settings.setBool(key='_test_running', value=False) system, arch = get_system_arch() settings.set(key="_system", value=system) settings.set(key="_arch", value=arch) settings.setInt(key='_proxyserver_port', value=find_free_port()) channels = False if settings.getInt(key='_channels_age') < int(time.time() - 86400): channels = True api.new_session(force=False, retry=False, channels=channels) api.update_prefs() hourly(type=0) daily() change_icon() hourly(type=2)
def play_url(self, type, channel=None, id=None, test=False, from_beginning=False): if self._debug_mode: log.debug('Executing: api.play_url') log.debug( 'Vars: type={type}, channel={channel}, id={id}, test={test}'. format(type=type, channel=channel, id=id, test=test)) playdata = {'path': '', 'license': '', 'token': ''} license = '' asset_id = '' militime = int(time.time() * 1000) typestr = 'PROGRAM' info = [] program_id = None if not test: while not self._abortRequested and not xbmc.Monitor( ).abortRequested() and settings.getBool(key='_test_running'): settings.setInt(key='_last_playing', value=time.time()) if self._abortRequested or xbmc.Monitor().waitForAbort(1): self._abortRequested = True break if self._abortRequested or xbmc.Monitor().abortRequested(): return playdata if type == 'channel': if not test: info_url = '{api_url}/TRAY/SEARCH/LIVE?maxResults=1&filter_airingTime=now&filter_channelIds={channel}&orderBy=airingStartTime&sortOrder=desc'.format( api_url=self._api_url, channel=channel) data = self.download(url=info_url, type='get', code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=True) if not data or not check_key(data['resultObj'], 'containers'): if self._debug_mode: log.debug('Failure to retrieve expected data') log.debug('Execution Done: api.play_url') return playdata for row in data['resultObj']['containers']: program_id = row['id'] info = data play_url = '{api_url}/CONTENT/VIDEOURL/LIVE/{channel}/{id}/?deviceId={device_key}&profile=G02&time={time}'.format( api_url=self._api_url, channel=channel, id=id, device_key=self._devicekey, time=militime) else: if type == 'program': typestr = "PROGRAM" else: typestr = "VOD" program_id = id program_url = '{api_url}/CONTENT/USERDATA/{type}/{id}'.format( api_url=self._api_url, type=typestr, id=id) data = self.download(url=program_url, type='get', code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=True) if not data or not check_key(data['resultObj'], 'containers'): if self._debug_mode: log.debug('Failure to retrieve expected data') log.debug('Execution Done: api.play_url') return playdata for row in data['resultObj']['containers']: if check_key(row, 'entitlement') and check_key( row['entitlement'], 'assets'): for asset in row['entitlement']['assets']: if type == 'program': if check_key(asset, 'videoType') and check_key( asset, 'programType' ) and asset['videoType'] == 'SD_DASH_PR' and asset[ 'programType'] == 'CUTV': asset_id = asset['assetId'] break else: if check_key(asset, 'videoType') and check_key( asset, 'assetType' ) and asset['videoType'] == 'SD_DASH_PR' and asset[ 'assetType'] == 'MASTER': if check_key( asset, 'rights') and asset['rights'] == 'buy': gui.ok(message=_.NO_STREAM_AUTH, heading=_.PLAY_ERROR) return playdata asset_id = asset['assetId'] break if len(unicode(asset_id)) == 0: if self._debug_mode: log.debug('Failure, empty asset_id') log.debug('Execution Done: api.play_url') return playdata play_url = '{api_url}/CONTENT/VIDEOURL/{type}/{id}/{asset_id}/?deviceId={device_key}&profile=G02&time={time}'.format( api_url=self._api_url, type=typestr, id=id, asset_id=asset_id, device_key=self._devicekey, time=militime) if self._abortRequested or xbmc.Monitor().abortRequested(): return playdata if program_id and not test: info_url = '{api_url}/CONTENT/DETAIL/{type}/{id}'.format( api_url=self._api_url, type=typestr, id=program_id) data = self.download(url=info_url, type='get', code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=True) if not data or not check_key(data['resultObj'], 'containers'): if self._debug_mode: log.debug('Failure to retrieve expected data') log.debug('Execution Done: api.play_url') return playdata info = data if self._abortRequested or xbmc.Monitor().waitForAbort(1): return playdata data = self.download(url=play_url, type='get', code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=True) if not data or not check_key( data['resultObj'], 'token') or not check_key( data['resultObj'], 'src') or not check_key( data['resultObj']['src'], 'sources') or not check_key( data['resultObj']['src']['sources'], 'src'): if self._debug_mode: log.debug('Failure, empty token or source') log.debug('Execution Done: api.play_url') return playdata if check_key( data['resultObj']['src']['sources'], 'contentProtection') and check_key( data['resultObj']['src']['sources']['contentProtection'], 'widevine') and check_key( data['resultObj']['src']['sources'] ['contentProtection']['widevine'], 'licenseAcquisitionURL'): license = data['resultObj']['src']['sources']['contentProtection'][ 'widevine']['licenseAcquisitionURL'] path = data['resultObj']['src']['sources']['src'] token = data['resultObj']['token'] if not test: real_url = "{hostscheme}://{netloc}".format( hostscheme=urlparse(path).scheme, netloc=urlparse(path).netloc) proxy_url = "http://127.0.0.1:{proxy_port}".format( proxy_port=settings.getInt(key='_proxyserver_port')) if self._debug_mode: log.debug('Real url: {real_url}'.format(real_url=real_url)) log.debug('Proxy url: {proxy_url}'.format(proxy_url=proxy_url)) settings.set(key='_stream_hostname', value=real_url) path = path.replace(real_url, proxy_url) settings.setInt(key='_drm_token_age', value=time.time()) settings.set(key='_renew_path', value=path) settings.set(key='_renew_token', value=token) playdata = { 'path': path, 'license': license, 'token': token, 'type': typestr, 'info': info } if self._debug_mode: log.debug( 'Returned Playdata: {playdata}'.format(playdata=playdata)) log.debug('Execution Done: api.play_url') return playdata
def test_channels(self, tested=False, channel=None): if self._debug_mode: log.debug('Executing: api.test_channels') log.debug('Vars: tested={tested}, channel={channel}'.format( tested=tested, channel=channel)) if channel: channel = unicode(channel) try: if not self._last_login_success or not settings.getBool( key='run_tests'): return 5 settings.setBool(key='_test_running', value=True) channels = load_file(file="channels.json", isJSON=True) results = load_file(file="channel_test.json", isJSON=True) count = 0 first = True last_tested_found = False test_run = False user_agent = settings.get(key='_user_agent') if not results: results = {} for row in channels: if count == 5 or (count == 1 and tested): if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return count channeldata = self.get_channel_data(row=row) id = unicode(channeldata['channel_id']) if len(id) > 0: if channel: if not id == channel: continue elif tested and check_key(results, 'last_tested'): if unicode(results['last_tested']) == id: last_tested_found = True continue elif last_tested_found: pass else: continue if check_key(results, id) and not tested and not first: continue livebandwidth = 0 replaybandwidth = 0 live = 'false' replay = 'false' epg = 'false' guide = 'false' if settings.getInt(key='_last_playing') > int(time.time() - 300): if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return 5 playdata = self.play_url(type='channel', channel=id, id=channeldata['asset_id'], test=True) if first and not self._last_login_success: if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return 5 if len(playdata['path']) > 0: CDMHEADERS = CONST_BASE_HEADERS CDMHEADERS['User-Agent'] = user_agent playdata['path'] = playdata['path'].split("&", 1)[0] self._session2 = Session(headers=CDMHEADERS) resp = self._session2.get(playdata['path']) if resp.status_code == 200: livebandwidth = find_highest_bandwidth( xml=resp.text) live = 'true' if check_key(results, id) and first and not tested: first = False if live == 'true': continue else: if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return 5 first = False counter = 0 while not self._abortRequested and not xbmc.Monitor( ).abortRequested() and counter < 5: if self._abortRequested or xbmc.Monitor().waitForAbort( 1): self._abortRequested = True break counter += 1 if settings.getInt( key='_last_playing') > int(time.time() - 300): if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return 5 if self._abortRequested or xbmc.Monitor().abortRequested(): return 5 program_url = '{api_url}/TRAY/AVA/TRENDING/YESTERDAY?maxResults=1&filter_channelIds={channel}'.format( api_url=self._api_url, channel=channeldata['channel_id']) data = self.download(url=program_url, type='get', code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=False, check_data=True) if data and check_key( data['resultObj'], 'containers') and check_key( data['resultObj']['containers'][0], 'id'): if settings.getInt( key='_last_playing') > int(time.time() - 300): if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return 5 playdata = self.play_url( type='program', channel=id, id=data['resultObj']['containers'][0]['id'], test=True) if len(playdata['path']) > 0: CDMHEADERS = CONST_BASE_HEADERS CDMHEADERS['User-Agent'] = user_agent playdata['path'] = playdata['path'].split( "&min_bitrate", 1)[0] self._session2 = Session(headers=CDMHEADERS) resp = self._session2.get(playdata['path']) if resp.status_code == 200: replaybandwidth = find_highest_bandwidth( xml=resp.text) replay = 'true' if os.path.isfile(ADDON_PROFILE + id + '_replay.json'): guide = 'true' if live == 'true': epg = 'true' results[id] = { 'id': id, 'live': live, 'replay': replay, 'livebandwidth': livebandwidth, 'replaybandwidth': replaybandwidth, 'epg': epg, 'guide': guide, } results['last_tested'] = id if not self._abortRequested: write_file(file="channel_test.json", data=results, isJSON=True) test_run = True counter = 0 while not self._abortRequested and not xbmc.Monitor( ).abortRequested() and counter < 15: if self._abortRequested or xbmc.Monitor().waitForAbort( 1): self._abortRequested = True break counter += 1 if settings.getInt( key='_last_playing') > int(time.time() - 300): if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return 5 if self._abortRequested or xbmc.Monitor().abortRequested(): return 5 count += 1 except: if test_run: self.update_prefs() count = 5 settings.setBool(key='_test_running', value=False) if self._debug_mode: log.debug('Execution Done: api.test_channels') return count
def check_vars(self): try: self._debug_mode except: self._debug_mode = settings.getBool(key='enable_debug') if self._debug_mode: log.debug('Executing: api.check_vars') try: self._cookies except: self._cookies = settings.get(key='_cookies') try: self._session_age except: self._session_age = settings.getInt(key='_session_age') try: self._last_login_success except: self._last_login_success = settings.getBool( key='_last_login_success') try: self._channels_age except: self._channels_age = settings.getInt(key='_channels_age') try: self._enable_cache except: self._enable_cache = settings.getBool(key='enable_cache') try: self._api_url except: self._api_url = settings.get(key='_api_url') try: self._devicekey except: self._devicekey = settings.get(key='_devicekey') try: self._username except: try: creds except: creds = get_credentials() self._username = creds['username'] try: self._abortRequested except: self._abortRequested = False try: self._password except: try: creds except: creds = get_credentials() self._password = creds['password'] if self._debug_mode: log.debug('Execution Done: api.check_vars')
def login(self, username, password, channels=False): settings.remove(key='_cookies') self._session = Session(cookies_key='_cookies') login_url = '{base_url}/inloggen'.format(base_url=CONST_BASE_URL) resp = self.download(url=login_url, type="get", code=None, data=None, json_data=False, data_return=True, return_json=False, retry=False, check_data=False) if resp.status_code != 200 and resp.status_code != 302: gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE) self.clear_session() return if self.check_data(resp=resp) == False: resp.encoding = 'utf-8' frmtoken = re.findall( r'name=\"form\[_token\]\"\s+value=\"([\S]*)\"', resp.text) session_post_data = { "form[password]": password, "form[email]": username, "form[login]": '', 'form[_token]': frmtoken[0], } resp = self.download(url=login_url, type="post", code=None, data=session_post_data, json_data=False, data_return=True, return_json=False, retry=False, check_data=False) if (resp.status_code != 200 and resp.status_code != 302) or self.check_data( resp=resp) == False: gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE) self.clear_session() return data = self.download( url='{base_url}/api/info'.format(base_url=CONST_BASE_URL), type="get", code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=False, check_data=True) if not data or not check_key(data, 'sessionToken') or not check_key( data, 'emp'): gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE) self.clear_session() return settings.set(key='_session_token', value=data['sessionToken']) settings.set(key='_emp_url', value=data['emp']['url']) settings.set(key='_emp_customer', value=data['emp']['customer']) settings.set(key='_emp_businessunit', value=data['emp']['businessunit']) if channels == True or settings.getInt( key='_channels_age') < int(time.time() - 86400): self.get_channels_for_user(channels=data['channels']) if settings.getBool(key='save_password', default=False): set_credentials(username=username, password=password) else: set_credentials(username=username, password='') self.logged_in = True
def play_url(self, type, channel=None, id=None, test=False, from_beginning='False'): self._session.headers = CONST_BASE_HEADERS self._session.headers.update({'Authorization': 'Bearer ' + self._session_token}) if self._debug_mode: log.debug('Executing: api.play_url') log.debug('Vars: type={type}, channel={channel}, id={id}, test={test}'.format(type=type, channel=channel, id=id, test=test)) log.debug('Request Session Headers') log.debug(self._session.headers) playdata = {'path': '', 'license': None, 'info': None} if not type or not len(unicode(type)) > 0: if self._debug_mode: log.debug('Failure executing api.play_url, no type set') log.debug('Execution Done: api.play_url') return playdata if not test: while not self._abortRequested and not xbmc.Monitor().abortRequested() and settings.getBool(key='_test_running'): settings.setInt(key='_last_playing', value=time.time()) if self._abortRequested or xbmc.Monitor().waitForAbort(1): self._abortRequested = True break if self._abortRequested or xbmc.Monitor().abortRequested(): return playdata if type == 'channel': info_url = '{api_url}/assets/{channel}'.format(api_url=CONST_DEFAULT_API, channel=channel) else: info_url = '{api_url}/assets/{id}'.format(api_url=CONST_DEFAULT_API, id=id) play_url = info_url + '/play' if not test: data = self.download(url=info_url, type="get", code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=True, allow_redirects=True) if not data or not check_key(data, 'id'): if self._debug_mode: log.debug('Failure to retrieve expected data') log.debug('Execution Done: api.play_url') return playdata session_post_data = { "player": { "name":"Bitmovin", "version":"8.22.0", "capabilities": { "mediaTypes": ["DASH","HLS","MSSS","Unspecified"], "drmSystems": ["Widevine"], }, "drmSystems": ["Widevine"], }, } if type == 'channel' and check_key(data, 'params') and check_key(data['params'], 'now') and check_key(data['params']['now'], 'id'): play_url2 = '{api_url}/assets/{id}/play'.format(api_url=CONST_DEFAULT_API, id=data['params']['now']['id']) info = data['params']['now'] data = self.download(url=play_url2, type="post", code=[200], data=session_post_data, json_data=True, data_return=True, return_json=True, retry=True, check_data=True, allow_redirects=True) if data and check_key(data, 'url'): if not settings.getBool(key='ask_start_from_beginning') or not gui.yes_no(message=_.START_FROM_BEGINNING, heading=info['title']): data = self.download(url=play_url, type="post", code=[200], data=session_post_data, json_data=True, data_return=True, return_json=True, retry=True, check_data=True, allow_redirects=True) else: data = self.download(url=play_url, type="post", code=[200], data=session_post_data, json_data=True, data_return=True, return_json=True, retry=True, check_data=True, allow_redirects=True) else: info = data data = self.download(url=play_url, type="post", code=[200], data=session_post_data, json_data=True, data_return=True, return_json=True, retry=True, check_data=True, allow_redirects=True) else: if self._abortRequested or xbmc.Monitor().abortRequested(): return playdata data = self.download(url=play_url, type="post", code=[200], data=session_post_data, json_data=True, data_return=True, return_json=True, retry=True, check_data=True, allow_redirects=True) if not data or not check_key(data, 'url'): if self._debug_mode: log.debug('Failure to retrieve expected data') log.debug('Execution Done: api.play_url') return playdata if check_key(data, 'drm') and check_key(data['drm'], 'licenseUrl'): license = data['drm']['licenseUrl'] path = data['url'] if not test: real_url = "{hostscheme}://{netloc}".format(hostscheme=urlparse(path).scheme, netloc=urlparse(path).netloc) proxy_url = "http://127.0.0.1:{proxy_port}".format(proxy_port=settings.getInt(key='_proxyserver_port')) if self._debug_mode: log.debug('Real url: {real_url}'.format(real_url=real_url)) log.debug('Proxy url: {proxy_url}'.format(proxy_url=proxy_url)) settings.set(key='_stream_hostname', value=real_url) path = path.replace(real_url, proxy_url) playdata = {'path': path, 'license': license, 'info': info} if self._debug_mode: log.debug('Returned Playdata: {playdata}'.format(playdata=playdata)) log.debug('Execution Done: api.play_url') return playdata
def play_url(self, type, channel=None, id=None, test=False, from_beginning=False): if not self.get_session(): return None profile_settings = load_profile(profile_id=1) headers = CONST_BASE_HEADERS headers.update( {'Authorization': 'Bearer ' + profile_settings['session_token']}) playdata = {'path': '', 'license': '', 'info': ''} if not test: counter = 0 while not self._abortRequested and not xbmc.Monitor( ).abortRequested() and counter < 5: profile_settings = load_profile(profile_id=1) if profile_settings['test_running'] == 0: break counter += 1 query = "UPDATE `vars` SET `last_playing`={last_playing} WHERE profile_id={profile_id}".format( last_playing=int(time.time()), profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) if self._abortRequested or xbmc.Monitor().waitForAbort(1): self._abortRequested = True break if self._abortRequested or xbmc.Monitor().abortRequested(): return playdata if type == 'channel': info_url = '{api_url}/assets/{channel}'.format( api_url=CONST_DEFAULT_API, channel=channel) else: info_url = '{api_url}/assets/{id}'.format( api_url=CONST_DEFAULT_API, id=id) play_url = info_url + '/play' playfrombeginning = False if not test: download = self.download(url=info_url, type='get', headers=headers, data=None, json_data=False, return_json=True) data = download['data'] resp = download['resp'] if not resp or not resp.status_code == 200 or not data or not check_key( data, 'id'): return playdata session_post_data = { "player": { "name": "Bitmovin", "version": "8.22.0", "capabilities": { "mediaTypes": ["DASH", "HLS", "MSSS", "Unspecified"], "drmSystems": ["Widevine"], }, "drmSystems": ["Widevine"], }, } if type == 'channel' and check_key(data, 'params') and check_key( data['params'], 'now') and check_key( data['params']['now'], 'id'): if settings.getBool(key='ask_start_from_beginning'): play_url2 = '{api_url}/assets/{id}/play'.format( api_url=CONST_DEFAULT_API, id=data['params']['now']['id']) info = data['params']['now'] download = self.download(url=play_url2, type='post', headers=headers, data=session_post_data, json_data=True, return_json=True) data = download['data'] resp = download['resp'] if resp and resp.status_code == 200 and data and check_key( data, 'url'): if gui.yes_no(message=_.START_FROM_BEGINNING, heading=info['title']): playfrombeginning = True if self._abortRequested or xbmc.Monitor().abortRequested(): return playdata if not playfrombeginning: download = self.download(url=play_url, type='post', headers=headers, data=session_post_data, json_data=True, return_json=True) data = download['data'] resp = download['resp'] if not resp or not resp.status_code == 200 or not data or not check_key( data, 'url'): return playdata if check_key(data, 'drm') and check_key(data['drm'], 'licenseUrl'): license = data['drm']['licenseUrl'] path = data['url'] if not test: real_url = "{hostscheme}://{netloc}".format( hostscheme=urlparse(path).scheme, netloc=urlparse(path).netloc) proxy_url = "http://127.0.0.1:{proxy_port}".format( proxy_port=settings.getInt(key='_proxyserver_port')) query = "UPDATE `vars` SET `stream_hostname`='{stream_hostname}' WHERE profile_id={profile_id}".format( stream_hostname=real_url, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) playdata = {'path': path, 'license': license, 'info': info} return playdata
def set_duration(xml): try: duration = settings.getInt(key='_stream_duration') if duration and duration > 0: given_duration = 0 matched = False duration += 300 regex = r"mediaPresentationDuration=\"PT([0-9]*)M([0-9]*)[0-9.]*S\"" matches2 = re.finditer(regex, xml, re.MULTILINE) if len([i for i in matches2]) > 0: matches = re.finditer(regex, xml, re.MULTILINE) matched = True else: regex2 = r"mediaPresentationDuration=\"PT([0-9]*)H([0-9]*)M([0-9]*)[0-9.]*S\"" matches3 = re.finditer(regex2, xml, re.MULTILINE) if len([i for i in matches3]) > 0: matches = re.finditer(regex2, xml, re.MULTILINE) matched = True else: regex3 = r"mediaPresentationDuration=\"PT([0-9]*)D([0-9]*)H([0-9]*)M([0-9]*)[0-9.]*S\"" matches4 = re.finditer(regex3, xml, re.MULTILINE) if len([i for i in matches4]) > 0: matches = re.finditer(regex3, xml, re.MULTILINE) matched = True if matched == True: given_day = 0 given_hour = 0 given_minute = 0 given_second = 0 for matchNum, match in enumerate(matches, start=1): if len(match.groups()) == 2: given_minute = int(match.group(1)) given_second = int(match.group(2)) elif len(match.groups()) == 3: given_hour = int(match.group(1)) given_minute = int(match.group(2)) given_second = int(match.group(3)) elif len(match.groups()) == 4: given_day = int(match.group(1)) given_hour = int(match.group(2)) given_minute = int(match.group(3)) given_second = int(match.group(4)) given_duration = (given_day * 24 * 60 * 60) + ( given_hour * 60 * 60) + (given_minute * 60) + given_second if not given_duration > 0 or given_duration > duration: minute, second = divmod(duration, 60) hour, minute = divmod(minute, 60) regex4 = r"mediaPresentationDuration=\"[a-zA-Z0-9.]*\"" subst = "mediaPresentationDuration=\"PT{hour}H{minute}M{second}S\"".format( hour=hour, minute=minute, second=second) regex5 = r"duration=\"[a-zA-Z0-9.]*\">" subst2 = "duration=\"PT{hour}H{minute}M{second}S\">".format( hour=hour, minute=minute, second=second) xml = re.sub(regex4, subst, xml, 0, re.MULTILINE) xml = re.sub(regex5, subst2, xml, 0, re.MULTILINE) except: pass return xml
def test_channels(self, tested=False, channel=None): if self._debug_mode: log.debug('Executing: api.test_channels') log.debug('Vars: tested={tested}, channel={channel}'.format(tested=tested, channel=channel)) if channel: channel = unicode(channel) try: if not self._last_login_success or not settings.getBool(key='run_tests'): return 5 settings.setBool(key='_test_running', value=True) channels = load_file(file="channels.json", isJSON=True) results = load_file(file="channel_test.json", isJSON=True) count = 0 first = True last_tested_found = False test_run = False user_agent = settings.get(key='_user_agent') if not results: results = {} for row in channels: if count == 5 or (count == 1 and tested): if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return count channeldata = self.get_channel_data(row=row, channelno=1) id = unicode(channeldata['channel_id']) if len(id) > 0: if channel: if not id == channel: continue elif tested and check_key(results, 'last_tested'): if unicode(results['last_tested']) == id: last_tested_found = True continue elif last_tested_found: pass else: continue if check_key(results, id) and not tested and not first: continue livebandwidth = 0 replaybandwidth = 0 live = 'false' replay = 'false' epg = 'false' guide = 'false' if settings.getInt(key='_last_playing') > int(time.time() - 300): if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return 5 playdata = self.play_url(type='channel', channel=id, id=id, test=True) if first and not self._last_login_success: if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return 5 if len(playdata['path']) > 0: CDMHEADERS = CONST_BASE_HEADERS CDMHEADERS['User-Agent'] = user_agent self._session2 = Session(headers=CDMHEADERS) resp = self._session2.get(playdata['path']) if resp.status_code == 200: livebandwidth = find_highest_bandwidth(xml=resp.text) live = 'true' if check_key(results, id) and first and not tested: first = False if live == 'true': continue else: if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return 5 first = False counter = 0 while not self._abortRequested and not xbmc.Monitor().abortRequested() and counter < 5: if self._abortRequested or xbmc.Monitor().waitForAbort(1): self._abortRequested = True break counter += 1 if settings.getInt(key='_last_playing') > int(time.time() - 300): if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return 5 if self._abortRequested or xbmc.Monitor().abortRequested(): return 5 self._session.headers = CONST_BASE_HEADERS self._session.headers.update({'Authorization': 'Bearer ' + self._session_token}) yesterday = datetime.datetime.now() - datetime.timedelta(1) fromtime = datetime.datetime.strftime(yesterday, '%Y-%m-%dT%H:%M:%S.000Z') tilltime = datetime.datetime.strftime(yesterday, '%Y-%m-%dT%H:%M:59.999Z') program_url = "{api_url}/schedule?channels={id}&from={fromtime}&until={tilltime}".format(api_url=CONST_DEFAULT_API, id=id, fromtime=fromtime, tilltime=tilltime); data = self.download(url=program_url, type="get", code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=False, allow_redirects=False) if data and check_key(data, 'epg') and check_key(data['epg'][0], 'id'): if settings.getInt(key='_last_playing') > int(time.time() - 300): if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return 5 playdata = self.play_url(type='program', channel=id, id=data['epg'][0]['id'], test=True) if len(playdata['path']) > 0: CDMHEADERS = CONST_BASE_HEADERS CDMHEADERS['User-Agent'] = user_agent self._session2 = Session(headers=CDMHEADERS) resp = self._session2.get(playdata['path']) if resp.status_code == 200: replaybandwidth = find_highest_bandwidth(xml=resp.text) replay = 'true' if os.path.isfile(ADDON_PROFILE + id + '_replay.json'): guide = 'true' if live == 'true': epg = 'true' results[id] = { 'id': id, 'live': live, 'replay': replay, 'livebandwidth': livebandwidth, 'replaybandwidth': replaybandwidth, 'epg': epg, 'guide': guide, } results['last_tested'] = id if not self._abortRequested: write_file(file="channel_test.json", data=results, isJSON=True) test_run = True counter = 0 while not self._abortRequested and not xbmc.Monitor().abortRequested() and counter < 15: if self._abortRequested or xbmc.Monitor().waitForAbort(1): self._abortRequested = True break counter += 1 if settings.getInt(key='_last_playing') > int(time.time() - 300): if test_run: self.update_prefs() settings.setBool(key='_test_running', value=False) return 5 if self._abortRequested or xbmc.Monitor().abortRequested(): return 5 count += 1 except: if test_run: self.update_prefs() count = 5 settings.setBool(key='_test_running', value=False) if self._debug_mode: log.debug('Execution Done: api.test_channels') return count