mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-11-10 04:06:11 +00:00
Preparation for new artwork method
Moved to cache texture to limit duplicated methods (video and music). Update backdrop instantly, should not cause any issues this time since it only triggers if the url is different than the new one.
This commit is contained in:
parent
3605a48933
commit
91396d84e8
1 changed files with 155 additions and 70 deletions
|
@ -1,36 +1,44 @@
|
|||
#################################################################################################
|
||||
# TextureCache
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
||||
import xbmc, xbmcaddon, xbmcvfs
|
||||
import json
|
||||
import requests
|
||||
import urllib
|
||||
import os
|
||||
|
||||
import xbmc
|
||||
import xbmcvfs
|
||||
|
||||
import Utils as utils
|
||||
from ClientInformation import ClientInformation
|
||||
|
||||
#################################################################################################
|
||||
|
||||
class TextureCache():
|
||||
|
||||
|
||||
addonName = ClientInformation().getAddonName()
|
||||
|
||||
xbmc_host = 'localhost'
|
||||
xbmc_port = None
|
||||
xbmc_username = None
|
||||
xbmc_password = None
|
||||
enableTextureCache = False
|
||||
enableTextureCache = utils.settings('enableTextureCache') == "true"
|
||||
|
||||
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):
|
||||
if not self.xbmc_port and self.enableTextureCache:
|
||||
self.setKodiWebServerDetails()
|
||||
|
||||
def logMsg(self, msg, lvl=1):
|
||||
|
||||
className = self.__class__.__name__
|
||||
utils.logMsg("%s %s" % (self.addonName, className), msg, int(lvl))
|
||||
|
||||
def double_urlencode(self, text):
|
||||
text = self.single_urlencode(text)
|
||||
text = self.single_urlencode(text)
|
||||
|
||||
return text
|
||||
|
||||
def single_urlencode(self, text):
|
||||
|
@ -38,66 +46,7 @@ class TextureCache():
|
|||
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!
|
||||
|
||||
#remove all existing textures first
|
||||
path = "special://thumbnails/"
|
||||
if xbmcvfs.exists(path):
|
||||
allDirs, allFiles = xbmcvfs.listdir(path)
|
||||
for dir in allDirs:
|
||||
allDirs, allFiles = xbmcvfs.listdir(path+dir)
|
||||
for file in allFiles:
|
||||
xbmcvfs.delete(os.path.join(path+dir,file))
|
||||
|
||||
textureconnection = utils.KodiSQL("texture")
|
||||
texturecursor = textureconnection.cursor()
|
||||
texturecursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
|
||||
rows = texturecursor.fetchall()
|
||||
for row in rows:
|
||||
tableName = row[0]
|
||||
if(tableName != "version"):
|
||||
texturecursor.execute("DELETE FROM " + tableName)
|
||||
textureconnection.commit()
|
||||
texturecursor.close()
|
||||
|
||||
|
||||
#cache all entries in video DB
|
||||
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()
|
||||
|
||||
#cache all entries in music DB
|
||||
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}')
|
||||
|
@ -125,4 +74,140 @@ class TextureCache():
|
|||
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"]
|
||||
self.xbmc_password = jsonobject["result"]["value"]
|
||||
|
||||
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!
|
||||
|
||||
# Remove all existing textures first
|
||||
path = "special://thumbnails/"
|
||||
if xbmcvfs.exists(path):
|
||||
allDirs, allFiles = xbmcvfs.listdir(path)
|
||||
for dir in allDirs:
|
||||
allDirs, allFiles = xbmcvfs.listdir(path+dir)
|
||||
for file in allFiles:
|
||||
xbmcvfs.delete(os.path.join(path+dir,file))
|
||||
|
||||
textureconnection = utils.KodiSQL('texture')
|
||||
texturecursor = textureconnection.cursor()
|
||||
texturecursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
|
||||
rows = texturecursor.fetchall()
|
||||
for row in rows:
|
||||
tableName = row[0]
|
||||
if(tableName != "version"):
|
||||
texturecursor.execute("DELETE FROM " + tableName)
|
||||
textureconnection.commit()
|
||||
texturecursor.close()
|
||||
|
||||
|
||||
# Cache all entries in video DB
|
||||
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()
|
||||
|
||||
# Cache all entries in music DB
|
||||
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 addArtwork(self, artwork, kodiId, mediaType, cursor):
|
||||
# Kodi conversion table
|
||||
kodiart = {
|
||||
|
||||
'Primary': ["thumb", "poster"],
|
||||
'Banner': "banner",
|
||||
'Logo': "clearlogo",
|
||||
'Art': "clearart",
|
||||
'Thumb': "landscape",
|
||||
'Disc': "discart",
|
||||
'Backdrop': "fanart"
|
||||
}
|
||||
|
||||
# Artwork is a dictionary
|
||||
for art in artwork:
|
||||
|
||||
if art == "Backdrop":
|
||||
# Backdrop entry is a list
|
||||
artList = artwork[art]
|
||||
if artList:
|
||||
self.addOrUpdateArt(artList[0], kodiId, mediaType, kodiart[art], cursor)
|
||||
|
||||
elif art == "Primary":
|
||||
# Primary art is processed as thumb and poster for Kodi.
|
||||
for artType in kodiart[art]:
|
||||
self.addOrUpdateArt(artwork[art], kodiId, mediaType, artType, cursor)
|
||||
|
||||
else:
|
||||
# For banner, logo, art, thumb, disc
|
||||
self.addOrUpdateArt(artwork[art], kodiId, mediaType, kodiart[art], cursor)
|
||||
|
||||
def addOrUpdateArt(self, imageUrl, kodiId, mediaType, imageType, cursor):
|
||||
# Possible that the imageurl is an empty string
|
||||
if imageUrl:
|
||||
cacheimage = False
|
||||
|
||||
cursor.execute("SELECT url FROM art WHERE media_id = ? AND media_type = ? AND type = ?", (kodiId, mediaType, imageType,))
|
||||
try: # Update the artwork
|
||||
url = cursor.fetchone()[0]
|
||||
|
||||
except: # Add the artwork
|
||||
cacheimage = True
|
||||
self.logMsg("Adding Art Link for kodiId: %s (%s)" % (kodiId, imageUrl), 2)
|
||||
query = "INSERT INTO art(media_id, media_type, type, url) values(?, ?, ?, ?)"
|
||||
cursor.execute(query, (kodiId, mediaType, imageType, imageUrl))
|
||||
|
||||
else:
|
||||
if url != imageUrl:
|
||||
cacheimage = True
|
||||
|
||||
# Only for backdrop
|
||||
if imageType == "fanart":
|
||||
# Delete current entry before updating with the new one
|
||||
self.deleteFanart(url)
|
||||
|
||||
self.logMsg("Updating Art Link for kodiId: %s (%s) -> (%s)" % (kodiId, url, imageUrl), 1)
|
||||
query = "UPDATE art set url = ? WHERE media_id = ? AND media_type = ? AND type = ?"
|
||||
cursor.execute(query, (imageUrl, kodiId, mediaType, imageType))
|
||||
|
||||
# Cache fanart and poster in Kodi texture cache
|
||||
if cacheimage and imageType in {"fanart", "poster"}:
|
||||
self.CacheTexture(imageUrl)
|
||||
|
||||
def CacheTexture(self, url):
|
||||
# Cache a single image url to the texture cache
|
||||
if url and self.enableTextureCache:
|
||||
self.logMsg("Processing: %s" % url, 2)
|
||||
|
||||
# add image to texture cache by simply calling it at the http endpoint
|
||||
url = self.double_urlencode(url)
|
||||
try:
|
||||
response = requests.head('http://%s:%s/image/image://%s' % (self.xbmc_host, self.xbmc_port, 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 deleteFanart(self, url):
|
||||
# Only necessary to remove and apply a new backdrop
|
||||
connection = utils.KodiSQL('texture')
|
||||
cursor = connection.cursor()
|
||||
|
||||
cursor.execute("SELECT cachedurl FROM texture WHERE url = ?", (url,))
|
||||
try:
|
||||
cursor.fetchone()[0]
|
||||
except:
|
||||
self.logMsg("Could not find cached url.", 1)
|
||||
else:
|
||||
cursor.execute("DELETE FROM texture WHERE url = ?", (url,))
|
||||
connection.commit()
|
||||
finally:
|
||||
cursor.close()
|
Loading…
Reference in a new issue