mirror of https://github.com/Nezreka/SoulSync.git
dev
feat/auto-sync-schedule-types
fix/usenet-album-poll-sab-handoff
main
fix/quarantine-source-dedup
release/2.5.3
fix/disable-beatport-features
johnbaumb-discover-redesign
1.0
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
1.9
2.0
2.1
2.2
2.3
2.4.0
2.4.1
2.4.2
2.5.0
2.5.1
2.5.2
2.5.3
2.5.4
2.5.5
2.5.6
2.5.7
2.5.9
2.6.0
2.6.1
2.6.2
v0.65
${ noResults }
1 Commits (dev)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
53284ee7c8 |
Personalized playlists (2/N): all 8 generators wired through manager
Adds the per-kind generator modules and registers them with the
PlaylistKindRegistry so the manager's `refresh_playlist` can dispatch
to any of them.
Generators (each in its own module under
`core/personalized/generators/`):
Singletons (variant=''):
- hidden_gems -> wraps service.get_hidden_gems
- discovery_shuffle -> wraps service.get_discovery_shuffle
- popular_picks -> wraps service.get_popular_picks
Variant-bearing kinds:
- time_machine -> variant = decade label ('1980s', '1990s', ...).
Variant resolver returns 7 standard decades.
Generator parses '1980s' -> 1980 + delegates
to service.get_decade_playlist.
- genre_playlist -> variant = URL-safe genre key
('electronic_dance', 'hip_hop_rap', ...).
Resolver normalizes parent-genre keys from
service.GENRE_MAPPING; free-form keywords
pass through to service.get_genre_playlist.
- daily_mix -> variant = top-genre rank ('1' / '2' / '3' / '4').
Generator looks up user's Nth-ranked library
genre and returns discovery picks within it.
Library half (was a stub returning []) is
intentionally dropped: tracks table has no
source IDs, so library rows can't sync. Fixed
the stub to return [] cleanly without the
misleading log warning.
- fresh_tape -> Spotify Release Radar. Reads curated track
IDs from discovery_curated_playlists (tries
'release_radar_<source>' first, falls back to
'release_radar') and hydrates against the
discovery pool.
- archives -> Spotify Discover Weekly. Same hydration path
as fresh_tape but uses 'discovery_weekly'.
- seasonal_mix -> variant = season key ('halloween' / 'christmas'
/ 'valentines' / 'summer' / 'spring' / 'autumn').
Reads curated IDs via SeasonalDiscoveryService
then hydrates from seasonal_tracks (which
carries full track_data_json).
Each module:
- Defines `generate(deps, variant, config) -> List[Track]`.
- Defines `SPEC = PlaylistKindSpec(...)` and registers it on import
(idempotent — re-import safe via `if registry.get(...) is None`).
- For variant-bearing kinds, also defines `variant_resolver(deps)`.
Shared helpers in `_common.py`:
- `get_service(deps)` pulls the legacy
`PersonalizedPlaylistsService` instance (deps.service or
deps['service']).
- `coerce_tracks(rows)` runs each dict through `Track.from_dict`,
tolerates None / non-list inputs.
Tests (50 new, total 85 across personalized subsystem):
- Singletons: registration + display name + dispatch + limit
forwarding + empty/None tolerance + missing-deps error +
dict-form deps acceptance (16 tests).
- Variants: variant_resolver listing + label parsing + invalid
variant errors + parent-key normalization + free-form passthrough
(13 tests).
- Curated/hybrid: daily_mix rank-to-genre resolution + rank-out-of-
range empty + invalid-variant error; fresh_tape & archives
hydration order + missing-id skip + source-specific-then-fallback
key dispatch + limit + missing-database-dep error; seasonal_mix
curated-id hydration order + missing-id skip + JSON round-trip +
empty-curated empty + limit + missing-service error (21 tests).
3304+ tests pass. No regression on existing 62 personalized tests.
|
2 weeks ago |