From b7e734f6d3e2babb828932e0a7d5aeb5f34e9e9a Mon Sep 17 00:00:00 2001 From: Warwick Harris Date: Sat, 11 Sep 2021 12:02:54 +1000 Subject: [PATCH 1/2] DB Working but slow --- main.py | 66 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/main.py b/main.py index 6dcdda5..ed604c9 100644 --- a/main.py +++ b/main.py @@ -20,6 +20,8 @@ from collections import namedtuple sys.path.append(xbmcvfs.translatePath(os.path.join(xbmcaddon.Addon("plugin.audio.subsonic").getAddonInfo("path"), "lib"))) import libsonic +#from lib.dbutils import SQLiteDatabase +import lib.dbutils from simpleplugin import Plugin from simpleplugin import Addon @@ -27,9 +29,14 @@ from simpleplugin import Addon # Create plugin instance plugin = Plugin() +db = None connection = None + cachetime = int(Addon().get_setting('cachetime')) +db_filename = "subsonic_sqlite.db" +db_path = os.path.join(plugin.profile_dir, db_filename) + local_starred = set({}) ListContext = namedtuple('ListContext', ['listing', 'succeeded','update_listing', 'cache_to_disk','sort_methods', 'view_mode','content', 'category']) PlayContext = namedtuple('PlayContext', ['path', 'play_item', 'succeeded']) @@ -748,34 +755,35 @@ def get_entry_playlist(item,params): } def get_artist_info(artist_id, forced=False): - print("Updating artist info for id: %s"%(artist_id)) - popup("Updating artist info\nplease wait") - last_update = 0 + db = get_db() artist_info = {} - cache_file = 'ar-%s'%hashlib.md5(artist_id.encode('utf-8')).hexdigest() - with plugin.get_storage(cache_file) as storage: - try: - last_update = storage['updated'] - except KeyError as e: - plugin.log("Artist keyerror, is this a new cache file? %s"%cache_file) - if(time.time()-last_update>(random.randint(1,111)*360) or forced): - plugin.log("Artist cache expired, updating %s elapsed vs random %s forced %s"%(int(time.time()-last_update),(random.randint(1,111)*3600), forced)) - try: - artist_info = connection.getArtistInfo2(artist_id).get('artistInfo2') - storage['artist_info'] = artist_info - storage['updated']=time.time() - except AttributeError as e: - plugin.log("Attribute error, probably couldn't find any info") - else: - print("Cache ok for %s retrieving"%artist_id) - artist_info = storage['artist_info'] + print("Retreiving artist info for id: %s"%(artist_id)) + popup("Updating artist info\nplease wait") + try: + artist_record = db.get_artist_info(artist_id) + print("Outer %s"%len(artist_record)) + if(len(artist_record)==0): + print("Empty record, getting data for %s"%artist_id) + artist_info = json.dumps(connection.getArtistInfo2(artist_id).get('artistInfo2')) + print("Adding to DB artist info: %s"%artist_info) + if(db.update_artist(artist_id, artist_info, time.time())): + plugin.log("Success") + else: + plugin.log("Failed") + artist_record = db.get_artist_info(artist_id) + artist_info = json.loads(artist_record[0][1]) + last_update = artist_record[0][2] + plugin.log("Artist info: %s"%artist_info) + plugin.log("Last update: %s"%last_update) + except Exception as e: + print("Error get info from DB %s"%e) return artist_info def get_entry_artist(item,params): image = connection.getCoverArtUrl(item.get('coverArt')) - #artist_info = get_artist_info(item.get('id')) - #artist_bio = artist_info.get('biography') - #fanart = artist_info.get('largeImageUrl') + artist_info = get_artist_info(item.get('id')) + artist_bio = artist_info.get('biography') + fanart = artist_info.get('largeImageUrl') fanart = image return { 'label': get_starred_label(item.get('id'),item.get('name')), @@ -795,7 +803,7 @@ def get_entry_artist(item,params): #'title': "testtitle", #'album': "testalbum", #'comment': "testcomment" - #'title': artist_bio + 'title': artist_bio } } } @@ -1512,6 +1520,16 @@ def walk_tracks_starred(): except KeyError: yield from () +def get_db(): + global db_path + #global db + plugin.log("Getting DB %s"%db_path) + if 1:#try: + db = lib.dbutils.SQLiteDatabase(db_path) + #except Exception as e: + # plugin.log("Connecting to DB failed: %s"%e) + return db + # Start plugin from within Kodi. if __name__ == "__main__": # Map actions From d85328ffa09ce397f515d76a04e256e92b60611a Mon Sep 17 00:00:00 2001 From: Warwick Harris Date: Sat, 11 Sep 2021 12:15:22 +1000 Subject: [PATCH 2/2] DB Working but slow --- lib/dbutils/__init__.py | 7 ++++ lib/dbutils/dbutils.py | 80 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 lib/dbutils/__init__.py create mode 100644 lib/dbutils/dbutils.py diff --git a/lib/dbutils/__init__.py b/lib/dbutils/__init__.py new file mode 100644 index 0000000..1171642 --- /dev/null +++ b/lib/dbutils/__init__.py @@ -0,0 +1,7 @@ +""" +Databse utilities for plugin.audio.subsonic +""" + +from .dbutils import * + +__version__ = '0.0.1' diff --git a/lib/dbutils/dbutils.py b/lib/dbutils/dbutils.py new file mode 100644 index 0000000..bb97c38 --- /dev/null +++ b/lib/dbutils/dbutils.py @@ -0,0 +1,80 @@ +import sqlite3 as sql + +tbl_artist_info_ddl = str('CREATE TABLE artist_info (' + 'artist_id TEXT NOT NULL PRIMARY KEY,' + 'artist_info TEXT,' + 'last_update TEXT);') + +class SQLiteDatabase(object): + def __init__(self, db_filename): + print("Init %s"%db_filename) + self.db_filename = db_filename + self.conn = None + + self.connect() + + def connect(self): + try: + #xbmc.log("Trying connection to the database %s"%self.db_filename, xbmc.LOGINFO) + print("Trying connection to the database %s"%self.db_filename) + self.conn = sql.connect(self.db_filename) + cursor = self.conn.cursor() + cursor.execute(str('SELECT SQLITE_VERSION()')) + #xbmc.log("Connection %s was successful %s"%(self.db_filename, cursor.fetchone()[0]), xbmc.LOGINFO) + print("Connection %s was successful %s"%(self.db_filename, cursor.fetchone()[0])) + cursor.row_factory = lambda cursor, row: row[0] + cursor.execute(str('SELECT name FROM sqlite_master WHERE type=\'table\' ''AND name NOT LIKE \'sqlite_%\'')) + list_tables = cursor.fetchall() + if not list_tables: + # If no tables exist create a new one + #xbmc.log("Creating Subsonic local DB", xbmc.LOGINFO) + print("Creating Subsonic local DB") + cursor.execute(tbl_artist_info_ddl) + except sql.Error as e: + #xbmc.log("SQLite error %s"%e.args[0], xbmc.LOGINFO) + print("SQLite error %s"%e.args[0]) + + def get_cursor(self): + return self.conn.cursor() + + def run_query(self, query, params=None, cursor=None): + print("Processing query %s params %s"%(str(query),str(params))) + try: + if cursor is None: + cursor = self.get_cursor() + if params is not None: + cursor.execute(query, params) + else: + cursor.execute(query) + return cursor + except sql.Error as e: + print("SQLite error %s"%e.args[0]) + except ValueError: + print("Error query %s"%str(query)) + print("Error query type %s"%type(query)) + print("Error params %s"%str(params)) + print("Error params type %s"%type(params)) + + def update_artist(self, artist_id, artist_info, update_time): + success = False + query = 'INSERT or REPLACE INTO artist_info VALUES (?, ?, ?)' + params = (str(artist_id), str(artist_info), str(update_time)) + cursor = self.run_query(query, params) + try: + self.conn.commit() + success = True + except Exception as e: + print("Exception %s"%e) + pass + return success + + def get_artist_info(self, artist_id): + query = 'SELECT * FROM artist_info WHERE artist_id = ?' + params = [str(artist_id)] + cursor = self.run_query(query, params) + return cursor.fetchall() + + def close(self): + if self.conn: + self.conn.close() +