Popular Picks: fix empty result for deezer (popularity threshold scale mismatch)
The discovery pool synthesizes deezer popularity onto a 0-100 score (base 45 + bonuses, capped at 100), but _get_popularity_thresholds had deezer on the raw-rank scale (500000/100000). So Popular Picks' 'popularity >= 500000' matched nothing — empty for every deezer-primary user — while Hidden Gems' '< 100000' caught the whole pool. Deezer thresholds now sit on the 0-100 scale (60/50, like Spotify's 60/40). Tested.
This commit is contained in:
parent
30ff0bde49
commit
c033656fdf
2 changed files with 42 additions and 2 deletions
|
|
@ -111,7 +111,10 @@ class PersonalizedPlaylistsService:
|
||||||
Either value can be None to skip that filter for that source.
|
Either value can be None to skip that filter for that source.
|
||||||
|
|
||||||
- Spotify: 60 / 40 (the existing 0-100 popularity scale)
|
- Spotify: 60 / 40 (the existing 0-100 popularity scale)
|
||||||
- Deezer: 500000 / 100000 (rank values — ballpark from real data)
|
- Deezer: 60 / 50 (ALSO 0-100 — the discovery pool SYNTHESIZES deezer popularity to a
|
||||||
|
0-100 score at scan time, capped at 100; it is NOT Deezer's raw rank. The old
|
||||||
|
500000/100000 rank thresholds matched nothing, so Popular Picks came back empty for
|
||||||
|
deezer users while Hidden Gems' < 100000 caught the whole pool.)
|
||||||
- iTunes / others: None / None (no popularity data; fall back to no
|
- iTunes / others: None / None (no popularity data; fall back to no
|
||||||
threshold filter, just diversity-on-random)
|
threshold filter, just diversity-on-random)
|
||||||
|
|
||||||
|
|
@ -121,7 +124,7 @@ class PersonalizedPlaylistsService:
|
||||||
if normalized == 'spotify':
|
if normalized == 'spotify':
|
||||||
return 60, 40
|
return 60, 40
|
||||||
if normalized == 'deezer':
|
if normalized == 'deezer':
|
||||||
return 500_000, 100_000
|
return 60, 50
|
||||||
# iTunes, hydrabase, anything else — no usable popularity data
|
# iTunes, hydrabase, anything else — no usable popularity data
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
|
|
|
||||||
37
tests/test_popularity_thresholds.py
Normal file
37
tests/test_popularity_thresholds.py
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
"""Popular Picks was empty for deezer users — wrong popularity-threshold scale.
|
||||||
|
|
||||||
|
The discovery pool synthesizes deezer popularity onto a 0-100 score (base 45 + bonuses, capped
|
||||||
|
at 100), but _get_popularity_thresholds had deezer on the raw-rank scale (500000/100000). So
|
||||||
|
`popularity >= 500000` matched nothing (Popular Picks empty) while `< 100000` matched the whole
|
||||||
|
pool (Hidden Gems caught everything). Thresholds must stay on the 0-100 scale.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from core.personalized_playlists import PersonalizedPlaylistsService
|
||||||
|
|
||||||
|
|
||||||
|
def _svc():
|
||||||
|
return PersonalizedPlaylistsService(database=None)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deezer_thresholds_are_on_the_0_100_scale():
|
||||||
|
popular_min, hidden_max = _svc()._get_popularity_thresholds('deezer')
|
||||||
|
assert (popular_min, hidden_max) == (60, 50) # was (500000, 100000) — unreachable
|
||||||
|
assert 0 < popular_min <= 100 and 0 < hidden_max <= 100
|
||||||
|
assert popular_min > hidden_max # popular tier sits above the hidden tier
|
||||||
|
|
||||||
|
|
||||||
|
def test_spotify_thresholds_unchanged():
|
||||||
|
assert _svc()._get_popularity_thresholds('spotify') == (60, 40)
|
||||||
|
|
||||||
|
|
||||||
|
def test_case_insensitive():
|
||||||
|
assert _svc()._get_popularity_thresholds('Deezer') == (60, 50)
|
||||||
|
assert _svc()._get_popularity_thresholds('SPOTIFY') == (60, 40)
|
||||||
|
|
||||||
|
|
||||||
|
def test_sources_without_popularity_skip_the_filter():
|
||||||
|
assert _svc()._get_popularity_thresholds('itunes') == (None, None)
|
||||||
|
assert _svc()._get_popularity_thresholds('musicbrainz') == (None, None)
|
||||||
|
assert _svc()._get_popularity_thresholds('') == (None, None)
|
||||||
Loading…
Reference in a new issue