Fix userclient

This commit is contained in:
tomkat83 2016-03-10 16:02:46 +01:00
parent d16b931486
commit a3c2d21757
17 changed files with 144 additions and 151 deletions

View file

@ -397,6 +397,7 @@
<string id="39308">Could not log in user </string>
<string id="39309">Please try again.</string>
<string id="39310">unknown</string>
<string id="39311">or press No to not sign in.</string>
<!-- Plex Librarysync.py -->
<string id="39400">Library sync thread has crashed. You should restart Kodi now. Please report this on the forum</string>

View file

@ -329,6 +329,7 @@
<string id="39308">Anmeldung fehlgeschlagen für Benutzer </string>
<string id="39309">Bitte erneut versuchen.</string>
<string id="39310">unbekannt</string>
<string id="39311">oder Nein drücken, um nicht bei plex.tv anzumelden</string>
<!-- Plex Librarysync.py -->
<string id="39400">Die Synchronisierung der Plex Bibliotheken ist abgestürzt. Bitte Kodi neu starten. Danke, wenn Sie sich die Zeit nehmen und im Plex Forum vom Absturz berichten.</string>

View file

@ -67,7 +67,7 @@ except ImportError:
class PlexAPI():
# CONSTANTS
# Timeout for POST/GET commands, I guess in seconds
timeout = 60
timeout = 10
# VARIABLES
def __init__(self):
@ -79,9 +79,9 @@ class PlexAPI():
self.deviceName = client.getDeviceName()
self.plexversion = client.getVersion()
self.platform = client.getPlatform()
self.userId = utils.window('emby_currUser')
self.token = utils.window('emby_accessToken%s' % self.userId)
self.server = utils.window('emby_server%s' % self.userId)
self.userId = utils.window('currUserId')
self.token = utils.window('pms_token')
self.server = utils.window('pms_server')
self.doUtils = downloadutils.DownloadUtils()
@ -182,9 +182,11 @@ class PlexAPI():
dialog.ok(self.addonName, string(39303))
return False
# Go to https://plex.tv/pin and enter the code:
# Or press No to cancel the sign in.
answer = dialog.yesno(self.addonName,
string(39304) + "\n\n",
code)
code + "\n\n",
string(39311))
if not answer:
return False
count = 0
@ -638,14 +640,17 @@ class PlexAPI():
else:
# MyPlex servers
self.getPMSListFromMyPlex(ATV_udid, authtoken)
# Delete plex.tv again
del self.g_PMS[ATV_udid]['plex.tv']
# all servers - update enableGzip
for uuid_id in self.g_PMS.get(ATV_udid, {}):
# Ping to check whether we need HTTPs or HTTP
url = (self.getPMSProperty(ATV_udid, uuid_id, 'ip') + ':'
+ self.getPMSProperty(ATV_udid, uuid_id, 'port'))
if PMSHttpsEnabled(url):
self.logMsg('PMS %s talks HTTPS' % uuid_id, 1)
self.updatePMSProperty(ATV_udid, uuid_id, 'scheme', 'https')
else:
self.updatePMSProperty(ATV_udid, uuid_id, 'scheme', 'http')
# enable Gzip if not on same host, local&remote PMS depending
# on setting
enableGzip = (not self.getPMSProperty(ATV_udid, uuid_id, 'ip') == IP_self) \
@ -657,8 +662,6 @@ class PlexAPI():
and True) == 'True'
)
self.updatePMSProperty(ATV_udid, uuid_id, 'enableGzip', enableGzip)
# Delete plex.tv again
del self.g_PMS[ATV_udid]['plex.tv']
def getPMSListFromMyPlex(self, ATV_udid, authtoken):
"""
@ -1128,13 +1131,18 @@ class PlexAPI():
trials += 1
continue
# Switch to this Plex Home user, if applicable
username, usertoken = self.PlexSwitchHomeUser(
result = self.PlexSwitchHomeUser(
user['id'],
pin,
plexToken,
utils.settings('plex_machineIdentifier'))
if result:
# Successfully retrieved username: break out of while loop
username = result['username']
usertoken = result['usertoken']
break
# Couldn't get user auth
if not username:
else:
trials += 1
# Could not login user, please try again
if not dialog.yesno(self.addonName,
@ -1142,9 +1150,6 @@ class PlexAPI():
string(39309)):
# User chose to cancel
break
else:
# Successfully retrieved username: break out of while loop
break
if not username:
self.logMsg('Failed signing in a user to plex.tv', -1)
@ -1161,6 +1166,7 @@ class PlexAPI():
def PlexSwitchHomeUser(self, userId, pin, token, machineIdentifier):
"""
Retrieves Plex home token for a Plex home user.
Returns False if unsuccessful
Input:
userId id of the Plex home user
@ -1168,9 +1174,14 @@ class PlexAPI():
token token for plex.tv
Output:
(username, token)
{
'username'
'usertoken' Might be empty strings if no token found
for the machineIdentifier that was chosen
}
Returns 2 empty strings if unsuccessful
Also sets the settings variable settings('accessToken'),
settings('userid') and settings('username') with new plex token
"""
url = 'https://plex.tv/api/home/users/' + userId + '/switch'
if pin:
@ -1181,32 +1192,50 @@ class PlexAPI():
answer.attrib
except:
self.logMsg('Error: plex.tv switch HomeUser change failed', -1)
return ('', '')
return False
username = answer.attrib.get('title', '')
token = answer.attrib.get('authenticationToken', '')
userid = answer.attrib.get('id', '')
# Get final token
# Write to settings file
utils.settings('username', username)
utils.settings('userid', userid)
utils.settings('accessToken', token)
# Get final token to the PMS we've chosen
url = 'https://plex.tv/api/resources?includeHttps=1'
xml = self.TalkToPlexServer(url, talkType="GET", token=token)
try:
xml.attrib
except:
self.logMsg('switch HomeUser failed - plex.tv answer wrong', -1)
return ('', '')
self.logMsg('Answer from plex.tv not as excepted', -1)
# Set to empty iterable list for loop
xml = []
found = 0
self.logMsg('Our machineIdentifier is %s' % machineIdentifier, 0)
for device in xml:
if device.attrib.get('clientIdentifier') == machineIdentifier:
identifier = device.attrib.get('clientIdentifier')
self.logMsg('Found a Plex machineIdentifier: %s' % identifier, 0)
if (identifier in machineIdentifier or
machineIdentifier in identifier):
found += 1
token = device.attrib.get('accessToken')
if found == 0:
self.logMsg('No tokens found for your server!', -1)
return ('', '')
self.logMsg('Plex.tv switch HomeUser change successfull', 0)
self.logMsg("username: %s, token: xxxx. " % username, 0)
return (username, token)
result = {
'username': username,
}
if found == 0:
self.logMsg('No tokens found for your server!', 0)
self.logMsg('Using empty string as token', 0)
result['usertoken'] = ''
else:
result['usertoken'] = token
self.logMsg('Plex.tv switch HomeUser change successfull for user %s'
% username, 0)
return result
def MyPlexListHomeUsers(self, authtoken):
"""
@ -1430,9 +1459,9 @@ class API():
self.clientId = self.clientinfo.getDeviceId()
self.__language__ = xbmcaddon.Addon().getLocalizedString
self.userId = utils.window('emby_currUser')
self.server = utils.window('emby_server%s' % self.userId)
self.token = utils.window('emby_accessToken%s' % self.userId)
self.userId = utils.window('currUserId')
self.server = utils.window('pms_server')
self.token = utils.window('pms_token')
def setPartNumber(self, number=None):
"""

View file

@ -36,6 +36,7 @@ class PlexCompanion(threading.Thread):
def run(self):
start_count = 0
window = utils.window
while True:
try:
httpd = listener.ThreadedHTTPServer(
@ -67,6 +68,12 @@ class PlexCompanion(threading.Thread):
if self.threadStopped():
break
xbmc.sleep(3000)
# If we are not authorized, sleep
# Otherwise, we trigger a download which leads to a
# re-authorizations
if window('emby_serverStatus'):
xbmc.sleep(3000)
continue
try:
httpd.handle_request()

View file

@ -357,14 +357,17 @@ def PMSHttpsEnabled(url):
This is done by GET /identity (returns an error if https is enabled and we
are trying to use http)
Prefers HTTPS over HTTP
"""
xml = downloadutils.DownloadUtils().downloadUrl('http://%s/identity' % url)
xml = downloadutils.DownloadUtils().downloadUrl(
'https://%s/identity' % url)
try:
# received a valid XML - http connection is possible
# received a valid XML - https connection is possible
xml.attrib
logMsg('PMSHttpsEnabled', 'PMS on %s talks HTTP' % url, 1)
return False
except:
# couldn't get an xml - switch to https traffic
logMsg('PMSHttpsEnabled', 'PMS on %s talks HTTPS' % url, 1)
return True
except:
# couldn't get an xml - switch to http traffic
logMsg('PMSHttpsEnabled', 'PMS on %s talks HTTPS' % url, 1)
return False

