DB functions working - slow to load

This commit is contained in:
warwickh 2021-09-11 10:55:43 +10:00
parent f97b9e1de9
commit 54a071a9c7
6 changed files with 208 additions and 34 deletions

66
dbtest.py Normal file
View File

@ -0,0 +1,66 @@
import sys
sys.path.insert(0,'lib')
import dbutils
import libsonic
import time
db = None
connection = None
db_filename = "subsonic_sqlite.db"
def get_db():
global db_filename
global db
print("Getting DB %s"%db_filename)
try:
db = dbutils.SQLiteDatabase(db_filename)
except Exception as e:
print("Connecting to DB failed: %s"%e)
return db
def get_connection():
global connection
if connection==None:
connected = False
# Create connection
try:
connection = libsonic.Connection(
baseUrl="http://192.168.25.16",
username="warwick.harris",
password="ducatiMonsterSoundsGreat$",
port="4040",
apiVersion="1.15.1",
insecure=False,
legacyAuth=False,
useGET=False,
)
connected = connection.ping()
except:
pass
if connected==False:
print('Connection error')
return False
return connection
db = get_db()
connection = get_connection()
#cursor = db.get_cursor()
#cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
#print(cursor.fetchall())
artist_id = 635
artist_info = connection.getArtistInfo2(artist_id)
#print("Artist info: %s"%artist_info)
print(db.update_artist(artist_id, artist_info, time.time()))
print(db.get_artist_info(artist_id))
print(db.update_artist(artist_id, "replace", time.time()))
print(db.get_artist_info(1))
db.close()

0
dbutils.py Normal file
View File

7
lib/dbutils/__init__.py Normal file
View File

@ -0,0 +1,7 @@
"""
Databse utilities for plugin.audio.subsonic
"""
from .dbutils import *
__version__ = '0.0.1'

80
lib/dbutils/dbutils.py Normal file
View File

@ -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()

View File

@ -228,11 +228,13 @@ class Connection(object):
"""
methodName = 'ping'
viewName = '%s.view' % methodName
print("test")
req = self._getRequest(viewName)
xbmc.log("Pinging %s"%str(req.full_url),xbmc.LOGDEBUG)
print("Pinging %s"%str(req.full_url))#,#xbmc.logDEBUG)
#xbmc.log("Pinging %s"%str(req.full_url),#xbmc.logDEBUG)
try:
res = self._doInfoReq(req)
print(res)
except Exception as e:
print("Ping failed %s"%e)
return False
@ -896,11 +898,11 @@ class Connection(object):
'converted': converted})
req = self._getRequest(viewName, q)
#xbmc.log("Requesting %s"%str(req.full_url),xbmc.LOGDEBUG)
##xbmc.log("Requesting %s"%str(req.full_url),#xbmc.logDEBUG)
return_url = req.full_url
if self._insecure:
return_url += '|verifypeer=false'
xbmc.log("Request is insecure %s"%return_url,level=xbmc.LOGDEBUG)
#xbmc.log("Request is insecure %s"%return_url,level=#xbmc.logDEBUG)
return return_url
@ -945,11 +947,11 @@ class Connection(object):
q = self._getQueryDict({'id': aid, 'size': size})
req = self._getRequest(viewName, q)
#xbmc.log("Requesting %s"%str(req.full_url),xbmc.LOGDEBUG)
##xbmc.log("Requesting %s"%str(req.full_url),#xbmc.logDEBUG)
return_url = req.full_url
if self._insecure:
return_url += '|verifypeer=false'
xbmc.log("Request is insecure %s"%return_url,level=xbmc.LOGDEBUG)
#xbmc.log("Request is insecure %s"%return_url,level=#xbmc.logDEBUG)
return return_url
@ -1997,7 +1999,7 @@ class Connection(object):
q['musicFolderId'] = musicFolderId
req = self._getRequest(viewName, q)
xbmc.log("Requesting %s"%str(req.full_url),xbmc.LOGDEBUG)
#xbmc.log("Requesting %s"%str(req.full_url),#xbmc.logDEBUG)
res = self._doInfoReq(req)
self._checkStatus(res)
return res
@ -2809,12 +2811,13 @@ class Connection(object):
qdict.update(query)
url = '%s:%d/%s/%s' % (self._baseUrl, self._port, self._serverPath,
viewName)
#xbmc.log("Standard URL %s"%url,level=xbmc.LOGDEBUG)
#xbmc.log("Qdict %s"%str(qdict),level=xbmc.LOGDEBUG)
#xbmc.log("Standard URL %s"%url,level=#xbmc.logDEBUG)
#xbmc.log("Qdict %s"%str(qdict),level=#xbmc.logDEBUG)
req = urllib.request.Request(url, urlencode(qdict).encode('utf-8'))
if(self._useGET or ('getCoverArt' in viewName) or ('stream' in viewName)):
url += '?%s' % urlencode(qdict)
#xbmc.log("UseGET URL %s"%(url),xbmc.LOGDEBUG)
#xbmc.log("UseGET URL %s"%(url), xbmc.logDEBUG)
print(url)
req = urllib.request.Request(url)
return req

66
main.py
View File

@ -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