mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-12-24 17:56:11 +00:00
Removed web server for image caching
This commit is contained in:
parent
2f9fb660cb
commit
3bff962cad
3 changed files with 1 additions and 181 deletions
|
@ -28,49 +28,27 @@ class Artwork(object):
|
|||
def __init__(self, cursor):
|
||||
|
||||
self.cursor = cursor
|
||||
self.enable_cache = settings('enableTextureCache.bool')
|
||||
self.queue = Queue.Queue()
|
||||
self.threads = []
|
||||
self.kodi = {
|
||||
'username': settings('webServerUser'),
|
||||
'password': settings('webServerPass'),
|
||||
'host': "localhost",
|
||||
'port': settings('webServerPort')
|
||||
}
|
||||
|
||||
def update(self, image_url, kodi_id, media, image):
|
||||
|
||||
''' Update artwork in the video database.
|
||||
Only cache artwork if it changed for the main backdrop, poster.
|
||||
Delete current entry before updating with the new one.
|
||||
Cache fanart and poster in Kodi texture cache.
|
||||
'''
|
||||
if not image_url or image == 'poster' and media in ('song', 'artist', 'album'):
|
||||
return
|
||||
|
||||
cache = False
|
||||
|
||||
try:
|
||||
self.cursor.execute(QU.get_art, (kodi_id, media, image,))
|
||||
url = self.cursor.fetchone()[0]
|
||||
except TypeError:
|
||||
|
||||
cache = True
|
||||
LOG.debug("ADD to kodi_id %s art: %s", kodi_id, image_url)
|
||||
self.cursor.execute(QU.add_art, (kodi_id, media, image, image_url))
|
||||
else:
|
||||
if url != image_url:
|
||||
cache = True
|
||||
|
||||
if image in ('fanart', 'poster'):
|
||||
self.delete_cache(url)
|
||||
|
||||
LOG.info("UPDATE to kodi_id %s art: %s", kodi_id, image_url)
|
||||
self.cursor.execute(QU.update_art, (image_url, kodi_id, media, image))
|
||||
|
||||
if cache and image in ('fanart', 'poster'):
|
||||
self.cache(image_url)
|
||||
|
||||
def add(self, artwork, *args):
|
||||
|
||||
''' Add all artworks.
|
||||
|
@ -106,113 +84,3 @@ class Artwork(object):
|
|||
|
||||
elif artwork.get(art):
|
||||
self.update(*(artwork[art],) + args + (KODI[art],))
|
||||
|
||||
def delete(self, *args):
|
||||
|
||||
''' Delete artwork from kodi database and remove cache for backdrop/posters.
|
||||
'''
|
||||
self.cursor.execute(QU.get_art_url, args)
|
||||
|
||||
for row in self.cursor.fetchall():
|
||||
if row[1] in ('poster', 'fanart'):
|
||||
self.delete_cache(row[0])
|
||||
|
||||
def cache(self, url):
|
||||
|
||||
''' Cache a single image to texture cache.
|
||||
'''
|
||||
if not url or not self.enable_cache:
|
||||
return
|
||||
|
||||
url = self.double_urlencode(url)
|
||||
self.queue.put(url)
|
||||
self.add_worker()
|
||||
|
||||
def double_urlencode(self, text):
|
||||
|
||||
text = self.single_urlencode(text)
|
||||
text = self.single_urlencode(text)
|
||||
|
||||
return text
|
||||
|
||||
def single_urlencode(self, text):
|
||||
|
||||
''' urlencode needs a utf-string.
|
||||
return the result as unicode
|
||||
'''
|
||||
text = urlencode({'blahblahblah': text})
|
||||
text = text[13:]
|
||||
|
||||
return text
|
||||
|
||||
def add_worker(self):
|
||||
|
||||
self.threads = [thread for thread in self.threads if not thread.is_done]
|
||||
|
||||
if self.queue.qsize() and len(self.threads) < 2:
|
||||
|
||||
new_thread = GetArtworkWorker(self.kodi, self.queue)
|
||||
new_thread.start()
|
||||
LOG.info("-->[ q:artwork/%s ]", id(new_thread))
|
||||
self.threads.append(new_thread)
|
||||
|
||||
def delete_cache(self, url):
|
||||
|
||||
''' Delete cached artwork.
|
||||
'''
|
||||
from database import Database
|
||||
|
||||
with Database('texture') as texturedb:
|
||||
try:
|
||||
texturedb.cursor.execute(QUTEX.get_cache, (url,))
|
||||
cached = texturedb.cursor.fetchone()[0]
|
||||
except TypeError:
|
||||
LOG.debug("Could not find cached url: %s", url)
|
||||
else:
|
||||
thumbnails = xbmc.translatePath("special://thumbnails/%s" % cached)
|
||||
xbmcvfs.delete(thumbnails)
|
||||
texturedb.cursor.execute(QUTEX.delete_cache, (url,))
|
||||
LOG.info("DELETE cached %s", cached)
|
||||
|
||||
|
||||
class GetArtworkWorker(threading.Thread):
|
||||
|
||||
is_done = False
|
||||
|
||||
def __init__(self, kodi, queue):
|
||||
|
||||
self.kodi = kodi
|
||||
self.queue = queue
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
def run(self):
|
||||
|
||||
''' Prepare the request. Request removes the urlencode which is required in this case.
|
||||
Use a session allows to use a pool of connections.
|
||||
'''
|
||||
with requests.Session() as s:
|
||||
while True:
|
||||
try:
|
||||
url = self.queue.get(timeout=2)
|
||||
except Queue.Empty:
|
||||
|
||||
self.is_done = True
|
||||
LOG.info("--<[ q:artwork/%s ]", id(self))
|
||||
|
||||
return
|
||||
|
||||
try:
|
||||
req = requests.Request(method='HEAD',
|
||||
url="http://%s:%s/image/image://%s" % (self.kodi['host'], self.kodi['port'], url),
|
||||
auth=(self.kodi['username'], self.kodi['password']))
|
||||
prep = req.prepare()
|
||||
prep.url = "http://%s:%s/image/image://%s" % (self.kodi['host'], self.kodi['port'], url)
|
||||
s.send(prep, timeout=(0.01, 0.01))
|
||||
s.content # release the connection
|
||||
except Exception as error:
|
||||
LOG.exception(error)
|
||||
|
||||
self.queue.task_done()
|
||||
|
||||
if xbmc.Monitor().abortRequested():
|
||||
break
|
||||
|
|
|
@ -18,50 +18,10 @@ class Setup(object):
|
|||
|
||||
def __init__(self):
|
||||
|
||||
self.set_web_server()
|
||||
self.setup()
|
||||
|
||||
LOG.info("---<[ setup ]")
|
||||
|
||||
def set_web_server(self):
|
||||
|
||||
''' Enable the webserver if not enabled. This is used to cache artwork.
|
||||
Will only test once, if it fails, user will be notified only once.
|
||||
'''
|
||||
if settings('enableTextureCache.bool'):
|
||||
|
||||
get_setting = JSONRPC('Settings.GetSettingValue')
|
||||
|
||||
if not self.get_web_server():
|
||||
|
||||
set_setting = JSONRPC('Settings.SetSetingValue')
|
||||
set_setting.execute({'setting': "services.webserverport", 'value': 8080})
|
||||
set_setting.execute({'setting': "services.webserver", 'value': True})
|
||||
|
||||
if not self.get_web_server():
|
||||
|
||||
settings('enableTextureCache.bool', False)
|
||||
dialog("ok", heading="{jellyfin}", line1=translate(33103))
|
||||
|
||||
return
|
||||
|
||||
result = get_setting.execute({'setting': "services.webserverport"})
|
||||
settings('webServerPort', str(result['result']['value'] or ""))
|
||||
result = get_setting.execute({'setting': "services.webserverusername"})
|
||||
settings('webServerUser', str(result['result']['value'] or ""))
|
||||
result = get_setting.execute({'setting': "services.webserverpassword"})
|
||||
settings('webServerPass', str(result['result']['value'] or ""))
|
||||
settings('useWebServer.bool', True)
|
||||
|
||||
def get_web_server(self):
|
||||
|
||||
result = JSONRPC('Settings.GetSettingValue').execute({'setting': "services.webserver"})
|
||||
|
||||
try:
|
||||
return result['result']['value']
|
||||
except (KeyError, TypeError):
|
||||
return False
|
||||
|
||||
def setup(self):
|
||||
|
||||
minimum = "3.0.24"
|
||||
|
@ -74,8 +34,6 @@ class Setup(object):
|
|||
|
||||
self._is_mode()
|
||||
LOG.info("Add-on playback: %s", settings('useDirectPaths') == "0")
|
||||
self._is_artwork_caching()
|
||||
LOG.info("Artwork caching: %s", settings('enableTextureCache.bool'))
|
||||
|
||||
# Setup completed
|
||||
settings('MinimumSetup', minimum)
|
||||
|
@ -95,11 +53,6 @@ class Setup(object):
|
|||
if value:
|
||||
dialog("ok", heading="{jellyfin}", line1=translate(33145))
|
||||
|
||||
def _is_artwork_caching(self):
|
||||
|
||||
value = dialog("yesno", heading="{jellyfin}", line1=translate(33117))
|
||||
settings('enableTextureCache.bool', value)
|
||||
|
||||
def _is_music(self):
|
||||
|
||||
value = dialog("yesno", heading="{jellyfin}", line1=translate(33039))
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
<setting label="30515" id="limitIndex" type="slider" default="15" range="1, 1, 100" option="int" />
|
||||
<setting label="33174" id="limitThreads" type="slider" default="3" range="1, 1, 50" option="int" />
|
||||
<setting label="33176" type="lsep" />
|
||||
<setting label="30512" id="enableTextureCache" type="bool" default="true" />
|
||||
<setting label="30157" id="enableCoverArt" type="bool" default="true" />
|
||||
<setting label="33116" id="compressArt" type="bool" default="false" />
|
||||
<setting id="enableMusic" visible="false" default="false" />
|
||||
|
|
Loading…
Reference in a new issue