def showServerSessions(): log.debug("showServerSessions Called") handle = int(sys.argv[1]) downloadUtils = DownloadUtils() url = "{server}/emby/Sessions" result_data = downloadUtils.downloadUrl(url) results = json.loads(result_data) if results is None: return list_items = [] for session in results: device_name = session.get("DeviceName", "na") user_name = session.get("UserName", "na") client_name = session.get("Client", "na") session_info = device_name + " - " + user_name + " - " + client_name # playstate percenatge_played = 0 play_state = session.get("PlayState", None) if play_state is not None: runtime = 0 media_id = play_state.get("MediaSourceId", None) log.debug("Media ID: {0}", media_id) if media_id is not None: url = "{server}/emby/Users/{userid}/Items/" + media_id + "?format=json" jsonData = downloadUtils.downloadUrl(url) media_info = json.loads(jsonData) if media_info: log.debug("Media Info: {0}", media_info) runtime = media_info.get("RunTimeTicks", 0) log.debug("Media Runtime: {0}", runtime) position_ticks = play_state.get("PositionTicks", 0) log.debug("Media PositionTicks: {0}", position_ticks) if position_ticks > 0 and runtime > 0: percenatge_played = (position_ticks / float(runtime)) * 100.0 percenatge_played = int(percenatge_played) now_playing = session.get("NowPlayingItem", None) log.debug("NOW_PLAYING: {0}", now_playing) if now_playing is not None: session_info += " (" + now_playing.get( "Name", "na") + " " + str(percenatge_played) + "%)" log.debug("session_info: {0}", session_info) list_item = xbmcgui.ListItem(label=session_info) item_tuple = ("", list_item, False) list_items.append(item_tuple) xbmcplugin.addDirectoryItems(handle, list_items) xbmcplugin.endOfDirectory(handle, cacheToDisc=False)
def process_plex_node(self, url, viewOffset, directplay=False, node=True): """ Called for Plex directories or redirect for playback (e.g. trailers, clips, watchlater) """ log.info('process_plex_node called with url: %s, viewOffset: %s' % (url, viewOffset)) # Plex redirect, e.g. watch later. Need to get actual URLs if url.startswith('http') or url.startswith('{server}'): xml = DownloadUtils().downloadUrl(url) else: xml = DownloadUtils().downloadUrl('{server}%s' % url) try: xml[0].attrib except: log.error('Could not download PMS metadata') return if viewOffset != '0': try: viewOffset = int(v.PLEX_TO_KODI_TIMEFACTOR * float(viewOffset)) except: pass else: window('plex_customplaylist.seektime', value=str(viewOffset)) log.info('Set resume point to %s' % str(viewOffset)) api = API(xml[0]) typus = v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()] if node is True: plex_id = None kodi_id = 'plexnode' else: plex_id = api.getRatingKey() kodi_id = None with plexdb.Get_Plex_DB() as plex_db: plexdb_item = plex_db.getItem_byId(plex_id) try: kodi_id = plexdb_item[0] except TypeError: log.info('Couldnt find item %s in Kodi db' % api.getRatingKey()) playqueue = self.playqueue.get_playqueue_from_type(typus) with lock: result = PlaybackUtils(xml, playqueue).play( plex_id, kodi_id=kodi_id, plex_lib_UUID=xml.attrib.get('librarySectionUUID')) if directplay: if result.listitem: listitem = convert_PKC_to_listitem(result.listitem) Player().play(listitem.getfilename(), listitem) return Playback_Successful() else: return result
def __init__(self, item): self.item = item self.API = PlexAPI.API(item) self.doUtils = DownloadUtils().downloadUrl self.machineIdentifier = window('plex_machineIdentifier')
def __init__(self, callback): self.mgr = callback self.doUtils = DownloadUtils().downloadUrl self.xbmcplayer = Player() self.playqueue = self.mgr.playqueue Monitor.__init__(self) log.info("Kodi monitor started.")
def __init__(self, item): self.item = item self.API = PlexAPI.API(item) self.doUtils = DownloadUtils().downloadUrl self.userid = window('currUserId') self.server = window('pms_server') self.machineIdentifier = window('plex_machineIdentifier')
def get_pin(): """ For plex.tv sign-in: returns 4-digit code and identifier as 2 str """ code = None identifier = None # Download xml = DU().downloadUrl('https://plex.tv/pins.xml', authenticate=False, action_type="POST") try: xml.attrib except AttributeError: LOG.error("Error, no PIN from plex.tv provided") return None, None code = xml.find('code').text identifier = xml.find('id').text LOG.info('Successfully retrieved code and id from plex.tv') return code, identifier
def check_pin(identifier): """ Checks with plex.tv whether user entered the correct PIN on plex.tv/pin Returns False if not yet done so, or the XML response file as etree """ # Try to get a temporary token xml = DU().downloadUrl('https://plex.tv/pins/%s.xml' % identifier, authenticate=False) try: temp_token = xml.find('auth_token').text except AttributeError: LOG.error("Could not find token in plex.tv answer") return False if not temp_token: return False # Use temp token to get the final plex credentials xml = DU().downloadUrl('https://plex.tv/users/account', authenticate=False, parameters={'X-Plex-Token': temp_token}) return xml
def _poke_pms(pms, queue): data = pms['connections'][0].attrib if data['local'] == '1': protocol = data['protocol'] address = data['address'] port = data['port'] url = '%s://%s:%s' % (protocol, address, port) else: url = data['uri'] if url.count(':') == 1: url = '%s:%s' % (url, data['port']) protocol, address, port = url.split(':', 2) address = address.replace('/', '') xml = DU().downloadUrl('%s/identity' % url, authenticate=False, headerOptions={'X-Plex-Token': pms['token']}, verifySSL=False, timeout=10) try: xml.attrib['machineIdentifier'] except (AttributeError, KeyError): # No connection, delete the one we just tested del pms['connections'][0] if pms['connections']: # Still got connections left, try them return _poke_pms(pms, queue) return else: # Connection successful - correct pms? if xml.get('machineIdentifier') == pms['machineIdentifier']: # process later pms['baseURL'] = url pms['protocol'] = protocol pms['ip'] = address pms['port'] = port queue.put(pms) return LOG.info('Found a pms at %s, but the expected machineIdentifier of ' '%s did not match the one we found: %s', url, pms['uuid'], xml.get('machineIdentifier'))
def __init__(self): self.__dict__ = self.__shared_state self.auth = True self.retry = 0 self.currUser = None self.currServer = None self.currToken = None self.HasAccess = True self.AdditionalUser = [] self.userSettings = None self.addon = xbmcaddon.Addon() self.doUtils = DU() Thread.__init__(self)
def get_items(self, url, gui_options, use_cache=False): home_window = HomeWindow() log.debug("last_content_url : {0}", url) home_window.setProperty("last_content_url", url) user_id = DownloadUtils().getUserId() m = hashlib.md5() m.update(user_id + "|" + url) url_hash = m.hexdigest() cache_file = os.path.join(self.addon_dir, "cache_" + url_hash + ".pickle") #changed_url = url + "&MinDateLastSavedForUser="******"2019-09-16T13:45:30") #results = self.GetContent(changed_url) #log.debug("DataManager Changes Since Date : {0}", results) item_list = None baseline_name = None cache_thread = CacheManagerThread() cache_thread.gui_options = gui_options home_window.setProperty(cache_file, "true") clear_cache = home_window.getProperty("skip_cache_for_" + url) if clear_cache and os.path.isfile(cache_file): log.debug("Clearing cache data and loading new data") home_window.clearProperty("skip_cache_for_" + url) os.remove(cache_file) # try to load the list item data form the cache if os.path.isfile(cache_file) and use_cache: log.debug("Loading url data from cached pickle data") with open(cache_file, 'rb') as handle: try: cache_item = cPickle.load(handle) cache_thread.cached_item = cache_item item_list = cache_item.item_list except Exception, err: log.debug("Pickle Data Load Failed : {0}", err) item_list = None
from utils import getArt from simple_logging import SimpleLogging from translation import i18n from downloadutils import DownloadUtils from datamanager import DataManager from kodi_utils import HomeWindow log = SimpleLogging(__name__) kodi_version = int(xbmc.getInfoLabel('System.BuildVersion')[:2]) addon_instance = xbmcaddon.Addon() addon_path = addon_instance.getAddonInfo('path') PLUGINPATH = xbmc.translatePath(os.path.join(addon_path)) download_utils = DownloadUtils() home_window = HomeWindow() class ItemDetails(): name = None id = None path = None is_folder = False plot = None series_name = None episode_number = 0 season_number = 0 track_number = 0
class UserClient(Thread): # Borg - multiple instances, shared state __shared_state = {} def __init__(self): self.__dict__ = self.__shared_state self.auth = True self.retry = 0 self.currUser = None self.currServer = None self.currToken = None self.HasAccess = True self.AdditionalUser = [] self.userSettings = None self.addon = xbmcaddon.Addon() self.doUtils = DU() Thread.__init__(self) def getUsername(self): """ Returns username as unicode """ username = settings('username') if not username: LOG.debug("No username saved, trying to get Plex username") username = settings('plexLogin') if not username: LOG.debug("Also no Plex username found") return "" return username def getServer(self, prefix=True): # Original host self.servername = settings('plex_servername') HTTPS = settings('https') == "true" host = settings('ipaddress') port = settings('port') self.machineIdentifier = settings('plex_machineIdentifier') server = host + ":" + port if not host: LOG.debug("No server information saved.") return False # If https is true if prefix and HTTPS: server = "https://%s" % server # If https is false elif prefix and not HTTPS: server = "http://%s" % server # User entered IP; we need to get the machineIdentifier if self.machineIdentifier == '' and prefix is True: self.machineIdentifier = PF.GetMachineIdentifier(server) if self.machineIdentifier is None: self.machineIdentifier = '' settings('plex_machineIdentifier', value=self.machineIdentifier) LOG.debug('Returning active server: %s', server) return server def getSSLverify(self): # Verify host certificate return None if settings('sslverify') == 'true' else False def getSSL(self): # Client side certificate return None if settings('sslcert') == 'None' \ else settings('sslcert') def setUserPref(self): LOG.debug('Setting user preferences') # Only try to get user avatar if there is a token if self.currToken: url = PF.GetUserArtworkURL(self.currUser) if url: window('PlexUserImage', value=url) # Set resume point max # url = "{server}/emby/System/Configuration?format=json" # result = doUtils.downloadUrl(url) def hasAccess(self): # Plex: always return True for now return True def loadCurrUser(self, username, userId, usertoken, authenticated=False): LOG.debug('Loading current user') doUtils = self.doUtils self.currToken = usertoken self.currServer = self.getServer() self.ssl = self.getSSLverify() self.sslcert = self.getSSL() if authenticated is False: if self.currServer is None: return False LOG.debug('Testing validity of current token') res = PF.check_connection(self.currServer, token=self.currToken, verifySSL=self.ssl) if res is False: # PMS probably offline return False elif res == 401: LOG.error('Token is no longer valid') return 401 elif res >= 400: LOG.error('Answer from PMS is not as expected. Retrying') return False # Set to windows property state.PLEX_USER_ID = userId or None state.PLEX_USERNAME = username # This is the token for the current PMS (might also be '') window('pms_token', value=usertoken) state.PMS_TOKEN = usertoken # This is the token for plex.tv for the current user # Is only '' if user is not signed in to plex.tv window('plex_token', value=settings('plexToken')) state.PLEX_TOKEN = settings('plexToken') or None window('plex_restricteduser', value=settings('plex_restricteduser')) state.RESTRICTED_USER = True \ if settings('plex_restricteduser') == 'true' else False window('pms_server', value=self.currServer) window('plex_machineIdentifier', value=self.machineIdentifier) window('plex_servername', value=self.servername) window('plex_authenticated', value='true') state.AUTHENTICATED = True window('useDirectPaths', value='true' if settings('useDirectPaths') == "1" else 'false') state.DIRECT_PATHS = True if settings('useDirectPaths') == "1" \ else False state.INDICATE_MEDIA_VERSIONS = True \ if settings('indicate_media_versions') == "true" else False window('plex_force_transcode_pix', value='true' if settings('force_transcode_pix') == "1" else 'false') # Start DownloadUtils session doUtils.startSession(reset=True) # self.getAdditionalUsers() # Set user preferences in settings self.currUser = username self.setUserPref() # Writing values to settings file settings('username', value=username) settings('userid', value=userId) settings('accessToken', value=usertoken) return True def authenticate(self): LOG.debug('Authenticating user') # Give attempts at entering password / selecting user if self.retry >= 2: LOG.error("Too many retries to login.") state.PMS_STATUS = 'Stop' dialog('ok', lang(33001), lang(39023)) executebuiltin( 'Addon.OpenSettings(plugin.video.plexkodiconnect)') return False # Get /profile/addon_data addondir = translatePath(self.addon.getAddonInfo('profile')) # If there's no settings.xml if not exists("%ssettings.xml" % addondir): LOG.error("Error, no settings.xml found.") self.auth = False return False server = self.getServer() # If there is no server we can connect to if not server: LOG.info("Missing server information.") self.auth = False return False # If there is a username in the settings, try authenticating username = settings('username') userId = settings('userid') usertoken = settings('accessToken') enforceLogin = settings('enforceUserLogin') # Found a user in the settings, try to authenticate if username and enforceLogin == 'false': LOG.debug('Trying to authenticate with old settings') answ = self.loadCurrUser(username, userId, usertoken, authenticated=False) if answ is True: # SUCCESS: loaded a user from the settings return True elif answ == 401: LOG.error("User token no longer valid. Sign user out") settings('username', value='') settings('userid', value='') settings('accessToken', value='') else: LOG.debug("Could not yet authenticate user") return False # Could not use settings - try to get Plex user list from plex.tv plextoken = settings('plexToken') if plextoken: LOG.info("Trying to connect to plex.tv to get a user list") userInfo = plex_tv.choose_home_user(plextoken) if userInfo is False: # FAILURE: Something went wrong, try again self.auth = True self.retry += 1 return False username = userInfo['username'] userId = userInfo['userid'] usertoken = userInfo['token'] else: LOG.info("Trying to authenticate without a token") username = '' userId = '' usertoken = '' if self.loadCurrUser(username, userId, usertoken, authenticated=False): # SUCCESS: loaded a user from the settings return True # Something went wrong, try again self.auth = True self.retry += 1 return False def resetClient(self): LOG.debug("Reset UserClient authentication.") self.doUtils.stopSession() window('plex_authenticated', clear=True) state.AUTHENTICATED = False window('pms_token', clear=True) state.PLEX_TOKEN = None state.PLEX_TRANSIENT_TOKEN = None state.PMS_TOKEN = None window('plex_token', clear=True) window('pms_server', clear=True) window('plex_machineIdentifier', clear=True) window('plex_servername', clear=True) state.PLEX_USER_ID = None state.PLEX_USERNAME = None window('plex_restricteduser', clear=True) state.RESTRICTED_USER = False settings('username', value='') settings('userid', value='') settings('accessToken', value='') self.currToken = None self.auth = True self.currUser = None self.retry = 0 def run(self): LOG.info("----===## Starting UserClient ##===----") stopped = self.stopped suspended = self.suspended while not stopped(): while suspended(): if stopped(): break sleep(1000) if state.PMS_STATUS == "Stop": sleep(500) continue # Verify the connection status to server elif state.PMS_STATUS == "restricted": # Parental control is restricting access self.HasAccess = False elif state.PMS_STATUS == "401": # Unauthorized access, revoke token state.PMS_STATUS = 'Auth' window('plex_serverStatus', value='Auth') self.resetClient() sleep(3000) if self.auth and (self.currUser is None): # Try to authenticate user if not state.PMS_STATUS or state.PMS_STATUS == "Auth": # Set auth flag because we no longer need # to authenticate the user self.auth = False if self.authenticate(): # Successfully authenticated and loaded a user LOG.info("Successfully authenticated!") LOG.info("Current user: %s", self.currUser) LOG.info("Current userId: %s", state.PLEX_USER_ID) self.retry = 0 state.SUSPEND_LIBRARY_THREAD = False window('plex_serverStatus', clear=True) state.PMS_STATUS = False if not self.auth and (self.currUser is None): # Loop if no server found server = self.getServer() # The status Stop is for when user cancelled password dialog. # Or retried too many times if server and state.PMS_STATUS != "Stop": # Only if there's information found to login LOG.debug("Server found: %s", server) self.auth = True # Minimize CPU load sleep(100) LOG.info("##===---- UserClient Stopped ----===##")
def _pms_list_from_plex_tv(token): """ get Plex media Server List from plex.tv/pms/resources """ xml = DU().downloadUrl('https://plex.tv/api/resources', authenticate=False, parameters={'includeHttps': 1}, headerOptions={'X-Plex-Token': token}) try: xml.attrib except AttributeError: LOG.error('Could not get list of PMS from plex.tv') return from Queue import Queue queue = Queue() thread_queue = [] max_age_in_seconds = 2*60*60*24 for device in xml.findall('Device'): if 'server' not in device.get('provides'): # No PMS - skip continue if device.find('Connection') is None: # no valid connection - skip continue # check MyPlex data age - skip if >2 days info_age = time() - int(device.get('lastSeenAt')) if info_age > max_age_in_seconds: LOG.debug("Skip server %s not seen for 2 days", device.get('name')) continue pms = { 'machineIdentifier': device.get('clientIdentifier'), 'name': device.get('name'), 'token': device.get('accessToken'), 'ownername': device.get('sourceTitle'), 'product': device.get('product'), # e.g. 'Plex Media Server' 'version': device.get('productVersion'), # e.g. '1.11.2.4772-3e...' 'device': device.get('device'), # e.g. 'PC' or 'Windows' 'platform': device.get('platform'), # e.g. 'Windows', 'Android' 'local': device.get('publicAddressMatches') == '1', 'owned': device.get('owned') == '1', 'relay': device.get('relay') == '1', 'presence': device.get('presence') == '1', 'httpsRequired': device.get('httpsRequired') == '1', 'connections': [] } # Try a local connection first, no matter what plex.tv tells us for connection in device.findall('Connection'): if connection.get('local') == '1': pms['connections'].append(connection) # Then try non-local for connection in device.findall('Connection'): if connection.get('local') != '1': pms['connections'].append(connection) # Spawn threads to ping each PMS simultaneously thread = Thread(target=_poke_pms, args=(pms, queue)) thread_queue.append(thread) max_threads = 5 threads = [] # poke PMS, own thread for each PMS while True: # Remove finished threads for thread in threads: if not thread.isAlive(): threads.remove(thread) if len(threads) < max_threads: try: thread = thread_queue.pop() except IndexError: # We have done our work break else: thread.start() threads.append(thread) else: sleep(50) # wait for requests being answered for thread in threads: thread.join() # declare new PMSs pms_list = [] while not queue.empty(): pms = queue.get() del pms['connections'] pms_list.append(pms) queue.task_done() return pms_list
def GetContent(self, url): jsonData = DownloadUtils().downloadUrl(url) result = self.loadJasonData(jsonData) return result
def showServerSessions(): log.debug("showServerSessions Called") handle = int(sys.argv[1]) downloadUtils = DownloadUtils() data_manager = DataManager() url = "{server}/emby/Users/{userid}" results = data_manager.GetContent(url) is_admin = results.get("Policy", {}).get("IsAdministrator", False) if not is_admin: xbmcplugin.endOfDirectory(handle, cacheToDisc=False) return url = "{server}/emby/Sessions" results = data_manager.GetContent(url) log.debug("session_info: {0}", results) if results is None: return list_items = [] for session in results: device_name = session.get("DeviceName", "na") user_name = session.get("UserName", "na") client_name = session.get("Client", "na") client_version = session.get("ApplicationVersion", "na") play_state = session.get("PlayState", None) now_playing = session.get("NowPlayingItem", None) transcoding_info = session.get("TranscodingInfo", None) session_info = user_name + " - " + client_name user_session_details = "" percenatge_played = 0 position_ticks = 0 runtime = 0 play_method = "na" if play_state is not None: position_ticks = play_state.get("PositionTicks", 0) play_method = play_state.get("PlayMethod", "na") art = {} if now_playing: server = downloadUtils.getServer() art = getArt(now_playing, server) runtime = now_playing.get("RunTimeTicks", 0) if position_ticks > 0 and runtime > 0: percenatge_played = (position_ticks / float(runtime)) * 100.0 percenatge_played = int(percenatge_played) session_info += " (" + now_playing.get( "Name", "na") + " " + str(percenatge_played) + "%)" user_session_details += now_playing.get( "Name", "na") + " " + str(percenatge_played) + "%" + "\n" else: session_info += " (idle)" user_session_details += "Idle" + "\n" transcoding_details = "" if transcoding_info: if not transcoding_info.get("IsVideoDirect", None): transcoding_details += "Video:" + transcoding_info.get( "VideoCodec", "") + ":" + str( transcoding_info.get("Width", 0)) + "x" + str( transcoding_info.get("Height", 0)) + "\n" else: transcoding_details += "Video:direct\n" if not transcoding_info.get("IsAudioDirect", None): transcoding_details += "Audio:" + transcoding_info.get( "AudioCodec", "") + ":" + str( transcoding_info.get("AudioChannels", 0)) + "\n" else: transcoding_details += "Audio:direct\n" transcoding_details += "Bitrate:" + str( transcoding_info.get("Bitrate", 0)) + "\n" list_item = xbmcgui.ListItem(label=session_info) list_item.setArt(art) user_session_details += device_name + "(" + client_version + ")\n" user_session_details += client_name + "\n" user_session_details += play_method + "\n" user_session_details += transcoding_details + "\n" info_labels = {} info_labels["duration"] = str(runtime / 10000000) info_labels["mediatype"] = "movie" info_labels["plot"] = user_session_details list_item.setInfo('video', info_labels) list_item.setProperty('TotalTime', str(runtime / 10000000)) list_item.setProperty('ResumeTime', str(position_ticks / 10000000)) list_item.setProperty("complete_percentage", str(percenatge_played)) item_tuple = ("", list_item, False) list_items.append(item_tuple) xbmcplugin.setContent(handle, "movies") xbmcplugin.addDirectoryItems(handle, list_items) xbmcplugin.endOfDirectory(handle, cacheToDisc=False)
def checkServer(force=False, change_user=False, notify=False): log.debug("checkServer Called") settings = xbmcaddon.Addon() serverUrl = "" something_changed = False if force is False: # if not forcing use server details from settings svr = downloadUtils.getServer() if svr is not None: serverUrl = svr # if the server is not set then try to detect it if serverUrl == "": serverInfo = getServerDetails() serverNames = [] for server in serverInfo: serverNames.append(server.get("Name", i18n('n/a'))) if serverNames: return_index = xbmcgui.Dialog().select(i18n('select_server'), serverNames) else: xbmcgui.Dialog().ok(__addon_name__, i18n('no_server_detected')) return_index = -1 if (return_index == -1): xbmc.executebuiltin("ActivateWindow(Home)") return serverUrl = serverInfo[return_index]["Address"] log.debug("Selected server: {0}", serverUrl) # parse the url url_bits = urlparse(serverUrl) server_address = url_bits.hostname server_port = str(url_bits.port) server_protocol = url_bits.scheme log.debug("Detected server info {0} - {1} - {2}", server_protocol, server_address, server_port) # save the server info settings.setSetting("port", server_port) settings.setSetting("ipaddress", server_address) if server_protocol == "https": settings.setSetting("use_https", "true") else: settings.setSetting("use_https", "false") something_changed = True if notify: xbmcgui.Dialog().ok(i18n('server_detect_succeeded'), i18n('found_server'), i18n('address:') + server_address, i18n('server_port:') + server_port) # we need to change the user current_username = settings.getSetting("username") current_username = unicode(current_username, "utf-8") # if asked or we have no current user then show user selection screen if change_user or len(current_username) == 0: # get a list of users log.debug("Getting user list") jsonData = downloadUtils.downloadUrl(serverUrl + "/emby/Users/Public?format=json", authenticate=False) # TODO: add a setting to enable this show_manual = False log.debug("jsonData: {0}", jsonData) try: result = json.loads(jsonData) except: result = None if result is None: xbmcgui.Dialog().ok(i18n('error'), i18n('unable_connect_server'), i18n('address:') + serverUrl) else: selected_id = 0 names = [] user_list = [] secured = [] for user in result: config = user.get("Configuration") if (config != None): if (config.get("IsHidden") is None) or (config.get("IsHidden") is False): name = user.get("Name") user_list.append(name) if (user.get("HasPassword") is True): secured.append(True) name = i18n('username_secured') % name else: secured.append(False) names.append(name) if current_username == name: selected_id = len(names) - 1 if (len(current_username) > 0) and (not any(n == current_username for n in user_list)): names.insert(0, i18n('username_userdefined') % current_username) user_list.insert(0, current_username) secured.insert(0, True) if show_manual: names.append(i18n('username_userinput')) user_list.append('') secured.append(True) log.debug("User List: {0}", names) log.debug("User List: {0}", user_list) if current_username: selection_title = i18n('select_user') + " (" + current_username + ")" else: selection_title = i18n('select_user') return_value = xbmcgui.Dialog().select(selection_title, names, preselect=selected_id) if return_value > -1 and return_value != selected_id: log.debug("Selected User Index: {0}", return_value) if show_manual and return_value == (len(user_list) -1): kb = xbmc.Keyboard() kb.setHeading(i18n('username:'******'password', saved_password) else: kb = xbmc.Keyboard() kb.setHeading(i18n('password:'******'password', kb.getText()) # should we save the password save_password = xbmcgui.Dialog().yesno( "Save Password?", "Do you want to save the password?") if save_password: log.debug("Saving password for fast user switching: {0}", hashed_username) settings.setSetting("saved_user_password_" + hashed_username, kb.getText()) else: log.debug("Saving username is no password: {0}", selected_user) settings.setSetting("username", selected_user) settings.setSetting('password', '') if something_changed: home_window = HomeWindow() home_window.clearProperty("userid") home_window.clearProperty("AccessToken") home_window.setProperty("embycon_widget_reload", str(time.time())) download_utils = DownloadUtils() download_utils.authenticate() download_utils.getUserId() xbmc.executebuiltin("ActivateWindow(Home)") xbmc.executebuiltin("ReloadSkin()")