def _(): (path, serverlist, titlelist, title) = request.parse(plugin.path, 'ServerListParser') position = Dialog().select(_addon.getLocalizedString(33500), titlelist) item = ListItem(title) url = False if position != -1: xbmc.executebuiltin('ActivateWindow(busydialognocancel)') resolveurl.add_plugin_dirs(_plugins) try: url = resolveurl.resolve(serverlist[position]) if url: edb.connect() edb.add(path) edb.close() item.setPath(url) subtitle = request.subtitle(serverlist[position]) if subtitle: item.setSubtitles([subtitle]) else: Dialog().notification(_addon.getLocalizedString(33502), '') except: Dialog().notification(_addon.getLocalizedString(33501), '') xbmc.executebuiltin('Dialog.Close(busydialognocancel)') else: xbmc.executebuiltin('Playlist.Clear') xbmc.sleep(500) xbmcplugin.setResolvedUrl(plugin.handle, isinstance(url, str), item)
def login(plugin): method = Dialog().yesno("Login", "Select Login Method", yeslabel="Keyboard", nolabel="WEB") if method == 1: login_type = Dialog().yesno("Login", "Select Login Type", yeslabel="OTP", nolabel="Password") if login_type == 1: mobile = keyboard("Enter your Jio mobile number") error = sendOTP(mobile) if error: Script.notify("Login Error", error) return otp = keyboard("Enter OTP", hidden=True) ULogin(mobile, otp, mode="otp") elif login_type == 0: username = keyboard("Enter your Jio mobile number or email") password = keyboard("Enter your password", hidden=True) ULogin(username, password) elif method == 0: pDialog = DialogProgress() pDialog.create( 'JioTV', 'Visit [B]http://%s:48996/[/B] to login' % socket.gethostbyname(socket.gethostname())) for i in range(120): sleep(1) with PersistentDict("headers") as db: headers = db.get("headers") if headers or pDialog.iscanceled(): break pDialog.update(i) pDialog.close()
def show_search(keyword): if len(keyword) < 3: keyword = Dialog().input("Search: ", type=INPUT_ALPHANUM) if keyword == "": return endOfDirectory(plugin.handle, succeeded=False) while len(keyword) < 3: keyword = Dialog().input( "Search, must be at least 3 characters, Try Again: ", type=INPUT_ALPHANUM) if keyword == "": return endOfDirectory(plugin.handle, succeeded=False) addDirectoryItem( plugin.handle, "", ListItem("[B]Search For:[/B] [LIGHT]{0}[/LIGHT]".format(keyword))) f = open(PROFILE + "/search.txt", 'a') f.write(keyword + "\n") f.close() for item in kaa.search(keyword): li = ListItem(item["name"]) li.setArt({ 'Poster': "https://www.kickassanime.rs/uploads/{0}".format(item["image"]) }) addDirectoryItem( plugin.handle, plugin.url_for(show_anime, item["slug"].split("/")[2]), li, True) endOfDirectory(plugin.handle)
def Update(username, plugin_id, branch, token, silent): REMOTE_PLUGIN_COMMITS = "https://api.github.com/repos/%s/%s/commits/%s" % (username, plugin_id, branch) REMOTE_PLUGIN_DOWNLOADS = "https://api.github.com/repos/%s/%s/zipball/%s" % (username, plugin_id, branch) auth = HTTPBasicAuth(username, token.decode('base64')) xbmc.log('%s - Search for update ' % plugin_id, LOGNOTICE) try: ADDON_DIR = translatePath(addon(plugin_id).getAddonInfo('profile')).decode('utf-8') LOCAL_PLUGIN_VERSION = os.path.join(ADDON_DIR, "update_sha") LOCAL_FILE_NAME_PLUGIN = os.path.join(ADDON_DIR, 'update-' + plugin_id + '.zip') if not os.path.exists(ADDON_DIR): os.mkdir(ADDON_DIR) #ka - Update erzwingen if addon().getSetting('enforceUpdate') == 'true': if silent == False and os.path.exists(LOCAL_PLUGIN_VERSION): os.remove(LOCAL_PLUGIN_VERSION) path = addon(plugin_id).getAddonInfo('Path') commitXML = _getXmlString(REMOTE_PLUGIN_COMMITS, auth) if commitXML: isTrue = commitUpdate(commitXML, LOCAL_PLUGIN_VERSION, REMOTE_PLUGIN_DOWNLOADS, path, plugin_id, LOCAL_FILE_NAME_PLUGIN, silent, auth) if isTrue == True: xbmc.log('%s - Update successful.' % plugin_id, LOGNOTICE) if silent == False: Dialog().ok(PLUGIN_NAME, plugin_id + " - Update erfolgreich.") return True elif isTrue == None: xbmc.log('%s - no new update ' % plugin_id, LOGNOTICE) if silent == False: Dialog().ok(PLUGIN_NAME, plugin_id + " - Kein Update verfügbar.") return None xbmc.log('%s - Update error ' % plugin_id, LOGERROR) Dialog().ok(PLUGIN_NAME, 'Fehler beim Update vom ' + plugin_id) return False except: xbmc.log('%s - Update error ' % plugin_id, LOGERROR) Dialog().ok(PLUGIN_NAME, 'Fehler beim Update vom ' + plugin_id)
def _http_request(url): ''' Perform an HTTP request and return request ''' log('Request URL: {url}', url=url) filename = url.split('/')[-1] for retry in (False, True): try: req = urlopen(url) log('Response code: {code}', code=req.getcode()) if 400 <= req.getcode() < 600: raise HTTPError('HTTP %s Error for url: %s' % (req.getcode(), url), response=req) break except HTTPError: Dialog().ok(localize(30004), localize( 30013, filename=filename)) # Failed to retrieve file return None except BadStatusLine: if retry: Dialog().ok( localize(30004), localize(30013, filename=filename)) # Failed to retrieve file return None return req
def check_addon(addonid, minVersion=False): """Checks if selected add-on is installed.""" try: curVersion = Script.get_info("version", addonid) if minVersion and LooseVersion(curVersion) < LooseVersion(minVersion): Script.log( '{addon} {curVersion} doesn\'t setisfy required version {minVersion}.' .format(addon=addonid, curVersion=curVersion, minVersion=minVersion)) Dialog().ok( "Error", "{minVersion} version of {addon} is required to play this content." .format(addon=addonid, minVersion=minVersion)) return False return True except RuntimeError: Script.log('{addon} is not installed.'.format(addon=addonid)) if not _install_addon(addonid): # inputstream is missing on system Dialog().ok( "Error", "[B]{addon}[/B] is missing on your Kodi install. This add-on is required to play this content." .format(addon=addonid)) return False return True
def start(self): while True: idx = Dialog().select(tr(30007), WINDOWS.values()) if idx == -1: break window = WINDOWS.keys()[idx] while True: idx = Dialog().select(tr(30008), ACTIONS.keys()) if idx == -1: break category = ACTIONS.keys()[idx] while True: curr_keymap = self._current_keymap(window, category) labels = [ "%s - %s" % (name, key) for _, key, name in curr_keymap ] idx = Dialog().select(tr(30009), labels) if idx == -1: break action, oldkey, _ = curr_keymap[idx] newkey = self._record_key() old = (window, action, oldkey) new = (window, action, newkey) if old in self.userkeymap: self.userkeymap.remove(old) self.userkeymap.append(new) if old != new: self.dirty = True
def _check_widevine(self): """Checks that all Widevine components are installed and available.""" if system_os() == 'Android': # no checks needed for Android return True if not os.path.exists(self._widevine_config_path()): log('Widevine or recovery config is missing. Reinstall is required.' ) Dialog().ok(localize(30001), localize(30031)) # An update of Widevine is required return self.install_widevine() if 'x86' in self._arch( ): # check that widevine arch matches system arch wv_config = self._load_widevine_config() if config.WIDEVINE_ARCH_MAP_X86[self._arch()] != wv_config['arch']: log('Widevine/system arch mismatch. Reinstall is required.') Dialog().ok( localize(30001), localize(30031)) # An update of Widevine is required return self.install_widevine() if self._missing_widevine_libs(): Dialog().ok( localize(30004), localize(30032, libs=', '.join( self._missing_widevine_libs()))) # Missing libraries return False self._update_widevine() return True
def Update(name, REMOTE_PLUGIN_COMMITS, REMOTE_PLUGIN_DOWNLOADS, silent): log('%s - Search for update ' % name, LOGNOTICE) try: ADDON_DIR = translatePath( addon(name).getAddonInfo('profile')).decode('utf-8') LOCAL_PLUGIN_VERSION = os.path.join(ADDON_DIR, "update_sha") LOCAL_FILE_NAME_PLUGIN = os.path.join(ADDON_DIR, 'update-' + name + '.zip') if not os.path.exists(ADDON_DIR): os.mkdir(ADDON_DIR) path = addon(name).getAddonInfo('Path') commitXML = _getXmlString(REMOTE_PLUGIN_COMMITS) if commitXML: isTrue = commitUpdate(commitXML, LOCAL_PLUGIN_VERSION, REMOTE_PLUGIN_DOWNLOADS, path, name, LOCAL_FILE_NAME_PLUGIN, silent) if isTrue == True: log('%s - Update successful.' % name, LOGNOTICE) if silent == False: Dialog().ok(PLUGIN, name + " - Update erfolgreich.") return elif isTrue == None: log('%s - no new update ' % name, LOGNOTICE) if silent == False: Dialog().ok(PLUGIN, name + " - Kein Update verfügbar.") return log('%s - Update error ' % name, LOGERROR) Dialog().ok(PLUGIN, 'Fehler beim ' + name + " - Update.") return except: log('%s - Update error ' % name, LOGERROR) Dialog().ok(PLUGIN, 'Fehler beim ' + name + " - Update.")
def _supports_widevine(self): """Checks if Widevine is supported on the architecture/operating system/Kodi version.""" if self._arch() not in config.WIDEVINE_SUPPORTED_ARCHS: log('Unsupported Widevine architecture found: {arch}', arch=self._arch()) Dialog().ok( localize(30004), localize(30007)) # Widevine not available on this architecture return False if system_os() not in config.WIDEVINE_SUPPORTED_OS: log('Unsupported Widevine OS found: {os}', os=system_os()) Dialog().ok(localize(30004), localize( 30011, os=system_os())) # Operating system not supported by Widevine return False if LooseVersion(config.WIDEVINE_MINIMUM_KODI_VERSION[ system_os()]) > LooseVersion(self._kodi_version()): log('Unsupported Kodi version for Widevine: {version}', version=self._kodi_version()) Dialog().ok(localize(30004), localize(30010, version=config.WIDEVINE_MINIMUM_KODI_VERSION[ system_os()])) # Kodi too old return False if 'WindowsApps' in translate_path( 'special://xbmcbin/'): # uwp is not supported log('Unsupported UWP Kodi version detected.') Dialog().ok(localize(30004), localize(30012)) # Windows Store Kodi falls short return False return True
def menu_index(): try: ''' it is supported only in newer versions of kodi ''' menu = Dialog().contextmenu([ 'Football', 'Tennis', 'Basketball', 'Ice Hockey', 'Baseball', 'Rugby', 'Table Tennis', 'Valleyball', 'Austranlian Rules' ]) except: menu = Dialog().select('', [ 'Football', 'Tennis', 'Basketball', 'Ice Hockey', 'Baseball', 'Rugby', 'Table Tennis', 'Valleyball', 'Austranlian Rules' ]) if menu == 0: plugin.redirect(plugin.url_for('open_live', sport='football')) if menu == 1: plugin.redirect(plugin.url_for('open_live', sport='tennis')) if menu == 2: plugin.redirect(plugin.url_for('open_live', sport='basketball')) if menu == 3: plugin.redirect(plugin.url_for('open_live', sport='ice_hockey')) if menu == 4: plugin.redirect(plugin.url_for('open_live', sport='baseball')) if menu == 5: plugin.redirect(plugin.url_for('open_live', sport='rugby')) if menu == 6: plugin.redirect(plugin.url_for('open_live', sport='table_tennis')) if menu == 7: plugin.redirect(plugin.url_for('open_live', sport='volleyball')) if menu == 8: plugin.redirect(plugin.url_for('open_live', sport='australian_rules'))
def check_inputstream(self): """Main function. Ensures that all components are available for InputStream add-on playback.""" if self._helper_disabled( ): # blindly return True if helper has been disabled return True if self.drm == 'widevine' and not self._supports_widevine(): return False if not self._has_inputstream(): # Try to install InputStream add-on if not self._install_inputstream(): Dialog().ok(localize(30004), localize(30008, addon=self.inputstream_addon) ) # inputstream is missing on system return False elif not self._inputstream_enabled(): ret = Dialog().yesno( localize(30001), localize( 30009, addon=self.inputstream_addon)) # inputstream is disabled if ret: self._enable_inputstream() return False log('{addon} {version} is installed and enabled.', addon=self.inputstream_addon, version=self._inputstream_version()) if self.protocol == 'hls' and not self._supports_hls(): Dialog().ok( localize(30004), # HLS Minimum version is needed localize(30017, addon=self.inputstream_addon, version=config.HLS_MINIMUM_IA_VERSION)) return False return self._check_drm()
def show_ok_dialog(self, heading='', message=''): """Show Kodi's OK dialog""" from xbmcgui import Dialog if not heading: heading = ADDON.getAddonInfo('name') if self.kodi_version_major() < 19: return Dialog().ok(heading=heading, line1=message) return Dialog().ok(heading=heading, message=message)
def yesno_dialog(heading='', message='', nolabel=None, yeslabel=None, autoclose=0): """Show Kodi's Yes/No dialog""" from xbmcgui import Dialog if not heading: heading = addon_name() if kodi_version_major() < 19: return Dialog().yesno(heading=heading, line1=message, nolabel=nolabel, yeslabel=yeslabel, autoclose=autoclose) return Dialog().yesno(heading=heading, message=message, nolabel=nolabel, yeslabel=yeslabel, autoclose=autoclose)
def textviewer(heading='', text='', usemono=False): """Show a Kodi textviewer dialog""" from xbmcgui import Dialog if not heading: heading = ADDON.getAddonInfo('name') if kodi_version_major() < 18: return Dialog().textviewer(heading=heading, text=text) return Dialog().textviewer(heading=heading, text=text, usemono=usemono)
def ok_dialog(heading='', message=''): """Show Kodi's OK dialog""" from xbmcgui import Dialog if not heading: heading = addon_name() if kodi_version_major() < 19: return Dialog().ok(heading=heading, line1=message) return Dialog().ok(heading=heading, message=message)
def show_ok_dialog(self, heading='', message=''): """Show Kodi's OK dialog""" from xbmcgui import Dialog if not heading: heading = ADDON.getAddonInfo('name') if self.kodi_version_major() < 19: return Dialog().ok(heading=heading, line1=message) # pylint: disable=unexpected-keyword-arg,no-value-for-parameter return Dialog().ok(heading=heading, message=message)
def add_to_lib(): item_type = plugin.args['item_type'][0] folder = Addon().getSettingString('library_folder') if Dialog().yesno(Addon().getLocalizedString(32071), f"{Addon().getLocalizedString(32071)} \"{unquote_plus(plugin.args['title'][0])}\"") == True: title = Dialog().input(Addon().getLocalizedString(32074)) else: title = unquote_plus(plugin.args['title'][0]) if item_type == "series": shows_folder = os.path.join(folder, "shows") files = parse_json(plugin.args['url'][0]) current_season = 1 current_episode = 1 remembered_season = False subfoldered_seasons = False if files[0]['url_type'] != "link": subfoldered_seasons == False current_season = Dialog().numeric(0, Addon().getLocalizedString(32091)) show_folder = os.path.join(bytes(shows_folder ,encoding="utf8"), bytes(correct_spaces(title), encoding="utf8")) if not os.path.isdir(show_folder): os.mkdir(show_folder) season_folder = os.path.join(show_folder, bytes("Season "+str(current_season), encoding="utf8")) if not os.path.isdir(season_folder): os.mkdir(season_folder) for ifile in files: if subfoldered_seasons == False: f = open(os.path.join(season_folder, bytes(f"S{str(current_season)}E{current_episode}"+".strm", encoding="utf8")), "w") f.write(generate_static_url(ifile['url_type'], ifile['url'], 1, order=int(ifile['index']))) f.close() current_episode += 1 else: folder = os.path.join(folder, "movies") if not os.path.isdir(folder): #print(season_folder) os.mkdir(folder) f = open(os.path.join(bytes(folder, encoding="utf8"), bytes(title+".strm", encoding="utf8")), "w") if 'url_type' in plugin.args: urltype = plugin.args['url_type'][0] else: urltype = 0 if 'page_type' in plugin.args: pagetype = plugin.args['page_type'][0] else: pagetype = "json" if 'suborder' in plugin.args: f.write(generate_static_url(plugin.args['item_type'][0], plugin.args['url'][0], int(plugin.args['order'][0]), urltype, pagetype, subindex=int(plugin.args['suborder'][0]))) else: f.write(generate_static_url(plugin.args['item_type'][0], plugin.args['url'][0], int(plugin.args['order'][0]), urltype, pagetype)) f.close() #executebuiltin('UpdateLibrary("video")') Dialog().notification(Addon().getLocalizedString(32066), Addon().getLocalizedString(32073), NOTIFICATION_INFO)
def ok_dialog(heading='', message=''): """Show Kodi's OK dialog""" from xbmcgui import Dialog if not heading: heading = addon_name() if kodi_version_major() < 19: # pylint: disable=unexpected-keyword-arg,no-value-for-parameter return Dialog().ok(heading=heading, line1=message) return Dialog().ok(heading=heading, message=message)
def onClick(self, control_id, *args): if control_id == self.TRIMBUTTONID: if Dialog().yesno(translate(32604), translate(32605)): self.getControl(self.TEXTBOXID).setText(self.log.trim()) elif control_id == self.CLEARBUTTONID: if Dialog().yesno(translate(32604), translate(32606)): self.getControl(self.TEXTBOXID).setText(self.log.clear()) else: raise ValueError("Unknown button pressed")
def reset(): """ Reset all user-set exclusion paths to blanks. """ if Dialog().yesno(translate(32604), translate(32610)): # Are you sure? ADDON.setSettingString(id="exclusion1", value=" ") ADDON.setSettingString(id="exclusion2", value=" ") ADDON.setSettingString(id="exclusion3", value=" ") ADDON.setSettingString(id="exclusion4", value=" ") ADDON.setSettingString(id="exclusion5", value=" ") Dialog().ok(translate(32630), translate(32631)) # Don't forget to save
def auth(): login = Addon().getSettingString('email') password = Addon().getSettingString('password') if len(login) == 0 or len(password) == 0: return Dialog().notification(Addon().getLocalizedString(32075), Addon().getLocalizedString(32076), icon=NOTIFICATION_ERROR) response = json.loads(get_page(f"http://forkplayer.tv/xml/account.php?act=submit&login={login}&password={password}")[0]) if 'error' in response: Dialog().notification(Addon().getLocalizedString(32070), response['error'], icon=NOTIFICATION_ERROR) else: Addon().setSetting('fork_cookie', response['setcookie']['sid']) Dialog().notification(Addon().getLocalizedString(32066), Addon().getLocalizedString(32069), icon=NOTIFICATION_INFO)
def main(): ## load mappings ## try: setup_keymap_folder() except Exception: traceback.print_exc() utils.rpc('GUI.ShowNotification', title="Keymap Editor", message="Failed to remove old keymap file", image='error') return defaultkeymap = utils.read_keymap(default) userkeymap = [] if os.path.exists(gen_file): try: userkeymap = utils.read_keymap(gen_file) except Exception: traceback.print_exc() utils.rpc('GUI.ShowNotification', title="Keymap Editor", message="Failed to load keymap file", image='error') return ## main loop ## confirm_discard = False while True: idx = Dialog().select(tr(30000), [tr(30003), tr(30004), tr(30005)]) if idx == 0: # edit editor = Editor(defaultkeymap, userkeymap) editor.start() confirm_discard = editor.dirty elif idx == 1: # reset confirm_discard = bool(userkeymap) userkeymap = [] elif idx == 2: # save if os.path.exists(gen_file): shutil.copyfile(gen_file, gen_file + ".old") utils.write_keymap(userkeymap, gen_file) xbmc.executebuiltin("action(reloadkeymaps)") break elif idx == -1 and confirm_discard: if Dialog().yesno(tr(30000), tr(30006)) == 1: break else: break sys.modules.clear()
def doLogin(self): with PersistentDict("userdata.pickle") as db: try: username = Settings.get_string( "username", "plugin.video.jiotv") or db.get("username") or Dialog( ).input("Username (MobileNo / Email)") password = Settings.get_string( "password", "plugin.video.jiotv") or db.get( "password") or Dialog().input("Password") except RuntimeError: username = Dialog().input("Username (MobileNo / Email)") password = Dialog().input("Password") if username and password: body = { "identifier": username if '@' in username else "+91" + username, "password": password, "rememberUser": "******", "upgradeAuth": "Y", "returnSessionDetails": "T", "deviceInfo": { "consumptionDeviceName": "Jio", "info": { "type": "android", "platform": { "name": "vbox86p", "version": "8.0.0" }, "androidId": "6fcadeb7b4b10d77" } } } resp = urlquick.post( "https://api.jio.com/v3/dip/user/unpw/verify", json=body, headers={ "x-api-key": "l7xx75e822925f184370b2e25170c5d5820a" }, verify=False, raise_for_status=False).json() if resp.get("ssoToken"): db["data"] = resp Script.notify("Login Successful", "You have been logged in successfully") else: Script.notify( "Login Failed", "Double check you username and password and try again") else: Script.notify("Login Required", "Please login with you Jio credentials")
def remove_widevine(self): """Removes Widevine CDM""" widevinecdm = self._widevine_path() if widevinecdm and xbmcvfs.exists(widevinecdm): log('Remove Widevine CDM at {path}', path=widevinecdm) xbmcvfs.delete(widevinecdm) Dialog().notification( localize(30037), localize(30052)) # Success! Widevine successfully removed. return True Dialog().notification( localize(30004), localize(30053)) # Error. Widevine CDM not found. return False
def start(self): while True: # Select context menu idx = Dialog().select(tr(30007), WINDOWS.values()) if idx == -1: break window = WINDOWS.keys()[idx] while True: # Select category menu idx = Dialog().select(tr(30008), ACTIONS.keys()) if idx == -1: break category = ACTIONS.keys()[idx] while True: # Select action menu current_keymap = self._current_keymap(window, category) labels = [ "%s - %s" % (name, key) for _, key, name in current_keymap ] idx = Dialog().select(tr(30009), labels) if idx == -1: break action, current_key, _ = current_keymap[idx] old_mapping = (window, action, current_key) # Ask what to do idx = Dialog().select(tr(30000), [tr(30011), tr(30012)]) if idx == -1: continue elif idx == 1: # Remove if old_mapping in self.userkeymap: self.userkeymap.remove(old_mapping) self.dirty = True elif idx == 0: # Edit key newkey = KeyListener.record_key() if newkey is None: continue new_mapping = (window, action, newkey) if old_mapping in self.userkeymap: self.userkeymap.remove(old_mapping) self.userkeymap.append(new_mapping) if old_mapping != new_mapping: self.dirty = True
def add_playlist(): print(plugin.args) url = plugin.args['url'][0] menu_slots = [] for slot in range(1, 8): current_slot = Addon().getSettingString('iptv'+str(slot)) if len(current_slot) > 0: menu_slots.append(current_slot) else: menu_slots.append(f"Playlist {str(slot)}") order = str(Dialog().select(Addon().getLocalizedString(32078), menu_slots) + 1) if Dialog().yesno(Addon().getLocalizedString(32064), f"{Addon().getLocalizedString(32065)} {order}") == False: return False Addon().setSetting(id=str('iptv'+order), value=url) Dialog().notification(Addon().getLocalizedString(32066), f"{Addon().getLocalizedString(32077)} " + order, NOTIFICATION_INFO)
def notification(self, msg, description, icon=NOTIFICATION_ERROR): if icon == NOTIFICATION_ERROR: time = 10000 else: time = 3000 return Dialog().notification(msg, description, icon, time)
def choose_video_stream(streams): stream_labels = [] streams.sort(key=operator.itemgetter('size'), reverse=settings.as_bool(SETTINGS.SORT_DESCENDING)) audio_info_list = [] for stream in streams: # Fix audio string that begins with the comma. audio_info = [] for audio in stream.get('audio'): audio_info.append('[I][{} {} {}][/I]'.format( audio.get('codec'), format(audio.get('channels'), '.1f'), audio.get('language'))) audio_info_list.append(' '.join(audio_info)) quality = STRINGS.STREAM_TITLE_BRACKETS.format( stream.get('quality')) size = STRINGS.BOLD.format(convert_size(stream.get('size'))) stream_labels.append([quality, size]) table = make_table(stream_labels) table = append_list_items_to_nested_list_items(table, audio_info_list) ret = Dialog().select('Choose the stream', [" ".join(item) for item in table]) if ret < 0: return None return streams[ret]
def devUpdates(): try: rs = False LS = False options = ['Beide', 'URL Resolver', 'Lastship'] result = Dialog().select('Welches Update ausführen?', options) if result == 0: rs = True LS = True elif result == 1: rs = True elif result == 2: LS = True if LS == True: try: pluginVideoLastship(False) except: pass if rs == True: try: urlResolverUpdate(False) except: pass return except Exception as e: log(e)