View file

@ -38,8 +38,8 @@ class Artwork():
if not self.xbmc_port and self.enableTextureCache:
self.setKodiWebServerDetails()
self.userId = utils.window('emby_currUser')
self.server = utils.window('emby_server%s' % self.userId)
self.userId = utils.window('currUserId')
self.server = utils.window('pms_server')
def double_urlencode(self, text):
text = self.single_urlencode(text)

View file

@ -222,10 +222,9 @@ class DownloadUtils():
# request session does not exists
self.logMsg("Request session does not exist: start one", 1)
# Get user information
self.userId = utils.window('emby_currUser')
self.server = utils.window('emby_server%s' % self.userId)
self.token = utils.window(
'emby_accessToken%s' % self.userId)
self.userId = utils.window('currUserId')
self.server = utils.window('pms_server')
self.token = utils.window('pms_token')
header = self.getHeader(options=headerOptions)
verifyssl = False
cert = None
@ -378,6 +377,7 @@ class DownloadUtils():
# Emby server errors
if r.headers['X-Application-Error-Code'] == "ParentalControl":
# Parental control - access restricted
self.logMsg('Setting emby_serverStatus to restricted')
utils.window('emby_serverStatus', value="restricted")
xbmcgui.Dialog().notification(
heading=self.addonName,
@ -392,6 +392,7 @@ class DownloadUtils():
elif status not in ("401", "Auth"):
# Tell userclient token has been revoked.
self.logMsg('Setting emby_serverStatus to 401')
utils.window('emby_serverStatus', value="401")
self.logMsg("HTTP Error: %s" % e, 0)
xbmcgui.Dialog().notification(

View file

@ -93,17 +93,15 @@ def reConnect():
utils.settings('plexLogin', value="")
utils.settings('plexToken', value=""),
utils.settings('plexid', value="")
utils.settings('plexHomeSize', value="")
utils.settings('plexHomeSize', value="1")
utils.settings('plexAvatar', value="")
# Wait max for 5 seconds for all lib scans to finish
counter = 0
while utils.window('emby_dbScan') == 'true':
if counter > 100:
dialog.ok(
heading=addonName,
message=string(39208),
)
dialog.ok(heading=addonName,
message=string(39208))
# Resuming threads, just in case
utils.window('suspend_LibraryThread', clear=True)
# Abort reConnection
@ -117,10 +115,8 @@ def reConnect():
counter = 0
while utils.window('emby_serverStatus') == "401":
if counter > 100:
dialog.ok(
heading=addonName,
message=string(39208),
)
dialog.ok(heading=addonName,
message=string(39208))
# Abort reConnection
return
counter += 1
@ -343,7 +339,7 @@ def addUser():
clientInfo = clientinfo.ClientInfo()
deviceId = clientInfo.getDeviceId()
deviceName = clientInfo.getDeviceName()
userid = utils.window('emby_currUser')
userid = utils.window('currUserId')
dialog = xbmcgui.Dialog()
# Get session

View file

@ -44,7 +44,8 @@ class InitialSetup():
plexLogin = plexdict['plexLogin']
plexToken = plexdict['plexToken']
plexid = plexdict['plexid']
self.logMsg('Plex info retrieved from settings', 1)
if plexToken:
self.logMsg('Found plex.tv token in settings', 0)
dialog = xbmcgui.Dialog()
@ -54,6 +55,7 @@ class InitialSetup():
chk = self.plx.CheckConnection('plex.tv', plexToken)
# HTTP Error: unauthorized. Token is no longer valid
if chk == 401:
self.logMsg('plex.tv connection returned HTTP 401', 0)
# Delete token in the settings
utils.settings('plexToken', value='')
# Could not login, please try again
@ -66,10 +68,12 @@ class InitialSetup():
plexid = result['plexid']
elif chk is False or chk >= 400:
# Problems connecting to plex.tv. Network or internet issue?
self.logMsg('plex.tv connection returned HTTP %s'
% str(chk), 0)
dialog.ok(self.addonName,
string(39010))
else:
# Successful connected to plex.tv
self.logMsg('plex.tv connection with token successful', 0)
# Refresh the info from Plex.tv
url = 'https://plex.tv/'
path = 'users/account'
@ -86,6 +90,7 @@ class InitialSetup():
self.logMsg('Updated Plex info from plex.tv', 0)
else:
self.logMsg('Failed to update Plex info from plex.tv', -1)
# If a Plex server IP has already been set, return.
if server and forcePlexTV is False:
self.logMsg("Server is already set.", 0)

View file

@ -1595,8 +1595,8 @@ class Music(Items):
self.enableimportsongrating = utils.settings('enableImportSongRating') == "true"
self.enableexportsongrating = utils.settings('enableExportSongRating') == "true"
self.enableupdatesongrating = utils.settings('enableUpdateSongRating') == "true"
self.userid = utils.window('emby_currUser')
self.server = utils.window('emby_server%s' % self.userid)
self.userid = utils.window('currUserId')
self.server = utils.window('pms_server')
def __enter__(self):
"""

View file

@ -34,8 +34,8 @@ class PlaybackUtils():
self.clientInfo = clientinfo.ClientInfo()
self.addonName = self.clientInfo.getAddonName()
self.userid = utils.window('emby_currUser')
self.server = utils.window('emby_server%s' % self.userid)
self.userid = utils.window('currUserId')
self.server = utils.window('pms_server')
self.artwork = artwork.Artwork()
self.emby = embyserver.Read_EmbyServer()

View file

@ -21,8 +21,8 @@ import PlexAPI
class Playlist():
def __init__(self):
self.userid = utils.window('emby_currUser')
self.server = utils.window('emby_server%s' % self.userid)
self.userid = utils.window('currUserId')
self.server = utils.window('pms_server')
self.emby = embyserver.Read_EmbyServer()

View file

@ -26,8 +26,8 @@ class PlayUtils():
self.clientInfo = clientinfo.ClientInfo()
self.userid = utils.window('emby_currUser')
self.server = utils.window('emby_server%s' % self.userid)
self.userid = utils.window('currUserId')
self.server = utils.window('pms_server')
self.machineIdentifier = utils.window('plex_machineIdentifier')
def getPlayUrl(self, partNumber=None):

View file

@ -70,8 +70,8 @@ class SubscriptionManager:
WINDOW = xbmcgui.Window(10000)
# pbmc_server = str(WINDOW.getProperty('plexbmc.nowplaying.server'))
# userId = str(WINDOW.getProperty('emby_currUser'))
# pbmc_server = str(WINDOW.getProperty('emby_server%s' % userId))
# userId = str(WINDOW.getProperty('currUserId'))
# pbmc_server = str(WINDOW.getProperty('pms_server'))
pbmc_server = None
keyid = None
count = 0

View file

@ -19,8 +19,8 @@ class Read_EmbyServer():
self.doUtils = downloadutils.DownloadUtils().downloadUrl
self.userId = utils.window('emby_currUser')
self.server = utils.window('emby_server%s' % self.userId)
self.userId = utils.window('currUserId')
self.server = utils.window('pms_server')
def split_list(self, itemlist, size):
# Split up list in pieces of size. Will generate a list of lists

View file

@ -71,41 +71,6 @@ class UserClient(threading.Thread):
return logLevel
def getUserId(self, username=None):
log = self.logMsg
window = utils.window
settings = utils.settings
if username is None:
username = self.getUsername()
w_userId = window('emby_currUser')
s_userId = settings('userId')
# Verify the window property
if w_userId:
if not s_userId:
# Save access token if it's missing from settings
settings('userId', value=w_userId)
log("Returning userId %s from WINDOW for username %s"
% (w_userId, username), 0)
return w_userId
# Verify the settings
elif s_userId:
log("Returning userId %s from SETTINGS for username %s"
% (w_userId, username), 0)
return s_userId
# No userId found
log("No userId saved. Trying to get Plex to use instead", 0)
plexId = settings('plexid')
if not plexId:
log('Also no Plex ID found in settings', 0)
return ''
log('Using Plex ID %s as userid for username %s'
% (plexId, username), 0)
settings('userId', value=plexId)
return plexId
def getServer(self, prefix=True):
settings = utils.settings
@ -135,37 +100,6 @@ class UserClient(threading.Thread):
elif not prefix:
return server
def getToken(self, username=None, userId=None):
log = self.logMsg
window = utils.window
settings = utils.settings
if username is None:
username = self.getUsername()
if userId is None:
userId = self.getUserId()
w_token = window('emby_accessToken%s' % userId)
s_token = settings('accessToken')
# Verify the window property
if w_token:
if not s_token:
# Save access token if it's missing from settings
settings('accessToken', value=w_token)
log("Returning accessToken from WINDOW for username: %s "
"accessToken: xxxx" % username, 2)
return w_token
# Verify the settings
elif s_token:
log("Returning accessToken from SETTINGS for username: %s "
"accessToken: xxxx" % username, 2)
window('emby_accessToken%s' % userId, value=s_token)
return s_token
else:
log("No token found.", 1)
return ""
def getSSLverify(self):
# Verify host certificate
settings = utils.settings
@ -245,9 +179,9 @@ class UserClient(threading.Thread):
if authenticated is False:
self.logMsg('Testing validity of current token', 0)
window('emby_currUser', value=userId)
window('currUserId', value=userId)
window('plex_username', value=username)
window('emby_accessToken%s' % userId, value=self.currToken)
window('pms_token', value=self.currToken)
res = PlexAPI.PlexAPI().CheckConnection(
self.currServer, self.currToken)
if res is False:
@ -261,10 +195,14 @@ class UserClient(threading.Thread):
return False
# Set to windows property
window('emby_currUser', value=userId)
window('currUserId', value=userId)
window('plex_username', value=username)
window('emby_accessToken%s' % userId, value=self.currToken)
window('emby_server%s' % userId, value=self.currServer)
# This is the token for the current PMS (might also be '')
window('pms_token', value=self.currToken)
# 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('accessToken'))
window('pms_server', value=self.currServer)
window('plex_machineIdentifier', value=self.machineIdentifier)
window('plex_servername', value=self.servername)
@ -387,12 +325,18 @@ class UserClient(threading.Thread):
def resetClient(self):
self.logMsg("Reset UserClient authentication.", 1)
self.doUtils.stopSession()
settings = utils.settings
window = utils.window
window('emby_accessToken%s' % self.currUserId, clear=True)
window('emby_server%s' % self.currUserId, clear=True)
window('emby_currUser', clear=True)
window('pms_token', clear=True)
window('plex_token', clear=True)
window('pms_server', clear=True)
window('plex_machineIdentifier', clear=True)
window('plex_servername', clear=True)
window('currUserId', clear=True)
window('plex_username', clear=True)
settings('username', value='')
@ -423,9 +367,13 @@ class UserClient(threading.Thread):
xbmc.sleep(1000)
status = window('emby_serverStatus')
if status:
if status == "Stop":
xbmc.sleep(500)
continue
# Verify the connection status to server
if status == "restricted":
elif status == "restricted":
# Parental control is restricting access
self.HasAccess = False
@ -455,6 +403,7 @@ class UserClient(threading.Thread):
server = self.getServer()
# The status Stop is for when user cancelled password dialog.
# Or retried too many times
if server and status != "Stop":
# Only if there's information found to login
log("Server found: %s" % server, 2)

View file

@ -75,9 +75,10 @@ class Service():
"emby_online", "emby_serverStatus", "emby_onWake",
"emby_syncRunning", "emby_dbCheck", "emby_kodiScan",
"emby_shouldStop", "emby_currUser", "emby_dbScan", "emby_sessionId",
"emby_shouldStop", "currUserId", "emby_dbScan", "emby_sessionId",
"emby_initialScan", "emby_customplaylist", "emby_playbackProps",
"plex_runLibScan", "plex_username"
"plex_runLibScan", "plex_username", "pms_token", "plex_token",
"pms_server", "plex_machineIdentifier", "plex_servername"
]
for prop in properties:
window(prop, clear=True)