Removed web server for image caching

This commit is contained in:
Abby Gourlay 2020-03-14 22:18:05 +00:00
parent 2f9fb660cb
commit 3bff962cad
3 changed files with 1 additions and 181 deletions

View file

@ -28,49 +28,27 @@ class Artwork(object):
def __init__(self, cursor): def __init__(self, cursor):
self.cursor = 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): def update(self, image_url, kodi_id, media, image):
''' Update artwork in the video database. ''' 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. 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'): if not image_url or image == 'poster' and media in ('song', 'artist', 'album'):
return return
cache = False
try: try:
self.cursor.execute(QU.get_art, (kodi_id, media, image,)) self.cursor.execute(QU.get_art, (kodi_id, media, image,))
url = self.cursor.fetchone()[0] url = self.cursor.fetchone()[0]
except TypeError: except TypeError:
cache = True
LOG.debug("ADD to kodi_id %s art: %s", kodi_id, image_url) 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)) self.cursor.execute(QU.add_art, (kodi_id, media, image, image_url))
else: else:
if url != image_url: 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) 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)) 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): def add(self, artwork, *args):
''' Add all artworks. ''' Add all artworks.
@ -106,113 +84,3 @@ class Artwork(object):
elif artwork.get(art): elif artwork.get(art):
self.update(*(artwork[art],) + args + (KODI[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

View file

@ -18,50 +18,10 @@ class Setup(object):
def __init__(self): def __init__(self):
self.set_web_server()
self.setup() self.setup()
LOG.info("---<[ 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): def setup(self):
minimum = "3.0.24" minimum = "3.0.24"
@ -74,8 +34,6 @@ class Setup(object):
self._is_mode() self._is_mode()
LOG.info("Add-on playback: %s", settings('useDirectPaths') == "0") LOG.info("Add-on playback: %s", settings('useDirectPaths') == "0")
self._is_artwork_caching()
LOG.info("Artwork caching: %s", settings('enableTextureCache.bool'))
# Setup completed # Setup completed
settings('MinimumSetup', minimum) settings('MinimumSetup', minimum)
@ -95,11 +53,6 @@ class Setup(object):
if value: if value:
dialog("ok", heading="{jellyfin}", line1=translate(33145)) 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): def _is_music(self):
value = dialog("yesno", heading="{jellyfin}", line1=translate(33039)) value = dialog("yesno", heading="{jellyfin}", line1=translate(33039))

View file

@ -28,7 +28,6 @@
<setting label="30515" id="limitIndex" type="slider" default="15" range="1, 1, 100" option="int" /> <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="33174" id="limitThreads" type="slider" default="3" range="1, 1, 50" option="int" />
<setting label="33176" type="lsep" /> <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="30157" id="enableCoverArt" type="bool" default="true" />
<setting label="33116" id="compressArt" type="bool" default="false" /> <setting label="33116" id="compressArt" type="bool" default="false" />
<setting id="enableMusic" visible="false" default="false" /> <setting id="enableMusic" visible="false" default="false" />