def online_search(query=None, **kwargs): if not query: query = gui.input(message=_.SEARCH, default='').strip() if not query: return for x in reversed(list(range(2, 10))): settings.set(key='_search' + unicode(x), value=settings.get(key='_search' + unicode(x - 1))) settings.set(key='_search_type' + unicode(x), value=settings.get(key='_search_type' + unicode(x - 1))) settings.set(key='_search1', value=query) settings.set(key='_search_type1', value=' (Online)') folder = plugin.Folder(title=_(_.SEARCH_FOR, query=query)) data = api.online_search(search=query, vod=settings.getBool('showMoviesSeries')) if data: processed = process_online_search(data=data) if processed: folder.add_items(processed) return folder
def add_to_watchlist(self, id, type): if type == "item": mediaitems_url = '{listings_url}/{id}'.format( listings_url=settings.get(key='_listings_url'), id=id) data = self.download(url=mediaitems_url, type="get", code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=False) if not data or not check_key(data, 'mediaGroupId'): return False id = data['mediaGroupId'] watchlist_url = '{watchlist_url}/entries'.format( watchlist_url=settings.get(key='_watchlist_url')) data = self.download(url=watchlist_url, type="post", code=[204], data={"mediaGroup": { 'id': id }}, json_data=True, data_return=False, return_json=False, retry=True, check_data=False) return data
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 new_session(self, force=False, channels=False): access_token = settings.get(key='_access_token') creds = get_credentials() username = creds['username'] password = creds['password'] if len(access_token) > 0 and len(username) > 0 and force == False: 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': access_token, 'X-OESP-Username': username, } self._session = Session(headers=HEADERS) self.logged_in = True return self.logged_in = False if not len(username) > 0: return if not len(password) > 0: password = gui.numeric(message=_.ASK_PASSWORD).strip() if not len(password) > 0: gui.ok(message=_.EMPTY_PASS, heading=_.LOGIN_ERROR_TITLE) return self.login(username=username, password=password, channels=channels)
def search_menu(**kwargs): folder = plugin.Folder(title=_.SEARCHMENU) label = _.NEWSEARCH folder.add_item( label = label, info = {'plot': _.NEWSEARCHDESC}, path = plugin.url_for(func_or_url=search), ) folder.add_item( label= label + " (Online)", path=plugin.url_for(func_or_url=online_search) ) for x in range(1, 10): searchstr = settings.get(key='_search' + unicode(x)) if searchstr != '': type = settings.get(key='_search_type' + unicode(x)) label = searchstr + type if type == " (Online)": path = plugin.url_for(func_or_url=online_search, query=searchstr) else: path = plugin.url_for(func_or_url=search, query=searchstr) folder.add_item( label = label, info = {'plot': _(_.SEARCH_FOR, query=searchstr)}, path = path, ) return folder
def do_GET(self): URL = settings.get(key='_stream_hostname') + str(self.path).replace( 'WIDEVINETOKEN', settings.get(key='_drm_token')) if "manifest.mpd" in self.path or "Manifest" in self.path: HEADERS = CONST_BASE_HEADERS for header in self.headers: if self.headers[ header] is not None and header in CONST_ALLOWED_HEADERS: HEADERS[header] = self.headers[header] self._session = Session(headers=HEADERS) r = self._session.get(URL) xml = r.text xml = set_duration(xml=xml) if settings.getBool(key='force_highest_bandwidth'): xml = force_highest_bandwidth(xml=xml) if settings.getBool(key="disableac3") == True: xml = remove_ac3(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 = time.time() try: if self._last_playing + 60 < self._now_playing: self._last_playing = time.time() settings.setInt(key='_last_playing', value=self._last_playing) except: self._last_playing = time.time() settings.setInt(key='_last_playing', value=self._last_playing) self.send_response(302) self.send_header('Location', URL) self.end_headers()
def get_credentials(): username = settings.get(key='_username') password = settings.get(key='_pswd') if len(username) < 50 and len(password) < 50: set_credentials(username, password) return {'username': username, 'password': password} return Credentials().decode_credentials(username, password)
def do_GET(self): try: self._stream_url except: self._stream_url = settings.get(key='_stream_hostname') if ".mpd" in self.path: self._stream_url = settings.get(key='_stream_hostname') session = Session(cookies_key='_cookies') 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 = time.time() try: if self._last_playing + 60 < self._now_playing: self._last_playing = time.time() settings.setInt(key='_last_playing', value=self._last_playing) except: self._last_playing = time.time() settings.setInt(key='_last_playing', value=self._last_playing) self.send_response(302) self.send_header('Location', self._stream_url + str(self.path)) self.end_headers()
def search(query=None, **kwargs): items = [] if not query: query = gui.input(message=_.SEARCH, default='').strip() if not query: return for x in reversed(list(range(2, 10))): settings.set(key='_search' + unicode(x), value=settings.get(key='_search' + unicode(x - 1))) settings.set(key='_search1', value=query) folder = plugin.Folder(title=_(_.SEARCH_FOR, query=query)) data = load_file(file='list_replay.json', isJSON=True) processed = process_replaytv_search(data=data, start=0, search=query) items += processed['items'] items[:] = sorted(items, key=_sort_replay_items, reverse=True) items = items[:25] folder.add_items(items) return folder
def new_session(self, force=False, channels=False): cookies = settings.get(key='_cookies') if len(cookies) > 0 and force == False: self._session = Session(cookies_key='_cookies') self.logged_in = True return self.logged_in = False creds = get_credentials() username = creds['username'] password = creds['password'] if not len(username) > 0: return if not len(password) > 0: password = gui.numeric(message=_.ASK_PASSWORD).strip() if not len(password) > 0: gui.ok(message=_.EMPTY_PASS, heading=_.LOGIN_ERROR_TITLE) return self.login(username=username, password=password, channels=channels)
def do_GET(self): URL = settings.get(key='_stream_hostname') + str(self.path) if ".mpd" in self.path: session = Session(cookies_key='_cookies') r = session.get(URL) xml = r.text xml = set_duration(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: 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.send_response(302) self.send_header('Location', URL) self.end_headers()
def login(**kwargs): if len(settings.get(key='_devicekey')) == 0: settings.set(key='_devicekey', value=''.join( random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(64))) creds = get_credentials() 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 api.login(username=username, password=password, channels=True) plugin.logged_in = api.logged_in gui.refresh()
def startup(): 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()) hourly() daily() change_icon() if settings.getBool(key='enable_simple_iptv') == True: try: IPTV_SIMPLE = xbmcaddon.Addon(id="pvr.iptvsimple") if IPTV_SIMPLE.getSetting("epgPath") == ( ADDON_PROFILE + "epg.xml") and IPTV_SIMPLE.getSetting("m3uPath") == ( ADDON_PROFILE + "playlist.m3u8"): user_agent = settings.get(key='_user_agent') if IPTV_SIMPLE.getSetting("userAgent") != user_agent: IPTV_SIMPLE.setSetting("userAgent", user_agent) xbmc.executeJSONRPC( '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":false}}}}' .format(IPTV_SIMPLE_ADDON_ID)) xbmc.sleep(2000) xbmc.executeJSONRPC( '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":true}}}}' .format(IPTV_SIMPLE_ADDON_ID)) except: pass
def vod_season(label, id, **kwargs): folder = plugin.Folder(title=label) items = [] season = api.vod_season(id) for episode in season: items.append( plugin.Item( label=episode['episodeNumber'] + " - " + episode['title'], info={ 'plot': episode['desc'], 'duration': episode['duration'], 'mediatype': 'video', }, art={ 'thumb': "{image_url}/vod/{image}/{img_size}.jpg?blurred=false". format(image_url=CONST_IMAGE_URL, image=episode['image'], img_size=settings.get(key='_img_size')) }, path=plugin.url_for(func_or_url=play_video, type='vod', id=episode['id'], asset_id=episode['assetid'], duration=episode['duration'], _is_live=False), playable=True, )) folder.add_items(items) return folder
def vod_series(label, description, image, id, **kwargs): folder = plugin.Folder(title=label) items = [] seasons = api.vod_seasons(id) for season in seasons: items.append( plugin.Item( label=_.SEASON + " " + unicode(season['seriesNumber']), info={'plot': season['desc']}, art={ 'thumb': "{image_url}/vod/{image}/{img_size}.jpg?blurred=false". format(image_url=CONST_IMAGE_URL, image=season['image'], img_size=settings.get(key='_img_size')) }, path=plugin.url_for(func_or_url=vod_season, label=label, id=season['id']), )) folder.add_items(items) return folder
def renew_images(): md5JSON = load_file(file='md5.json', isJSON=True) try: if settings.get(key='_epg_md5') != md5JSON['images.zip']: download_images() except: download_images()
def update_img_size(): settingsJSON = load_file(file='settings.json', isJSON=True) try: settings.set(key='_img_size', value=settingsJSON['img_size']) except: pass if len(settings.get(key='_img_size')) == 0: settings.set(key='_img_size', value=CONST_DEFAULT_IMG_SIZE)
def update_os_browser(): user_agent = settings.get(key='_user_agent') settings.set(key='_browser_name', value=uaparser.detect(user_agent)['browser']['name']) settings.set(key='_browser_version', value=uaparser.detect(user_agent)['browser']['version']) settings.set(key='_os_name', value=uaparser.detect(user_agent)['os']['name']) settings.set(key='_os_version', value=uaparser.detect(user_agent)['os']['version'])
def update_api_url(): settingsJSON = load_file(file='settings.json', isJSON=True) try: settings.set(key='_api_url', value=settingsJSON['api_url']) except: pass if len(settings.get(key='_api_url')) == 0: settings.set(key='_api_url', value=CONST_DEFAULT_API)
def search(query=None, **kwargs): items = [] if not query: query = gui.input(message=_.SEARCH, default='').strip() if not query: return for x in reversed(list(range(2, 10))): settings.set(key='_search' + unicode(x), value=settings.get(key='_search' + unicode(x - 1))) settings.set(key='_search_type' + unicode(x), value=settings.get(key='_search_type' + unicode(x - 1))) settings.set(key='_search1', value=query) settings.set(key='_search_type1', value='') folder = plugin.Folder(title=_(_.SEARCH_FOR, query=query)) data = load_file(file='list_replay.json', isJSON=True) processed = process_replaytv_search(data=data, start=0, search=query) items += processed['items'] if settings.getBool('showMoviesSeries') == True: processed = process_vod_content(data=load_file(file='vod.json', isJSON=True)['series'], start=0, series=0, search=query, type=_.SERIES) items += processed['items'] processed = process_vod_content(data=load_file(file='vod.json', isJSON=True)['movies'], start=0, series=0, search=query, type=_.MOVIES) items += processed['items'] processed = process_vod_content(data=load_file(file='vod.json', isJSON=True)['hboseries'], start=0, series=0, search=query, type=_.HBO_SERIES) items += processed['items'] processed = process_vod_content(data=load_file(file='vod.json', isJSON=True)['hbomovies'], start=0, series=0, search=query, type=_.HBO_MOVIES) items += processed['items'] processed = process_vod_content(data=load_file(file='vod.json', isJSON=True)['kids'], start=0, series=1, search=query, type=_.KIDS_SERIES) items += processed['items'] processed = process_vod_content(data=load_file(file='vod.json', isJSON=True)['kids'], start=0, series=2, search=query, type=_.KIDS_MOVIES) items += processed['items'] items[:] = sorted(items, key=_sort_replay_items, reverse=True) items = items[:25] folder.add_items(items) return folder
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 load_profile(profile_id=1): query = "SELECT * FROM `vars` WHERE `profile_id`='{id}'".format(id=int(profile_id)) result = query_settings(query=query, return_result=True, return_insert=False, commit=False) if not result or len(result) < 1: pswd = settings.get(key='_pswd') username = settings.get(key='_username') create_query = '''CREATE TABLE IF NOT EXISTS `prefs_{profile_id}` ( `id` INT(11) PRIMARY KEY, `live` TINYINT(1) DEFAULT 1, `live_auto` TINYINT(1) DEFAULT 1, `replay` TINYINT(1) DEFAULT 1, `replay_auto` TINYINT(1) DEFAULT 1, `epg` TINYINT(1) DEFAULT 1, `epg_auto` TINYINT(1) DEFAULT 1 )'''.format(profile_id=int(profile_id)) result = query_settings(query=create_query, return_result=False, return_insert=True, commit=True) create_query = '''CREATE TABLE IF NOT EXISTS `tests_{profile_id}` ( `id` VARCHAR(255) PRIMARY KEY, `live` TINYINT(1) DEFAULT 1, `livebandwidth` INT(11) DEFAULT NULL, `replay` TINYINT(1) DEFAULT 1, `replaybandwidth` INT(11) DEFAULT NULL, `epg` TINYINT(1) DEFAULT 1, `guide` TINYINT(1) DEFAULT 1 )'''.format(profile_id=int(profile_id)) result = query_settings(query=create_query, return_result=False, return_insert=True, commit=True) add_query = "INSERT INTO `vars` (`profile_id`, `pswd`, `username`) VALUES ('{id}', '{pswd}', '{username}')".format(id=int(profile_id), pswd=pswd, username=username) result = query_settings(query=add_query, return_result=False, return_insert=True, commit=True) if result and result == profile_id: result = query_settings(query=query, return_result=True, return_insert=False, commit=False) if not result or len(result) < 1: return None return result[0]
def remove_from_watchlist(self, id): remove_url = '{watchlist_url}/entries/{id}'.format( watchlist_url=settings.get(key='_watchlist_url'), id=id) data = self.download(url=remove_url, type="delete", code=[204], data=None, json_data=False, data_return=False, return_json=False, retry=True, check_data=False) return data
def check_iptv_link(): if settings.getBool(key='enable_simple_iptv') == True: try: IPTV_SIMPLE = xbmcaddon.Addon(id="pvr.iptvsimple") if not IPTV_SIMPLE.getSetting("epgPath") == (ADDON_PROFILE + "epg.xml") or not IPTV_SIMPLE.getSetting("m3uPath") == (ADDON_PROFILE + "playlist.m3u8"): settings.setBool(key='enable_simple_iptv', value=False) else: user_agent = settings.get(key='_user_agent') if IPTV_SIMPLE.getSetting("userAgent") != user_agent: IPTV_SIMPLE.setSetting("userAgent", user_agent) except: pass
def renew_vod(): if settings.getBool(key='showMoviesSeries') == True: md5JSON = load_file(file='md5.json', isJSON=True) try: if ADDON_ID == "plugin.video.ziggo" and settings.getBool(key='_base_v3') == True: key = 'vod.v3.json' else: key = 'vod.json' if settings.get(key='_vod_md5') != md5JSON[key]: download_vod() except: download_vod()
def check_entitlements(**kwargs): if plugin.logged_in: user_agent = settings.get(key='_user_agent') media_groups_url = '{mediagroups_url}/lgi-nl-vod-myprime-movies?byHasCurrentVod=true&range=1-1&sort=playCount7%7Cdesc'.format(mediagroups_url=settings.get('_mediagroupsfeeds_url')) data = api.download(url=media_groups_url, type="get", code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=False) if not data or not check_key(data, 'entryCount'): gui.ok(message=_.NO_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=False) return media_item_url = '{mediaitem_url}/{mediaitem_id}'.format(mediaitem_url=settings.get(key='_mediaitems_url'), mediaitem_id=data['mediaGroups'][0]['id']) data = api.download(url=media_item_url, type="get", code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=False) if not data or not check_key(data, 'videoStreams'): gui.ok(message=_.NO_MOVIES_SERIES, heading=_.CHECKED_ENTITLEMENTS) settings.setBool(key='showMoviesSeries', value=False) return urldata = get_play_url(content=data['videoStreams']) 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'], force=True) 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 list_watchlist(self): data = self.download(url=settings.get(key='_watchlist_url'), type="get", code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=False) if not data or not check_key(data, 'entries'): return False return data
def play_video(type=None, channel=None, id=None, catchup=None, duration=0, **kwargs): properties = {} if not type and not len(type) > 0: return False if (catchup and len(catchup) > 0) or type == 'program': if catchup and len(catchup) > 0: id = catchup properties['seekTime'] = 1 type = 'program' playdata = api.play_url(type=type, channel=channel, id=id) if not playdata or not check_key(playdata, 'path') or not check_key( playdata, 'token'): return False CDMHEADERS = CONST_BASE_HEADERS CDMHEADERS['User-Agent'] = settings.get(key='_user_agent') if type == 'channel': playdata['path'] = playdata['path'].split("&", 1)[0] else: playdata['path'] = playdata['path'].split("&min_bitrate", 1)[0] if check_key(playdata, 'license'): item_inputstream = inputstream.Widevine( license_key=playdata['license'], ) else: item_inputstream = inputstream.MPD() settings.setInt(key='_stream_duration', value=duration) listitem = plugin.Item( properties=properties, path=playdata['path'], headers=CDMHEADERS, inputstream=item_inputstream, ) return listitem
def get_channels_for_user(self, location): channels_url = '{channelsurl}?byLocationId={location}&includeInvisible=true&personalised=true'.format( channelsurl=settings.get('_channels_url'), location=location) data = self.download(url=channels_url, type="get", code=[200], data=None, json_data=False, data_return=True, return_json=True, retry=True, check_data=False) if data and check_key(data, 'entryCount') and check_key( data, 'channels'): settings.setInt(key='_channels_age', value=time.time()) write_file(file="channels.json", data=data['channels'], isJSON=True) playlist = u'#EXTM3U\n' for row in sorted( data['channels'], key=lambda r: float(r.get('channelNumber', 'inf'))): channeldata = self.get_channel_data(row=row) urldata = get_play_url(content=channeldata['stream']) if urldata and check_key(urldata, 'play_url') and check_key( urldata, 'locator'): path = 'plugin://{addonid}/?_=play_video&type=channel&id={play_url}&locator={locator}&_l=.pvr'.format( addonid=ADDON_ID, play_url=quote(urldata['play_url']), locator=quote(urldata['locator'])) playlist += u'#EXTINF:-1 tvg-id="{id}" tvg-chno="{channel}" tvg-name="{name}" tvg-logo="{logo}" group-title="TV" radio="false",{name}\n{path}\n'.format( id=channeldata['channel_id'], channel=channeldata['channel_number'], name=channeldata['label'], logo=channeldata['station_image_large'], path=path) write_file(file="tv.m3u8", data=playlist, isJSON=False) combine_playlist()
def __init__(self, headers=None, cookies_key=None, base_url='{}', timeout=None, attempts=None): super(Session, self).__init__() user_agent = settings.get(key='_user_agent') CONST_BASE_HEADERS.update({'User-Agent': user_agent}) if headers: CONST_BASE_HEADERS.update(headers) self._headers = CONST_BASE_HEADERS or {} self._cookies_key = cookies_key self._base_url = base_url self._timeout = timeout or (5, 10) self._attempts = attempts or 2 self.headers.update(self._headers) if self._cookies_key: self.cookies.update(settings.getDict(self._cookies_key, {}))