mirror of
https://github.com/jellyfin/jellycon.git
synced 2024-11-23 22:19:54 +00:00
switch to use the python loggin module
This commit is contained in:
parent
2b36f6edc3
commit
f474070424
@ -1,8 +1,11 @@
|
||||
from uuid import uuid4 as uuid4
|
||||
import logging
|
||||
import xbmcaddon
|
||||
import xbmc
|
||||
import xbmcgui
|
||||
|
||||
log = logging.getLogger("EmbyCon." + __name__)
|
||||
|
||||
class ClientInformation():
|
||||
|
||||
def getMachineId(self):
|
||||
@ -12,20 +15,20 @@ class ClientInformation():
|
||||
clientId = WINDOW.getProperty("client_id")
|
||||
|
||||
if(clientId == None or clientId == ""):
|
||||
xbmc.log("CLIENT_ID - > No Client ID in WINDOW")
|
||||
log.info("CLIENT_ID - > No Client ID in WINDOW")
|
||||
addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
clientId = addonSettings.getSetting("client_id")
|
||||
|
||||
if(clientId == None or clientId == ""):
|
||||
xbmc.log("CLIENT_ID - > No Client ID in SETTINGS")
|
||||
log.info("CLIENT_ID - > No Client ID in SETTINGS")
|
||||
uuid = uuid4()
|
||||
clientId = "%012X" % uuid
|
||||
WINDOW.setProperty("client_id", clientId)
|
||||
addonSettings.setSetting("client_id",clientId)
|
||||
xbmc.log("CLIENT_ID - > New Client ID : " + clientId)
|
||||
log.info("CLIENT_ID - > New Client ID : " + clientId)
|
||||
else:
|
||||
WINDOW.setProperty("client_id", clientId)
|
||||
xbmc.log("CLIENT_ID - > Client ID saved to WINDOW from Settings : " + clientId)
|
||||
log.info("CLIENT_ID - > Client ID saved to WINDOW from Settings : " + clientId)
|
||||
|
||||
return clientId
|
||||
|
||||
|
@ -2,6 +2,7 @@ import hashlib
|
||||
import os
|
||||
import threading
|
||||
import json as json
|
||||
import logging
|
||||
|
||||
import xbmcplugin
|
||||
import xbmcgui
|
||||
@ -10,25 +11,17 @@ import xbmc
|
||||
|
||||
from downloadutils import DownloadUtils
|
||||
|
||||
log = logging.getLogger("EmbyCon." + __name__)
|
||||
|
||||
class DataManager():
|
||||
|
||||
cacheDataResult = None
|
||||
dataUrl = None
|
||||
cacheDataPath = None
|
||||
canRefreshNow = False
|
||||
logLevel = 0
|
||||
|
||||
def __init__(self, *args):
|
||||
addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
self.addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
level = addonSettings.getSetting('logLevel')
|
||||
self.logLevel = 0
|
||||
if(level != None):
|
||||
self.logLevel = int(level)
|
||||
|
||||
def logMsg(self, msg, level = 1):
|
||||
if(self.logLevel >= level):
|
||||
xbmc.log("EmbyCon DataManager -> " + msg)
|
||||
log.info("DataManager __init__")
|
||||
|
||||
def getCacheValidatorFromData(self, result):
|
||||
result = result.get("Items")
|
||||
@ -56,7 +49,7 @@ class DataManager():
|
||||
itemPercent = (float(itemPossition) / float(itemRuntime)) * 100
|
||||
|
||||
itemString = str(itemCount) + "_" + item.get("Name", "name") + "_" + str(int(itemPercent)) + "-" + str(unwatchedItemCount) + "|"
|
||||
self.logMsg(itemString, level=2)
|
||||
log.debug(itemString)
|
||||
dataHashString = dataHashString + itemString
|
||||
else:
|
||||
itemCount = itemCount + item.get("RecursiveItemCount", 0)
|
||||
@ -65,7 +58,7 @@ class DataManager():
|
||||
if PlayedPercentage == None:
|
||||
PlayedPercentage = 0
|
||||
itemString = str(itemCount) + "_" + item.get("Name", "name") + "_" + str(int(PlayedPercentage)) + "-" + str(unwatchedItemCount) + "|"
|
||||
self.logMsg(itemString, level=2)
|
||||
log.debug(itemString)
|
||||
dataHashString = dataHashString + itemString
|
||||
|
||||
# hash the data
|
||||
@ -74,8 +67,8 @@ class DataManager():
|
||||
m.update(dataHashString)
|
||||
validatorString = m.hexdigest()
|
||||
|
||||
self.logMsg("getCacheValidatorFromData : RawData : " + dataHashString, level=2)
|
||||
self.logMsg("getCacheValidatorFromData : hashData : " + validatorString, level=2)
|
||||
log.debug("getCacheValidatorFromData : RawData : " + dataHashString)
|
||||
log.debug("getCacheValidatorFromData : hashData : " + validatorString)
|
||||
|
||||
return validatorString
|
||||
|
||||
@ -96,7 +89,7 @@ class DataManager():
|
||||
os.makedirs(os.path.join(__addondir__, "cache"))
|
||||
cacheDataPath = os.path.join(__addondir__, "cache", urlHash)
|
||||
|
||||
self.logMsg("Cache_Data_Manager:" + cacheDataPath)
|
||||
log.info("Cache_Data_Manager:" + cacheDataPath)
|
||||
|
||||
# are we forcing a reload
|
||||
WINDOW = xbmcgui.Window( 10000 )
|
||||
@ -106,7 +99,7 @@ class DataManager():
|
||||
if(os.path.exists(cacheDataPath)) and force_data_reload != "true":
|
||||
# load data from cache if it is available and trigger a background
|
||||
# verification process to test cache validity
|
||||
self.logMsg("Loading Cached File")
|
||||
log.info("Loading Cached File")
|
||||
cachedfie = open(cacheDataPath, 'r')
|
||||
jsonData = cachedfie.read()
|
||||
cachedfie.close()
|
||||
@ -120,58 +113,46 @@ class DataManager():
|
||||
actionThread.setCacheData(self)
|
||||
actionThread.start()
|
||||
|
||||
self.logMsg("Returning Cached Result")
|
||||
log.info("Returning Cached Result")
|
||||
return result
|
||||
else:
|
||||
# no cache data so load the url and save it
|
||||
jsonData = DownloadUtils().downloadUrl(url, suppress=False, popup=1)
|
||||
self.logMsg("Loading URL and saving to cache")
|
||||
log.info("Loading URL and saving to cache")
|
||||
cachedfie = open(cacheDataPath, 'w')
|
||||
cachedfie.write(jsonData)
|
||||
cachedfie.close()
|
||||
result = self.loadJasonData(jsonData)
|
||||
self.cacheManagerFinished = True
|
||||
self.logMsg("Returning Loaded Result")
|
||||
log.info("Returning Loaded Result")
|
||||
return result
|
||||
|
||||
|
||||
class CacheManagerThread(threading.Thread):
|
||||
|
||||
dataManager = None
|
||||
logLevel = 0
|
||||
|
||||
def __init__(self, *args):
|
||||
addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
self.addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
level = addonSettings.getSetting('logLevel')
|
||||
self.logLevel = 0
|
||||
if(level != None):
|
||||
self.logLevel = int(level)
|
||||
|
||||
threading.Thread.__init__(self, *args)
|
||||
|
||||
def logMsg(self, msg, level = 1):
|
||||
if(self.logLevel >= level):
|
||||
xbmc.log("EmbyCon CacheManagerThread -> " + msg)
|
||||
|
||||
def setCacheData(self, data):
|
||||
self.dataManager = data
|
||||
|
||||
def run(self):
|
||||
|
||||
self.logMsg("CacheManagerThread Started")
|
||||
log.info("CacheManagerThread Started")
|
||||
|
||||
cacheValidatorString = self.dataManager.getCacheValidatorFromData(self.dataManager.cacheDataResult)
|
||||
self.logMsg("Cache Validator String (" + cacheValidatorString + ")")
|
||||
log.info("Cache Validator String (" + cacheValidatorString + ")")
|
||||
|
||||
jsonData = DownloadUtils().downloadUrl(self.dataManager.dataUrl, suppress=False, popup=1)
|
||||
loadedResult = self.dataManager.loadJasonData(jsonData)
|
||||
loadedValidatorString = self.dataManager.getCacheValidatorFromData(loadedResult)
|
||||
self.logMsg("Loaded Validator String (" + loadedValidatorString + ")")
|
||||
log.info("Loaded Validator String (" + loadedValidatorString + ")")
|
||||
|
||||
# if they dont match then save the data and trigger a content reload
|
||||
if(cacheValidatorString != loadedValidatorString):
|
||||
self.logMsg("CacheManagerThread Saving new cache data and reloading container")
|
||||
log.info("CacheManagerThread Saving new cache data and reloading container")
|
||||
cachedfie = open(self.dataManager.cacheDataPath, 'w')
|
||||
cachedfie.write(jsonData)
|
||||
cachedfie.close()
|
||||
@ -179,11 +160,11 @@ class CacheManagerThread(threading.Thread):
|
||||
# we need to refresh but will wait until the main function has finished
|
||||
loops = 0
|
||||
while(self.dataManager.canRefreshNow == False and loops < 200):
|
||||
#xbmc.log("Cache_Data_Manager: Not finished yet")
|
||||
log.debug("Cache_Data_Manager: Not finished yet")
|
||||
xbmc.sleep(100)
|
||||
loops = loops + 1
|
||||
|
||||
self.logMsg("Sending container refresh (" + str(loops) + ")")
|
||||
log.info("Sending container refresh (" + str(loops) + ")")
|
||||
xbmc.executebuiltin("Container.Refresh")
|
||||
|
||||
self.logMsg("CacheManagerThread Exited")
|
||||
log.info("CacheManagerThread Exited")
|
||||
|
@ -9,30 +9,24 @@ import StringIO
|
||||
import gzip
|
||||
import sys
|
||||
import json as json
|
||||
import logging
|
||||
from clientinfo import ClientInformation
|
||||
|
||||
log = logging.getLogger("EmbyCon." + __name__)
|
||||
|
||||
class DownloadUtils():
|
||||
|
||||
logLevel = 0
|
||||
addonSettings = None
|
||||
getString = None
|
||||
|
||||
def __init__(self, *args):
|
||||
self.addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
self.getString = self.addonSettings.getLocalizedString
|
||||
level = self.addonSettings.getSetting('logLevel')
|
||||
self.logLevel = 0
|
||||
if(level != None):
|
||||
self.logLevel = int(level)
|
||||
|
||||
port = self.addonSettings.getSetting('port')
|
||||
host = self.addonSettings.getSetting('ipaddress')
|
||||
self.server = host + ":" + port
|
||||
|
||||
def logMsg(self, msg, level = 1):
|
||||
if(self.logLevel >= level):
|
||||
xbmc.log("EmbyCon DownloadUtils -> " + msg)
|
||||
|
||||
def getArtwork(self, data, type, index = "0", width = 10000, height = 10000):
|
||||
|
||||
id = data.get("Id")
|
||||
@ -61,21 +55,21 @@ class DownloadUtils():
|
||||
if(BGTags != None and len(BGTags) > 0):
|
||||
bgIndex = int(index)
|
||||
imageTag = data.get("BackdropImageTags")[bgIndex]
|
||||
#self.logMsg("Background Image Tag:" + imageTag, level=1)
|
||||
log.debug("Background Image Tag:" + imageTag)
|
||||
else:
|
||||
if(data.get("ImageTags") != None and data.get("ImageTags").get(type) != None):
|
||||
imageTag = data.get("ImageTags").get(type)
|
||||
#self.logMsg("Image Tag:" + imageTag, level=1)
|
||||
log.debug("Image Tag:" + imageTag)
|
||||
|
||||
if(imageTag == "" or imageTag == None):
|
||||
#self.logMsg("No Image Tag", level=1)
|
||||
log.debug("No Image Tag")
|
||||
return ""
|
||||
|
||||
query = ""
|
||||
|
||||
artwork = "http://%s/mediabrowser/Items/%s/Images/%s/%s?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (self.server, id, type, index, width, height, imageTag, query)
|
||||
|
||||
self.logMsg("getArtwork : " + artwork, level=2)
|
||||
log.debug("getArtwork : " + artwork)
|
||||
|
||||
'''
|
||||
# do not return non-existing images
|
||||
@ -114,44 +108,44 @@ class DownloadUtils():
|
||||
userid = WINDOW.getProperty("userid")
|
||||
|
||||
if(userid != None and userid != ""):
|
||||
self.logMsg("EmbyCon DownloadUtils -> Returning saved UserID : " + userid)
|
||||
log.info("EmbyCon DownloadUtils -> Returning saved UserID : " + userid)
|
||||
return userid
|
||||
|
||||
port = self.addonSettings.getSetting('port')
|
||||
host = self.addonSettings.getSetting('ipaddress')
|
||||
userName = self.addonSettings.getSetting('username')
|
||||
|
||||
self.logMsg("Looking for user name: " + userName)
|
||||
log.info("Looking for user name: " + userName)
|
||||
|
||||
jsonData = None
|
||||
try:
|
||||
jsonData = self.downloadUrl(host + ":" + port + "/mediabrowser/Users/Public?format=json", suppress=True, authenticate=False)
|
||||
except Exception, msg:
|
||||
error = "Get User unable to connect to " + host + ":" + port + " : " + str(msg)
|
||||
xbmc.log (error)
|
||||
log.error(error)
|
||||
return ""
|
||||
|
||||
self.logMsg("GETUSER_JSONDATA_01:" + str(jsonData))
|
||||
log.info("GETUSER_JSONDATA_01:" + str(jsonData))
|
||||
|
||||
result = []
|
||||
|
||||
try:
|
||||
result = json.loads(jsonData)
|
||||
except Exception, e:
|
||||
self.logMsg("jsonload : " + str(e) + " (" + jsonData + ")", level=1)
|
||||
log.info("jsonload : " + str(e) + " (" + jsonData + ")")
|
||||
return ""
|
||||
|
||||
self.logMsg("GETUSER_JSONDATA_02:" + str(result))
|
||||
log.info("GETUSER_JSONDATA_02:" + str(result))
|
||||
|
||||
userid = ""
|
||||
secure = False
|
||||
for user in result:
|
||||
if(user.get("Name") == userName):
|
||||
userid = user.get("Id")
|
||||
self.logMsg("Username Found:" + user.get("Name"))
|
||||
log.info("Username Found:" + user.get("Name"))
|
||||
if(user.get("HasPassword") == True):
|
||||
secure = True
|
||||
self.logMsg("Username Is Secure (HasPassword=True)")
|
||||
log.info("Username Is Secure (HasPassword=True)")
|
||||
break
|
||||
|
||||
if(secure):
|
||||
@ -163,7 +157,7 @@ class DownloadUtils():
|
||||
if userid == "":
|
||||
return_value = xbmcgui.Dialog().ok(self.getString(30045),self.getString(30045))
|
||||
|
||||
self.logMsg("userid : " + userid)
|
||||
log.info("userid : " + userid)
|
||||
|
||||
WINDOW.setProperty("userid", userid)
|
||||
|
||||
@ -175,7 +169,7 @@ class DownloadUtils():
|
||||
|
||||
token = WINDOW.getProperty("AccessToken")
|
||||
if(token != None and token != ""):
|
||||
self.logMsg("EmbyCon DownloadUtils -> Returning saved AccessToken : " + token)
|
||||
log.info("EmbyCon DownloadUtils -> Returning saved AccessToken : " + token)
|
||||
return token
|
||||
|
||||
port = self.addonSettings.getSetting("port")
|
||||
@ -208,11 +202,11 @@ class DownloadUtils():
|
||||
pass
|
||||
|
||||
if(accessToken != None):
|
||||
self.logMsg("User Authenticated : " + accessToken)
|
||||
log.info("User Authenticated : " + accessToken)
|
||||
WINDOW.setProperty("AccessToken", accessToken)
|
||||
return accessToken
|
||||
else:
|
||||
self.logMsg("User NOT Authenticated")
|
||||
log.info("User NOT Authenticated")
|
||||
WINDOW.setProperty("AccessToken", "")
|
||||
return ""
|
||||
|
||||
@ -237,11 +231,11 @@ class DownloadUtils():
|
||||
if(authToken != ""):
|
||||
headers["X-MediaBrowser-Token"] = authToken
|
||||
|
||||
self.logMsg("EmbyCon Authentication Header : " + str(headers))
|
||||
log.info("EmbyCon Authentication Header : " + str(headers))
|
||||
return headers
|
||||
|
||||
def downloadUrl(self, url, suppress=False, postBody=None, type="GET", popup=0, authenticate=True):
|
||||
self.logMsg("== ENTER: getURL ==")
|
||||
log.info("downloadUrl")
|
||||
link = ""
|
||||
try:
|
||||
if url[0:4] == "http":
|
||||
@ -254,9 +248,9 @@ class DownloadUtils():
|
||||
server = url.split('/')[serversplit]
|
||||
urlPath = "/"+"/".join(url.split('/')[urlsplit:])
|
||||
|
||||
self.logMsg("DOWNLOAD_URL = " + url)
|
||||
self.logMsg("server = "+str(server), level=2)
|
||||
self.logMsg("urlPath = "+str(urlPath), level=2)
|
||||
log.info("DOWNLOAD_URL = " + url)
|
||||
log.debug("server = "+str(server))
|
||||
log.debug("urlPath = "+str(urlPath))
|
||||
|
||||
# check the server details
|
||||
tokens = server.split(':')
|
||||
@ -268,34 +262,34 @@ class DownloadUtils():
|
||||
conn = httplib.HTTPConnection(server, timeout=40)
|
||||
|
||||
head = self.getAuthHeader(authenticate)
|
||||
self.logMsg("HEADERS : " + str(head), level=1)
|
||||
log.info("HEADERS : " + str(head))
|
||||
|
||||
if(postBody != None):
|
||||
head["Content-Type"] = "application/x-www-form-urlencoded"
|
||||
self.logMsg("POST DATA : " + postBody)
|
||||
log.info("POST DATA : " + postBody)
|
||||
conn.request(method=type, url=urlPath, body=postBody, headers=head)
|
||||
else:
|
||||
conn.request(method=type, url=urlPath, headers=head)
|
||||
|
||||
data = conn.getresponse()
|
||||
self.logMsg("GET URL HEADERS : " + str(data.getheaders()), level=2)
|
||||
log.debug("GET URL HEADERS : " + str(data.getheaders()))
|
||||
|
||||
contentType = "none"
|
||||
if int(data.status) == 200:
|
||||
retData = data.read()
|
||||
contentType = data.getheader('content-encoding')
|
||||
self.logMsg("Data Len Before : " + str(len(retData)), level=2)
|
||||
log.debug("Data Len Before : " + str(len(retData)))
|
||||
if(contentType == "gzip"):
|
||||
retData = StringIO.StringIO(retData)
|
||||
gzipper = gzip.GzipFile(fileobj=retData)
|
||||
link = gzipper.read()
|
||||
else:
|
||||
link = retData
|
||||
self.logMsg("Data Len After : " + str(len(link)), level=2)
|
||||
self.logMsg("====== 200 returned =======", level=2)
|
||||
self.logMsg("Content-Type : " + str(contentType), level=2)
|
||||
self.logMsg(link, level=2)
|
||||
self.logMsg("====== 200 finished ======", level=2)
|
||||
log.debug("Data Len After : " + str(len(link)))
|
||||
log.debug("====== 200 returned =======")
|
||||
log.debug("Content-Type : " + str(contentType))
|
||||
log.debug(link)
|
||||
log.debug("====== 200 finished ======")
|
||||
|
||||
elif ( int(data.status) == 301 ) or ( int(data.status) == 302 ):
|
||||
try: conn.close()
|
||||
@ -304,13 +298,13 @@ class DownloadUtils():
|
||||
|
||||
elif int(data.status) >= 400:
|
||||
error = "HTTP response error: " + str(data.status) + " " + str(data.reason)
|
||||
xbmc.log(error)
|
||||
log.error(error)
|
||||
if suppress is False:
|
||||
if popup == 0:
|
||||
xbmc.executebuiltin("XBMC.Notification(URL error: "+ str(data.reason) +",)")
|
||||
else:
|
||||
xbmcgui.Dialog().ok(self.getString(30135),server)
|
||||
xbmc.log (error)
|
||||
log.error(error)
|
||||
try: conn.close()
|
||||
except: pass
|
||||
return ""
|
||||
@ -318,7 +312,7 @@ class DownloadUtils():
|
||||
link = ""
|
||||
except Exception, msg:
|
||||
error = "Unable to connect to " + str(server) + " : " + str(msg)
|
||||
xbmc.log(error)
|
||||
log.error(error)
|
||||
if suppress is False:
|
||||
if popup == 0:
|
||||
xbmc.executebuiltin("XBMC.Notification(\"EmbyCon\": URL error: Unable to connect to server,)")
|
||||
|
@ -213,7 +213,7 @@ def getServerDetails():
|
||||
data, addr = sock.recvfrom(1024) # buffer size
|
||||
servers.append(json.loads(data))
|
||||
except Exception as e:
|
||||
xbmc.log("Read UPD responce: %s" % e)
|
||||
log.error("Read UPD responce: %s" % e)
|
||||
break
|
||||
|
||||
log.info("Found Servers: %s" % servers)
|
||||
|
@ -12,9 +12,11 @@ from datetime import datetime
|
||||
from downloadutils import DownloadUtils
|
||||
import urllib
|
||||
import sys
|
||||
import logging
|
||||
|
||||
#define our global download utils
|
||||
downloadUtils = DownloadUtils()
|
||||
log = logging.getLogger("EmbyCon." + __name__)
|
||||
|
||||
###########################################################################
|
||||
class PlayUtils():
|
||||
@ -23,7 +25,7 @@ class PlayUtils():
|
||||
|
||||
addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
# if the path is local and depending on the video quality play we can direct play it do so-
|
||||
xbmc.log("EmbyCon getPlayUrl")
|
||||
log.info("EmbyCon getPlayUrl")
|
||||
|
||||
playurl = result.get("Path")
|
||||
if playurl != None:
|
||||
@ -71,14 +73,14 @@ class PlayUtils():
|
||||
if(mediaSources != None):
|
||||
if mediaSources[0].get('Bitrate') != None:
|
||||
if settingsVideoBitRate < int(mediaSources[0].get('Bitrate')):
|
||||
xbmc.log("EmbyCon isNetworkQualitySufficient -> FALSE bit rate - settingsVideoBitRate: " + str(settingsVideoBitRate) + " mediasource bitrate: " + str(mediaSources[0].get('Bitrate')))
|
||||
log.info("EmbyCon isNetworkQualitySufficient -> FALSE bit rate - settingsVideoBitRate: " + str(settingsVideoBitRate) + " mediasource bitrate: " + str(mediaSources[0].get('Bitrate')))
|
||||
return False
|
||||
else:
|
||||
xbmc.log("EmbyCon isNetworkQualitySufficient -> TRUE bit rate")
|
||||
log.info("EmbyCon isNetworkQualitySufficient -> TRUE bit rate")
|
||||
return True
|
||||
|
||||
# Any thing else is ok
|
||||
xbmc.log("EmbyCon isNetworkQualitySufficient -> TRUE default")
|
||||
log.info("EmbyCon isNetworkQualitySufficient -> TRUE default")
|
||||
return True
|
||||
|
||||
|
||||
|
@ -7,8 +7,11 @@ import xbmcgui
|
||||
import xbmcaddon
|
||||
import json as json
|
||||
import urllib
|
||||
import logging
|
||||
from downloadutils import DownloadUtils
|
||||
|
||||
log = logging.getLogger("EmbyCon." + __name__)
|
||||
|
||||
def loadSkinDefaults():
|
||||
|
||||
defaultViewData = {}
|
||||
@ -33,14 +36,14 @@ class DefaultViews(xbmcgui.WindowXMLDialog):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)
|
||||
xbmc.log("WINDOW INITIALISED")
|
||||
log.info("WINDOW INITIALISED")
|
||||
|
||||
def onInit(self):
|
||||
self.action_exitkeys_id = [10, 13]
|
||||
|
||||
# load skin views
|
||||
skin_view_file = os.path.join(xbmc.translatePath('special://skin'), "views.xml")
|
||||
xbmc.log("Loading Skin View List From : " + skin_view_file)
|
||||
log.info("Loading Skin View List From : " + skin_view_file)
|
||||
if os.path.exists(skin_view_file):
|
||||
data = etree.parse(skin_view_file).getroot()
|
||||
for view in data.iter("view"):
|
||||
|
@ -72,7 +72,7 @@ STATUS_INVALID_EXTENSION = 1010
|
||||
STATUS_UNEXPECTED_CONDITION = 1011
|
||||
STATUS_TLS_HANDSHAKE_ERROR = 1015
|
||||
|
||||
logger = logging.getLogger()
|
||||
logger = logging.getLogger("EmbyCon." + __name__)
|
||||
|
||||
|
||||
class WebSocketException(Exception):
|
||||
@ -107,10 +107,10 @@ def enableTrace(tracable):
|
||||
"""
|
||||
global traceEnabled
|
||||
traceEnabled = tracable
|
||||
if tracable:
|
||||
if not logger.handlers:
|
||||
logger.addHandler(logging.StreamHandler())
|
||||
logger.setLevel(logging.DEBUG)
|
||||
#if tracable:
|
||||
# if not logger.handlers:
|
||||
# logger.addHandler(logging.StreamHandler())
|
||||
# logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
def setdefaulttimeout(timeout):
|
||||
|
@ -11,108 +11,101 @@ import threading
|
||||
import urllib
|
||||
import socket
|
||||
import websocket
|
||||
import logging
|
||||
|
||||
from clientinfo import ClientInformation
|
||||
from downloadutils import DownloadUtils
|
||||
|
||||
log = logging.getLogger("EmbyCon." + __name__)
|
||||
|
||||
class WebSocketThread(threading.Thread):
|
||||
|
||||
logLevel = 0
|
||||
client = None
|
||||
keepRunning = True
|
||||
|
||||
def __init__(self, *args):
|
||||
addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
level = addonSettings.getSetting('logLevel')
|
||||
self.logLevel = 0
|
||||
if(level != None):
|
||||
self.logLevel = int(level)
|
||||
|
||||
xbmc.log("EmbyCon WebSocketThread -> Log Level:" + str(self.logLevel))
|
||||
def __init__(self, *args):
|
||||
log.info("EmbyCon WebSocketThread")
|
||||
|
||||
threading.Thread.__init__(self, *args)
|
||||
|
||||
def logMsg(self, msg, level = 1):
|
||||
if(self.logLevel >= level):
|
||||
xbmc.log("EmbyCon WebSocketThread -> " + msg)
|
||||
|
||||
def playbackStarted(self, itemId):
|
||||
if(self.client != None):
|
||||
try:
|
||||
self.logMsg("Sending Playback Started")
|
||||
log.info("Sending Playback Started")
|
||||
messageData = {}
|
||||
messageData["MessageType"] = "PlaybackStart"
|
||||
messageData["Data"] = itemId + "|true|audio,video"
|
||||
messageString = json.dumps(messageData)
|
||||
self.logMsg("Message Data : " + messageString)
|
||||
log.info("Message Data : " + messageString)
|
||||
self.client.send(messageString)
|
||||
except Exception, e:
|
||||
self.logMsg("Exception : " + str(e), level=0)
|
||||
log.debug("Exception : " + str(e))
|
||||
else:
|
||||
self.logMsg("Sending Playback Started NO Object ERROR")
|
||||
log.info("Sending Playback Started NO Object ERROR")
|
||||
|
||||
def playbackStopped(self, itemId, ticks):
|
||||
if(self.client != None):
|
||||
try:
|
||||
self.logMsg("Sending Playback Stopped : " + str(ticks))
|
||||
log.info("Sending Playback Stopped : " + str(ticks))
|
||||
messageData = {}
|
||||
messageData["MessageType"] = "PlaybackStopped"
|
||||
messageData["Data"] = itemId + "|" + str(ticks)
|
||||
messageString = json.dumps(messageData)
|
||||
self.client.send(messageString)
|
||||
except Exception, e:
|
||||
self.logMsg("Exception : " + str(e), level=0)
|
||||
log.error("Exception : " + str(e))
|
||||
else:
|
||||
self.logMsg("Sending Playback Stopped NO Object ERROR")
|
||||
log.info("Sending Playback Stopped NO Object ERROR")
|
||||
|
||||
def sendProgressUpdate(self, itemId, ticks):
|
||||
if(self.client != None):
|
||||
try:
|
||||
self.logMsg("Sending Progress Update : " + str(ticks))
|
||||
log.info("Sending Progress Update : " + str(ticks))
|
||||
messageData = {}
|
||||
messageData["MessageType"] = "PlaybackProgress"
|
||||
messageData["Data"] = itemId + "|" + str(ticks) + "|false|false"
|
||||
messageString = json.dumps(messageData)
|
||||
self.logMsg("Message Data : " + messageString)
|
||||
log.info("Message Data : " + messageString)
|
||||
self.client.send(messageString)
|
||||
except Exception, e:
|
||||
self.logMsg("Exception : " + str(e), level=0)
|
||||
log.error("Exception : " + str(e))
|
||||
else:
|
||||
self.logMsg("Sending Progress Update NO Object ERROR")
|
||||
log.info("Sending Progress Update NO Object ERROR")
|
||||
|
||||
def stopClient(self):
|
||||
# stopping the client is tricky, first set keep_running to false and then trigger one
|
||||
# more message by requesting one SessionsStart message, this causes the
|
||||
# client to receive the message and then exit
|
||||
if(self.client != None):
|
||||
self.logMsg("Stopping Client")
|
||||
log.info("Stopping Client")
|
||||
self.keepRunning = False
|
||||
self.client.keep_running = False
|
||||
self.client.close()
|
||||
self.logMsg("Stopping Client : KeepRunning set to False")
|
||||
log.info("Stopping Client : KeepRunning set to False")
|
||||
'''
|
||||
try:
|
||||
self.keepRunning = False
|
||||
self.client.keep_running = False
|
||||
self.logMsg("Stopping Client")
|
||||
self.logMsg("Calling Ping")
|
||||
log.debug("Stopping Client")
|
||||
log.debug("Calling Ping")
|
||||
self.client.sock.ping()
|
||||
|
||||
self.logMsg("Calling Socket Shutdown()")
|
||||
log.debug("Calling Socket Shutdown()")
|
||||
self.client.sock.sock.shutdown(socket.SHUT_RDWR)
|
||||
self.logMsg("Calling Socket Close()")
|
||||
log.debug("Calling Socket Close()")
|
||||
self.client.sock.sock.close()
|
||||
self.logMsg("Stopping Client Done")
|
||||
self.logMsg("Calling Ping")
|
||||
log.debug("Stopping Client Done")
|
||||
log.debug("Calling Ping")
|
||||
self.client.sock.ping()
|
||||
|
||||
except Exception, e:
|
||||
self.logMsg("Exception : " + str(e), level=0)
|
||||
log.debug("Exception : " + str(e))
|
||||
'''
|
||||
else:
|
||||
self.logMsg("Stopping Client NO Object ERROR")
|
||||
log.info("Stopping Client NO Object ERROR")
|
||||
|
||||
def on_message(self, ws, message):
|
||||
self.logMsg("Message : " + str(message))
|
||||
log.info("Message : " + str(message))
|
||||
result = json.loads(message)
|
||||
|
||||
messageType = result.get("MessageType")
|
||||
@ -125,7 +118,7 @@ class WebSocketThread(threading.Thread):
|
||||
if(playCommand != None and playCommand == "PlayNow"):
|
||||
|
||||
startPositionTicks = data.get("StartPositionTicks")
|
||||
self.logMsg("Playing Media With ID : " + itemIds[0])
|
||||
log.info("Playing Media With ID : " + itemIds[0])
|
||||
|
||||
addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
mb3Host = addonSettings.getSetting('ipaddress')
|
||||
@ -146,21 +139,21 @@ class WebSocketThread(threading.Thread):
|
||||
elif(messageType != None and messageType == "Playstate"):
|
||||
command = data.get("Command")
|
||||
if(command != None and command == "Stop"):
|
||||
self.logMsg("Playback Stopped")
|
||||
log.info("Playback Stopped")
|
||||
xbmc.executebuiltin('xbmc.activatewindow(10000)')
|
||||
xbmc.Player().stop()
|
||||
|
||||
if(command != None and command == "Seek"):
|
||||
seekPositionTicks = data.get("SeekPositionTicks")
|
||||
self.logMsg("Playback Seek : " + str(seekPositionTicks))
|
||||
log.info("Playback Seek : " + str(seekPositionTicks))
|
||||
seekTime = (seekPositionTicks / 1000) / 10000
|
||||
xbmc.Player().seekTime(seekTime)
|
||||
|
||||
def on_error(self, ws, error):
|
||||
self.logMsg("Error : " + str(error))
|
||||
log.info("Error : " + str(error))
|
||||
|
||||
def on_close(self, ws):
|
||||
self.logMsg("Closed")
|
||||
log.info("Closed")
|
||||
|
||||
def on_open(self, ws):
|
||||
try:
|
||||
@ -176,7 +169,7 @@ class WebSocketThread(threading.Thread):
|
||||
|
||||
messageData["Data"] = "XBMC|" + machineId + "|" + version + "|" + deviceName
|
||||
messageString = json.dumps(messageData)
|
||||
self.logMsg("Opened : " + str(messageString))
|
||||
log.info("Opened : " + str(messageString))
|
||||
ws.send(messageString)
|
||||
|
||||
downloadUtils = DownloadUtils()
|
||||
@ -187,25 +180,25 @@ class WebSocketThread(threading.Thread):
|
||||
mb3Port = addonSettings.getSetting('port')
|
||||
|
||||
url = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Sessions?DeviceId=" + machineId + "&format=json"
|
||||
self.logMsg("Session URL : " + url);
|
||||
log.info("Session URL : " + url);
|
||||
jsonData = downloadUtils.downloadUrl(url)
|
||||
self.logMsg("Session JsonData : " + jsonData)
|
||||
log.info("Session JsonData : " + jsonData)
|
||||
result = json.loads(jsonData)
|
||||
self.logMsg("Session JsonData : " + str(result))
|
||||
log.info("Session JsonData : " + str(result))
|
||||
sessionId = result[0].get("Id")
|
||||
self.logMsg("Session Id : " + str(sessionId))
|
||||
log.info("Session Id : " + str(sessionId))
|
||||
|
||||
url = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Sessions/Capabilities?Id=" + sessionId + "&PlayableMediaTypes=Video&SupportedCommands=Play&SupportsMediaControl=True"
|
||||
postData = {}
|
||||
postData["Id"] = sessionId;
|
||||
postData["PlayableMediaTypes"] = "Video";
|
||||
stringdata = json.dumps(postData)
|
||||
self.logMsg("Capabilities URL : " + url);
|
||||
self.logMsg("Capabilities Data : " + stringdata)
|
||||
log.info("Capabilities URL : " + url);
|
||||
log.info("Capabilities Data : " + stringdata)
|
||||
downloadUtils.downloadUrl(url, postBody=stringdata, type="POST")
|
||||
|
||||
except Exception, e:
|
||||
self.logMsg("Exception : " + str(e), level=0)
|
||||
log.error("Exception : " + str(e))
|
||||
|
||||
def run(self):
|
||||
|
||||
@ -215,26 +208,28 @@ class WebSocketThread(threading.Thread):
|
||||
mb3Host = addonSettings.getSetting('ipaddress')
|
||||
mb3Port = addonSettings.getSetting('port')
|
||||
|
||||
if(self.logLevel >= 1):
|
||||
websocket.enableTrace(True)
|
||||
addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
logLevel = int(addonSettings.getSetting('logLevel'))
|
||||
if(logLevel == 2):
|
||||
websocket.enableTrace(True)
|
||||
|
||||
if(mb3Host != None and len(mb3Host) > 0):
|
||||
|
||||
try:
|
||||
|
||||
wsPort = mb3Port
|
||||
self.logMsg("WebSocketPortNumber = " + str(wsPort))
|
||||
log.info("WebSocketPortNumber = " + str(wsPort))
|
||||
|
||||
downloadUtils = DownloadUtils()
|
||||
authHeaders = downloadUtils.getAuthHeader()
|
||||
flatHeaders = []
|
||||
for header in authHeaders:
|
||||
flatHeaders.append(header + ": " + authHeaders[header])
|
||||
self.logMsg("Flat Header : " + str(flatHeaders))
|
||||
log.info("Flat Header : " + str(flatHeaders))
|
||||
|
||||
# Make a call to /System/Info. WebSocketPortNumber is the port hosting the web socket.
|
||||
webSocketUrl = "ws://" + mb3Host + ":" + str(wsPort) + "/mediabrowser"
|
||||
self.logMsg("WebSocket URL : " + webSocketUrl)
|
||||
log.info("WebSocket URL : " + webSocketUrl)
|
||||
self.client = websocket.WebSocketApp(webSocketUrl,
|
||||
header = flatHeaders,
|
||||
on_message = self.on_message,
|
||||
@ -243,17 +238,17 @@ class WebSocketThread(threading.Thread):
|
||||
|
||||
self.client.on_open = self.on_open
|
||||
|
||||
self.logMsg("Client Starting")
|
||||
log.info("Client Starting")
|
||||
if(self.keepRunning):
|
||||
self.client.run_forever()
|
||||
except:
|
||||
self.logMsg("Error thrown in Web Socket Setup")
|
||||
log.info("Error thrown in Web Socket Setup")
|
||||
|
||||
if(self.keepRunning and xbmc.abortRequested == False):
|
||||
self.logMsg("Client Needs To Restart")
|
||||
log.info("Client Needs To Restart")
|
||||
xbmc.sleep(5000)
|
||||
|
||||
self.logMsg("Thread Exited")
|
||||
log.info("Thread Exited")
|
||||
|
||||
|
||||
|
||||
|
37
service.py
37
service.py
@ -16,19 +16,24 @@ import mimetypes
|
||||
from threading import Thread
|
||||
from urlparse import parse_qs
|
||||
from urllib import urlretrieve
|
||||
import logging
|
||||
|
||||
from random import randint
|
||||
import random
|
||||
import urllib2
|
||||
|
||||
__cwd__ = xbmcaddon.Addon(id='plugin.video.embycon').getAddonInfo('path')
|
||||
__addon__ = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
__language__ = __addon__.getLocalizedString
|
||||
BASE_RESOURCE_PATH = xbmc.translatePath( os.path.join( __cwd__, 'resources', 'lib' ) )
|
||||
addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
addonPath = addonSettings.getAddonInfo('path')
|
||||
BASE_RESOURCE_PATH = xbmc.translatePath( os.path.join( addonPath, 'resources', 'lib' ) )
|
||||
sys.path.append(BASE_RESOURCE_PATH)
|
||||
|
||||
from websocketclient import WebSocketThread
|
||||
from downloadutils import DownloadUtils
|
||||
import loghandler
|
||||
|
||||
log_level = addonSettings.getSetting('logLevel')
|
||||
loghandler.config(int(log_level))
|
||||
log = logging.getLogger("EmbyCon.service")
|
||||
|
||||
downloadUtils = DownloadUtils()
|
||||
|
||||
@ -55,19 +60,19 @@ def stopAll(played_information):
|
||||
return
|
||||
|
||||
addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
xbmc.log ("EmbyCon Service -> played_information : " + str(played_information))
|
||||
log.info("EmbyCon Service -> played_information : " + str(played_information))
|
||||
|
||||
for item_url in played_information:
|
||||
data = played_information.get(item_url)
|
||||
if(data != None):
|
||||
xbmc.log ("EmbyCon Service -> item_url : " + item_url)
|
||||
xbmc.log ("EmbyCon Service -> item_data : " + str(data))
|
||||
log.info("EmbyCon Service -> item_url : " + item_url)
|
||||
log.info("EmbyCon Service -> item_data : " + str(data))
|
||||
|
||||
currentPossition = data.get("currentPossition")
|
||||
item_id = data.get("item_id")
|
||||
|
||||
if(hasData(item_id)):
|
||||
xbmc.log("EmbyCon Service -> Playback Stopped at :" + str(int(currentPossition * 10000000)))
|
||||
log.info("EmbyCon Service -> Playback Stopped at :" + str(int(currentPossition * 10000000)))
|
||||
newWebSocketThread.playbackStopped(item_id, str(int(currentPossition * 10000000)))
|
||||
|
||||
played_information.clear()
|
||||
@ -78,7 +83,7 @@ class Service( xbmc.Player ):
|
||||
played_information = {}
|
||||
|
||||
def __init__( self, *args ):
|
||||
xbmc.log("EmbyCon Service -> starting monitor service")
|
||||
log.info("EmbyCon Service -> starting monitor service")
|
||||
self.played_information = {}
|
||||
pass
|
||||
|
||||
@ -87,7 +92,7 @@ class Service( xbmc.Player ):
|
||||
stopAll(self.played_information)
|
||||
|
||||
currentFile = xbmc.Player().getPlayingFile()
|
||||
xbmc.log("EmbyCon Service -> onPlayBackStarted" + currentFile)
|
||||
log.info("EmbyCon Service -> onPlayBackStarted" + currentFile)
|
||||
|
||||
WINDOW = xbmcgui.Window( 10000 )
|
||||
item_id = WINDOW.getProperty("item_id")
|
||||
@ -104,17 +109,17 @@ class Service( xbmc.Player ):
|
||||
data["item_id"] = item_id
|
||||
self.played_information[currentFile] = data
|
||||
|
||||
xbmc.log("EmbyCon Service -> ADDING_FILE : " + currentFile)
|
||||
xbmc.log("EmbyCon Service -> ADDING_FILE : " + str(self.played_information))
|
||||
log.info("EmbyCon Service -> ADDING_FILE : " + currentFile)
|
||||
log.info("EmbyCon Service -> ADDING_FILE : " + str(self.played_information))
|
||||
|
||||
def onPlayBackEnded( self ):
|
||||
# Will be called when xbmc stops playing a file
|
||||
xbmc.log("EmbyCon Service -> onPlayBackEnded")
|
||||
log.info("EmbyCon Service -> onPlayBackEnded")
|
||||
stopAll(self.played_information)
|
||||
|
||||
def onPlayBackStopped( self ):
|
||||
# Will be called when user stops xbmc playing a file
|
||||
xbmc.log("EmbyCon Service -> onPlayBackStopped")
|
||||
log.info("EmbyCon Service -> onPlayBackStopped")
|
||||
stopAll(self.played_information)
|
||||
|
||||
monitor = Service()
|
||||
@ -140,7 +145,7 @@ while not xbmc.abortRequested:
|
||||
lastProgressUpdate = datetime.today()
|
||||
|
||||
except Exception, e:
|
||||
xbmc.log("EmbyCon Service -> Exception in Playback Monitor : " + str(e))
|
||||
log.error("EmbyCon Service -> Exception in Playback Monitor : " + str(e))
|
||||
pass
|
||||
|
||||
xbmc.sleep(1000)
|
||||
@ -149,4 +154,4 @@ while not xbmc.abortRequested:
|
||||
# stop the WebSocket client
|
||||
newWebSocketThread.stopClient()
|
||||
|
||||
xbmc.log("EmbyCon Service -> Service shutting down")
|
||||
log.info("EmbyCon Service -> Service shutting down")
|
||||
|
Loading…
Reference in New Issue
Block a user