Files
jellycon/resources/lib/DataManager.py

190 lines
7.4 KiB
Python

import hashlib
import os
import threading
import json as json
import xbmcplugin
import xbmcgui
import xbmcaddon
import xbmc
from DownloadUtils import DownloadUtils
class DataManager():
cacheDataResult = None
dataUrl = None
cacheDataPath = None
canRefreshNow = False
logLevel = 0
def __init__(self, *args):
addonSettings = xbmcaddon.Addon(id='plugin.video.mbcon')
self.addonSettings = xbmcaddon.Addon(id='plugin.video.mbcon')
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("MBCon DataManager -> " + msg)
def getCacheValidatorFromData(self, result):
result = result.get("Items")
if(result == None):
result = []
itemCount = 0
unwatchedItemCount = 0
dataHashString = "";
for item in result:
userData = item.get("UserData")
if(userData != None):
if(item.get("IsFolder") == False):
itemCount = itemCount + 1
itemPercent = 0.0
if userData.get("Played") == False:
unwatchedItemCount = unwatchedItemCount + 1
# calc the percentage
itemPercent = 0.0
itemPossition = userData.get("PlaybackPositionTicks")
itemRuntime = item.get("RunTimeTicks")
if(itemRuntime != None and itemPossition != None):
itemPercent = (float(itemPossition) / float(itemRuntime)) * 100
itemString = str(itemCount) + "_" + item.get("Name", "name") + "_" + str(int(itemPercent)) + "-" + str(unwatchedItemCount) + "|"
self.logMsg(itemString, level=2)
dataHashString = dataHashString + itemString
else:
itemCount = itemCount + item.get("RecursiveItemCount")
unwatchedItemCount = unwatchedItemCount + userData.get("UnplayedItemCount")
PlayedPercentage = userData.get("PlayedPercentage")
if PlayedPercentage == None:
PlayedPercentage = 0
itemString = str(itemCount) + "_" + item.get("Name", "name") + "_" + str(int(PlayedPercentage)) + "-" + str(unwatchedItemCount) + "|"
self.logMsg(itemString, level=2)
dataHashString = dataHashString + itemString
# hash the data
dataHashString = dataHashString.encode("UTF-8")
m = hashlib.md5()
m.update(dataHashString)
validatorString = m.hexdigest()
self.logMsg("getCacheValidatorFromData : RawData : " + dataHashString, level=2)
self.logMsg("getCacheValidatorFromData : hashData : " + validatorString, level=2)
return validatorString
def loadJasonData(self, jsonData):
return json.loads(jsonData)
def GetContent(self, url):
# first get the url hash
m = hashlib.md5()
m.update(url)
urlHash = m.hexdigest()
# build cache data path
__addon__ = xbmcaddon.Addon(id='plugin.video.mbcon')
__addondir__ = xbmc.translatePath( __addon__.getAddonInfo('profile'))
if not os.path.exists(os.path.join(__addondir__, "cache")):
os.makedirs(os.path.join(__addondir__, "cache"))
cacheDataPath = os.path.join(__addondir__, "cache", urlHash)
self.logMsg("Cache_Data_Manager:" + cacheDataPath)
# are we forcing a reload
WINDOW = xbmcgui.Window( 10000 )
force_data_reload = WINDOW.getProperty("force_data_reload")
WINDOW.setProperty("force_data_reload", "false")
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")
cachedfie = open(cacheDataPath, 'r')
jsonData = cachedfie.read()
cachedfie.close()
result = self.loadJasonData(jsonData)
# start a worker thread to process the cache validity
self.cacheDataResult = result
self.dataUrl = url
self.cacheDataPath = cacheDataPath
actionThread = CacheManagerThread()
actionThread.setCacheData(self)
actionThread.start()
self.logMsg("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")
cachedfie = open(cacheDataPath, 'w')
cachedfie.write(jsonData)
cachedfie.close()
result = self.loadJasonData(jsonData)
self.cacheManagerFinished = True
self.logMsg("Returning Loaded Result")
return result
class CacheManagerThread(threading.Thread):
dataManager = None
logLevel = 0
def __init__(self, *args):
addonSettings = xbmcaddon.Addon(id='plugin.video.mbcon')
self.addonSettings = xbmcaddon.Addon(id='plugin.video.mbcon')
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("MBCon CacheManagerThread -> " + msg)
def setCacheData(self, data):
self.dataManager = data
def run(self):
self.logMsg("CacheManagerThread Started")
cacheValidatorString = self.dataManager.getCacheValidatorFromData(self.dataManager.cacheDataResult)
self.logMsg("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 + ")")
# 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")
cachedfie = open(self.dataManager.cacheDataPath, 'w')
cachedfie.write(jsonData)
cachedfie.close()
# 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")
xbmc.sleep(100)
loops = loops + 1
self.logMsg("Sending container refresh (" + str(loops) + ")")
xbmc.executebuiltin("Container.Refresh")
self.logMsg("CacheManagerThread Exited")