Code refactoring

This commit is contained in:
tomkat83 2017-01-24 16:53:50 +01:00
parent 8aba0d998d
commit 579b52905e
11 changed files with 117 additions and 153 deletions

View file

@ -45,7 +45,7 @@ import xbmcgui
import xbmc import xbmc
import xbmcvfs import xbmcvfs
import clientinfo import clientinfo as client
import downloadutils import downloadutils
from utils import window, settings, language as lang, tryDecode, tryEncode, \ from utils import window, settings, language as lang, tryDecode, tryEncode, \
DateToKodi DateToKodi
@ -70,7 +70,6 @@ class PlexAPI():
def __init__(self): def __init__(self):
self.g_PMS = {} self.g_PMS = {}
self.doUtils = downloadutils.DownloadUtils().downloadUrl self.doUtils = downloadutils.DownloadUtils().downloadUrl
self.client = clientinfo.ClientInfo()
def GetPlexLoginFromSettings(self): def GetPlexLoginFromSettings(self):
""" """
@ -131,7 +130,7 @@ class PlexAPI():
retrievedPlexLogin, authtoken = self.MyPlexSignIn( retrievedPlexLogin, authtoken = self.MyPlexSignIn(
plexLogin, plexLogin,
plexPassword, plexPassword,
{'X-Plex-Client-Identifier': self.client.getDeviceId()}) {'X-Plex-Client-Identifier': window('plex_client_Id')})
log.debug("plex.tv username and token: %s, %s" log.debug("plex.tv username and token: %s, %s"
% (plexLogin, authtoken)) % (plexLogin, authtoken))
if plexLogin == '': if plexLogin == '':
@ -721,7 +720,7 @@ class PlexAPI():
MyPlexURL = 'https://' + MyPlexHost + MyPlexSignInPath MyPlexURL = 'https://' + MyPlexHost + MyPlexSignInPath
# create POST request # create POST request
xargs = self.client.getXArgsDeviceInfo(options) xargs = client.getXArgsDeviceInfo(options)
request = urllib2.Request(MyPlexURL, None, xargs) request = urllib2.Request(MyPlexURL, None, xargs)
request.get_method = lambda: 'POST' request.get_method = lambda: 'POST'
@ -834,7 +833,7 @@ class PlexAPI():
log.info("No user selected.") log.info("No user selected.")
settings('username', value='') settings('username', value='')
xbmc.executebuiltin('Addon.OpenSettings(%s)' xbmc.executebuiltin('Addon.OpenSettings(%s)'
% self.client.getAddonId()) % v.ADDON_ID)
return False return False
# Only 1 user received, choose that one # Only 1 user received, choose that one
else: else:
@ -878,8 +877,7 @@ class PlexAPI():
break break
if not username: if not username:
log.error('Failed signing in a user to plex.tv') log.error('Failed signing in a user to plex.tv')
xbmc.executebuiltin('Addon.OpenSettings(%s)' xbmc.executebuiltin('Addon.OpenSettings(%s)' % v.ADDON_ID)
% self.client.getAddonId())
return False return False
return { return {
'username': username, 'username': username,
@ -1105,7 +1103,7 @@ class PlexAPI():
args['protocol'] = 'http' args['protocol'] = 'http'
args['maxAudioBitrate'] = maxAudioBitrate args['maxAudioBitrate'] = maxAudioBitrate
xargs = self.client.getXArgsDeviceInfo(options) xargs = client.getXArgsDeviceInfo(options)
if not AuthToken == '': if not AuthToken == '':
xargs['X-Plex-Token'] = AuthToken xargs['X-Plex-Token'] = AuthToken
@ -1187,7 +1185,6 @@ class API():
self.part = 0 self.part = 0
self.mediastream = None self.mediastream = None
self.server = window('pms_server') self.server = window('pms_server')
self.client = clientinfo.ClientInfo()
def setPartNumber(self, number=None): def setPartNumber(self, number=None):
""" """
@ -1624,7 +1621,7 @@ class API():
arguments overrule everything arguments overrule everything
""" """
xargs = self.client.getXArgsDeviceInfo() xargs = client.getXArgsDeviceInfo()
xargs.update(arguments) xargs.update(arguments)
if '?' not in url: if '?' not in url:
url = "%s?%s" % (url, urlencode(xargs)) url = "%s?%s" % (url, urlencode(xargs))
@ -2253,7 +2250,7 @@ class API():
self.getMediastreamNumber() self.getMediastreamNumber()
if quality is None: if quality is None:
quality = {} quality = {}
xargs = self.client.getXArgsDeviceInfo() xargs = client.getXArgsDeviceInfo()
# For DirectPlay, path/key of PART is needed # For DirectPlay, path/key of PART is needed
# trailers are 'clip' with PMS xmls # trailers are 'clip' with PMS xmls
if action == "DirectStream": if action == "DirectStream":
@ -2273,7 +2270,7 @@ class API():
'/video/:/transcode/universal/start.m3u8?' '/video/:/transcode/universal/start.m3u8?'
args = { args = {
'protocol': 'hls', # seen in the wild: 'dash', 'http', 'hls' 'protocol': 'hls', # seen in the wild: 'dash', 'http', 'hls'
'session': self.client.getDeviceId(), 'session': window('plex_client_Id'),
'fastSeek': 1, 'fastSeek': 1,
'path': path, 'path': path,
'mediaIndex': self.mediastream, 'mediaIndex': self.mediastream,

View file

@ -1,14 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################################### ###############################################################################
import logging import logging
from uuid import uuid4
import xbmc from utils import window, settings
import xbmcaddon import variables as v
from utils import window, settings, tryDecode
############################################################################### ###############################################################################
@ -17,111 +13,68 @@ log = logging.getLogger("PLEX."+__name__)
############################################################################### ###############################################################################
class ClientInfo(): def getXArgsDeviceInfo(self, options=None):
"""
Returns a dictionary that can be used as headers for GET and POST
requests. An authentication option is NOT yet added.
def __init__(self): Inputs:
self.addon = xbmcaddon.Addon() options: dictionary of options that will override the
standard header options otherwise set.
Output:
header dictionary
"""
xargs = {
'Accept': '*/*',
'Connection': 'keep-alive',
"Content-Type": "application/x-www-form-urlencoded",
# "Access-Control-Allow-Origin": "*",
# 'X-Plex-Language': 'en',
'X-Plex-Device': v.ADDON_NAME,
'X-Plex-Client-Platform': v.PLATFORM,
'X-Plex-Device-Name': v.DEVICENAME,
'X-Plex-Platform': v.PLATFORM,
# 'X-Plex-Platform-Version': 'unknown',
# 'X-Plex-Model': 'unknown',
'X-Plex-Product': v.ADDON_NAME,
'X-Plex-Version': v.ADDON_VERSION,
'X-Plex-Client-Identifier': self.getDeviceId(),
'X-Plex-Provides': 'client,controller,player',
}
if window('pms_token'):
xargs['X-Plex-Token'] = window('pms_token')
if options is not None:
xargs.update(options)
return xargs
def getXArgsDeviceInfo(self, options=None):
"""
Returns a dictionary that can be used as headers for GET and POST
requests. An authentication option is NOT yet added.
Inputs: def getDeviceId(self, reset=False):
options: dictionary of options that will override the """
standard header options otherwise set. Returns a unique Plex client id "X-Plex-Client-Identifier" from Kodi
Output: settings file.
header dictionary Also loads Kodi window property 'plex_client_Id'
"""
# Get addon infos
xargs = {
'Accept': '*/*',
'Connection': 'keep-alive',
"Content-Type": "application/x-www-form-urlencoded",
# "Access-Control-Allow-Origin": "*",
# 'X-Plex-Language': 'en',
'X-Plex-Device': self.getAddonName(),
'X-Plex-Client-Platform': self.getPlatform(),
'X-Plex-Device-Name': self.getDeviceName(),
'X-Plex-Platform': self.getPlatform(),
# 'X-Plex-Platform-Version': 'unknown',
# 'X-Plex-Model': 'unknown',
'X-Plex-Product': self.getAddonName(),
'X-Plex-Version': self.getVersion(),
'X-Plex-Client-Identifier': self.getDeviceId(),
'X-Plex-Provides': 'client,controller,player',
}
if window('pms_token'): If id does not exist, create one and save in Kodi settings file.
xargs['X-Plex-Token'] = window('pms_token') """
if options is not None: if reset is True:
xargs.update(options) window('plex_client_Id', clear=True)
return xargs settings('plex_client_Id', value="")
def getAddonName(self): clientId = window('plex_client_Id')
# Used for logging if clientId:
return self.addon.getAddonInfo('name') return clientId
def getAddonId(self): clientId = settings('plex_client_Id')
return "plugin.video.plexkodiconnect" # Because Kodi appears to cache file settings!!
if clientId != "" and reset is False:
def getVersion(self):
return self.addon.getAddonInfo('version')
def getDeviceName(self):
if settings('deviceNameOpt') == "false":
# Use Kodi's deviceName
deviceName = tryDecode(xbmc.getInfoLabel('System.FriendlyName'))
else:
deviceName = settings('deviceName')
deviceName = deviceName.replace("\"", "_")
deviceName = deviceName.replace("/", "_")
return deviceName
def getPlatform(self):
if xbmc.getCondVisibility('system.platform.osx'):
return "MacOSX"
elif xbmc.getCondVisibility('system.platform.atv2'):
return "AppleTV2"
elif xbmc.getCondVisibility('system.platform.ios'):
return "iOS"
elif xbmc.getCondVisibility('system.platform.windows'):
return "Windows"
elif xbmc.getCondVisibility('system.platform.raspberrypi'):
return "RaspberryPi"
elif xbmc.getCondVisibility('system.platform.linux'):
return "Linux"
elif xbmc.getCondVisibility('system.platform.android'):
return "Android"
else:
return "Unknown"
def getDeviceId(self, reset=False):
"""
Returns a unique Plex client id "X-Plex-Client-Identifier" from Kodi
settings file.
Also loads Kodi window property 'plex_client_Id'
If id does not exist, create one and save in Kodi settings file.
"""
if reset is True:
window('plex_client_Id', clear=True)
settings('plex_client_Id', value="")
clientId = window('plex_client_Id')
if clientId:
return clientId
clientId = settings('plex_client_Id')
# Because Kodi appears to cache file settings!!
if clientId != "" and reset is False:
window('plex_client_Id', value=clientId)
log.warn("Unique device Id plex_client_Id loaded: %s" % clientId)
return clientId
log.warn("Generating a new deviceid.")
clientId = str(uuid4())
settings('plex_client_Id', value=clientId)
window('plex_client_Id', value=clientId) window('plex_client_Id', value=clientId)
log.warn("Unique device Id plex_client_Id loaded: %s" % clientId) log.warn("Unique device Id plex_client_Id loaded: %s" % clientId)
return clientId return clientId
log.warn("Generating a new deviceid.")
from uuid import uuid4
clientId = str(uuid4())
settings('plex_client_Id', value=clientId)
window('plex_client_Id', value=clientId)
log.warn("Unique device Id plex_client_Id loaded: %s" % clientId)
return clientId

View file

@ -9,7 +9,7 @@ import xml.etree.ElementTree as etree
import xbmcgui import xbmcgui
from utils import settings, window, language as lang from utils import settings, window, language as lang
import clientinfo import clientinfo as client
############################################################################### ###############################################################################
@ -100,7 +100,6 @@ class DownloadUtils():
# Start session # Start session
self.s = requests.Session() self.s = requests.Session()
client = clientinfo.ClientInfo()
self.deviceId = client.getDeviceId() self.deviceId = client.getDeviceId()
# Attach authenticated header to the session # Attach authenticated header to the session
self.s.headers = client.getXArgsDeviceInfo() self.s.headers = client.getXArgsDeviceInfo()
@ -139,7 +138,7 @@ class DownloadUtils():
log.info('Request session stopped') log.info('Request session stopped')
def getHeader(self, options=None): def getHeader(self, options=None):
header = clientinfo.ClientInfo().getXArgsDeviceInfo() header = client.getXArgsDeviceInfo()
if options is not None: if options is not None:
header.update(options) header.update(options)
return header return header

View file

@ -15,7 +15,6 @@ import xbmcplugin
from utils import window, settings, language as lang from utils import window, settings, language as lang
from utils import tryDecode, tryEncode, CatchExceptions from utils import tryDecode, tryEncode, CatchExceptions
import clientinfo
import downloadutils import downloadutils
import plexdb_functions as plexdb import plexdb_functions as plexdb
import playbackutils as pbutils import playbackutils as pbutils
@ -204,8 +203,9 @@ def resetDeviceId():
dialog = xbmcgui.Dialog() dialog = xbmcgui.Dialog()
deviceId_old = window('plex_client_Id') deviceId_old = window('plex_client_Id')
from clientinfo import getDeviceId
try: try:
deviceId = clientinfo.ClientInfo().getDeviceId(reset=True) deviceId = getDeviceId(reset=True)
except Exception as e: except Exception as e:
log.error("Failed to generate a new device Id: %s" % e) log.error("Failed to generate a new device Id: %s" % e)
dialog.ok(heading=lang(29999), line1=lang(33032)) dialog.ok(heading=lang(29999), line1=lang(33032))

View file

@ -7,12 +7,12 @@ import xbmc
import xbmcgui import xbmcgui
from utils import settings, window, language as lang from utils import settings, window, language as lang
import clientinfo
import downloadutils import downloadutils
from userclient import UserClient from userclient import UserClient
import PlexAPI from PlexAPI import PlexAPI
from PlexFunctions import GetMachineIdentifier, get_PMS_settings from PlexFunctions import GetMachineIdentifier, get_PMS_settings
import variables as v
############################################################################### ###############################################################################
@ -25,10 +25,8 @@ class InitialSetup():
def __init__(self): def __init__(self):
log.debug('Entering initialsetup class') log.debug('Entering initialsetup class')
self.clientInfo = clientinfo.ClientInfo()
self.addonId = self.clientInfo.getAddonId()
self.doUtils = downloadutils.DownloadUtils().downloadUrl self.doUtils = downloadutils.DownloadUtils().downloadUrl
self.plx = PlexAPI.PlexAPI() self.plx = PlexAPI()
self.dialog = xbmcgui.Dialog() self.dialog = xbmcgui.Dialog()
self.server = UserClient().getServer() self.server = UserClient().getServer()

View file

@ -17,7 +17,6 @@ from utils import window, settings, getUnixTimestamp, sourcesXML,\
advancedSettingsXML, getKodiVideoDBPath, tryDecode, deletePlaylists,\ advancedSettingsXML, getKodiVideoDBPath, tryDecode, deletePlaylists,\
deleteNodes, ThreadMethodsAdditionalSuspend, create_actor_db_index, \ deleteNodes, ThreadMethodsAdditionalSuspend, create_actor_db_index, \
tryEncode tryEncode
import clientinfo
import downloadutils import downloadutils
import itemtypes import itemtypes
import plexdb_functions as plexdb import plexdb_functions as plexdb
@ -372,7 +371,6 @@ class LibrarySync(Thread):
self.fullSyncInterval = int(settings('fullSyncInterval')) * 60 self.fullSyncInterval = int(settings('fullSyncInterval')) * 60
self.clientInfo = clientinfo.ClientInfo()
self.user = userclient.UserClient() self.user = userclient.UserClient()
self.vnodes = videonodes.VideoNodes() self.vnodes = videonodes.VideoNodes()
self.dialog = xbmcgui.Dialog() self.dialog = xbmcgui.Dialog()
@ -1816,8 +1814,7 @@ class LibrarySync(Thread):
log.info("Initial start-up full sync successful") log.info("Initial start-up full sync successful")
startupComplete = True startupComplete = True
settings('SyncInstallRunDone', value="true") settings('SyncInstallRunDone', value="true")
settings("dbCreatedWithVersion", settings("dbCreatedWithVersion", v.ADDON_VERSION)
self.clientInfo.getVersion())
installSyncDone = True installSyncDone = True
else: else:
log.error("Initial start-up full sync unsuccessful") log.error("Initial start-up full sync unsuccessful")

View file

@ -9,7 +9,6 @@ import xbmcgui
from utils import window, settings, language as lang, DateToKodi, \ from utils import window, settings, language as lang, DateToKodi, \
getUnixTimestamp getUnixTimestamp
import clientinfo
import downloadutils import downloadutils
import plexdb_functions as plexdb import plexdb_functions as plexdb
import kodidb_functions as kodidb import kodidb_functions as kodidb
@ -32,14 +31,9 @@ class Player(xbmc.Player):
currentFile = None currentFile = None
def __init__(self): def __init__(self):
self.__dict__ = self._shared_state self.__dict__ = self._shared_state
self.clientInfo = clientinfo.ClientInfo()
self.doUtils = downloadutils.DownloadUtils().downloadUrl self.doUtils = downloadutils.DownloadUtils().downloadUrl
xbmc.Player.__init__(self) xbmc.Player.__init__(self)
log.info("Started playback monitor.") log.info("Started playback monitor.")
def GetPlayStats(self): def GetPlayStats(self):
@ -409,6 +403,6 @@ class Player(xbmc.Player):
log.info("Transcoding for %s terminating" % itemid) log.info("Transcoding for %s terminating" % itemid)
self.doUtils( self.doUtils(
"{server}/video/:/transcode/universal/stop", "{server}/video/:/transcode/universal/stop",
parameters={'session': self.clientInfo.getDeviceId()}) parameters={'session': window('plex_client_Id')})
self.played_info.clear() self.played_info.clear()

View file

@ -1,6 +1,6 @@
import logging import logging
from utils import guisettingsXML, settings from utils import guisettingsXML, settings
import clientinfo import variables as v
############################################################################### ###############################################################################
@ -21,7 +21,6 @@ def getGUI(name):
def getSettings(): def getSettings():
client = clientinfo.ClientInfo()
options = {} options = {}
options['gdm_debug'] = settings('companionGDMDebugging') options['gdm_debug'] = settings('companionGDMDebugging')
@ -47,10 +46,10 @@ def getSettings():
log.info('Webserver username: %s, password: %s' log.info('Webserver username: %s, password: %s'
% (options['user'], options['passwd'])) % (options['user'], options['passwd']))
options['addonName'] = client.getAddonName() options['addonName'] = v.ADDON_NAME
options['uuid'] = settings('plex_client_Id') options['uuid'] = settings('plex_client_Id')
options['platform'] = client.getPlatform() options['platform'] = v.PLATFORM
options['version'] = client.getVersion() options['version'] = v.ADDON_VERSION
options['plexbmc_version'] = options['version'] options['plexbmc_version'] = options['version']
options['myplex_user'] = settings('username') options['myplex_user'] = settings('username')
try: try:

View file

@ -20,8 +20,6 @@ import xbmcaddon
import xbmcgui import xbmcgui
import xbmcvfs import xbmcvfs
from variables import addonName
############################################################################### ###############################################################################
log = logging.getLogger("PLEX."+__name__) log = logging.getLogger("PLEX."+__name__)
@ -420,7 +418,7 @@ def reset():
log.info("Deleting: settings.xml") log.info("Deleting: settings.xml")
dialog.ok( dialog.ok(
heading=addonName, heading=language(29999),
line1="Database reset has completed, Kodi will now restart to apply the changes.") line1="Database reset has completed, Kodi will now restart to apply the changes.")
xbmc.executebuiltin('RestartApp') xbmc.executebuiltin('RestartApp')

View file

@ -1,9 +1,40 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import xbmc import xbmc
from xbmcaddon import Addon
from utils import settings, tryDecode
ADDON_NAME = 'PlexKodiConnect'
ADDON_ID = 'plugin.video.plexkodiconnect'
ADDON_VERSION = Addon().getAddonInfo('version')
KODILANGUAGE = xbmc.getLanguage(xbmc.ISO_639_1) KODILANGUAGE = xbmc.getLanguage(xbmc.ISO_639_1)
KODIVERSION = int(xbmc.getInfoLabel("System.BuildVersion")[:2]) KODIVERSION = int(xbmc.getInfoLabel("System.BuildVersion")[:2])
if xbmc.getCondVisibility('system.platform.osx'):
PLATFORM = "MacOSX"
elif xbmc.getCondVisibility('system.platform.atv2'):
PLATFORM = "AppleTV2"
elif xbmc.getCondVisibility('system.platform.ios'):
PLATFORM = "iOS"
elif xbmc.getCondVisibility('system.platform.windows'):
PLATFORM = "Windows"
elif xbmc.getCondVisibility('system.platform.raspberrypi'):
PLATFORM = "RaspberryPi"
elif xbmc.getCondVisibility('system.platform.linux'):
PLATFORM = "Linux"
elif xbmc.getCondVisibility('system.platform.android'):
PLATFORM = "Android"
else:
PLATFORM = "Unknown"
if settings('deviceNameOpt') == "false":
# Use Kodi's deviceName
DEVICENAME = tryDecode(xbmc.getInfoLabel('System.FriendlyName'))
else:
DEVICENAME = settings('deviceName')
DEVICENAME = DEVICENAME.replace("\"", "_")
DEVICENAME = DEVICENAME.replace("/", "_")
# Multiply Plex time by this factor to receive Kodi time # Multiply Plex time by this factor to receive Kodi time
PLEX_TO_KODI_TIMEFACTOR = 1.0 / 1000.0 PLEX_TO_KODI_TIMEFACTOR = 1.0 / 1000.0

View file

@ -33,7 +33,6 @@ sys.path.append(_base_resource)
from utils import settings, window, language as lang from utils import settings, window, language as lang
from userclient import UserClient from userclient import UserClient
import clientinfo
import initialsetup import initialsetup
from kodimonitor import KodiMonitor from kodimonitor import KodiMonitor
from librarysync import LibrarySync from librarysync import LibrarySync
@ -47,6 +46,7 @@ from PlexCompanion import PlexCompanion
from monitor_kodi_play import Monitor_Kodi_Play from monitor_kodi_play import Monitor_Kodi_Play
from playback_starter import Playback_Starter from playback_starter import Playback_Starter
from artwork import Image_Cache_Thread from artwork import Image_Cache_Thread
import variables as v
############################################################################### ###############################################################################
@ -80,7 +80,6 @@ class Service():
def __init__(self): def __init__(self):
self.clientInfo = clientinfo.ClientInfo()
logLevel = self.getLogLevel() logLevel = self.getLogLevel()
self.monitor = xbmc.Monitor() self.monitor = xbmc.Monitor()
@ -93,11 +92,10 @@ class Service():
value=settings('fetch_pms_item_number')) value=settings('fetch_pms_item_number'))
# Initial logging # Initial logging
log.warn("======== START %s ========" % lang(29999)) log.warn("======== START %s ========" % v.ADDON_NAME)
log.warn("Platform: %s" % (self.clientInfo.getPlatform())) log.warn("Platform: %s" % v.PLATFORM)
log.warn("KODI Version: %s" % xbmc.getInfoLabel('System.BuildVersion')) log.warn("KODI Version: %s" % xbmc.getInfoLabel('System.BuildVersion'))
log.warn("%s Version: %s" log.warn("%s Version: %s" % (v.ADDON_NAME, v.ADDON_VERSION))
% (lang(29999), self.clientInfo.getVersion()))
log.warn("Using plugin paths: %s" log.warn("Using plugin paths: %s"
% (settings('useDirectPaths') != "true")) % (settings('useDirectPaths') != "true"))
log.warn("Number of sync threads: %s" log.warn("Number of sync threads: %s"
@ -340,7 +338,7 @@ class Service():
except: except:
pass pass
log.warn("======== STOP %s ========" % lang(29999)) log.warn("======== STOP %s ========" % v.ADDON_NAME)
# Delay option # Delay option
delay = int(settings('startupDelay')) delay = int(settings('startupDelay'))