mirror of
https://github.com/gordielachance/plugin.audio.subsonic
synced 2025-02-18 04:30:59 +01:00
DB functions working - slow to load
This commit is contained in:
parent
f97b9e1de9
commit
54a071a9c7
66
dbtest.py
Normal file
66
dbtest.py
Normal 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
0
dbutils.py
Normal file
7
lib/dbutils/__init__.py
Normal file
7
lib/dbutils/__init__.py
Normal 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
80
lib/dbutils/dbutils.py
Normal 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()
|
||||||
|
|
@ -228,11 +228,13 @@ class Connection(object):
|
|||||||
"""
|
"""
|
||||||
methodName = 'ping'
|
methodName = 'ping'
|
||||||
viewName = '%s.view' % methodName
|
viewName = '%s.view' % methodName
|
||||||
|
print("test")
|
||||||
req = self._getRequest(viewName)
|
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:
|
try:
|
||||||
res = self._doInfoReq(req)
|
res = self._doInfoReq(req)
|
||||||
|
print(res)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Ping failed %s"%e)
|
print("Ping failed %s"%e)
|
||||||
return False
|
return False
|
||||||
@ -896,11 +898,11 @@ class Connection(object):
|
|||||||
'converted': converted})
|
'converted': converted})
|
||||||
|
|
||||||
req = self._getRequest(viewName, q)
|
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
|
return_url = req.full_url
|
||||||
if self._insecure:
|
if self._insecure:
|
||||||
return_url += '|verifypeer=false'
|
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
|
return return_url
|
||||||
|
|
||||||
|
|
||||||
@ -945,11 +947,11 @@ class Connection(object):
|
|||||||
q = self._getQueryDict({'id': aid, 'size': size})
|
q = self._getQueryDict({'id': aid, 'size': size})
|
||||||
|
|
||||||
req = self._getRequest(viewName, q)
|
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
|
return_url = req.full_url
|
||||||
if self._insecure:
|
if self._insecure:
|
||||||
return_url += '|verifypeer=false'
|
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
|
return return_url
|
||||||
|
|
||||||
|
|
||||||
@ -1997,7 +1999,7 @@ class Connection(object):
|
|||||||
q['musicFolderId'] = musicFolderId
|
q['musicFolderId'] = musicFolderId
|
||||||
|
|
||||||
req = self._getRequest(viewName, q)
|
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)
|
res = self._doInfoReq(req)
|
||||||
self._checkStatus(res)
|
self._checkStatus(res)
|
||||||
return res
|
return res
|
||||||
@ -2809,12 +2811,13 @@ class Connection(object):
|
|||||||
qdict.update(query)
|
qdict.update(query)
|
||||||
url = '%s:%d/%s/%s' % (self._baseUrl, self._port, self._serverPath,
|
url = '%s:%d/%s/%s' % (self._baseUrl, self._port, self._serverPath,
|
||||||
viewName)
|
viewName)
|
||||||
#xbmc.log("Standard URL %s"%url,level=xbmc.LOGDEBUG)
|
#xbmc.log("Standard URL %s"%url,level=#xbmc.logDEBUG)
|
||||||
#xbmc.log("Qdict %s"%str(qdict),level=xbmc.LOGDEBUG)
|
#xbmc.log("Qdict %s"%str(qdict),level=#xbmc.logDEBUG)
|
||||||
req = urllib.request.Request(url, urlencode(qdict).encode('utf-8'))
|
req = urllib.request.Request(url, urlencode(qdict).encode('utf-8'))
|
||||||
if(self._useGET or ('getCoverArt' in viewName) or ('stream' in viewName)):
|
if(self._useGET or ('getCoverArt' in viewName) or ('stream' in viewName)):
|
||||||
url += '?%s' % urlencode(qdict)
|
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)
|
req = urllib.request.Request(url)
|
||||||
return req
|
return req
|
||||||
|
|
||||||
|
66
main.py
66
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")))
|
sys.path.append(xbmcvfs.translatePath(os.path.join(xbmcaddon.Addon("plugin.audio.subsonic").getAddonInfo("path"), "lib")))
|
||||||
|
|
||||||
import libsonic
|
import libsonic
|
||||||
|
#from lib.dbutils import SQLiteDatabase
|
||||||
|
import lib.dbutils
|
||||||
|
|
||||||
from simpleplugin import Plugin
|
from simpleplugin import Plugin
|
||||||
from simpleplugin import Addon
|
from simpleplugin import Addon
|
||||||
@ -27,9 +29,14 @@ from simpleplugin import Addon
|
|||||||
# Create plugin instance
|
# Create plugin instance
|
||||||
plugin = Plugin()
|
plugin = Plugin()
|
||||||
|
|
||||||
|
db = None
|
||||||
connection = None
|
connection = None
|
||||||
|
|
||||||
cachetime = int(Addon().get_setting('cachetime'))
|
cachetime = int(Addon().get_setting('cachetime'))
|
||||||
|
|
||||||
|
db_filename = "subsonic_sqlite.db"
|
||||||
|
db_path = os.path.join(plugin.profile_dir, db_filename)
|
||||||
|
|
||||||
local_starred = set({})
|
local_starred = set({})
|
||||||
ListContext = namedtuple('ListContext', ['listing', 'succeeded','update_listing', 'cache_to_disk','sort_methods', 'view_mode','content', 'category'])
|
ListContext = namedtuple('ListContext', ['listing', 'succeeded','update_listing', 'cache_to_disk','sort_methods', 'view_mode','content', 'category'])
|
||||||
PlayContext = namedtuple('PlayContext', ['path', 'play_item', 'succeeded'])
|
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):
|
def get_artist_info(artist_id, forced=False):
|
||||||
print("Updating artist info for id: %s"%(artist_id))
|
db = get_db()
|
||||||
popup("Updating artist info\nplease wait")
|
|
||||||
last_update = 0
|
|
||||||
artist_info = {}
|
artist_info = {}
|
||||||
cache_file = 'ar-%s'%hashlib.md5(artist_id.encode('utf-8')).hexdigest()
|
print("Retreiving artist info for id: %s"%(artist_id))
|
||||||
with plugin.get_storage(cache_file) as storage:
|
popup("Updating artist info\nplease wait")
|
||||||
try:
|
try:
|
||||||
last_update = storage['updated']
|
artist_record = db.get_artist_info(artist_id)
|
||||||
except KeyError as e:
|
print("Outer %s"%len(artist_record))
|
||||||
plugin.log("Artist keyerror, is this a new cache file? %s"%cache_file)
|
if(len(artist_record)==0):
|
||||||
if(time.time()-last_update>(random.randint(1,111)*360) or forced):
|
print("Empty record, getting data for %s"%artist_id)
|
||||||
plugin.log("Artist cache expired, updating %s elapsed vs random %s forced %s"%(int(time.time()-last_update),(random.randint(1,111)*3600), forced))
|
artist_info = json.dumps(connection.getArtistInfo2(artist_id).get('artistInfo2'))
|
||||||
try:
|
print("Adding to DB artist info: %s"%artist_info)
|
||||||
artist_info = connection.getArtistInfo2(artist_id).get('artistInfo2')
|
if(db.update_artist(artist_id, artist_info, time.time())):
|
||||||
storage['artist_info'] = artist_info
|
plugin.log("Success")
|
||||||
storage['updated']=time.time()
|
else:
|
||||||
except AttributeError as e:
|
plugin.log("Failed")
|
||||||
plugin.log("Attribute error, probably couldn't find any info")
|
artist_record = db.get_artist_info(artist_id)
|
||||||
else:
|
artist_info = json.loads(artist_record[0][1])
|
||||||
print("Cache ok for %s retrieving"%artist_id)
|
last_update = artist_record[0][2]
|
||||||
artist_info = storage['artist_info']
|
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
|
return artist_info
|
||||||
|
|
||||||
def get_entry_artist(item,params):
|
def get_entry_artist(item,params):
|
||||||
image = connection.getCoverArtUrl(item.get('coverArt'))
|
image = connection.getCoverArtUrl(item.get('coverArt'))
|
||||||
#artist_info = get_artist_info(item.get('id'))
|
artist_info = get_artist_info(item.get('id'))
|
||||||
#artist_bio = artist_info.get('biography')
|
artist_bio = artist_info.get('biography')
|
||||||
#fanart = artist_info.get('largeImageUrl')
|
fanart = artist_info.get('largeImageUrl')
|
||||||
fanart = image
|
fanart = image
|
||||||
return {
|
return {
|
||||||
'label': get_starred_label(item.get('id'),item.get('name')),
|
'label': get_starred_label(item.get('id'),item.get('name')),
|
||||||
@ -795,7 +803,7 @@ def get_entry_artist(item,params):
|
|||||||
#'title': "testtitle",
|
#'title': "testtitle",
|
||||||
#'album': "testalbum",
|
#'album': "testalbum",
|
||||||
#'comment': "testcomment"
|
#'comment': "testcomment"
|
||||||
#'title': artist_bio
|
'title': artist_bio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1512,6 +1520,16 @@ def walk_tracks_starred():
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
yield from ()
|
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.
|
# Start plugin from within Kodi.
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Map actions
|
# Map actions
|
||||||
|
Loading…
x
Reference in New Issue
Block a user