def plugin_login_error(login_result): 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)
def plugin_login_error(login_result): email_or_pin = settings.getBool(key='email_instead_of_customer') if email_or_pin: gui.ok(message=_.LOGIN_ERROR2, heading=_.LOGIN_ERROR_TITLE) else: gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
def login(ask=1, **kwargs): ask = int(ask) creds = get_credentials() if len(creds['username']) < 1 or len(creds['password']) < 1 or ask == 1: user_info = plugin_ask_for_creds(creds) if user_info['result']: set_credentials(username=user_info['username'], password=user_info['password']) login_result = api_login() if not login_result['result']: profile_settings = load_profile(profile_id=1) profile_settings['last_login_success'] = 0 profile_settings['pswd'] = '' save_profile(profile_id=1, profile=profile_settings) plugin_login_error(login_result) else: profile_settings = load_profile(profile_id=1) profile_settings['last_login_success'] = 1 save_profile(profile_id=1, profile=profile_settings) gui.ok(message=_.LOGIN_SUCCESS) api_get_channels() plugin_post_login() gui.refresh()
def plugin_ask_for_creds(creds): 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 {'result': False, 'username': '', 'password': ''} 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 {'result': False, 'username': '', 'password': ''} return {'result': True, 'username': username, 'password': password}
def _error(e): try: error = str(e) except: error = e.message.encode('utf-8') if not hasattr(e, 'heading') or not e.heading: e.heading = _(_.PLUGIN_ERROR, addon=ADDON_NAME) log.error(error) _close() gui.ok(error, heading=e.heading) resolve()
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) data = api_get_channels() if data and check_key(data, id) and prefs and check_key(prefs, id) and int(prefs[id][type]) == 0: if type == 'replay' and int(data[id]['replay']) == 0: gui.ok(message=_.EXPLAIN_NO_REPLAY) return False elif settings.getBool(key='homeConnection') == False and int(data[id]['home_only']) == 1: gui.ok(message=_.EXPLAIN_HOME_CONNECTION) return False keys = ['live', 'replay'] mod_pref = { 'live': 1, 'replay': 1, } if prefs and check_key(prefs, id): for key in keys: if key == type: continue mod_pref[key] = prefs[id][key] if change == 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[type] = 1 prefs[id] = mod_pref save_prefs(profile_id=1, prefs=prefs) xbmc.executeJSONRPC('{{"jsonrpc":"2.0","id":1,"method":"GUI.ActivateWindow","params":{{"window":"videos","parameters":["plugin://' + unicode(ADDON_ID) + '/?_=channel_picker&type=' + type + '"]}}}}')
def plugin_ask_for_creds(creds): if str(creds['username']).isnumeric(): creds['username'] = '' username = str( gui.input(message=_.ASK_USERNAME2, default=creds['username'])).strip() if not len(str(username)) > 0: gui.ok(message=_.EMPTY_USER2, heading=_.LOGIN_ERROR_TITLE) return {'result': False, 'username': '', 'password': ''} password = str(gui.input(message=_.ASK_PASSWORD2, hide_input=True)).strip() if not len(str(password)) > 0: gui.ok(message=_.EMPTY_PASS2, heading=_.LOGIN_ERROR_TITLE) return {'result': False, 'username': '', 'password': ''} return {'result': True, 'username': username, 'password': password}
def plugin_login_error(login_result): try: 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) except: gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
def plugin_login_error(login_result): try: if (login_result['code'] == 403 and 'Teveel verschillende apparaten' in login_result['data']): gui.ok(message=_.TOO_MANY_DEVICES, heading=_.LOGIN_ERROR_TITLE) else: gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE) except: gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
def plugin_ask_for_creds(creds): email_or_pin = settings.getBool(key='email_instead_of_customer') if email_or_pin: if unicode(creds['username']).isnumeric(): creds['username'] = '' username = unicode( gui.input(message=_.ASK_USERNAME2, default=creds['username'])).strip() else: if not unicode(creds['username']).isnumeric(): creds['username'] = '' username = unicode( gui.input(message=_.ASK_USERNAME, default=creds['username'])).strip() if not len(unicode(username)) > 0: if email_or_pin: gui.ok(message=_.EMPTY_USER2, heading=_.LOGIN_ERROR_TITLE) else: gui.ok(message=_.EMPTY_USER, heading=_.LOGIN_ERROR_TITLE) return {'result': False, 'username': '', 'password': ''} if email_or_pin: password = unicode(gui.input(message=_.ASK_PASSWORD2, hide_input=True)).strip() else: password = unicode(gui.input(message=_.ASK_PASSWORD, hide_input=True)).strip() if not len(unicode(password)) > 0: if email_or_pin: gui.ok(message=_.EMPTY_PASS2, heading=_.LOGIN_ERROR_TITLE) else: gui.ok(message=_.EMPTY_PASS, heading=_.LOGIN_ERROR_TITLE) return {'result': False, 'username': '', 'password': ''} return {'result': True, 'username': username, 'password': password}
def plugin_login_error(login_result): gui.ok(message=_.LOGIN_ERROR, heading=_.LOGIN_ERROR_TITLE)
def install_widevine(reinstall=False): ia_addon = get_ia_addon(required=True) system, arch = _get_system_arch() kodi_version = get_kodi_version() if kodi_version < 18: raise InputStreamError(_(_.IA_KODI18_REQUIRED, system=system)) elif system == 'Android': return True elif system == 'UWP': raise InputStreamError(_.IA_UWP_ERROR) elif 'aarch64' in arch or 'arm64' in arch: raise InputStreamError(_.IA_AARCH64_ERROR) last_check = int(ia_addon.getSetting('_last_check') or 0) ver_slug = system + arch + str(kodi_version) + ia_addon.getAddonInfo( 'version') if ver_slug != ia_addon.getSetting(IA_VERSION_KEY): reinstall = True if not reinstall and time.time() - last_check < 86400: return True ia_addon.setSetting(IA_VERSION_KEY, '') ia_addon.setSetting('_last_check', str(int(time.time()))) r = api_get_widevine() widevine = r['widevine'] wv_platform = widevine['platforms'].get(system + arch, None) if not wv_platform: raise InputStreamError( _(_.IA_NOT_SUPPORTED, system=system, arch=arch, kodi_version=kodi_version)) decryptpath = xbmc.translatePath(ia_addon.getSetting('DECRYPTERPATH')) if sys.version_info < (3, 0): decryptpath = decryptpath.decode("utf-8") if 'arm' in arch: url = wv_platform['zip'] else: url = widevine['base_url'] + wv_platform['zip'] wv_path = os.path.join(decryptpath, wv_platform['dst']) if not os.path.isdir(decryptpath): os.makedirs(decryptpath) if not os.path.isdir(ADDON_PROFILE + "tmp"): os.makedirs(ADDON_PROFILE + "tmp") if not _download(url, wv_platform['dst'], wv_path, arch, wv_platform['md5']): return False ia_addon.setSetting(IA_VERSION_KEY, ver_slug) if reinstall: gui.ok(_.IA_WV_INSTALL_OK) return True
def check_entitlements(): from resources.lib.api import api_get_play_token media_groups_url = '{mediagroups_url}/crid%3A~~2F~~2Fschange.com~~2F64e9e221-aebf-4620-b248-8681feada6e8?byHasCurrentVod=true&range=1-1&sort=playCount7%7Cdesc'.format( mediagroups_url=CONST_URLS['mediagroupsfeeds_url']) download = api_download(url=media_groups_url, type='get', headers=None, data=None, json_data=False, return_json=True) data = download['data'] code = download['code'] if not code or not code == 200 or not data or not check_key( data, 'entryCount'): gui.ok(message=_.NO_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=False) return id = data['mediaGroups'][0]['id'] media_item_url = '{mediaitem_url}/{mediaitem_id}'.format( mediaitem_url=CONST_URLS['mediaitems_url'], mediaitem_id=id) download = api_download(url=media_item_url, type='get', headers=None, data=None, json_data=False, return_json=True) data = download['data'] code = download['code'] if not code or not code == 200 or not data: gui.ok(message=_.NO_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=False) return if check_key(data, 'videoStreams'): urldata = get_play_url(content=data['videoStreams']) if (not urldata or not check_key(urldata, 'play_url') or not check_key(urldata, 'locator') or urldata['play_url'] == 'http://Playout/using/Session/Service'): urldata = {} playout_url = '{base_url}/playout/vod/{id}?abrType=BR-AVC-DASH'.format( base_url=CONST_URLS['base_url'], id=id) download = api_download(url=playout_url, type='get', headers=None, data=None, json_data=False, return_json=True) data = download['data'] code = download['code'] if not code or not code == 200 or not data or not check_key( data, 'url') or not check_key(data, 'contentLocator'): gui.ok(message=_.NO_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=False) return urldata['play_url'] = data['url'] urldata['locator'] = data['contentLocator'] if not urldata or not check_key(urldata, 'play_url') or not check_key( urldata, 'locator'): gui.ok(message=_.NO_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=False) return token = api_get_play_token(locator=urldata['locator'], path=urldata['play_url'], force=1) if not token or not len(token) > 0: gui.ok(message=_.NO_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=False) return gui.ok(message=_.YES_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=True) return
def play_video(type=None, channel=None, id=None, data=None, title=None, from_beginning=0, pvr=0, **kwargs): profile_settings = load_profile(profile_id=1) from_beginning = int(from_beginning) pvr = int(pvr) if not type or not len(unicode(type)) > 0: return False proxy_url = "http://127.0.0.1:11189/{provider}".format(provider=PROVIDER_NAME) code = 0 try: test_proxy = api_download(url=proxy_url + "/status", type='get', headers=None, data=None, json_data=False, return_json=False) code = test_proxy['code'] except: code = 404 if not code or not code == 200: gui.ok(message=_.PROXY_NOT_SET) return False playdata = api_play_url(type=type, channel=channel, id=id, video_data=data, from_beginning=from_beginning, pvr=pvr) if not playdata or not check_key(playdata, 'path'): return False playdata['channel'] = channel playdata['title'] = title if check_key(playdata, 'alt_path') and (from_beginning == 1 or (settings.getBool(key='ask_start_from_beginning') and gui.yes_no(message=_.START_FROM_BEGINNING, heading=playdata['title']))): path = playdata['alt_path'] license = playdata['alt_license'] else: path = playdata['path'] license = playdata['license'] real_url = "{hostscheme}://{netloc}".format(hostscheme=urlparse(path).scheme, netloc=urlparse(path).netloc) path = path.replace(real_url, proxy_url) playdata['path'] = path playdata['license'] = license item_inputstream, CDMHEADERS = plugin_process_playdata(playdata) info = plugin_process_info(playdata) write_file(file='stream_hostname', data=real_url, isJSON=False) write_file(file='stream_duration', data=info['duration'], isJSON=False) listitem = plugin.Item( label = unicode(info['label1']), label2 = unicode(info['label2']), art = { 'thumb': unicode(info['image']), 'fanart': unicode(info['image_large']) }, info = { 'credits': info['credits'], 'cast': info['cast'], 'writer': info['writer'], 'director': info['director'], 'genre': info['genres'], 'plot': unicode(info['description']), 'duration': info['duration'], 'mediatype': 'video', 'year': info['year'], 'sorttitle': unicode(info['label1']).upper(), }, path = path, headers = CDMHEADERS, inputstream = item_inputstream, ) return listitem
def check_entitlements(): from resources.lib.api import api_get_play_token profile_settings = load_profile(profile_id=1) v3 = int(profile_settings['v3']) if v3 == 0: media_groups_url = '{mediagroups_url}/lgi-nl-vod-myprime-movies?byHasCurrentVod=true&range=1-1&sort=playCount7%7Cdesc'.format(mediagroups_url=CONST_API_URLS[int(profile_settings['v3'])]['mediagroupsfeeds_url']) else: media_groups_url = '{mediagroups_url}/crid:~~2F~~2Fschange.com~~2Fdc30ecd3-4701-4993-993b-9ad4ff5fc301?byHasCurrentVod=true&range=1-1&sort=playCount7%7Cdesc'.format(mediagroups_url=CONST_API_URLS[int(profile_settings['v3'])]['mediagroupsfeeds_url']) download = api_download(url=media_groups_url, type='get', headers=None, data=None, json_data=False, return_json=True) data = download['data'] code = download['code'] if not code or not code == 200 or not data or not check_key(data, 'entryCount'): gui.ok(message=_.NO_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=False) return id = data['mediaGroups'][0]['id'] media_item_url = '{mediaitem_url}/{mediaitem_id}'.format(mediaitem_url=CONST_API_URLS[int(profile_settings['v3'])]['mediaitems_url'], mediaitem_id=id) download = api_download(url=media_item_url, type='get', headers=None, data=None, json_data=False, return_json=True) data = download['data'] code = download['code'] if not code or not code == 200 or not data: gui.ok(message=_.NO_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=False) return if check_key(data, 'videoStreams'): urldata = get_play_url(content=data['videoStreams']) if (not urldata or not check_key(urldata, 'play_url') or not check_key(urldata, 'locator') or urldata['play_url'] == 'http://Playout/using/Session/Service') and v3: urldata = {} playout_url = '{base_url}/playout/vod/{id}?abrType=BR-AVC-DASH'.format(base_url=CONST_API_URLS[int(profile_settings['v3'])]['base_url'], id=id) download = api_download(url=playout_url, type='get', headers=None, data=None, json_data=False, return_json=True) data = download['data'] code = download['code'] if not code or not code == 200 or not data or not check_key(data, 'url') or not check_key(data, 'contentLocator'): gui.ok(message=_.NO_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=False) return urldata['play_url'] = data['url'] urldata['locator'] = data['contentLocator'] if not urldata or not check_key(urldata, 'play_url') or not check_key(urldata, 'locator'): gui.ok(message=_.NO_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=False) return token = api_get_play_token(locator=urldata['locator'], path=urldata['play_url'], force=1) if not token or not len(token) > 0: gui.ok(message=_.NO_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=False) return gui.ok(message=_.YES_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=True) return
def check_devices(): device_id = load_file('device_id', isJSON=False) if not device_id: LOGPATH = xbmcvfs.translatePath('special://logpath') LOGFILE = os.path.join(LOGPATH, 'kodi.old.log') with io.open(LOGFILE, 'r', encoding='utf-8', errors='ignore') as f: text = f.read() regex = r"HEADER_IN:\sX-DRM-Device-ID:\s([a-zA-Z0-9]*)" matches = re.finditer(regex, text, re.MULTILINE) for matchNum, match in enumerate(matches, start=1): device_id = match.group(1) break if not device_id: LOGFILE = os.path.join(LOGPATH, 'kodi.log') with io.open(LOGFILE, 'r', encoding='utf-8', errors='ignore') as f: text = f.read() regex = r"HEADER_IN:\sX-DRM-Device-ID:\s([a-zA-Z0-9]*)" matches = re.finditer(regex, text, re.MULTILINE) for matchNum, match in enumerate(matches, start=1): device_id = match.group(1) break if device_id: from resources.lib.api import api_list_devices, api_replace_device, api_new_device devices = api_list_devices() select_list = [] device_ar = {} count = 0 if devices: found = False for device in devices: if str(device['deviceId']) == device_id: found = True break device_ar[count] = device['deviceId'] count += 1 select_list.append(device['customerDefinedName']) if found == False: if len(devices) == 5: selected = gui.select( 'Selecteer Device om te vervangen:', select_list) if check_key(device_ar, selected): api_replace_device(device_ar[selected], device_id) else: api_new_device(device_id) else: gui.ok( message= 'Geen device ID gevonden. Het afspelen zal zo mislukken, hierna wordt automatisch een device ID gegenereerd. Je krijgt hier geen bericht van. Herstart direct het afspelen.', heading='Geen device ID gevonden')
def api_play_url(type, channel=None, id=None, video_data=None, test=False, from_beginning=0, pvr=0): playdata = { 'path': '', 'license': '', 'token': '', 'locator': '', 'type': '', 'alt_path': '', 'alt_license': '', 'alt_locator': '' } if not api_get_session(): return playdata from_beginning = int(from_beginning) pvr = int(pvr) profile_settings = load_profile(profile_id=1) if type == "channel": id = channel alt_path = '' alt_license = '' alt_locator = '' info = {} base_listing_url = profile_settings['listings_url'] urldata = None urldata2 = None path = None locator = None if not type or not len(unicode(type)) > 0 or not id or not len( unicode(id)) > 0: return playdata if not test: counter = 0 while 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 xbmc.Monitor().waitForAbort(1): break if xbmc.Monitor().abortRequested(): return playdata if type == 'channel': query = "SELECT assetid FROM `channels` WHERE id='{channel}'".format( channel=id) data = query_epg(query=query, return_result=True, return_insert=False, commit=False) if data: for row in data: split = row['assetid'].rsplit('&%%&', 1) if len(split) == 2: urldata = {'play_url': split[0], 'locator': split[1]} else: return playdata listing_url = '{listings_url}?byEndTime={time}~&byStationId={channel}&range=1-1&sort=startTime'.format( listings_url=base_listing_url, time=int(time.time() * 1000), channel=id) download = api_download(url=listing_url, type='get', headers=api_get_headers(), data=None, json_data=False, return_json=True) data = download['data'] code = download['code'] if code and code == 200 and data and check_key(data, 'listings'): for row in data['listings']: if check_key(row, 'program'): info = row['program'] elif type == 'program': listings_url = "{listings_url}/{id}".format( listings_url=base_listing_url, id=id) download = api_download(url=listings_url, type='get', headers=api_get_headers(), data=None, json_data=False, return_json=True) data = download['data'] code = download['code'] if not code or not code == 200 or not data or not check_key( data, 'program'): return playdata info = data['program'] elif type == 'vod': mediaitems_url = '{mediaitems_url}/{id}'.format( mediaitems_url=profile_settings['mediaitems_url'], id=id) download = api_download(url=mediaitems_url, type='get', headers=api_get_headers(), data=None, json_data=False, return_json=True) data = download['data'] code = download['code'] if not code or not code == 200 or not data: return playdata info = data if check_key(info, 'videoStreams'): urldata2 = get_play_url(content=info['videoStreams']) if not type == 'channel' and ( not urldata2 or not check_key(urldata2, 'play_url') or not check_key(urldata2, 'locator') or urldata2['play_url'] == 'http://Playout/using/Session/Service' ) and profile_settings['base_v3'] == 1: urldata2 = {} if type == 'program': playout_str = 'replay' elif type == 'vod': playout_str = 'vod' else: return playdata playout_url = '{base_url}/playout/{playout_str}/{id}?abrType=BR-AVC-DASH'.format( base_url=profile_settings['base_url'], playout_str=playout_str, id=id) download = api_download(url=playout_url, type='get', headers=api_get_headers(), data=None, json_data=False, return_json=True) data = download['data'] code = download['code'] if not code or not code == 200 or not data or not check_key( data, 'url') or not check_key(data, 'contentLocator'): return playdata urldata2['play_url'] = data['url'] urldata2['locator'] = data['contentLocator'] if urldata and urldata2 and check_key(urldata, 'play_url') and check_key( urldata, 'locator') and check_key( urldata2, 'play_url') and check_key(urldata2, 'locator'): path = urldata['play_url'] locator = urldata['locator'] alt_path = urldata2['play_url'] alt_locator = urldata2['locator'] else: if urldata and check_key(urldata, 'play_url') and check_key( urldata, 'locator'): path = urldata['play_url'] locator = urldata['locator'] elif urldata2 and check_key(urldata2, 'play_url') and check_key( urldata2, 'locator'): path = urldata2['play_url'] locator = urldata2['locator'] if not locator or not len(unicode(locator)) > 0: return playdata license = profile_settings['widevine_url'] alt_license = profile_settings['widevine_url'] if xbmc.Monitor().abortRequested(): return playdata token = api_get_play_token(locator=locator, path=path, force=1) if not token or not len(unicode(token)) > 0: if not test: gui.ok(message=_.NO_STREAM_AUTH, heading=_.PLAY_ERROR) return playdata if not test: token = 'WIDEVINETOKEN' token_regex = re.search(r"(?<=;vxttoken=)(.*?)(?=/)", path) if token_regex and token_regex.group(1) and len(token_regex.group(1)) > 0: path = path.replace(token_regex.group(1), token) else: if 'sdash/' in path: spliturl = path.split('sdash/', 1) if len(spliturl) == 2: if profile_settings['base_v3'] == 1: path = '{urlpart1}sdash;vxttoken={token}/{urlpart2}'.format( urlpart1=spliturl[0], token=token, urlpart2=spliturl[1]) else: path = '{urlpart1}sdash;vxttoken={token}/{urlpart2}?device=Orion-Replay-DASH'.format( urlpart1=spliturl[0], token=token, urlpart2=spliturl[1]) else: spliturl = path.rsplit('/', 1) if len(spliturl) == 2: path = '{urlpart1};vxttoken={token}/{urlpart2}'.format( urlpart1=spliturl[0], token=token, urlpart2=spliturl[1]) playdata = { 'path': path, 'license': license, 'token': token, 'locator': locator, 'info': info, 'type': type, 'alt_path': alt_path, 'alt_license': alt_license, 'alt_locator': alt_license } return playdata