Fix KodiVideoDB object has no attribute kodiconn

- Partially fixes #593
- Fixes #614
This commit is contained in:
croneter 2019-01-23 10:00:49 +01:00
parent d6246a1cab
commit 5de91ff9b5
6 changed files with 41 additions and 26 deletions

View file

@ -42,7 +42,9 @@ class ImageCachingThread(backgroundthread.KillableThread):
while True: while True:
batch = [] batch = []
with kind(texture_db=True) as kodidb: with kind(texture_db=True) as kodidb:
texture_db = KodiTextureDB(cursor=kodidb.artcursor) texture_db = KodiTextureDB(kodiconn=kodidb.kodiconn,
artconn=kodidb.artconn,
lock=False)
for i, url in enumerate(kodidb.artwork_generator(kodi_type, for i, url in enumerate(kodidb.artwork_generator(kodi_type,
BATCH_SIZE, BATCH_SIZE,
offset)): offset)):

View file

@ -41,14 +41,14 @@ class ItemBase(object):
def __init__(self, last_sync, plexdb=None, kodidb=None, lock=True): def __init__(self, last_sync, plexdb=None, kodidb=None, lock=True):
self.last_sync = last_sync self.last_sync = last_sync
self.lock = lock self.lock = lock
self.plexconn = None self.plexdb = plexdb
self.kodidb = kodidb
self.plexconn = plexdb.plexconn if plexdb else None
self.plexcursor = plexdb.cursor if plexdb else None self.plexcursor = plexdb.cursor if plexdb else None
self.kodiconn = None self.kodiconn = kodidb.kodiconn if kodidb else None
self.kodicursor = kodidb.cursor if kodidb else None self.kodicursor = kodidb.cursor if kodidb else None
self.artconn = kodidb.artconn if kodidb else None self.artconn = kodidb.artconn if kodidb else None
self.artcursor = kodidb.artcursor if kodidb else None self.artcursor = kodidb.artcursor if kodidb else None
self.plexdb = plexdb
self.kodidb = kodidb
def __enter__(self): def __enter__(self):
""" """
@ -67,10 +67,11 @@ class ItemBase(object):
else: else:
self.artconn = None self.artconn = None
self.artcursor = None self.artcursor = None
self.plexdb = PlexDB(cursor=self.plexcursor) self.plexdb = PlexDB(plexconn=self.plexconn, lock=False)
self.kodidb = KodiVideoDB(texture_db=True, self.kodidb = KodiVideoDB(texture_db=app.SYNC.artwork,
cursor=self.kodicursor, kodiconn=self.kodiconn,
artcursor=self.artcursor) artconn=self.artconn,
lock=False)
return self return self
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, exc_type, exc_val, exc_tb):

View file

@ -27,10 +27,14 @@ class MusicMixin(object):
if app.SYNC.artwork: if app.SYNC.artwork:
self.artconn = utils.kodi_sql('texture') self.artconn = utils.kodi_sql('texture')
self.artcursor = self.artconn.cursor() self.artcursor = self.artconn.cursor()
self.plexdb = PlexDB(self.plexcursor) else:
self.kodidb = KodiMusicDB(texture_db=True, self.artconn = None
cursor=self.kodicursor, self.artcursor = None
artcursor=self.artcursor) self.plexdb = PlexDB(plexconn=self.plexconn, lock=False)
self.kodidb = KodiMusicDB(texture_db=app.SYNC.artwork,
kodiconn=self.kodiconn,
artconn=self.artconn,
lock=False)
return self return self
def update_userdata(self, xml_element, plex_type): def update_userdata(self, xml_element, plex_type):

View file

@ -10,6 +10,13 @@ KODIDB_LOCK = Lock()
DB_WRITE_ATTEMPTS = 100 DB_WRITE_ATTEMPTS = 100
class LockedKodiDatabase(Exception):
"""
Dedicated class to make sure we're not silently catching locked DBs.
"""
pass
def catch_operationalerrors(method): def catch_operationalerrors(method):
""" """
sqlite.OperationalError is raised immediately if another DB connection sqlite.OperationalError is raised immediately if another DB connection
@ -32,7 +39,7 @@ def catch_operationalerrors(method):
attempts -= 1 attempts -= 1
if attempts == 0: if attempts == 0:
# Reraise in order to NOT catch nested OperationalErrors # Reraise in order to NOT catch nested OperationalErrors
raise RuntimeError('Kodi database locked') raise LockedKodiDatabase('Kodi database locked')
# Need to close the transactions and begin new ones # Need to close the transactions and begin new ones
self.kodiconn.commit() self.kodiconn.commit()
if self.artconn: if self.artconn:
@ -51,24 +58,24 @@ class KodiDBBase(object):
""" """
Kodi database methods used for all types of items Kodi database methods used for all types of items
""" """
def __init__(self, texture_db=False, cursor=None, artcursor=None, lock=True): def __init__(self, texture_db=False, kodiconn=None, artconn=None, lock=True):
""" """
Allows direct use with a cursor instead of context mgr Allows direct use with a cursor instead of context mgr
""" """
self._texture_db = texture_db self._texture_db = texture_db
self.cursor = cursor
self.artconn = None
self.artcursor = artcursor
self.lock = lock self.lock = lock
self.kodiconn = kodiconn
self.cursor = self.kodiconn.cursor() if self.kodiconn else None
self.artconn = artconn
self.artcursor = self.artconn.cursor() if self.artconn else None
def __enter__(self): def __enter__(self):
if self.lock: if self.lock:
KODIDB_LOCK.acquire() KODIDB_LOCK.acquire()
self.kodiconn = utils.kodi_sql(self.db_kind) self.kodiconn = utils.kodi_sql(self.db_kind)
self.cursor = self.kodiconn.cursor() self.cursor = self.kodiconn.cursor()
if self._texture_db: self.artconn = utils.kodi_sql('texture') if self._texture_db else None
self.artconn = utils.kodi_sql('texture') self.artcursor = self.artconn.cursor() if self._texture_db else None
self.artcursor = self.artconn.cursor()
return self return self
def __exit__(self, e_typ, e_val, trcbak): def __exit__(self, e_typ, e_val, trcbak):

View file

@ -12,6 +12,6 @@ class KodiTextureDB(common.KodiDBBase):
""" """
Returns True if url has not yet been cached to the Kodi texture cache Returns True if url has not yet been cached to the Kodi texture cache
""" """
self.cursor.execute('SELECT url FROM texture WHERE url = ? LIMIT 1', self.artcursor.execute('SELECT url FROM texture WHERE url = ? LIMIT 1',
(url, )) (url, ))
return self.cursor.fetchone() is None return self.artcursor.fetchone() is None

View file

@ -22,9 +22,10 @@ class PlexDBBase(object):
""" """
Plex database methods used for all types of items Plex database methods used for all types of items
""" """
def __init__(self, cursor=None, lock=True): def __init__(self, plexconn=None, lock=True):
# Allows us to use this class with a cursor instead of context mgr # Allows us to use this class with a cursor instead of context mgr
self.cursor = cursor self.plexconn = plexconn
self.cursor = self.plexconn.cursor() if self.plexconn else None
self.lock = lock self.lock = lock
def __enter__(self): def __enter__(self):