diff --git a/default.py b/default.py
index af514198..68d0294f 100644
--- a/default.py
+++ b/default.py
@@ -47,6 +47,10 @@ elif mode == "settings":
elif mode == "manualsync":
from LibrarySync import LibrarySync
LibrarySync().FullLibrarySync(True)
+
+elif mode == "texturecache":
+ from TextureCache import TextureCache
+ TextureCache().FullTextureCacheSync()
##### BROWSE EMBY CHANNELS ROOT #####
elif mode == "channels":
diff --git a/resources/lib/Entrypoint.py b/resources/lib/Entrypoint.py
index f86af5d1..5cdf39f9 100644
--- a/resources/lib/Entrypoint.py
+++ b/resources/lib/Entrypoint.py
@@ -486,5 +486,6 @@ def doMainListing():
addDirectoryItem("Perform manual sync", "plugin://plugin.video.emby/?mode=manualsync")
addDirectoryItem("Add user to session", "plugin://plugin.video.emby/?mode=adduser")
addDirectoryItem("Perform local database reset (full resync)", "plugin://plugin.video.emby/?mode=reset")
+ addDirectoryItem("Cache all images to Kodi texture cache (advanced)", "plugin://plugin.video.emby/?mode=texturecache")
xbmcplugin.endOfDirectory(int(sys.argv[1]))
diff --git a/resources/lib/LibrarySync.py b/resources/lib/LibrarySync.py
index 02a2dea8..5570cdf2 100644
--- a/resources/lib/LibrarySync.py
+++ b/resources/lib/LibrarySync.py
@@ -618,7 +618,6 @@ class LibrarySync():
xbmc.executebuiltin("UpdateLibrary(video)")
WINDOW.setProperty("SyncDatabaseRunning", "false")
-
def ShouldStop(self):
if(xbmc.abortRequested):
diff --git a/resources/lib/TextureCache.py b/resources/lib/TextureCache.py
new file mode 100644
index 00000000..e095cbec
--- /dev/null
+++ b/resources/lib/TextureCache.py
@@ -0,0 +1,105 @@
+#################################################################################################
+# TextureCache
+#################################################################################################
+
+
+import xbmc
+import xbmcaddon
+import json
+import requests
+import urllib
+
+import Utils as utils
+
+class TextureCache():
+
+
+ xbmc_host = 'localhost'
+ xbmc_port = None
+ xbmc_username = None
+ xbmc_password = None
+ enableTextureCache = False
+
+ def __init__(self):
+
+ addon = xbmcaddon.Addon(id='plugin.video.emby')
+ self.enableTextureCache = addon.getSetting("enableTextureCache") == "true"
+
+ if (not self.xbmc_port and self.enableTextureCache == True):
+ self.setKodiWebServerDetails()
+
+ def double_urlencode(self, text):
+ text = self.single_urlencode(text)
+ text = self.single_urlencode(text)
+ return text
+
+ def single_urlencode(self, text):
+ blah = urllib.urlencode({'blahblahblah':text})
+ blah = blah[13:]
+
+ return blah
+
+ def FullTextureCacheSync(self):
+ #this method can be called from the plugin to sync all Kodi textures to the texture cache.
+ #Warning: this means that every image will be cached locally, this takes diskspace!
+ connection = utils.KodiSQL("video")
+ cursor = connection.cursor()
+ cursor.execute("SELECT url FROM art")
+ result = cursor.fetchall()
+ for url in result:
+ self.CacheTexture(url[0])
+
+ cursor.close()
+
+ connection = utils.KodiSQL("music")
+ cursor = connection.cursor()
+ cursor.execute("SELECT url FROM art")
+ result = cursor.fetchall()
+ for url in result:
+ self.CacheTexture(url[0])
+
+ cursor.close()
+
+
+ def CacheTexture(self,url):
+ #cache a single image url to the texture cache
+ if url and self.enableTextureCache == True:
+
+ utils.logMsg("cache texture for URL", "Processing : " + url)
+ # add image to texture cache by simply calling it at the http endpoint
+ url = self.double_urlencode(url)
+ try:
+ response = requests.head('http://' + self.xbmc_host + ':' + str(self.xbmc_port) + '/image/image://' + url, auth=(self.xbmc_username, self.xbmc_password),timeout=(0.01, 0.01))
+ except:
+ #extreme short timeouts so we will have a exception, but we don't need the result so pass
+ pass
+
+
+ def setKodiWebServerDetails(self):
+ # Get the Kodi webserver details - used to set the texture cache
+ json_response = xbmc.executeJSONRPC('{"jsonrpc":"2.0", "id":1, "method":"Settings.GetSettingValue","params":{"setting":"services.webserver"}, "id":1}')
+ jsonobject = json.loads(json_response.decode('utf-8','replace'))
+ if(jsonobject.has_key('result')):
+ xbmc_webserver_enabled = jsonobject["result"]["value"]
+
+ if not xbmc_webserver_enabled:
+ #enable the webserver if not enabled
+ xbmc.executeJSONRPC('{"jsonrpc":"2.0", "id":1, "method":"Settings.SetSettingValue","params":{"setting":"services.webserverport","value":8080}, "id":1}')
+ self.xbmc_port = 8080
+ xbmc.executeJSONRPC('{"jsonrpc":"2.0", "id":1, "method":"Settings.SetSettingValue","params":{"setting":"services.webserver","value":true}, "id":1}')
+ self.xbmc_port = "kodi"
+
+ json_response = xbmc.executeJSONRPC('{"jsonrpc":"2.0", "id":1, "method":"Settings.GetSettingValue","params":{"setting":"services.webserverport"}, "id":1}')
+ jsonobject = json.loads(json_response.decode('utf-8','replace'))
+ if(jsonobject.has_key('result')):
+ self.xbmc_port = jsonobject["result"]["value"]
+
+ json_response = xbmc.executeJSONRPC('{"jsonrpc":"2.0", "id":1, "method":"Settings.GetSettingValue","params":{"setting":"services.webserverusername"}, "id":1}')
+ jsonobject = json.loads(json_response.decode('utf-8','replace'))
+ if(jsonobject.has_key('result')):
+ self.xbmc_username = jsonobject["result"]["value"]
+
+ json_response = xbmc.executeJSONRPC('{"jsonrpc":"2.0", "id":1, "method":"Settings.GetSettingValue","params":{"setting":"services.webserverpassword"}, "id":1}')
+ jsonobject = json.loads(json_response.decode('utf-8','replace'))
+ if(jsonobject.has_key('result')):
+ self.xbmc_password = jsonobject["result"]["value"]
\ No newline at end of file
diff --git a/resources/lib/WriteKodiMusicDB.py b/resources/lib/WriteKodiMusicDB.py
index 2847e7c7..5d242b33 100644
--- a/resources/lib/WriteKodiMusicDB.py
+++ b/resources/lib/WriteKodiMusicDB.py
@@ -18,6 +18,7 @@ from DownloadUtils import DownloadUtils
from PlayUtils import PlayUtils
from ReadKodiDB import ReadKodiDB
from ReadEmbyDB import ReadEmbyDB
+from TextureCache import TextureCache
from API import API
import Utils as utils
@@ -32,7 +33,7 @@ addondir = xbmc.translatePath(addon.getAddonInfo('profile'))
class WriteKodiMusicDB():
-
+ textureCache = TextureCache()
def updatePlayCountFromKodi(self, id, type, playcount=0):
#when user marks item watched from kodi interface update this in Emby
@@ -495,6 +496,10 @@ class WriteKodiMusicDB():
if(url != imageUrl):
utils.logMsg("ArtworkSync", "Updating Art Link for kodiId: " + str(kodiId) + " (" + url + ") -> (" + imageUrl + ")")
cursor.execute("UPDATE art set url = ? WHERE media_id = ? AND media_type = ? AND type = ?", (imageUrl, kodiId, mediaType, imageType))
+
+ #cache fanart textures in Kodi texture cache
+ if imageType == "fanart":
+ self.textureCache.CacheTexture(imageUrl)
def AddGenresToMedia(self, id, genres, mediatype, cursor):
diff --git a/resources/lib/WriteKodiVideoDB.py b/resources/lib/WriteKodiVideoDB.py
index 26e9cd30..a5dbad8d 100644
--- a/resources/lib/WriteKodiVideoDB.py
+++ b/resources/lib/WriteKodiVideoDB.py
@@ -13,10 +13,12 @@ import sqlite3
import os
from decimal import Decimal
+
from DownloadUtils import DownloadUtils
from PlayUtils import PlayUtils
from ReadKodiDB import ReadKodiDB
from ReadEmbyDB import ReadEmbyDB
+from TextureCache import TextureCache
from API import API
import Utils as utils
@@ -26,6 +28,8 @@ from xml.dom import minidom
import xml.etree.cElementTree as ET
class WriteKodiVideoDB():
+
+ textureCache = TextureCache()
def updatePlayCountFromKodi(self, id, type, playcount=0):
#when user marks item watched from kodi interface update this in Emby
@@ -772,6 +776,10 @@ class WriteKodiVideoDB():
if(url != imageUrl):
utils.logMsg("ArtworkSync", "Updating Art Link for kodiId: " + str(kodiId) + " (" + url + ") -> (" + imageUrl + ")")
cursor.execute("UPDATE art set url = ? WHERE media_id = ? AND media_type = ? AND type = ?", (imageUrl, kodiId, mediaType, imageType))
+
+ #cache fanart and poster in Kodi texture cache
+ if imageType == "fanart" or imageType == "poster":
+ self.textureCache.CacheTexture(imageUrl)
def setKodiResumePoint(self, fileid, resume_seconds, total_seconds, cursor):
@@ -990,8 +998,7 @@ class WriteKodiVideoDB():
else:
#only movies have a country field
return
-
-
+
def AddStudiosToMedia(self, id, studios, mediatype, cursor):
if studios:
@@ -1208,5 +1215,4 @@ class WriteKodiVideoDB():
#update the checksum in emby table
cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(boxsetmovie),boxsetmovie["Id"]))
-
-
+
\ No newline at end of file
diff --git a/resources/settings.xml b/resources/settings.xml
index 635c5474..41a1ee6f 100644
--- a/resources/settings.xml
+++ b/resources/settings.xml
@@ -16,7 +16,8 @@
-
+
+