diff --git a/dbutils.py b/dbutils.py deleted file mode 100644 index e69de29..0000000 diff --git a/lib/dbutils/dbutils.py b/lib/dbutils/dbutils.py index 8e4b9c0..b1e6811 100644 --- a/lib/dbutils/dbutils.py +++ b/lib/dbutils/dbutils.py @@ -46,7 +46,7 @@ class SQLiteDatabase(object): return self.conn.cursor() def run_query(self, query, params=None, cursor=None): - print("Processing query %s params %s"%(str(query),str(params))) + #print("Processing query %s params %s"%(str(query),str(params))) try: if cursor is None: cursor = self.get_cursor() @@ -54,7 +54,7 @@ class SQLiteDatabase(object): cursor.execute(query, params) else: cursor.execute(query) - print("%s rows affected"%cursor.rowcount) + #print("%s rows affected"%cursor.rowcount) return cursor except sql.Error as e: print("SQLite error %s"%e.args[0]) @@ -71,7 +71,7 @@ class SQLiteDatabase(object): return record_age except Exception as e: print("get_record_age failed %s" % e) - return + return 0 def get_artist_info(self, artist_id): query = 'SELECT * FROM artist_info WHERE artist_id = ?'# %str(artist_id) diff --git a/main.py b/main.py index 8eb4339..bb8ecc2 100644 --- a/main.py +++ b/main.py @@ -19,9 +19,8 @@ from collections import namedtuple # Add the /lib folder to sys sys.path.append(xbmcvfs.translatePath(os.path.join(xbmcaddon.Addon("plugin.audio.subsonic").getAddonInfo("path"), "lib"))) +import dbutils import libsonic -#from lib.dbutils import SQLiteDatabase -import lib.dbutils from simpleplugin import Plugin from simpleplugin import Addon @@ -29,13 +28,13 @@ from simpleplugin import Addon # Create plugin instance plugin = Plugin() -db = None connection = None +db = 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']) @@ -1524,13 +1523,14 @@ def walk_tracks_starred(): yield from () def get_db(): - global db_path - #global db + global db + global db_filename + db_path = os.path.join(plugin.profile_dir, db_filename) 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) + try: + db = dbutils.SQLiteDatabase(db_path) + except Exception as e: + plugin.log("Connecting to DB failed: %s"%e) return db # Start plugin from within Kodi. diff --git a/resources/language/English/strings.po b/resources/language/English/strings.po index cf0e1e6..6dc9167 100644 --- a/resources/language/English/strings.po +++ b/resources/language/English/strings.po @@ -176,3 +176,7 @@ msgstr "" msgctxt "#30044" msgid "Scrobble to Last.FM" msgstr "" + +msgctxt "#30045" +msgid "Enhanced Information" +msgstr "" diff --git a/resources/language/French/strings.po b/resources/language/French/strings.po index 88f7515..0951a0b 100644 --- a/resources/language/French/strings.po +++ b/resources/language/French/strings.po @@ -176,3 +176,7 @@ msgstr "" msgctxt "#30044" msgid "Scrobble to Last.FM" msgstr "" + +msgctxt "#30045" +msgid "Enhanced Information" +msgstr "" diff --git a/resources/language/German/strings.po b/resources/language/German/strings.po index 46ba647..630230f 100644 --- a/resources/language/German/strings.po +++ b/resources/language/German/strings.po @@ -175,3 +175,7 @@ msgstr "" msgctxt "#30044" msgid "Scrobble to Last.FM" msgstr "" + +msgctxt "#30045" +msgid "Enhanced Information" +msgstr "" diff --git a/resources/settings.xml b/resources/settings.xml index 0f09285..f33e052 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -28,6 +28,7 @@ + diff --git a/service.py b/service.py index 50ac438..69e9dd1 100644 --- a/service.py +++ b/service.py @@ -3,17 +3,34 @@ import xbmc import xbmcvfs import os import xbmcaddon +import time +import random + # Add the /lib folder to sys sys.path.append(xbmcvfs.translatePath(os.path.join(xbmcaddon.Addon("plugin.audio.subsonic").getAddonInfo("path"), "lib"))) +import dbutils import libsonic +import musicbrainz + +connection = None +db = None +mb = None + +db_filename = "subsonic_sqlite.db" + +last_db_check = 0 from simpleplugin import Plugin from simpleplugin import Addon # Create plugin instance plugin = Plugin() -connection = None + +try: + enhancedInfo = Addon().get_setting('enhanced_info') +except: + enhancedInfo = False try: scrobbleEnabled = Addon().get_setting('scrobble') @@ -54,6 +71,118 @@ def get_connection(): return connection +def get_mb(): + global mb + mb = musicbrainz.MBConnection() + return mb + +def get_db(): + global db + global db_filename + db_path = os.path.join(plugin.profile_dir, db_filename) + print("Getting DB %s"%db_path) + try: + db = dbutils.SQLiteDatabase(db_path) + except Exception as e: + print("Connecting to DB failed: %s"%e) + return db + +def check_artist_info(): + db = get_db() + connection = get_connection() + response = connection.getArtists() + for index in response["artists"]["index"]: + for artist in index["artist"]: + artist_id = artist['id'] + artist_name = db.get_value(artist_id, 'artist_name') + artist_info = db.get_value(artist_id, 'artist_info') + artist_wiki = db.get_value(artist_id, 'wikipedia_extract') + print("Name %s"%(artist_name)) + print("LastFM %s"%(artist_info)) + print("Wiki %s"%(artist_wiki)) + +def refresh_artist(artist_id): + db = get_db() + mb = get_mb() + connection = get_connection() + artist = connection.getArtist(artist_id)#['subsonic-response'] + artist_name = artist['artist']['name'] + artist_info = connection.getArtistInfo2(artist_id) + try: + artist_info = artist_info['artistInfo2']['biography'] + #pattern = 'Read more on Last.fm + artist_info = re.sub('', '', artist_info) + print("subbed: %s"%artist_info) + except: + artist_info = "" + mb_artist_id = mb.get_artist_id(artist_name) + artist_image_url = mb.get_artist_image(mb_artist_id) + wikipedia_url = mb.get_artist_wikpedia(mb_artist_id) + artist_wiki_extract = mb.get_wiki_extract(wikipedia_url) + wikipedia_image = mb.get_wiki_image(wikipedia_url) + db.update_value(artist_id, 'artist_name', artist_name) + db.update_value(artist_id, 'artist_info', artist_info) + db.update_value(artist_id, 'mb_artist_id', mb_artist_id) + db.update_value(artist_id, 'image_url', artist_image_url) + db.update_value(artist_id, 'wikipedia_url', wikipedia_url) + db.update_value(artist_id, 'wikipedia_extract', artist_wiki_extract) + db.update_value(artist_id, 'wikipedia_image', wikipedia_image) + +def check_db_status(forced=False): + global last_db_check + refresh_age = 86400 + check_freq = 300#3600 + refresh_single_flag = False + if(enhancedInfo): + try: + if(time.time()-check_freq > last_db_check) or forced: + #popup("DB Check Starting") + xbmc.log("DB check starting %s %s" % (time.time(), last_db_check), xbmc.LOGINFO) + db = get_db() + connection = get_connection() + response = connection.getArtists() + for index in response["artists"]["index"]: + for artist in index["artist"]: + artist_id = artist['id'] + record_age = db.get_record_age(artist_id) + if(forced or not record_age or (record_age > (random.randint(1,111)*refresh_age))) and not refresh_single_flag: + print("If flag is True I shouldn't be here %s"% refresh_single_flag) + print("Record age %s vs %s for %s"%(record_age, (random.randint(1,111)*refresh_age), artist_id)) + #popup("Refreshing %s" % artist_id) + refresh_artist(artist_id) + refresh_single_flag = True + last_db_check = time.time() + except Exception as e: + xbmc.log("DB rcheck failed %e"%e, xbmc.LOGINFO) + + return + +def check_player_status(): + if (scrobbleEnabled and xbmc.getCondVisibility("Player.HasMedia")): + try: + currentFileName = xbmc.getInfoLabel("Player.Filenameandpath") + currentFileProgress = xbmc.getInfoLabel("Player.Progress") + pattern = re.compile(r'plugin:\/\/plugin\.audio\.subsonic\/\?action=play_track&id=(.*?)&') + currentTrackId = re.findall(pattern, currentFileName)[0] + #xbmc.log("Name %s Id %s Progress %s"%(currentFileName,currentTrackId,currentFileProgress), xbmc.LOGDEBUG) + if (int(currentFileProgress)<50): + scrobbled = False + elif (int(currentFileProgress)>=50 and scrobbled == False): + xbmc.log("Scrobbling Track Id %s"%(currentTrackId), xbmc.LOGDEBUG) + success = scrobble_track(currentTrackId) + if success: + scrobbled = True + else: + pass + except IndexError: + print ("Not a Subsonic track") + scrobbled = True + except Exception as e: + xbmc.log("Subsonic scrobble check failed %e"%e, xbmc.LOGINFO) + return + #pass + #xbmc.log("Playing stopped", xbmc.LOGINFO) + def scrobble_track(track_id): connection = get_connection() @@ -69,37 +198,14 @@ def scrobble_track(track_id): return False if __name__ == '__main__': - if(scrobbleEnabled): + if(scrobbleEnabled or enhancedInfo): monitor = xbmc.Monitor() xbmc.log("Subsonic service started", xbmc.LOGINFO) popup("Subsonic service started") while not monitor.abortRequested(): if monitor.waitForAbort(10): break - if (xbmc.getCondVisibility("Player.HasMedia")): - try: - - currentFileName = xbmc.getInfoLabel("Player.Filenameandpath") - currentFileProgress = xbmc.getInfoLabel("Player.Progress") - pattern = re.compile(r'plugin:\/\/plugin\.audio\.subsonic\/\?action=play_track&id=(.*?)&') - currentTrackId = re.findall(pattern, currentFileName)[0] - #xbmc.log("Name %s Id %s Progress %s"%(currentFileName,currentTrackId,currentFileProgress), xbmc.LOGDEBUG) - if (int(currentFileProgress)<50): - scrobbled = False - elif (int(currentFileProgress)>=50 and scrobbled == False): - xbmc.log("Scrobbling Track Id %s"%(currentTrackId), xbmc.LOGDEBUG) - success = scrobble_track(currentTrackId) - if success: - scrobbled = True - else: - pass - except IndexError: - print ("Not a Subsonic track") - scrobbled = True - except Exception as e: - xbmc.log("Subsonic service failed %e"%e, xbmc.LOGINFO) - else: - pass - #xbmc.log("Playing stopped", xbmc.LOGINFO) + check_player_status() + check_db_status() else: xbmc.log("Subsonic service not started due to settings", xbmc.LOGINFO)