From 3bff962cad015440e38c48397a9b6193e5394f8d Mon Sep 17 00:00:00 2001 From: Abby Gourlay Date: Sat, 14 Mar 2020 22:18:05 +0000 Subject: [PATCH] Removed web server for image caching --- jellyfin_kodi/objects/kodi/artwork.py | 134 +------------------------- jellyfin_kodi/setup.py | 47 --------- resources/settings.xml | 1 - 3 files changed, 1 insertion(+), 181 deletions(-) diff --git a/jellyfin_kodi/objects/kodi/artwork.py b/jellyfin_kodi/objects/kodi/artwork.py index b9fc4f93..a1e2bdd3 100644 --- a/jellyfin_kodi/objects/kodi/artwork.py +++ b/jellyfin_kodi/objects/kodi/artwork.py @@ -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. @@ -105,114 +83,4 @@ class Artwork(object): self.update(*(artwork['Primary'],) + args + (kodi_image,)) 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 + self.update(*(artwork[art],) + args + (KODI[art],)) \ No newline at end of file diff --git a/jellyfin_kodi/setup.py b/jellyfin_kodi/setup.py index 3305c485..6381fce1 100644 --- a/jellyfin_kodi/setup.py +++ b/jellyfin_kodi/setup.py @@ -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)) diff --git a/resources/settings.xml b/resources/settings.xml index 661da59b..65a9f3f1 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -28,7 +28,6 @@ -