def startup(): directory = os.path.dirname(ADDON_PROFILE + os.sep + "images") try: if not os.path.exists(directory): os.makedirs(directory) except: pass directory = os.path.dirname(ADDON_PROFILE + os.sep + "cache") try: if not os.path.exists(directory): os.makedirs(directory) except: pass system, arch = get_system_arch() proxyserver_port = find_free_port() query = "UPDATE `vars` SET `arch`='{arch}', `system`='{system}', `test_running`=0, `proxyserver_port`={proxyserver_port} WHERE profile_id={profile_id}".format(arch=arch, system=system, proxyserver_port=proxyserver_port, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) hourly(type=0) daily() change_icon() update_prefs() hourly(type=2)
def do_GET(self): try: self._stream_url except: profile_settings = load_profile(profile_id=1) self._stream_url = profile_settings['stream_hostname'] try: self._last_playing except: self._last_playing = 0 if ".mpd" in self.path: profile_settings = load_profile(profile_id=1) self._stream_url = profile_settings['stream_hostname'] session = Session(cookies_key='cookies', save_cookies=False) r = session.get(self._stream_url + str(self.path)) xml = r.text xml = set_duration(xml=xml) if settings.getBool(key='force_highest_bandwidth'): xml = force_highest_bandwidth(xml=xml) self.send_response(r.status_code) r.headers['Content-Length'] = len(xml) for header in r.headers: if not 'Content-Encoding' in header and not 'Transfer-Encoding' in header: self.send_header(header, r.headers[header]) self.end_headers() try: xml = xml.encode('utf-8') except: pass try: self.wfile.write(xml) except: pass else: self._now_playing = int(time.time()) if self._last_playing + 60 < self._now_playing: self._last_playing = int(time.time()) query = "UPDATE `vars` SET `last_playing`='{last_playing}' WHERE profile_id={profile_id}".format( last_playing=self._last_playing, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) self.send_response(302) self.send_header('Location', self._stream_url + str(self.path)) self.end_headers()
def test_channel(channel, **kwargs): profile_settings = load_profile(profile_id=1) test_running = profile_settings['test_running'] while not api._abortRequested and not xbmc.Monitor().abortRequested( ) and test_running == 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 xbmc.Monitor().waitForAbort(1): api._abortRequested = True break profile_settings = load_profile(profile_id=1) test_running = profile_settings['test_running'] if api._abortRequested or xbmc.Monitor().abortRequested(): return None query = "UPDATE `vars` SET `last_playing`=0 WHERE profile_id={profile_id}".format( profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) api.test_channels(tested=True, channel=channel)
def change_channel(type, id, change, **kwargs): change = int(change) if not id or len(unicode(id)) == 0 or not type or len(unicode(type)) == 0: return False prefs = load_prefs(profile_id=1) id = unicode(id) type = unicode(type) mod_pref = { 'live': 1, 'live_auto': 1, 'replay': 1, 'replay_auto': 1, 'epg': 1, 'epg_auto': 1, } if change == 0: mod_pref[unicode(type) + '_auto'] = 0 if not check_key(prefs, id): mod_pref[type] = 0 else: if prefs[id][type] == 1: mod_pref[type] = 0 else: mod_pref[type] = 1 else: mod_pref[unicode(type) + '_auto'] = 1 results = load_tests(profile_id=1) if not results or not check_key(results, id) or not results[id][type] == 1: mod_pref[type] = 1 else: mod_pref[type] = 0 query = "REPLACE INTO `prefs_{profile_id}` VALUES ('{id}', '{live}', '{live_auto}', '{replay}', '{replay_auto}', '{epg}', '{epg_auto}')".format( profile_id=1, id=id, live=mod_pref['live'], live_auto=mod_pref['live_auto'], replay=mod_pref['replay'], replay_auto=mod_pref['replay_auto'], epg=mod_pref['epg'], epg_auto=mod_pref['epg_auto']) query_settings(query=query, return_result=False, return_insert=False, commit=True) if type == 'epg': create_playlist() xbmc.executeJSONRPC( '{{"jsonrpc":"2.0","id":1,"method":"GUI.ActivateWindow","params":{{"window":"videos","parameters":["plugin://' + unicode(ADDON_ID) + '/?_=channel_picker&type=' + type + '"]}}}}')
def search(query=None, **kwargs): items = [] if not query: query = gui.input(message=_.SEARCH, default='').strip() if not query: return db_query = "UPDATE `vars` SET `search10`=`search9`, `search9`=`search8`, `search8`=`search7`, `search7`=`search6`, `search6`=`search5`, `search5`=`search4`, `search4`=`search3`, `search3`=`search2`, `search2`=`search1`, `search1`='{search1}' WHERE profile_id={profile_id}".format(search1=query, profile_id=1) query_settings(query=db_query, return_result=False, return_insert=False, commit=False) folder = plugin.Folder(title=_(_.SEARCH_FOR, query=query)) processed = process_replaytv_search(search=query) items += processed['items'] if settings.getBool('showMoviesSeries'): processed = process_vod_content(data='series', start=0, search=query, type=_.SERIES) items += processed['items'] processed = process_vod_content(data='film1', start=0, search=query, type=_.MOVIES) items += processed['items'] processed = process_vod_content(data='videoshop', start=0, search=query, type=_.VIDEOSHOP) items += processed['items'] items[:] = sorted(items, key=_sort_replay_items, reverse=True) items = items[:25] folder.add_items(items) return folder
def logout(**kwargs): if not gui.yes_no(message=_.LOGOUT_YES_NO): return query = "UPDATE `vars` SET `pswd`='', `username`='' WHERE profile_id={profile_id}".format(profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) gui.refresh()
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)) profile_settings = load_profile(profile_id=1) proxyserver_port = int(profile_settings['proxyserver_port']) system = profile_settings['system'] arch = profile_settings['arch'] shutil.rmtree(ADDON_PROFILE) directory = os.path.dirname(ADDON_PROFILE + os.sep + "images") try: if not os.path.exists(directory): os.makedirs(directory) except: pass directory = os.path.dirname(ADDON_PROFILE + os.sep + "cache") try: if not os.path.exists(directory): os.makedirs(directory) except: pass query = "UPDATE `vars` SET `arch`='{arch}', `system`='{system}', `test_running`=0, `proxyserver_port`={proxyserver_port} WHERE profile_id={profile_id}".format( arch=arch, system=system, proxyserver_port=proxyserver_port, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) download_files() update_settings() update_prefs() 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 save_cookies(self): if not self._cookies_key: raise Exception('A cookies key needs to be set to save cookies') query = "UPDATE `vars` SET `cookies`='{cookies}' WHERE profile_id={profile_id}".format( cookies=json.dumps(self.cookies.get_dict()), profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True)
def startup(): system, arch = get_system_arch() proxyserver_port = find_free_port() query = "UPDATE `vars` SET `arch`='{arch}', `system`='{system}', `test_running`=0, `proxyserver_port`={proxyserver_port} WHERE profile_id={profile_id}".format(arch=arch, system=system, proxyserver_port=proxyserver_port, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) hourly(type=0) daily() change_icon() update_prefs() hourly(type=2)
def first_boot(): if gui.yes_no(message=_.SET_IPTV): try: plugin._set_settings_iptv() except: pass if gui.yes_no(message=_.SET_KODI): try: plugin._set_settings_kodi() except: pass query = "UPDATE `vars` SET `first_boot`='{first_boot}' WHERE profile_id={profile_id}".format(first_boot=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True)
def get_session(self): profile_settings = load_profile(profile_id=1) if check_key(profile_settings, 'last_login_time' ) and profile_settings['last_login_time'] > int(time.time( ) - 3600) and profile_settings['last_login_success'] == 1: return True heartbeat_url = '{base_url}/VSP/V3/OnLineHeartbeat?from=inMSAAccess'.format( base_url=CONST_BASE_URL) headers = CONST_BASE_HEADERS headers.update({'Content-Type': 'application/json'}) headers.update({'X_CSRFToken': profile_settings['csrf_token']}) session_post_data = {} download = self.download(url=heartbeat_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, 'result') or not check_key( data['result'], 'retCode') or not data['result']['retCode'] == '000000000': login_result = self.login() if not login_result['result']: return False try: query = "UPDATE `vars` SET `last_login_time`={last_login_time}, `last_login_success`=1 WHERE profile_id={profile_id}".format( last_login_time=int(time.time()), profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) except: pass return True
def update_settings(): profile_settings = load_profile(profile_id=1) user_agent = profile_settings['user_agent'] browser_name = uaparser.detect(user_agent)['browser']['name'] browser_version = uaparser.detect(user_agent)['browser']['version'] os_name = uaparser.detect(user_agent)['os']['name'] os_version = uaparser.detect(user_agent)['os']['version'] query = "UPDATE `vars` SET `browser_name`='{browser_name}', `browser_version`='{browser_version}', `os_name`='{os_name}', `os_version`='{os_version}' WHERE profile_id={profile_id}".format( browser_name=browser_name, browser_version=browser_version, os_name=os_name, os_version=os_version, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True)
def get_session(self): profile_settings = load_profile(profile_id=1) if check_key(profile_settings, 'last_login_time' ) and profile_settings['last_login_time'] > int(time.time( ) - 3600) and profile_settings['last_login_success'] == 1: return True devices_url = '{api_url}/USER/DEVICES'.format( api_url=profile_settings['api_url']) download = self.download(url=devices_url, type='get', headers=None, 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, 'resultCode') or not data['resultCode'] == 'OK': login_result = self.login() if not login_result['result']: return False try: query = "UPDATE `vars` SET `last_login_time`={last_login_time}, `last_login_success`=1 WHERE profile_id={profile_id}".format( last_login_time=int(time.time()), profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) except: pass return True
def login(ask=1, **kwargs): ask = int(ask) profile_settings = load_profile(profile_id=1) if len(profile_settings['devicekey']) == 0: _devicekey = 'w{uuid}'.format(uuid=uuid.uuid4()) query = "UPDATE `vars` SET `devicekey`='{devicekey}' WHERE profile_id={profile_id}".format( devicekey=_devicekey, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) creds = get_credentials() if len(creds['username']) < 1 or len(creds['password']) < 1 or ask == 1: username = gui.input(message=_.ASK_USERNAME, default=creds['username']).strip() if not len(username) > 0: gui.ok(message=_.EMPTY_USER, heading=_.LOGIN_ERROR_TITLE) return password = gui.input(message=_.ASK_PASSWORD, hide_input=True).strip() if not len(password) > 0: gui.ok(message=_.EMPTY_PASS, heading=_.LOGIN_ERROR_TITLE) return set_credentials(username=username, password=password) login_result = api.login() if login_result['result'] == False: query = "UPDATE `vars` SET `pswd`='', `last_login_success`='{last_login_success}' WHERE profile_id={profile_id}".format( last_login_success=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) if check_key(login_result['data'], 'error') and login_result['data']['error'] == 'toomany': gui.ok(message=_.TOO_MANY_DEVICES, heading=_.LOGIN_ERROR_TITLE) else: gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE) else: gui.ok(message=_.LOGIN_SUCCESS) query = "UPDATE `vars` SET `last_login_success`='{last_login_success}' WHERE profile_id={profile_id}".format( last_login_success=1, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) gui.refresh()
def update_settings(): profile_settings = load_profile(profile_id=1) settingsJSON = load_file(file='settings.json', isJSON=True) try: api_url = settingsJSON['api_url'] if len(api_url) == 0: api_url = CONST_DEFAULT_API except: api_url = CONST_DEFAULT_API try: img_size = settingsJSON['img_size'] if len(img_size) == 0: img_size = CONST_DEFAULT_IMG_SIZE except: img_size = CONST_DEFAULT_IMG_SIZE user_agent = profile_settings['user_agent'] browser_name = uaparser.detect(user_agent)['browser']['name'] browser_version = uaparser.detect(user_agent)['browser']['version'] os_name = uaparser.detect(user_agent)['os']['name'] os_version = uaparser.detect(user_agent)['os']['version'] query = "UPDATE `vars` SET `api_url`='{api_url}', `img_size`='{img_size}', `browser_name`='{browser_name}', `browser_version`='{browser_version}', `os_name`='{os_name}', `os_version`='{os_version}' WHERE profile_id={profile_id}".format( api_url=api_url, img_size=img_size, browser_name=browser_name, browser_version=browser_version, os_name=os_name, os_version=os_version, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True)
def login(ask=1, **kwargs): ask = int(ask) profile_settings = load_profile(profile_id=1) if len(profile_settings['devicekey']) == 0: devicekey = ''.join(random.choice(string.digits) for _ in range(10)) query = "UPDATE `vars` SET `devicekey`='{devicekey}' WHERE profile_id={profile_id}".format(devicekey=devicekey, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) creds = get_credentials() if len(creds['username']) < 1 or len(creds['password']) < 1 or ask == 1: username = gui.numeric(message=_.ASK_USERNAME, default=creds['username']).strip() if not len(username) > 0: gui.ok(message=_.EMPTY_USER, heading=_.LOGIN_ERROR_TITLE) return password = gui.numeric(message=_.ASK_PASSWORD).strip() if not len(password) > 0: gui.ok(message=_.EMPTY_PASS, heading=_.LOGIN_ERROR_TITLE) return set_credentials(username=username, password=password) login_result = api.login() if login_result['result'] == False: query = "UPDATE `vars` SET `pswd`='', `last_login_success`='{last_login_success}' WHERE profile_id={profile_id}".format(last_login_success=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) if check_key(login_result['data'], 'result') and check_key(login_result['data']['result'], 'retCode') and login_result['data']['result']['retCode'] == "157022007": gui.ok(message=_.TOO_MANY_DEVICES, heading=_.LOGIN_ERROR_TITLE) else: gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE) else: query = "UPDATE `vars` SET `last_login_success`='{last_login_success}' WHERE profile_id={profile_id}".format(last_login_success=1, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) gui.ok(message=_.LOGIN_SUCCESS) gui.refresh()
def play_video(type=None, channel=None, id=None, title=None, from_beginning=0, **kwargs): from_beginning = int(from_beginning) profile_settings = load_profile(profile_id=1) properties = {} if not type and not len(unicode(type)) > 0: return False if type == 'program': properties['seekTime'] = 1 playdata = api.play_url(type=type, channel=channel, id=id, from_beginning=from_beginning) if not playdata or not check_key(playdata, 'path'): return False CDMHEADERS = CONST_BASE_HEADERS CDMHEADERS['User-Agent'] = profile_settings['user_agent'] if check_key(playdata, 'license'): item_inputstream = inputstream.Widevine( license_key=playdata['license'], ) else: item_inputstream = inputstream.MPD() itemlabel = '' label2 = '' description = '' program_image = '' program_image_large = '' duration = 0 cast = [] director = [] writer = [] genres = [] if playdata['info']: if check_key(playdata['info'], 'params'): if check_key(playdata['info']['params'], 'start') and check_key( playdata['info']['params'], 'end'): startT = datetime.datetime.fromtimestamp( time.mktime( time.strptime(playdata['info']['params']['start'], "%Y-%m-%dT%H:%M:%SZ"))) endT = datetime.datetime.fromtimestamp( time.mktime( time.strptime(playdata['info']['params']['end'], "%Y-%m-%dT%H:%M:%SZ"))) duration = int((endT - startT).total_seconds()) if xbmc.getLanguage(xbmc.ISO_639_1) == 'nl': itemlabel = '{weekday} {day} {month} {yearhourminute} '.format( weekday=date_to_nl_dag(startT), day=startT.strftime("%d"), month=date_to_nl_maand(startT), yearhourminute=startT.strftime("%Y %H:%M")) else: itemlabel = startT.strftime( "%A %d %B %Y %H:%M ").capitalize() itemlabel += " - " if title: itemlabel += title + ' - ' if check_key(playdata['info'], 'title'): itemlabel += playdata['info']['title'] if check_key(playdata['info'], 'desc'): description = playdata['info']['desc'] if check_key(playdata['info'], 'images') and check_key( playdata['info']['images'][0], 'url'): program_image = playdata['info']['images'][0]['url'] program_image_large = playdata['info']['images'][0]['url'] if check_key(playdata['info'], 'params'): if check_key(playdata['info']['params'], 'credits'): for castmember in playdata['info']['params']['credits']: if castmember['role'] == "Actor": cast.append(castmember['person']) elif castmember['role'] == "Director": director.append(castmember['person']) elif castmember['role'] == "Writer": writer.append(castmember['person']) if check_key(playdata['info']['params'], 'genres'): for genre in playdata['info']['params']['genres']: genres.append(genre['title']) if check_key(playdata['info']['params'], 'duration'): duration = playdata['info']['params']['duration'] epcode = '' if check_key(playdata['info']['params'], 'seriesSeason'): epcode += 'S' + unicode( playdata['info']['params']['seriesSeason']) if check_key(playdata['info']['params'], 'seriesEpisode'): epcode += 'E' + unicode( playdata['info']['params']['seriesEpisode']) if check_key(playdata['info']['params'], 'episodeTitle'): label2 = playdata['info']['params']['episodeTitle'] if len(epcode) > 0: label2 += " (" + epcode + ")" elif check_key(playdata['info'], 'title'): label2 = playdata['info']['title'] if check_key(playdata['info']['params'], 'channelId'): query = "SELECT name FROM `channels` WHERE id='{channel}'".format( channel=playdata['info']['params']['channelId']) data = query_epg(query=query, return_result=True, return_insert=False, commit=False) if data: for row in data: label2 += " - " + row['name'] query = "UPDATE `vars` SET `stream_duration`='{stream_duration}' WHERE profile_id={profile_id}".format( stream_duration=duration, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) listitem = plugin.Item( label=itemlabel, label2=label2, art={ 'thumb': program_image, 'fanart': program_image_large }, info={ 'cast': cast, 'writer': writer, 'director': director, 'genre': genres, 'plot': description, 'duration': duration, 'mediatype': 'video', }, properties=properties, path=playdata['path'], headers=CDMHEADERS, inputstream=item_inputstream, ) return listitem
def play_video(type=None, channel=None, id=None, from_beginning=0, **kwargs): from_beginning = int(from_beginning) profile_settings = load_profile(profile_id=1) properties = {} if not type and not len(unicode(type)) > 0: return False if type == 'program': properties['seekTime'] = 1 playdata = api.play_url(type=type, channel=channel, id=id, from_beginning=from_beginning) if not playdata or not check_key(playdata, 'path'): return False CDMHEADERS = { 'User-Agent': profile_settings['user_agent'], 'X_CSRFToken': profile_settings['csrf_token'], 'Cookie': playdata['license']['cookie'], } if check_key(playdata, 'license') and check_key(playdata['license'], 'triggers') and check_key(playdata['license']['triggers'][0], 'licenseURL'): item_inputstream = inputstream.Widevine( license_key = playdata['license']['triggers'][0]['licenseURL'], ) if check_key(playdata['license']['triggers'][0], 'customData'): CDMHEADERS['AcquireLicense.CustomData'] = playdata['license']['triggers'][0]['customData'] CDMHEADERS['CADeviceType'] = 'Widevine OTT client' else: item_inputstream = inputstream.MPD() itemlabel = '' label2 = '' description = '' program_image = '' program_image_large = '' duration = 0 cast = [] director = [] writer = [] credits = [] if check_key(playdata['info'], 'startTime') and check_key(playdata['info'], 'endTime'): startT = datetime.datetime.fromtimestamp((int(playdata['info']['startTime']) / 1000)) startT = convert_datetime_timezone(startT, "UTC", "UTC") endT = datetime.datetime.fromtimestamp((int(playdata['info']['endTime']) / 1000)) endT = convert_datetime_timezone(endT, "UTC", "UTC") duration = int((endT - startT).total_seconds()) if xbmc.getLanguage(xbmc.ISO_639_1) == 'nl': itemlabel = '{weekday} {day} {month} {yearhourminute} '.format(weekday=date_to_nl_dag(startT), day=startT.strftime("%d"), month=date_to_nl_maand(startT), yearhourminute=startT.strftime("%Y %H:%M")) else: itemlabel = startT.strftime("%A %d %B %Y %H:%M ").capitalize() itemlabel += " - " if check_key(playdata['info'], 'name'): itemlabel += playdata['info']['name'] label2 = playdata['info']['name'] if type == 'channel': if from_beginning == 1: properties['seekTime'] = 1 elif settings.getBool(key='ask_start_from_beginning'): if gui.yes_no(message=_.START_FROM_BEGINNING, heading=label2): properties['seekTime'] = 1 if check_key(playdata['info'], 'introduce'): description = playdata['info']['introduce'] if check_key(playdata['info'], 'picture'): program_image = playdata['info']['picture']['posters'][0] program_image_large = playdata['info']['picture']['posters'][0] query = "SELECT name FROM `channels` WHERE id='{channel}'".format(channel=channel) data = query_epg(query=query, return_result=True, return_insert=False, commit=False) if data: for row in data: label2 += " - " + row['name'] query = "UPDATE `vars` SET `stream_duration`='{stream_duration}' WHERE profile_id={profile_id}".format(stream_duration=duration, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) listitem = plugin.Item( label = itemlabel, label2 = label2, art = { 'thumb': program_image, 'fanart': program_image_large }, info = { 'credits': credits, 'cast': cast, 'writer': writer, 'director': director, 'plot': description, 'duration': duration, 'mediatype': 'video', }, properties = properties, path = playdata['path'], headers = CDMHEADERS, inputstream = item_inputstream, ) return listitem
def login(self): creds = get_credentials() username = creds['username'] password = creds['password'] query = "UPDATE `vars` SET `cookies`='', `session_token`='' WHERE profile_id={profile_id}".format( profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) profile_settings = load_profile(profile_id=1) oauth = '' auth_url = '{login_url}/authenticate?redirect_uri=https%3A%2F%2Flivetv.canaldigitaal.nl%2Fauth.aspx&state={state}&response_type=code&scope=TVE&client_id=StreamGroup'.format( login_url=CONST_LOGIN_URL, state=int(time.time())) download = self.download(url=auth_url, type='get', headers=None, data=None, json_data=False, return_json=False, allow_redirects=False) data = download['data'] resp = download['resp'] if not resp or not resp.status_code == 200 or not data: if not data: data = {} return {'data': data, 'result': False} headers = CONST_LOGIN_HEADERS headers.update({'Referer': auth_url}) session_post_data = { "Password": password, "Username": username, } download = self.download(url=CONST_LOGIN_URL, type='post', headers=headers, data=session_post_data, json_data=False, return_json=False, allow_redirects=False) data = download['data'] resp = download['resp'] if not resp or not resp.status_code == 302: if not data: data = {} return {'data': data, 'result': False} params = parse_qs(urlparse(resp.headers['Location']).query) if check_key(params, 'code'): oauth = params['code'][0] if len(oauth) == 0: if not data: data = {} return {'data': data, 'result': False} challenge_url = "{base_url}/m7be2iphone/challenge.aspx".format( base_url=CONST_BASE_URL) session_post_data = { "autotype": "nl", "app": "cds", "prettyname": profile_settings['browser_name'], "model": "web", "serial": profile_settings['devicekey'], "oauthcode": oauth } headers = CONST_BASE_HEADERS headers.update({'Content-Type': 'application/json;charset=UTF-8'}) download = self.download(url=challenge_url, type='post', headers=headers, data=session_post_data, json_data=True, return_json=True, allow_redirects=False) data = download['data'] resp = download['resp'] if not resp or not resp.status_code == 200 or not data or not check_key( data, 'id') or not check_key(data, 'secret'): if not data: data = {} return {'data': data, 'result': False} login_url = "{base_url}/m7be2iphone/login.aspx".format( base_url=CONST_BASE_URL) headers = CONST_BASE_HEADERS headers.update({ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }) secret = '{id}\t{secr}'.format(id=data['id'], secr=data['secret']) session_post_data = { "secret": secret, "uid": self._devicekey, "app": "cds", } download = self.download(url=login_url, type='post', headers=headers, data=session_post_data, json_data=False, return_json=False, allow_redirects=False) data = download['data'] resp = download['resp'] if not resp or not resp.status_code == 302: if not data: data = {} return {'data': data, 'result': False} ssotoken_url = "{base_url}/m7be2iphone/capi.aspx?z=ssotoken".format( base_url=CONST_BASE_URL) headers = CONST_BASE_HEADERS download = self.download(url=ssotoken_url, type='get', headers=headers, data=None, json_data=False, return_json=True, allow_redirects=False) data = download['data'] resp = download['resp'] if not resp or not resp.status_code == 200 or not data or not check_key( data, 'ssotoken'): if not data: data = {} return {'data': data, 'result': False} session_url = "{api_url}/session".format(api_url=CONST_DEFAULT_API) session_post_data = { "sapiToken": data['ssotoken'], "deviceType": "PC", "deviceModel": profile_settings['browser_name'], "osVersion": '{name} {version}'.format(name=profile_settings['os_name'], version=profile_settings['os_version']), "deviceSerial": profile_settings['devicekey'], "appVersion": profile_settings['browser_version'], "brand": "cds" } headers = CONST_BASE_HEADERS headers.update({'Content-Type': 'application/json;charset=UTF-8'}) download = self.download(url=session_url, type='post', headers=headers, data=session_post_data, json_data=True, return_json=True, allow_redirects=False) data = download['data'] resp = download['resp'] if not resp or not resp.status_code == 200 or not data or not check_key( data, 'token'): if not data: data = {} return {'data': data, 'result': False} query = "UPDATE `vars` SET `session_token`={session_token} WHERE profile_id={profile_id}".format( session_token=data['token'], profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return {'data': data, 'result': True}
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 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) playdata = { 'path': '', 'license': '', 'token': '', 'type': '', 'info': '' } license = '' asset_id = '' militime = int(time.time() * 1000) typestr = 'PROGRAM' info = [] program_id = None 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': 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=profile_settings['api_url'], channel=channel) download = self.download(url=info_url, type='get', headers=None, 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, 'resultCode' ) or not data['resultCode'] == 'OK' or not check_key( data, 'resultObj') or not check_key( data['resultObj'], 'containers'): 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=profile_settings['api_url'], channel=channel, id=id, device_key=profile_settings['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=profile_settings['api_url'], type=typestr, id=id) download = self.download(url=program_url, type='get', headers=None, 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, 'resultCode' ) or not data['resultCode'] == 'OK' or not check_key( data, 'resultObj') or not check_key( data['resultObj'], 'containers'): 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: return playdata play_url = '{api_url}/CONTENT/VIDEOURL/{type}/{id}/{asset_id}/?deviceId={device_key}&profile=G02&time={time}'.format( api_url=profile_settings['api_url'], type=typestr, id=id, asset_id=asset_id, device_key=profile_settings['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=profile_settings['api_url'], type=typestr, id=program_id) download = self.download(url=info_url, type='get', headers=None, 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, 'resultCode' ) or not data['resultCode'] == 'OK' or not check_key( data, 'resultObj') or not check_key( data['resultObj'], 'containers'): return playdata info = data if self._abortRequested or xbmc.Monitor().waitForAbort(1): return playdata download = self.download(url=play_url, type='get', headers=None, 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, 'resultCode' ) or not data['resultCode'] == 'OK' or not check_key( data, 'resultObj') 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'): 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=profile_settings['proxyserver_port']) path = path.replace(real_url, proxy_url) 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, 'token': token, 'type': typestr, 'info': info } return playdata
def login(self): creds = get_credentials() username = creds['username'] password = creds['password'] query = "UPDATE `vars` SET `cookies`='' WHERE profile_id={profile_id}".format( profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) profile_settings = load_profile(profile_id=1) session_url = '{api_url}/USER/SESSIONS/'.format( api_url=profile_settings['api_url']) email_or_pin = settings.getBool(key='email_instead_of_customer') if email_or_pin: session_post_data = { "credentialsExtAuth": { 'credentials': { 'loginType': 'UsernamePassword', 'username': username, 'password': password, 'appId': 'KPN', }, 'remember': 'Y', 'deviceInfo': { 'deviceId': profile_settings['devicekey'], 'deviceIdType': 'DEVICEID', 'deviceType': 'PCTV', 'deviceVendor': profile_settings['browser_name'], 'deviceModel': profile_settings['browser_version'], 'deviceFirmVersion': profile_settings['os_name'], 'appVersion': profile_settings['os_version'] } }, } else: session_post_data = { "credentialsStdAuth": { 'username': username, 'password': password, 'remember': 'Y', 'deviceRegistrationData': { 'deviceId': profile_settings['devicekey'], 'accountDeviceIdType': 'DEVICEID', 'deviceType': 'PCTV', 'vendor': profile_settings['browser_name'], 'model': profile_settings['browser_version'], 'deviceFirmVersion': profile_settings['os_name'], 'appVersion': profile_settings['os_version'] } }, } download = self.download(url=session_url, type='post', headers=None, 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, 'resultCode') or not data['resultCode'] == 'OK': if not data: data = {} return {'data': data, 'result': False} return {'data': data, 'result': True}
def test_channels(self, tested=False, channel=None): profile_settings = load_profile(profile_id=1) if channel: channel = unicode(channel) try: if not profile_settings[ 'last_login_success'] == 1 or not settings.getBool( key='run_tests'): return 5 query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=1, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) query = "SELECT * FROM `channels`" channels = query_epg(query=query, return_result=True, return_insert=False, commit=False) results = load_tests(profile_id=1) count = 0 first = True last_tested_found = False test_run = False user_agent = profile_settings['user_agent'] if not results: results = {} for row in channels: if count == 5 or (count == 1 and tested): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return count id = unicode(row['id']) if len(id) > 0: if channel: if not id == channel: continue elif tested: if unicode(profile_settings['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 = 0 replay = 0 epg = 0 guide = 0 profile_settings = load_profile(profile_id=1) if profile_settings['last_playing'] > int(time.time() - 300): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return 5 playdata = self.play_url(type='channel', channel=id, id=row['assetid'], test=True) if first and not profile_settings['last_login_success']: if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return 5 if len(playdata['path']) > 0: CDMHEADERS = CONST_BASE_HEADERS CDMHEADERS['User-Agent'] = user_agent playdata['path'] = playdata['path'].split("&", 1)[0] session = Session(headers=CDMHEADERS) resp = session.get(playdata['path']) if resp.status_code == 200: livebandwidth = find_highest_bandwidth( xml=resp.text) live = 1 if check_key(results, id) and first and not tested: first = False if live == 1: continue else: if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) 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 profile_settings = load_profile(profile_id=1) if profile_settings['last_playing'] > int(time.time() - 300): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) 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=profile_settings['api_url'], channel=channeldata['channel_id']) download = self.download(url=program_url, type='get', headers=None, data=None, json_data=False, return_json=True) data = download['data'] resp = download['resp'] if resp and resp.status_code == 200 and data and check_key( data, 'resultCode' ) and data['resultCode'] == 'OK' and check_key( data, 'resultObj') and check_key( data['resultObj'], 'containers') and check_key( data['resultObj']['containers'][0], 'id'): profile_settings = load_profile(profile_id=1) if profile_settings['last_playing'] > int(time.time() - 300): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) 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] session = Session(headers=CDMHEADERS) resp = session.get(playdata['path']) if resp.status_code == 200: replaybandwidth = find_highest_bandwidth( xml=resp.text) replay = 1 query = "SELECT id FROM `epg` WHERE channel='{channel}' LIMIT 1".format( channel=id) data = query_epg(query=query, return_result=True, return_insert=False, commit=False) if len(data) > 0: guide = 1 if live == 1: epg = 1 if not self._abortRequested: query = "UPDATE `vars` SET `last_tested`='{last_tested}' WHERE profile_id={profile_id}".format( last_tested=id, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) query = "REPLACE INTO `tests_{profile_id}` VALUES ('{id}', '{live}', '{livebandwidth}', '{replay}', '{replaybandwidth}', '{epg}', '{guide}')".format( profile_id=1, id=id, live=live, livebandwidth=livebandwidth, replay=replay, replaybandwidth=replaybandwidth, epg=epg, guide=guide) query_settings(query=query, return_result=False, return_insert=False, commit=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 profile_settings = load_profile(profile_id=1) if profile_settings['last_playing'] > int(time.time() - 300): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return 5 if self._abortRequested or xbmc.Monitor().abortRequested(): return 5 count += 1 except: if test_run: update_prefs() count = 5 query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return count
def play_url(self, type, channel=None, id=None, test=False, from_beginning=0): from_beginning = int(from_beginning) if not self.get_session(): return None profile_settings = load_profile(profile_id=1) playdata = {'path': '', 'license': '', 'info': ''} headers = CONST_BASE_HEADERS headers.update({'Content-Type': 'application/json'}) headers.update({'X_CSRFToken': profile_settings['csrf_token']}) mediaID = None info = {} if not type or not len(unicode(type)) > 0: return playdata 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 militime = int(time.time() * 1000) if not type == 'vod': mediaID = int(channel) + 1 query = "SELECT assetid FROM `channels` WHERE id='{channel}'".format( channel=channel) data = query_epg(query=query, return_result=True, return_insert=False, commit=False) if data: for row in data: mediaID = row['assetid'] if type == 'channel' and channel: if not test: session_post_data = { 'needChannel': '0', 'queryChannel': { 'channelIDs': [ channel, ], 'isReturnAllMedia': '1', }, 'queryPlaybill': { 'count': '1', 'endTime': militime, 'isFillProgram': '1', 'offset': '0', 'startTime': militime, 'type': '0', } } channel_url = '{base_url}/VSP/V3/QueryPlaybillListStcProps?SID=queryPlaybillListStcProps3&DEVICE=PC&DID={deviceID}&from=throughMSAAccess'.format( base_url=CONST_BASE_URL, deviceID=profile_settings['devicekey']) download = self.download(url=channel_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, 'result') or not check_key( data['result'], 'retCode') or not data['result'][ 'retCode'] == '000000000' or not check_key( data, 'channelPlaybills') or not check_key( data['channelPlaybills'][0], 'playbillLites') or not check_key( data['channelPlaybills'][0] ['playbillLites'][0], 'ID'): return playdata id = data['channelPlaybills'][0]['playbillLites'][0]['ID'] session_post_data = { 'playbillID': id, 'channelNamespace': '310303', 'isReturnAllMedia': '1', } program_url = '{base_url}/VSP/V3/QueryPlaybill?from=throughMSAAccess'.format( base_url=CONST_BASE_URL) download = self.download(url=program_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, 'result') or not check_key( data['result'], 'retCode') or not data['result'][ 'retCode'] == '000000000' or not check_key( data, 'playbillDetail'): return playdata info = data['playbillDetail'] session_post_data = { "businessType": "BTV", "channelID": channel, "checkLock": { "checkType": "0", }, "isHTTPS": "1", "isReturnProduct": "1", "mediaID": mediaID, } elif type == 'program' and id: if not test: session_post_data = { 'playbillID': id, 'channelNamespace': '310303', 'isReturnAllMedia': '1', } program_url = '{base_url}/VSP/V3/QueryPlaybill?from=throughMSAAccess'.format( base_url=CONST_BASE_URL) download = self.download(url=program_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, 'result') or not check_key( data['result'], 'retCode') or not data['result'][ 'retCode'] == '000000000' or not check_key( data, 'playbillDetail'): return playdata info = data['playbillDetail'] session_post_data = { "businessType": "CUTV", "channelID": channel, "checkLock": { "checkType": "0", }, "isHTTPS": "1", "isReturnProduct": "1", "mediaID": mediaID, "playbillID": id, } elif type == 'vod' and id: session_post_data = {'VODID': id} program_url = '{base_url}/VSP/V3/QueryVOD?from=throughMSAAccess'.format( base_url=CONST_BASE_URL) download = self.download(url=program_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, 'result') or not check_key( data['result'], 'retCode') or not data['result'][ 'retCode'] == '000000000' or not check_key( data, 'VODDetail') or not check_key( data['VODDetail'], 'VODType'): return playdata info = data['VODDetail'] session_post_data = { "VODID": id, "checkLock": { "checkType": "0", }, "isHTTPS": "1", "isReturnProduct": "1", "mediaID": '', } if check_key(info, 'series') and check_key(info['series'][0], 'VODID'): session_post_data["seriesID"] = info['series'][0]['VODID'] session_post_data["mediaID"] = channel else: if not check_key(info, 'mediaFiles') or not check_key( info['mediaFiles'][0], 'ID'): return playdata session_post_data["mediaID"] = info['mediaFiles'][0]['ID'] if not len(unicode(session_post_data["mediaID"])) > 0: return playdata if type == 'vod': play_url_path = '{base_url}/VSP/V3/PlayVOD?from=throughMSAAccess'.format( base_url=CONST_BASE_URL) else: play_url_path = '{base_url}/VSP/V3/PlayChannel?from=throughMSAAccess'.format( base_url=CONST_BASE_URL) if self._abortRequested or xbmc.Monitor().abortRequested(): return playdata download = self.download(url=play_url_path, 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, 'result') or not check_key( data['result'], 'retCode') or not data['result'][ 'retCode'] == '000000000' or not check_key( data, 'playURL'): return playdata path = data['playURL'] if check_key(data, 'authorizeResult'): profile_settings = load_profile(profile_id=1) data['authorizeResult']['cookie'] = self.getCookies( profile_settings['cookies'], '') license = data['authorizeResult'] 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=profile_settings['proxyserver_port']) path = path.replace(real_url, proxy_url) 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 login(self): creds = get_credentials() username = creds['username'] password = creds['password'] query = "UPDATE `vars` SET `csrf_token`='', `cookies`='', `user_filter`='' WHERE profile_id={profile_id}".format( profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) profile_settings = load_profile(profile_id=1) login_url = '{base_url}/VSP/V3/Authenticate?from=throughMSAAccess'.format( base_url=CONST_BASE_URL) session_post_data = { "authenticateBasic": { #'VUID': '6_7_{devicekey}'.format(devicekey=profile_settings['devicekey']), 'clientPasswd': password, 'isSupportWebpImgFormat': '0', 'lang': 'nl', 'needPosterTypes': [ '1', '2', '3', '4', '5', '6', '7', ], 'timeZone': 'Europe/Amsterdam', 'userID': username, 'userType': '0', }, 'authenticateDevice': { 'CADeviceInfos': [ { 'CADeviceID': profile_settings['devicekey'], 'CADeviceType': '7', }, ], 'deviceModel': '3103_PCClient', 'physicalDeviceID': profile_settings['devicekey'], 'terminalID': profile_settings['devicekey'], }, 'authenticateTolerant': { 'areaCode': '', 'bossID': '', 'subnetID': '', 'templateName': '', 'userGroup': '', }, } headers = CONST_BASE_HEADERS download = self.download(url=login_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, 'result') or not check_key( data['result'], 'retCode') or not data['result'][ 'retCode'] == '000000000' or not check_key( data, 'csrfToken'): if not resp: resp = {} if not data: data = {} return {'resp': resp, 'data': data, 'result': False} query = "UPDATE `vars` SET `csrf_token`='{csrf_token}', `user_filter`='{user_filter}' WHERE profile_id={profile_id}".format( csrf_token=data['csrfToken'], user_filter=data['userFilter'], profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return {'resp': resp, 'data': data, 'result': True}
def test_channels(self, tested=False, channel=None): profile_settings = load_profile(profile_id=1) if channel: channel = unicode(channel) try: if not profile_settings[ 'last_login_success'] == 1 or not settings.getBool( key='run_tests') or not self.get_session(): return 5 query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=1, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) query = "SELECT * FROM `channels`" channels = query_epg(query=query, return_result=True, return_insert=False, commit=False) results = load_tests(profile_id=1) count = 0 first = True last_tested_found = False test_run = False user_agent = profile_settings['user_agent'] if not results: results = {} for row in channels: if count == 5 or (count == 1 and tested): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return count id = unicode(row['id']) if len(id) > 0: if channel: if not id == channel: continue elif tested: if unicode(profile_settings['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 = 0 replay = 0 epg = 0 guide = 0 profile_settings = load_profile(profile_id=1) if profile_settings['last_playing'] > int(time.time() - 300): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return 5 playdata = self.play_url(type='channel', channel=id, id=None, test=True) if first and not profile_settings['last_login_success']: if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return 5 if len(playdata['path']) > 0: CDMHEADERS = { 'User-Agent': user_agent, 'X_CSRFToken': profile_settings['csrf_token'], 'Cookie': playdata['license']['cookie'], } if check_key(playdata, 'license') and check_key( playdata['license'], 'triggers') and check_key( playdata['license']['triggers'][0], 'licenseURL'): if check_key(playdata['license']['triggers'][0], 'customData'): CDMHEADERS[ 'AcquireLicense.CustomData'] = playdata[ 'license']['triggers'][0]['customData'] CDMHEADERS[ 'CADeviceType'] = 'Widevine OTT client' session = Session(headers=CDMHEADERS) resp = session.get(playdata['path']) if resp.status_code == 200: livebandwidth = find_highest_bandwidth( xml=resp.text) live = 1 if check_key(results, id) and first and not tested: first = False if live == 1: continue else: if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) 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 profile_settings = load_profile(profile_id=1) if profile_settings['last_playing'] > int(time.time() - 300): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return 5 if self._abortRequested or xbmc.Monitor().abortRequested(): return 5 militime = int(int(time.time() - 86400) * 1000) session_post_data = { 'needChannel': '0', 'queryChannel': { 'channelIDs': [ id, ], 'isReturnAllMedia': '1', }, 'queryPlaybill': { 'count': '1', 'endTime': militime, 'isFillProgram': '1', 'offset': '0', 'startTime': militime, 'type': '0', } } headers = CONST_BASE_HEADERS headers.update({'Content-Type': 'application/json'}) headers.update( {'X_CSRFToken': profile_settings['csrf_token']}) channel_url = '{base_url}/VSP/V3/QueryPlaybillListStcProps?SID=queryPlaybillListStcProps3&DEVICE=PC&DID={deviceID}&from=throughMSAAccess'.format( base_url=CONST_BASE_URL, deviceID=profile_settings['devicekey']) download = self.download(url=channel_url, 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, 'channelPlaybills') and check_key( data['channelPlaybills'][0], 'playbillLites') and check_key( data['channelPlaybills'][0] ['playbillLites'][0], 'ID'): profile_settings = load_profile(profile_id=1) if profile_settings['last_playing'] > int(time.time() - 300): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return 5 playdata = self.play_url(type='program', channel=id, id=data['channelPlaybills'][0] ['playbillLites'][0]['ID'], test=True) if len(playdata['path']) > 0: CDMHEADERS = { 'User-Agent': user_agent, 'X_CSRFToken': profile_settings['csrf_token'], 'Cookie': playdata['license']['cookie'], } if check_key(playdata, 'license') and check_key( playdata['license'], 'triggers') and check_key( playdata['license']['triggers'][0], 'licenseURL'): if check_key( playdata['license']['triggers'][0], 'customData'): CDMHEADERS[ 'AcquireLicense.CustomData'] = playdata[ 'license']['triggers'][0][ 'customData'] CDMHEADERS[ 'CADeviceType'] = 'Widevine OTT client' session = Session(headers=CDMHEADERS) resp = session.get(playdata['path']) if resp.status_code == 200: replaybandwidth = find_highest_bandwidth( xml=resp.text) replay = 1 query = "SELECT id FROM `epg` WHERE channel='{channel}' LIMIT 1".format( channel=id) data = query_epg(query=query, return_result=True, return_insert=False, commit=False) if len(data) > 0: guide = 1 if live == 1: epg = 1 if not self._abortRequested: query = "UPDATE `vars` SET `last_tested`='{last_tested}' WHERE profile_id={profile_id}".format( last_tested=id, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) query = "REPLACE INTO `tests_{profile_id}` VALUES ('{id}', '{live}', '{livebandwidth}', '{replay}', '{replaybandwidth}', '{epg}', '{guide}')".format( profile_id=1, id=id, live=live, livebandwidth=livebandwidth, replay=replay, replaybandwidth=replaybandwidth, epg=epg, guide=guide) query_settings(query=query, return_result=False, return_insert=False, commit=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 profile_settings = load_profile(profile_id=1) if profile_settings['last_playing'] > int(time.time() - 300): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return 5 if self._abortRequested or xbmc.Monitor().abortRequested(): return 5 count += 1 except: if test_run: update_prefs() count = 5 query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return count
def test_channels(self, tested=False, channel=None): profile_settings = load_profile(profile_id=1) if channel: channel = unicode(channel) try: if not profile_settings[ 'last_login_success'] == 1 or not settings.getBool( key='run_tests'): return 5 query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=1, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) query = "SELECT * FROM `channels`" channels = query_epg(query=query, return_result=True, return_insert=False, commit=False) results = load_tests(profile_id=1) count = 0 first = True last_tested_found = False test_run = False user_agent = profile_settings['user_agent'] if not results: results = {} for row in channels: if count == 5 or (count == 1 and tested): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return count id = unicode(row['id']) if len(id) > 0: if channel: if not id == channel: continue elif tested: if unicode(profile_settings['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 = 0 replay = 0 epg = 0 guide = 0 profile_settings = load_profile(profile_id=1) if profile_settings['last_playing'] > int(time.time() - 300): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return 5 playdata = self.play_url(type='channel', channel=id, id=id, test=True) if first and not profile_settings['last_login_success']: if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return 5 if len(playdata['path']) > 0: CDMHEADERS = CONST_BASE_HEADERS CDMHEADERS['User-Agent'] = user_agent session = Session(headers=CDMHEADERS) resp = session.get(playdata['path']) if resp.status_code == 200: livebandwidth = find_highest_bandwidth( xml=resp.text) live = 1 if check_key(results, id) and first and not tested: first = False if live == 1: continue else: if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) 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 profile_settings = load_profile(profile_id=1) if profile_settings['last_playing'] > int(time.time() - 300): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return 5 if self._abortRequested or xbmc.Monitor().abortRequested(): return 5 headers = CONST_BASE_HEADERS headers.update({ 'Authorization': 'Bearer ' + profile_settings['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) download = self.download(url=program_url, type='get', headers=headers, data=None, json_data=False, return_json=True) data = download['data'] resp = download['resp'] if resp and resp.status_code == 200 and data and check_key( data, 'epg') and check_key(data['epg'][0], 'id'): profile_settings = load_profile(profile_id=1) if profile_settings['last_playing'] > int(time.time() - 300): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) 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 session = Session(headers=CDMHEADERS) resp = session.get(playdata['path']) if resp.status_code == 200: replaybandwidth = find_highest_bandwidth( xml=resp.text) replay = 1 query = "SELECT id FROM `epg` WHERE channel='{channel}' LIMIT 1".format( channel=id) data = query_epg(query=query, return_result=True, return_insert=False, commit=False) if len(data) > 0: guide = 1 if live == 1: epg = 1 if not self._abortRequested: query = "UPDATE `vars` SET `last_tested`='{last_tested}' WHERE profile_id={profile_id}".format( last_tested=id, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) query = "REPLACE INTO `tests_{profile_id}` VALUES ('{id}', '{live}', '{livebandwidth}', '{replay}', '{replaybandwidth}', '{epg}', '{guide}')".format( profile_id=1, id=id, live=live, livebandwidth=livebandwidth, replay=replay, replaybandwidth=replaybandwidth, epg=epg, guide=guide) query_settings(query=query, return_result=False, return_insert=False, commit=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 profile_settings = load_profile(profile_id=1) if profile_settings['last_playing'] > int(time.time() - 300): if test_run: update_prefs() query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return 5 if self._abortRequested or xbmc.Monitor().abortRequested(): return 5 count += 1 except: if test_run: update_prefs() count = 5 query = "UPDATE `vars` SET `test_running`={test_running} WHERE profile_id={profile_id}".format( test_running=0, profile_id=1) query_settings(query=query, return_result=False, return_insert=False, commit=True) return count