From 05759314f0d28fab592a3168caa344595bdddd26 Mon Sep 17 00:00:00 2001 From: krateng Date: Fri, 31 Mar 2023 15:19:17 +0200 Subject: [PATCH 1/7] Turned aux mode check into decorator --- maloja/database/__init__.py | 10 +++++++++- maloja/database/dbcache.py | 22 +++++----------------- maloja/database/sqldb.py | 9 +++------ 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/maloja/database/__init__.py b/maloja/database/__init__.py index 184a437..f37910e 100644 --- a/maloja/database/__init__.py +++ b/maloja/database/__init__.py @@ -11,7 +11,15 @@ def set_aux_mode(): global AUX_MODE AUX_MODE = True - +# decorator that makes sure this function is only run in normal operation, +# not when we run a task that needs to access the database +def no_aux_mode(func): + def wrapper(*args,**kwargs): + if AUX_MODE: return + return func(*args,**kwargs) + return wrapper + + # rest of the project from ..cleanup import CleanerAgent from .. import images diff --git a/maloja/database/dbcache.py b/maloja/database/dbcache.py index 0bd0c9a..da812a5 100644 --- a/maloja/database/dbcache.py +++ b/maloja/database/dbcache.py @@ -10,7 +10,7 @@ from doreah.regular import runhourly from doreah.logging import log from ..pkg_global.conf import malojaconfig - +from . import no_aux_mode if malojaconfig['USE_GLOBAL_CACHE']: @@ -21,15 +21,12 @@ if malojaconfig['USE_GLOBAL_CACHE']: @runhourly + @no_aux_mode def maintenance(): - from . import AUX_MODE - if AUX_MODE: return print_stats() trim_cache() def print_stats(): - from . import AUX_MODE - if AUX_MODE: return for name,c in (('Cache',cache),('Entity Cache',entitycache)): hits, misses = c.get_stats() log(f"{name}: Size: {len(c)} | Hits: {hits}/{hits+misses} | Estimated Memory: {human_readable_size(c)}") @@ -37,8 +34,6 @@ if malojaconfig['USE_GLOBAL_CACHE']: def cached_wrapper(inner_func): - from . import AUX_MODE - if AUX_MODE: return inner_func def outer_func(*args,**kwargs): @@ -63,8 +58,6 @@ if malojaconfig['USE_GLOBAL_CACHE']: # we don't want a new cache entry for every single combination, but keep a common # cache that's aware of what we're calling def cached_wrapper_individual(inner_func): - from . import AUX_MODE - if AUX_MODE: return def outer_func(set_arg,**kwargs): if 'dbconn' in kwargs: @@ -88,9 +81,8 @@ if malojaconfig['USE_GLOBAL_CACHE']: return outer_func + @no_aux_mode def invalidate_caches(scrobbletime=None): - from . import AUX_MODE - if AUX_MODE: return cleared, kept = 0, 0 for k in cache.keys(): @@ -102,16 +94,12 @@ if malojaconfig['USE_GLOBAL_CACHE']: kept += 1 log(f"Invalidated {cleared} of {cleared+kept} DB cache entries") - + @no_aux_mode def invalidate_entity_cache(): - from . import AUX_MODE - if AUX_MODE: return entitycache.clear() - + @no_aux_mode def trim_cache(): - from . import AUX_MODE - if AUX_MODE: return ramprct = psutil.virtual_memory().percent if ramprct > malojaconfig["DB_MAX_MEMORY"]: log(f"{ramprct}% RAM usage, clearing cache!") diff --git a/maloja/database/sqldb.py b/maloja/database/sqldb.py index f64c43e..dec7da5 100644 --- a/maloja/database/sqldb.py +++ b/maloja/database/sqldb.py @@ -8,6 +8,7 @@ from threading import Lock from ..pkg_global.conf import data_dir from .dbcache import cached_wrapper, cached_wrapper_individual, invalidate_caches, invalidate_entity_cache from . import exceptions as exc +from . import no_aux_mode from doreah.logging import log from doreah.regular import runhourly, runmonthly @@ -1361,11 +1362,9 @@ def search_album(searchterm,dbconn=None): @runhourly @connection_provider +@no_aux_mode def clean_db(dbconn=None): - from . import AUX_MODE - if AUX_MODE: return - with SCROBBLE_LOCK: log(f"Database Cleanup...") @@ -1410,11 +1409,9 @@ def clean_db(dbconn=None): @runmonthly +@no_aux_mode def renormalize_names(): - from . import AUX_MODE - if AUX_MODE: return - with SCROBBLE_LOCK: with engine.begin() as conn: rows = conn.execute(DB['artists'].select()).all() From d8e5f6552e8921af05f77adcc40c48096c26e36f Mon Sep 17 00:00:00 2001 From: krateng Date: Fri, 31 Mar 2023 17:31:46 +0200 Subject: [PATCH 2/7] Improved aux mode again --- maloja/database/__init__.py | 12 ++---------- maloja/database/dbcache.py | 1 - maloja/pkg_global/conf.py | 2 ++ maloja/proccontrol/tasks/import_scrobbles.py | 3 --- maloja/proccontrol/tasks/parse_albums.py | 6 +----- maloja/server.py | 3 +++ 6 files changed, 8 insertions(+), 19 deletions(-) diff --git a/maloja/database/__init__.py b/maloja/database/__init__.py index f37910e..4549c9d 100644 --- a/maloja/database/__init__.py +++ b/maloja/database/__init__.py @@ -2,20 +2,12 @@ from bottle import request, response, FormsDict -# we're running an auxiliary task that doesn't require all the random background -# nonsense to be fired up -# this is temporary -# FIX YO DAMN ARCHITECTURE ALREADY -AUX_MODE = False -def set_aux_mode(): - global AUX_MODE - AUX_MODE = True - # decorator that makes sure this function is only run in normal operation, # not when we run a task that needs to access the database def no_aux_mode(func): def wrapper(*args,**kwargs): - if AUX_MODE: return + from ..pkg_global import conf + if conf.AUX_MODE: return return func(*args,**kwargs) return wrapper diff --git a/maloja/database/dbcache.py b/maloja/database/dbcache.py index da812a5..42695dc 100644 --- a/maloja/database/dbcache.py +++ b/maloja/database/dbcache.py @@ -98,7 +98,6 @@ if malojaconfig['USE_GLOBAL_CACHE']: def invalidate_entity_cache(): entitycache.clear() - @no_aux_mode def trim_cache(): ramprct = psutil.virtual_memory().percent if ramprct > malojaconfig["DB_MAX_MEMORY"]: diff --git a/maloja/pkg_global/conf.py b/maloja/pkg_global/conf.py index f519dc5..5d9b885 100644 --- a/maloja/pkg_global/conf.py +++ b/maloja/pkg_global/conf.py @@ -6,6 +6,8 @@ from doreah.configuration import types as tp from ..__pkginfo__ import VERSION +# this mode specifies whether we run some auxiliary task instead of the main server +AUX_MODE = True # if DATA_DIRECTORY is specified, this is the directory to use for EVERYTHING, no matter what diff --git a/maloja/proccontrol/tasks/import_scrobbles.py b/maloja/proccontrol/tasks/import_scrobbles.py index b34ccc0..1bab1c6 100644 --- a/maloja/proccontrol/tasks/import_scrobbles.py +++ b/maloja/proccontrol/tasks/import_scrobbles.py @@ -21,9 +21,6 @@ outputs = { def import_scrobbles(inputf): - from ...database import set_aux_mode - set_aux_mode() - from ...database.sqldb import add_scrobbles result = { diff --git a/maloja/proccontrol/tasks/parse_albums.py b/maloja/proccontrol/tasks/parse_albums.py index 125df0c..afeb8c9 100644 --- a/maloja/proccontrol/tasks/parse_albums.py +++ b/maloja/proccontrol/tasks/parse_albums.py @@ -1,11 +1,7 @@ - - +from doreah.io import col def parse_albums(replace=False): - from ...database import set_aux_mode - set_aux_mode() - from ...database.sqldb import guess_albums, get_album_id, add_track_to_album print("Parsing album information...") diff --git a/maloja/server.py b/maloja/server.py index 6f76524..a071c98 100644 --- a/maloja/server.py +++ b/maloja/server.py @@ -22,6 +22,7 @@ from .database.jinjaview import JinjaDBConnection from .images import resolve_track_image, resolve_artist_image, resolve_album_image from .malojauri import uri_to_internal, remove_identical from .pkg_global.conf import malojaconfig, data_dir +from .pkg_global import conf from .jinjaenv.context import jinja_environment from .apis import init_apis, apikeystore @@ -285,6 +286,8 @@ logging.getLogger().addHandler(WaitressLogHandler()) def run_server(): + conf.AUX_MODE = False + log("Starting up Maloja server...") ## start database From e4bf26b86d6840d904b68b9ec68cbecfc481763e Mon Sep 17 00:00:00 2001 From: krateng Date: Fri, 31 Mar 2023 17:38:36 +0200 Subject: [PATCH 3/7] Added meta table to database --- maloja/database/sqldb.py | 31 +++++++++++++++++++++++++++++++ maloja/pkg_global/conf.py | 12 ++---------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/maloja/database/sqldb.py b/maloja/database/sqldb.py index dec7da5..c16cf30 100644 --- a/maloja/database/sqldb.py +++ b/maloja/database/sqldb.py @@ -1,4 +1,5 @@ import sqlalchemy as sql +from sqlalchemy.dialects.sqlite import insert as sqliteinsert import json import unicodedata import math @@ -20,6 +21,13 @@ from doreah.regular import runhourly, runmonthly DBTABLES = { # name - type - foreign key - kwargs + '_maloja':{ + 'columns':[ + ("key", sql.String, {'primary_key':True}), + ("value", sql.String, {}) + ], + 'extraargs':(),'extrakwargs':{} + }, 'scrobbles':{ 'columns':[ ("timestamp", sql.Integer, {'primary_key':True}), @@ -151,6 +159,29 @@ def connection_provider(func): wrapper.__innerfunc__ = func return wrapper +@connection_provider +def get_maloja_info(keys,dbconn=None): + op = DB['_maloja'].select().where( + DB['_maloja'].c.key.in_(keys) + ) + result = dbconn.execute(op).all() + + info = {} + for row in result: + info[row.key] = row.value + return info + +@connection_provider +def set_maloja_info(info,dbconn=None): + for k in info: + op = sqliteinsert(DB['_maloja']).values( + key=k, value=info[k] + ).on_conflict_do_update( + index_elements=['key'], + set_={'value':info[k]} + ) + dbconn.execute(op) + ##### DB <-> Dict translations ## ATTENTION ALL ADVENTURERS diff --git a/maloja/pkg_global/conf.py b/maloja/pkg_global/conf.py index 5d9b885..3f49c0f 100644 --- a/maloja/pkg_global/conf.py +++ b/maloja/pkg_global/conf.py @@ -302,15 +302,6 @@ data_dir = { -### write down the last ran version -with open(pthj(dir_settings['state'],".lastmalojaversion"),"w") as filed: - filed.write(VERSION) - filed.write("\n") - - - - - ### DOREAH CONFIGURATION from doreah import config @@ -336,7 +327,8 @@ config( custom_css_files = [f for f in os.listdir(data_dir['css']()) if f.lower().endswith('.css')] - +from ..database.sqldb import set_maloja_info +set_maloja_info({'last_run_version':VERSION}) # what the fuck did i just write # this spaghetti file is proudly sponsored by the rice crackers i'm eating at the From 517bc6f5c0ccb2263356f95945284fb84bc6e64d Mon Sep 17 00:00:00 2001 From: krateng Date: Fri, 31 Mar 2023 21:04:30 +0200 Subject: [PATCH 4/7] Completely reworked album parsing --- maloja/__main__.py | 4 +- maloja/database/sqldb.py | 43 +++++----- maloja/proccontrol/tasks/parse_albums.py | 105 +++++++++++++++++++++-- maloja/web/jinja/artist.jinja | 6 +- 4 files changed, 123 insertions(+), 35 deletions(-) diff --git a/maloja/__main__.py b/maloja/__main__.py index 4694a40..e39fce3 100644 --- a/maloja/__main__.py +++ b/maloja/__main__.py @@ -148,7 +148,7 @@ def print_info(): print("Could not determine dependency versions.") print() -@mainfunction({"l":"level","v":"version","V":"version"},flags=['version','include_images'],shield=True) +@mainfunction({"l":"level","v":"version","V":"version"},flags=['version','include_images','prefer_existing'],shield=True) def main(*args,**kwargs): actions = { @@ -166,7 +166,7 @@ def main(*args,**kwargs): "generate":generate.generate_scrobbles, # maloja generate 400 "export":tasks.export, # maloja export "apidebug":apidebug.run, # maloja apidebug - "parsealbums":tasks.parse_albums, # maloja parsealbums + "parsealbums":tasks.parse_albums, # maloja parsealbums --strategy majority # aux "info":print_info } diff --git a/maloja/database/sqldb.py b/maloja/database/sqldb.py index c16cf30..5be84e6 100644 --- a/maloja/database/sqldb.py +++ b/maloja/database/sqldb.py @@ -483,14 +483,11 @@ def get_artist_id(artistname,create_new=True,dbconn=None): @cached_wrapper @connection_provider -def get_album_id(albumdict,create_new=True,dbconn=None): +def get_album_id(albumdict,create_new=True,ignore_albumartists=False,dbconn=None): ntitle = normalize_name(albumdict['albumtitle']) artist_ids = [get_artist_id(a,dbconn=dbconn) for a in albumdict.get('artists') or []] artist_ids = list(set(artist_ids)) - - - op = DB['albums'].select( # DB['albums'].c.id ).where( @@ -498,20 +495,23 @@ def get_album_id(albumdict,create_new=True,dbconn=None): ) result = dbconn.execute(op).all() for row in result: - # check if the artists are the same - foundtrackartists = [] - - op = DB['albumartists'].select( -# DB['albumartists'].c.artist_id - ).where( - DB['albumartists'].c.album_id==row.id - ) - result = dbconn.execute(op).all() - match_artist_ids = [r.artist_id for r in result] - #print("required artists",artist_ids,"this match",match_artist_ids) - if set(artist_ids) == set(match_artist_ids): - #print("ID for",albumdict['title'],"was",row[0]) + if ignore_albumartists: return row.id + else: + # check if the artists are the same + foundtrackartists = [] + + op = DB['albumartists'].select( + # DB['albumartists'].c.artist_id + ).where( + DB['albumartists'].c.album_id==row.id + ) + result = dbconn.execute(op).all() + match_artist_ids = [r.artist_id for r in result] + #print("required artists",artist_ids,"this match",match_artist_ids) + if set(artist_ids) == set(match_artist_ids): + #print("ID for",albumdict['title'],"was",row[0]) + return row.id if not create_new: return None @@ -1601,7 +1601,7 @@ def guess_albums(track_ids=None,replace=False,dbconn=None): }} if len(artists) == 0: # for albums without artist, assume track artist - res[track_id]["guess_artists"] = True + res[track_id]["guess_artists"] = [] else: res[track_id] = {"assigned":False,"reason":"Not enough data"} @@ -1610,7 +1610,7 @@ def guess_albums(track_ids=None,replace=False,dbconn=None): - missing_artists = [track_id for track_id in res if res[track_id].get("guess_artists")] + missing_artists = [track_id for track_id in res if "guess_artists" in res[track_id]] #we're pointlessly getting the albumartist names here even though the IDs would be enough #but it's better for function separation I guess @@ -1627,10 +1627,7 @@ def guess_albums(track_ids=None,replace=False,dbconn=None): result = dbconn.execute(op).all() for row in result: - res[row.track_id]["assigned"]["artists"].append(row.name) - for track_id in res: - if res[track_id].get("guess_artists"): - del res[track_id]["guess_artists"] + res[row.track_id]["guess_artists"].append(row.name) return res diff --git a/maloja/proccontrol/tasks/parse_albums.py b/maloja/proccontrol/tasks/parse_albums.py index afeb8c9..7a9d354 100644 --- a/maloja/proccontrol/tasks/parse_albums.py +++ b/maloja/proccontrol/tasks/parse_albums.py @@ -1,19 +1,106 @@ from doreah.io import col -def parse_albums(replace=False): +def parse_albums(strategy=None,prefer_existing=False): + + if strategy not in ("track","none","all","majority","most"): + print(""" +Please specify your album parsing strategy: + + --strategy Specify what strategy to use when the scrobble contains + no information about album artists. + track Take the track artists. This can lead to + separate albums being created for compilation + albums or albums that have collaboration tracks. + none Merge all albums with the same name and assign + 'Various Artists' as the album artist. + all Merge all albums with the same name and assign + every artist that appears on the album as an album + artist. + majority Merge all albums with the same name and assign + artists that appear in at least half the tracks + of the album as album artists. [RECOMMENDED] + most Merge all albums with the same name and assign + the artist that appears most on the album as album + artist. + --prefer_existing If an album with the same name already exists, use it + without further examination of track artists. + """) + return + + from ...database.sqldb import guess_albums, get_album_id, add_track_to_album print("Parsing album information...") - result = guess_albums(replace=replace) + result = guess_albums() result = {track_id:result[track_id] for track_id in result if result[track_id]["assigned"]} - print("Adding",len(result),"tracks to albums...") + print("Found",col['yellow'](len(result)),"Tracks to assign albums to") + + result_authorative = {track_id:result[track_id] for track_id in result if result[track_id]["assigned"]["artists"]} + result_guesswork = {track_id:result[track_id] for track_id in result if not result[track_id]["assigned"]["artists"]} + i = 0 - for track_id in result: - album_id = get_album_id(result[track_id]["assigned"]) - add_track_to_album(track_id,album_id) - i += 1 + + def countup(i): + i+=1 if (i % 100) == 0: - print(i,"of",len(result)) - print("Done!") + print(f"Added album information for {i} of {len(result)} tracks...") + return i + + for track_id in result_authorative: + albuminfo = result[track_id]['assigned'] + album_id = get_album_id(albuminfo) + add_track_to_album(track_id,album_id) + i=countup(i) + + albums = {} + for track_id in result_guesswork: + albuminfo = result[track_id]['assigned'] + + # check if already exists + if prefer_existing: + album_id = get_album_id(albuminfo,ignore_albumartists=True,create_new=False) + if album_id: + add_track_to_album(track_id,album_id) + i=countup(i) + continue + + if strategy == 'track': + albuminfo['artists'] = result[track_id]['guess_artists'] + album_id = get_album_id(albuminfo) + add_track_to_album(track_id,album_id) + i=countup(i) + continue + + if strategy == 'none': + albuminfo['artists'] = [] + album_id = get_album_id(albuminfo) + add_track_to_album(track_id,album_id) + i=countup(i) + continue + + if strategy in ['all','majority','most']: + albums.setdefault(albuminfo['albumtitle'],{'track_ids':[],'artists':{}}) + albums[albuminfo['albumtitle']]['track_ids'].append(track_id) + for a in result[track_id]['guess_artists']: + albums[albuminfo['albumtitle']]['artists'].setdefault(a,0) + albums[albuminfo['albumtitle']]['artists'][a] += 1 + + + for title in albums: + artistoptions = albums[title]['artists'] + track_ids = albums[title]['track_ids'] + if strategy == 'all': + artists = [a for a in artistoptions] + elif strategy == 'majority': + artists = [a for a in artistoptions if artistoptions[a] >= (len(track_ids) / 2)] + elif strategy == 'most': + artists = [max(artistoptions,key=artistoptions.get)] + + for track_id in track_ids: + album_id = get_album_id({'albumtitle':title,'artists':artists}) + add_track_to_album(track_id,album_id) + i=countup(i) + + print(col['lawngreen']("Done!")) diff --git a/maloja/web/jinja/artist.jinja b/maloja/web/jinja/artist.jinja index f9b5c42..29d8879 100644 --- a/maloja/web/jinja/artist.jinja +++ b/maloja/web/jinja/artist.jinja @@ -90,7 +90,11 @@ -{% if info["isalbumartist"] %} +{% set albums_info = dbc.get_albums_artist_appears_on(filterkeys,limitkeys) %} +{% set ownalbums = albums_info.own_albums %} +{% set otheralbums = albums_info.appears_on %} + +{% if ownalbums or otheralbums %} {% if settings['ALBUM_SHOWCASE'] %}

