mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-12-26 10:46:11 +00:00
added support for kodi texturecache:
- setting in addon settings to turn on the cache feature (now for testing, maybe hidden later) - for all new items the poster and the fanart image will be cached automatically (when setting is on) - added a option to the plugin root options to perform full cache fill which will pull every single image to the cache.
This commit is contained in:
parent
8f8f39bb75
commit
cdf78de132
7 changed files with 128 additions and 7 deletions
|
@ -48,6 +48,10 @@ elif mode == "manualsync":
|
||||||
from LibrarySync import LibrarySync
|
from LibrarySync import LibrarySync
|
||||||
LibrarySync().FullLibrarySync(True)
|
LibrarySync().FullLibrarySync(True)
|
||||||
|
|
||||||
|
elif mode == "texturecache":
|
||||||
|
from TextureCache import TextureCache
|
||||||
|
TextureCache().FullTextureCacheSync()
|
||||||
|
|
||||||
##### BROWSE EMBY CHANNELS ROOT #####
|
##### BROWSE EMBY CHANNELS ROOT #####
|
||||||
elif mode == "channels":
|
elif mode == "channels":
|
||||||
entrypoint.BrowseChannels(id)
|
entrypoint.BrowseChannels(id)
|
||||||
|
|
|
@ -486,5 +486,6 @@ def doMainListing():
|
||||||
addDirectoryItem("Perform manual sync", "plugin://plugin.video.emby/?mode=manualsync")
|
addDirectoryItem("Perform manual sync", "plugin://plugin.video.emby/?mode=manualsync")
|
||||||
addDirectoryItem("Add user to session", "plugin://plugin.video.emby/?mode=adduser")
|
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("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]))
|
xbmcplugin.endOfDirectory(int(sys.argv[1]))
|
||||||
|
|
|
@ -618,7 +618,6 @@ class LibrarySync():
|
||||||
xbmc.executebuiltin("UpdateLibrary(video)")
|
xbmc.executebuiltin("UpdateLibrary(video)")
|
||||||
WINDOW.setProperty("SyncDatabaseRunning", "false")
|
WINDOW.setProperty("SyncDatabaseRunning", "false")
|
||||||
|
|
||||||
|
|
||||||
def ShouldStop(self):
|
def ShouldStop(self):
|
||||||
|
|
||||||
if(xbmc.abortRequested):
|
if(xbmc.abortRequested):
|
||||||
|
|
105
resources/lib/TextureCache.py
Normal file
105
resources/lib/TextureCache.py
Normal file
|
@ -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"]
|
|
@ -18,6 +18,7 @@ from DownloadUtils import DownloadUtils
|
||||||
from PlayUtils import PlayUtils
|
from PlayUtils import PlayUtils
|
||||||
from ReadKodiDB import ReadKodiDB
|
from ReadKodiDB import ReadKodiDB
|
||||||
from ReadEmbyDB import ReadEmbyDB
|
from ReadEmbyDB import ReadEmbyDB
|
||||||
|
from TextureCache import TextureCache
|
||||||
from API import API
|
from API import API
|
||||||
import Utils as utils
|
import Utils as utils
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ addondir = xbmc.translatePath(addon.getAddonInfo('profile'))
|
||||||
|
|
||||||
class WriteKodiMusicDB():
|
class WriteKodiMusicDB():
|
||||||
|
|
||||||
|
textureCache = TextureCache()
|
||||||
|
|
||||||
def updatePlayCountFromKodi(self, id, type, playcount=0):
|
def updatePlayCountFromKodi(self, id, type, playcount=0):
|
||||||
#when user marks item watched from kodi interface update this in Emby
|
#when user marks item watched from kodi interface update this in Emby
|
||||||
|
@ -496,6 +497,10 @@ class WriteKodiMusicDB():
|
||||||
utils.logMsg("ArtworkSync", "Updating Art Link for kodiId: " + str(kodiId) + " (" + 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))
|
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):
|
def AddGenresToMedia(self, id, genres, mediatype, cursor):
|
||||||
|
|
||||||
if genres:
|
if genres:
|
||||||
|
|
|
@ -13,10 +13,12 @@ import sqlite3
|
||||||
import os
|
import os
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
|
|
||||||
from DownloadUtils import DownloadUtils
|
from DownloadUtils import DownloadUtils
|
||||||
from PlayUtils import PlayUtils
|
from PlayUtils import PlayUtils
|
||||||
from ReadKodiDB import ReadKodiDB
|
from ReadKodiDB import ReadKodiDB
|
||||||
from ReadEmbyDB import ReadEmbyDB
|
from ReadEmbyDB import ReadEmbyDB
|
||||||
|
from TextureCache import TextureCache
|
||||||
from API import API
|
from API import API
|
||||||
import Utils as utils
|
import Utils as utils
|
||||||
|
|
||||||
|
@ -27,6 +29,8 @@ import xml.etree.cElementTree as ET
|
||||||
|
|
||||||
class WriteKodiVideoDB():
|
class WriteKodiVideoDB():
|
||||||
|
|
||||||
|
textureCache = TextureCache()
|
||||||
|
|
||||||
def updatePlayCountFromKodi(self, id, type, playcount=0):
|
def updatePlayCountFromKodi(self, id, type, playcount=0):
|
||||||
#when user marks item watched from kodi interface update this in Emby
|
#when user marks item watched from kodi interface update this in Emby
|
||||||
|
|
||||||
|
@ -773,6 +777,10 @@ class WriteKodiVideoDB():
|
||||||
utils.logMsg("ArtworkSync", "Updating Art Link for kodiId: " + str(kodiId) + " (" + 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))
|
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):
|
def setKodiResumePoint(self, fileid, resume_seconds, total_seconds, cursor):
|
||||||
|
|
||||||
cursor.execute("delete FROM bookmark WHERE idFile = ?", (fileid,))
|
cursor.execute("delete FROM bookmark WHERE idFile = ?", (fileid,))
|
||||||
|
@ -991,7 +999,6 @@ class WriteKodiVideoDB():
|
||||||
#only movies have a country field
|
#only movies have a country field
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def AddStudiosToMedia(self, id, studios, mediatype, cursor):
|
def AddStudiosToMedia(self, id, studios, mediatype, cursor):
|
||||||
|
|
||||||
if studios:
|
if studios:
|
||||||
|
@ -1209,4 +1216,3 @@ class WriteKodiVideoDB():
|
||||||
cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(boxsetmovie),boxsetmovie["Id"]))
|
cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(boxsetmovie),boxsetmovie["Id"]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
<setting id="dbSyncIndication" type="bool" label="Show sync progress on screen" default="false" visible="true" enable="true" />
|
<setting id="dbSyncIndication" type="bool" label="Show sync progress on screen" default="false" visible="true" enable="true" />
|
||||||
<setting id="enableMusicSync" type="bool" label="Enable Music Library Sync" default="true" visible="true" enable="true" />
|
<setting id="enableMusicSync" type="bool" label="Enable Music Library Sync" default="true" visible="true" enable="true" />
|
||||||
<setting id="useDirectPaths" type="bool" label="30250" default="false" visible="true" enable="true" />
|
<setting id="useDirectPaths" type="bool" label="30250" default="false" visible="true" enable="true" />
|
||||||
|
<setting id="enableTextureCache" type="bool" label="Trigger images in the Kodi texture cache" default="false" visible="true" enable="true" />
|
||||||
</category>
|
</category>
|
||||||
<category label="Playback"> <!-- Extra Sync options -->
|
<category label="Playback"> <!-- Extra Sync options -->
|
||||||
<setting id="smbusername" type="text" label="30007" default="" visible="true" enable="true" />
|
<setting id="smbusername" type="text" label="30007" default="" visible="true" enable="true" />
|
||||||
|
|
Loading…
Reference in a new issue