mirror of
https://github.com/krateng/maloja.git
synced 2025-04-13 07:27:12 +03:00
Added UI selector for including associated artists
This commit is contained in:
parent
acf7402095
commit
b9e3cd7624
@ -6,6 +6,8 @@ minor_release_name: "Nicole"
|
||||
- "[Feature] Added basic support for albums"
|
||||
- "[Feature] New start page"
|
||||
- "[Feature] Added UI for track-artist, track-album and album-artist association"
|
||||
- "[Feature] Added inline UI for association and merging in chart lists"
|
||||
- "[Feature] Added UI selector for including associated artists"
|
||||
- "[Performance] Improved image rendering"
|
||||
- "[Bugfix] Fixed configuration of time format"
|
||||
- "[Bugfix] Fixed search on manual scrobble page"
|
||||
|
@ -309,8 +309,9 @@ def associate_tracks_to_album(target_id,source_ids):
|
||||
@waitfordb
|
||||
def get_scrobbles(dbconn=None,**keys):
|
||||
(since,to) = keys.get('timerange').timestamps()
|
||||
associated = keys.get('associated',False)
|
||||
if 'artist' in keys:
|
||||
result = sqldb.get_scrobbles_of_artist(artist=keys['artist'],since=since,to=to,dbconn=dbconn)
|
||||
result = sqldb.get_scrobbles_of_artist(artist=keys['artist'],since=since,to=to,associated=associated,dbconn=dbconn)
|
||||
elif 'track' in keys:
|
||||
result = sqldb.get_scrobbles_of_track(track=keys['track'],since=since,to=to,dbconn=dbconn)
|
||||
elif 'album' in keys:
|
||||
@ -324,8 +325,9 @@ def get_scrobbles(dbconn=None,**keys):
|
||||
@waitfordb
|
||||
def get_scrobbles_num(dbconn=None,**keys):
|
||||
(since,to) = keys.get('timerange').timestamps()
|
||||
associated = keys.get('associated',False)
|
||||
if 'artist' in keys:
|
||||
result = len(sqldb.get_scrobbles_of_artist(artist=keys['artist'],since=since,to=to,resolve_references=False,dbconn=dbconn))
|
||||
result = len(sqldb.get_scrobbles_of_artist(artist=keys['artist'],since=since,to=to,associated=associated,resolve_references=False,dbconn=dbconn))
|
||||
elif 'track' in keys:
|
||||
result = len(sqldb.get_scrobbles_of_track(track=keys['track'],since=since,to=to,resolve_references=False,dbconn=dbconn))
|
||||
elif 'album' in keys:
|
||||
@ -370,14 +372,15 @@ def get_tracks_without_album(dbconn=None,resolve_ids=True):
|
||||
@waitfordb
|
||||
def get_charts_artists(dbconn=None,resolve_ids=True,**keys):
|
||||
(since,to) = keys.get('timerange').timestamps()
|
||||
result = sqldb.count_scrobbles_by_artist(since=since,to=to,resolve_ids=resolve_ids,dbconn=dbconn)
|
||||
associated = keys.get('associated',True)
|
||||
result = sqldb.count_scrobbles_by_artist(since=since,to=to,resolve_ids=resolve_ids,associated=associated,dbconn=dbconn)
|
||||
return result
|
||||
|
||||
@waitfordb
|
||||
def get_charts_tracks(dbconn=None,resolve_ids=True,**keys):
|
||||
(since,to) = keys.get('timerange').timestamps()
|
||||
if 'artist' in keys:
|
||||
result = sqldb.count_scrobbles_by_track_of_artist(since=since,to=to,artist=keys['artist'],resolve_ids=resolve_ids,dbconn=dbconn)
|
||||
result = sqldb.count_scrobbles_by_track_of_artist(since=since,to=to,artist=keys['artist'],associated=keys.get('associated',False),resolve_ids=resolve_ids,dbconn=dbconn)
|
||||
elif 'album' in keys:
|
||||
result = sqldb.count_scrobbles_by_track_of_album(since=since,to=to,album=keys['album'],resolve_ids=resolve_ids,dbconn=dbconn)
|
||||
else:
|
||||
@ -388,7 +391,7 @@ def get_charts_tracks(dbconn=None,resolve_ids=True,**keys):
|
||||
def get_charts_albums(dbconn=None,resolve_ids=True,**keys):
|
||||
(since,to) = keys.get('timerange').timestamps()
|
||||
if 'artist' in keys:
|
||||
result = sqldb.count_scrobbles_by_album_of_artist(since=since,to=to,artist=keys['artist'],resolve_ids=resolve_ids,dbconn=dbconn)
|
||||
result = sqldb.count_scrobbles_by_album_of_artist(since=since,to=to,artist=keys['artist'],associated=keys.get('associated',False),resolve_ids=resolve_ids,dbconn=dbconn)
|
||||
else:
|
||||
result = sqldb.count_scrobbles_by_album(since=since,to=to,resolve_ids=resolve_ids,dbconn=dbconn)
|
||||
return result
|
||||
@ -629,15 +632,16 @@ def get_featured(dbconn=None):
|
||||
alltime()
|
||||
]
|
||||
funcs = {
|
||||
"artist": get_charts_artists,
|
||||
"album": get_charts_albums,
|
||||
"track": get_charts_tracks
|
||||
"artist": (get_charts_artists,{'associated':False}),
|
||||
"album": (get_charts_albums,{}),
|
||||
"track": (get_charts_tracks,{})
|
||||
}
|
||||
result = {t:None for t in funcs}
|
||||
|
||||
for entity_type in funcs:
|
||||
for r in ranges:
|
||||
chart = funcs[entity_type](timerange=r)
|
||||
func,kwargs = funcs[entity_type]
|
||||
chart = func(timerange=r,**kwargs)
|
||||
if chart:
|
||||
result[entity_type] = chart[0][entity_type]
|
||||
break
|
||||
|
@ -763,19 +763,23 @@ def merge_albums(target_id,source_ids,dbconn=None):
|
||||
|
||||
@cached_wrapper
|
||||
@connection_provider
|
||||
def get_scrobbles_of_artist(artist,since=None,to=None,resolve_references=True,dbconn=None):
|
||||
def get_scrobbles_of_artist(artist,since=None,to=None,resolve_references=True,associated=False,dbconn=None):
|
||||
|
||||
if since is None: since=0
|
||||
if to is None: to=now()
|
||||
|
||||
artist_id = get_artist_id(artist,dbconn=dbconn)
|
||||
if associated:
|
||||
artist_ids = get_associated_artists(artist,resolve_ids=False,dbconn=dbconn) + [get_artist_id(artist,dbconn=dbconn)]
|
||||
else:
|
||||
artist_ids = [get_artist_id(artist,dbconn=dbconn)]
|
||||
|
||||
|
||||
jointable = sql.join(DB['scrobbles'],DB['trackartists'],DB['scrobbles'].c.track_id == DB['trackartists'].c.track_id)
|
||||
|
||||
op = jointable.select().where(
|
||||
DB['scrobbles'].c.timestamp<=to,
|
||||
DB['scrobbles'].c.timestamp>=since,
|
||||
DB['trackartists'].c.artist_id==artist_id
|
||||
DB['trackartists'].c.artist_id.in_(artist_ids)
|
||||
).order_by(sql.asc('timestamp'))
|
||||
result = dbconn.execute(op).all()
|
||||
|
||||
@ -911,7 +915,7 @@ def get_tracks(dbconn=None):
|
||||
|
||||
@cached_wrapper
|
||||
@connection_provider
|
||||
def count_scrobbles_by_artist(since,to,resolve_ids=True,dbconn=None):
|
||||
def count_scrobbles_by_artist(since,to,associated=True,resolve_ids=True,dbconn=None):
|
||||
jointable = sql.join(
|
||||
DB['scrobbles'],
|
||||
DB['trackartists'],
|
||||
@ -924,18 +928,24 @@ def count_scrobbles_by_artist(since,to,resolve_ids=True,dbconn=None):
|
||||
DB['trackartists'].c.artist_id == DB['associated_artists'].c.source_artist,
|
||||
isouter=True
|
||||
)
|
||||
|
||||
if associated:
|
||||
artistselect = sql.func.coalesce(DB['associated_artists'].c.target_artist,DB['trackartists'].c.artist_id)
|
||||
else:
|
||||
artistselect = DB['trackartists'].c.artist_id
|
||||
|
||||
op = sql.select(
|
||||
sql.func.count(sql.func.distinct(DB['scrobbles'].c.timestamp)).label('count'),
|
||||
# only count distinct scrobbles - because of artist replacement, we could end up
|
||||
# with two artists of the same scrobble counting it twice for the same artist
|
||||
# e.g. Irene and Seulgi adding two scrobbles to Red Velvet for one real scrobble
|
||||
sql.func.coalesce(DB['associated_artists'].c.target_artist,DB['trackartists'].c.artist_id).label('artist_id')
|
||||
artistselect.label('artist_id')
|
||||
# use the replaced artist as artist to count if it exists, otherwise original one
|
||||
).select_from(jointable2).where(
|
||||
DB['scrobbles'].c.timestamp<=to,
|
||||
DB['scrobbles'].c.timestamp>=since
|
||||
).group_by(
|
||||
sql.func.coalesce(DB['associated_artists'].c.target_artist,DB['trackartists'].c.artist_id)
|
||||
artistselect
|
||||
).order_by(sql.desc('count'))
|
||||
result = dbconn.execute(op).all()
|
||||
|
||||
@ -1001,9 +1011,12 @@ def count_scrobbles_by_album(since,to,resolve_ids=True,dbconn=None):
|
||||
@connection_provider
|
||||
# this ranks the albums of that artist, not albums the artist appears on - even scrobbles
|
||||
# of tracks the artist is not part of!
|
||||
def count_scrobbles_by_album_of_artist(since,to,artist,resolve_ids=True,dbconn=None):
|
||||
def count_scrobbles_by_album_of_artist(since,to,artist,associated=False,resolve_ids=True,dbconn=None):
|
||||
|
||||
artist_id = get_artist_id(artist,dbconn=dbconn)
|
||||
if associated:
|
||||
artist_ids = get_associated_artists(artist,resolve_ids=False,dbconn=dbconn) + [get_artist_id(artist,dbconn=dbconn)]
|
||||
else:
|
||||
artist_ids = [get_artist_id(artist,dbconn=dbconn)]
|
||||
|
||||
jointable = sql.join(
|
||||
DB['scrobbles'],
|
||||
@ -1022,7 +1035,7 @@ def count_scrobbles_by_album_of_artist(since,to,artist,resolve_ids=True,dbconn=N
|
||||
).select_from(jointable2).where(
|
||||
DB['scrobbles'].c.timestamp<=to,
|
||||
DB['scrobbles'].c.timestamp>=since,
|
||||
DB['albumartists'].c.artist_id == artist_id
|
||||
DB['albumartists'].c.artist_id.in_(artist_ids)
|
||||
).group_by(DB['tracks'].c.album_id).order_by(sql.desc('count'))
|
||||
result = dbconn.execute(op).all()
|
||||
|
||||
@ -1038,9 +1051,12 @@ def count_scrobbles_by_album_of_artist(since,to,artist,resolve_ids=True,dbconn=N
|
||||
@connection_provider
|
||||
# this ranks the tracks of that artist by the album they appear on - even when the album
|
||||
# is not the artist's
|
||||
def count_scrobbles_of_artist_by_album(since,to,artist,resolve_ids=True,dbconn=None):
|
||||
def count_scrobbles_of_artist_by_album(since,to,artist,associated=False,resolve_ids=True,dbconn=None):
|
||||
|
||||
artist_id = get_artist_id(artist,dbconn=dbconn)
|
||||
if associated:
|
||||
artist_ids = get_associated_artists(artist,resolve_ids=False,dbconn=dbconn) + [get_artist_id(artist,dbconn=dbconn)]
|
||||
else:
|
||||
artist_ids = [get_artist_id(artist,dbconn=dbconn)]
|
||||
|
||||
jointable = sql.join(
|
||||
DB['scrobbles'],
|
||||
@ -1059,7 +1075,7 @@ def count_scrobbles_of_artist_by_album(since,to,artist,resolve_ids=True,dbconn=N
|
||||
).select_from(jointable2).where(
|
||||
DB['scrobbles'].c.timestamp<=to,
|
||||
DB['scrobbles'].c.timestamp>=since,
|
||||
DB['trackartists'].c.artist_id == artist_id
|
||||
DB['trackartists'].c.artist_id.in_(artist_ids)
|
||||
).group_by(DB['tracks'].c.album_id).order_by(sql.desc('count'))
|
||||
result = dbconn.execute(op).all()
|
||||
|
||||
@ -1074,9 +1090,12 @@ def count_scrobbles_of_artist_by_album(since,to,artist,resolve_ids=True,dbconn=N
|
||||
|
||||
@cached_wrapper
|
||||
@connection_provider
|
||||
def count_scrobbles_by_track_of_artist(since,to,artist,resolve_ids=True,dbconn=None):
|
||||
def count_scrobbles_by_track_of_artist(since,to,artist,associated=False,resolve_ids=True,dbconn=None):
|
||||
|
||||
artist_id = get_artist_id(artist,dbconn=dbconn)
|
||||
if associated:
|
||||
artist_ids = get_associated_artists(artist,resolve_ids=False,dbconn=dbconn) + [get_artist_id(artist,dbconn=dbconn)]
|
||||
else:
|
||||
artist_ids = [get_artist_id(artist,dbconn=dbconn)]
|
||||
|
||||
jointable = sql.join(
|
||||
DB['scrobbles'],
|
||||
@ -1090,7 +1109,7 @@ def count_scrobbles_by_track_of_artist(since,to,artist,resolve_ids=True,dbconn=N
|
||||
).select_from(jointable).filter(
|
||||
DB['scrobbles'].c.timestamp<=to,
|
||||
DB['scrobbles'].c.timestamp>=since,
|
||||
DB['trackartists'].c.artist_id==artist_id
|
||||
DB['trackartists'].c.artist_id.in_(artist_ids)
|
||||
).group_by(DB['scrobbles'].c.track_id).order_by(sql.desc('count'))
|
||||
result = dbconn.execute(op).all()
|
||||
|
||||
@ -1301,7 +1320,7 @@ def get_albums_map(album_ids,dbconn=None):
|
||||
|
||||
@cached_wrapper
|
||||
@connection_provider
|
||||
def get_associated_artists(*artists,dbconn=None):
|
||||
def get_associated_artists(*artists,resolve_ids=True,dbconn=None):
|
||||
artist_ids = [get_artist_id(a,dbconn=dbconn) for a in artists]
|
||||
|
||||
jointable = sql.join(
|
||||
@ -1319,8 +1338,11 @@ def get_associated_artists(*artists,dbconn=None):
|
||||
)
|
||||
result = dbconn.execute(op).all()
|
||||
|
||||
artists = artists_db_to_dict(result,dbconn=dbconn)
|
||||
return artists
|
||||
if resolve_ids:
|
||||
artists = artists_db_to_dict(result,dbconn=dbconn)
|
||||
return artists
|
||||
else:
|
||||
return [a.id for a in result]
|
||||
|
||||
@cached_wrapper
|
||||
@connection_provider
|
||||
|
@ -72,6 +72,10 @@ def update_jinja_environment():
|
||||
{"identifier":"longtrailing","replacekeys":{"trail":3},"localisation":"Long Trailing"},
|
||||
{"identifier":"inert","replacekeys":{"trail":10},"localisation":"Inert","heavy":True},
|
||||
{"identifier":"cumulative","replacekeys":{"trail":math.inf},"localisation":"Cumulative","heavy":True}
|
||||
],
|
||||
"xassociated": [
|
||||
{"identifier":"include_associated","replacekeys":{"associated":True},"localisation":"Associated"},
|
||||
{"identifier":"exclude_associated","replacekeys":{"associated":False},"localisation":"Exclusive"}
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -31,12 +31,18 @@ def uri_to_internal(keys,forceTrack=False,forceArtist=False,forceAlbum=False,api
|
||||
filterkeys = {"track":{"artists":keys.getall("artist"),"title":keys.get("title")}}
|
||||
elif type == "artist":
|
||||
filterkeys = {"artist":keys.get("artist")}
|
||||
if "associated" in keys: filterkeys["associated"] = True
|
||||
filterkeys["associated"] = (keys.get('associated','no').lower() == 'yes')
|
||||
# associated is only used for filtering by artist, to indicate that we include associated artists
|
||||
# for actual artist charts, to show that we want to count them, use 'unified'
|
||||
elif type == "album":
|
||||
filterkeys = {"album":{"artists":keys.getall("artist"),"albumtitle":keys.get("albumtitle") or keys.get("title")}}
|
||||
else:
|
||||
filterkeys = {}
|
||||
|
||||
# this can be the case regardless of actual entity filter
|
||||
# e.g if i get scrobbles of an artist associated tells me i want all scrobbles by associated artists
|
||||
# but seeing the artist charts (wich have no filterkeys) also is affected by this
|
||||
|
||||
# 2
|
||||
limitkeys = {}
|
||||
since,to,within = None,None,None
|
||||
@ -105,6 +111,7 @@ def internal_to_uri(keys):
|
||||
urikeys.append("artist",a)
|
||||
urikeys.append("albumtitle",keys["album"]["albumtitle"])
|
||||
|
||||
|
||||
#time
|
||||
if "timerange" in keys:
|
||||
keydict = keys["timerange"].urikeys()
|
||||
|
@ -3,7 +3,7 @@
|
||||
{% macro desc(filterkeys,limitkeys,prefix="by") %}
|
||||
|
||||
{% if filterkeys.get('artist') is not none %}
|
||||
{{ prefix }} {{ links.link(filterkeys.get('artist')) }}
|
||||
{{ prefix }} {{ links.link(filterkeys.get('artist')) }}{% if filterkeys.get('associated') %} (and associated artists){% endif %}
|
||||
{% elif filterkeys.get('track') is not none %}
|
||||
of {{ links.link(filterkeys.get('track')) }}
|
||||
by {{ links.links(filterkeys["track"]["artists"]) }}
|
||||
|
@ -61,3 +61,17 @@
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if 'artist' in filterkeys %}
|
||||
<div>
|
||||
{% for o in xassociated %}
|
||||
{% if o.replacekeys | map('compare_key_in_dicts',o.replacekeys,allkeys) | alltrue %}
|
||||
<span style='opacity:0.5;'>{{ o.localisation }}</span>
|
||||
{% else %}
|
||||
<a href='{{ mlj_uri.create_uri("",allkeys,o.replacekeys) }}'><span>{{ o.localisation }}</span></a>
|
||||
{% endif %}
|
||||
{{ "|" if not loop.last }}
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user