Albums

From 54a085c5b23ab1bc1b2f3a51cf40666115d00deb Mon Sep 17 00:00:00 2001 From: krateng Date: Fri, 31 Mar 2023 21:06:54 +0200 Subject: [PATCH 5/7] Added startup upgrade task for album parsing --- maloja/database/__init__.py | 1 + maloja/database/exceptions.py | 2 +- maloja/upgrade.py | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/maloja/database/__init__.py b/maloja/database/__init__.py index 4549c9d..fcdb861 100644 --- a/maloja/database/__init__.py +++ b/maloja/database/__init__.py @@ -619,6 +619,7 @@ def start_db(): # Upgrade database from .. import upgrade upgrade.upgrade_db(sqldb.add_scrobbles) + upgrade.parse_old_albums() # Load temporary tables from . import associated diff --git a/maloja/database/exceptions.py b/maloja/database/exceptions.py index 0d4fce4..4a98d5c 100644 --- a/maloja/database/exceptions.py +++ b/maloja/database/exceptions.py @@ -16,7 +16,7 @@ class DatabaseNotBuilt(HTTPError): def __init__(self): super().__init__( status=503, - body="The Maloja Database is being upgraded to Version 3. This could take quite a long time! (~ 2-5 minutes per 10 000 scrobbles)", + body="The Maloja Database is being upgraded to support new Maloja features. This could take a while.", headers={"Retry-After":120} ) diff --git a/maloja/upgrade.py b/maloja/upgrade.py index 67d1176..a4f20cc 100644 --- a/maloja/upgrade.py +++ b/maloja/upgrade.py @@ -11,6 +11,9 @@ from .pkg_global.conf import data_dir, dir_settings from .apis import _apikeys +from .database.sqldb import get_maloja_info, set_maloja_info + + # Dealing with old style tsv files - these should be phased out everywhere def read_tsvs(path,types): result = [] @@ -40,7 +43,7 @@ def upgrade_apikeys(): except Exception: pass - +# v2 to v3 iupgrade def upgrade_db(callback_add_scrobbles): oldfolder = os.path.join(dir_settings['state'],"scrobbles") @@ -88,3 +91,13 @@ def upgrade_db(callback_add_scrobbles): callback_add_scrobbles(scrobblelist) os.rename(os.path.join(oldfolder,sf),os.path.join(newfolder,sf)) log("Done!",color='yellow') + + +# 3.2 album support +def parse_old_albums(): + setting_name = "db_upgrade_albums" + if get_maloja_info([setting_name]).get(setting_name): + pass + else: + pass + #set_maloja_info({setting_name:True}) From 9443ad2f624b94b3e9408534a8609b8bab48e4e5 Mon Sep 17 00:00:00 2001 From: krateng Date: Sat, 1 Apr 2023 00:49:31 +0200 Subject: [PATCH 6/7] Case insensitive album merging --- maloja/proccontrol/tasks/parse_albums.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/maloja/proccontrol/tasks/parse_albums.py b/maloja/proccontrol/tasks/parse_albums.py index 7a9d354..e499818 100644 --- a/maloja/proccontrol/tasks/parse_albums.py +++ b/maloja/proccontrol/tasks/parse_albums.py @@ -81,16 +81,18 @@ Please specify your album parsing strategy: continue if strategy in ['all','majority','most']: - albums.setdefault(albuminfo['albumtitle'],{'track_ids':[],'artists':{}}) - albums[albuminfo['albumtitle']]['track_ids'].append(track_id) + cleantitle = albuminfo['albumtitle'].lower() + albums.setdefault(cleantitle,{'track_ids':[],'artists':{},'title':albuminfo['albumtitle']}) + albums[cleantitle]['track_ids'].append(track_id) for a in result[track_id]['guess_artists']: - albums[albuminfo['albumtitle']]['artists'].setdefault(a,0) - albums[albuminfo['albumtitle']]['artists'][a] += 1 + albums[cleantitle]['artists'].setdefault(a,0) + albums[cleantitle]['artists'][a] += 1 - for title in albums: - artistoptions = albums[title]['artists'] - track_ids = albums[title]['track_ids'] + for cleantitle in albums: + artistoptions = albums[cleantitle]['artists'] + track_ids = albums[cleantitle]['track_ids'] + realtitle = albums[cleantitle]['title'] if strategy == 'all': artists = [a for a in artistoptions] elif strategy == 'majority': @@ -99,7 +101,7 @@ Please specify your album parsing strategy: artists = [max(artistoptions,key=artistoptions.get)] for track_id in track_ids: - album_id = get_album_id({'albumtitle':title,'artists':artists}) + album_id = get_album_id({'albumtitle':realtitle,'artists':artists}) add_track_to_album(track_id,album_id) i=countup(i) From 501984d04eaeeb0a928ee56fc3f0b7b0997e729b Mon Sep 17 00:00:00 2001 From: krateng Date: Sat, 1 Apr 2023 04:16:58 +0200 Subject: [PATCH 7/7] Added option to show album art for tracks --- maloja/images.py | 8 ++++++++ maloja/pkg_global/conf.py | 1 + 2 files changed, 9 insertions(+) diff --git a/maloja/images.py b/maloja/images.py index f4425e4..e6ffec7 100644 --- a/maloja/images.py +++ b/maloja/images.py @@ -134,6 +134,14 @@ resolve_semaphore = BoundedSemaphore(8) def resolve_track_image(track_id): + if malojaconfig["USE_ALBUM_ARTWORK_FOR_TRACKS"]: + track = database.sqldb.get_track(track_id) + if "album" in track: + album_id = database.sqldb.get_album_id(track["album"]) + albumart = resolve_album_image(album_id) + if albumart: + return albumart + with resolve_semaphore: # check cache result = get_image_from_cache(track_id,'tracks') diff --git a/maloja/pkg_global/conf.py b/maloja/pkg_global/conf.py index 3f49c0f..a9be47b 100644 --- a/maloja/pkg_global/conf.py +++ b/maloja/pkg_global/conf.py @@ -196,6 +196,7 @@ malojaconfig = Configuration( "album_showcase":(tp.Boolean(), "Display Album Showcase", True, "Display a graphical album showcase for artist overview pages instead of a chart list"), "display_art_icons":(tp.Boolean(), "Display Album/Artist Icons", True), "default_album_artist":(tp.String(), "Default Albumartist", "Various Artists"), + "use_album_artwork_for_tracks":(tp.Boolean(), "Use Album Artwork for tracks", True), "discourage_cpu_heavy_stats":(tp.Boolean(), "Discourage CPU-heavy stats", False, "Prevent visitors from mindlessly clicking on CPU-heavy options. Does not actually disable them for malicious actors!"), "use_local_images":(tp.Boolean(), "Use Local Images", True), #"local_image_rotate":(tp.Integer(), "Local Image Rotate", 3600),