feat: rebuild the moods from real tags, add exclusions, fix playlist ownership #12
@@ -174,17 +174,40 @@ An artist neither key resolves is recorded as fetched with no tags, so the next
|
||||
pass does not spend a request on it again. A genuine failure — a rate limit, a
|
||||
bad key — is *not* recorded, so that one is retried.
|
||||
|
||||
The built-in moods are chosen for this library rather than as a general
|
||||
taxonomy:
|
||||
The built-in moods are built from the **tag distribution of this library**,
|
||||
measured, rather than from a general taxonomy:
|
||||
|
||||
| Mood | Selected on |
|
||||
| ------------------ | ------------------------------------------------- |
|
||||
| `80s-synths` | synthpop, new wave, synthwave — released 1975-1992 |
|
||||
| `high-energy-rock` | hard rock, punk, pop punk, alternative |
|
||||
| `screamo` | screamo, post-hardcore, metalcore, emo |
|
||||
| `drum-and-bass` | drum and bass, liquid funk, neurofunk, jungle |
|
||||
| `dance` | house, big room, hardstyle, trance, dubstep |
|
||||
| `classic-rock` | classic rock, prog, psychedelic, blues rock |
|
||||
| --------------- | -------------------------------------------------------- |
|
||||
| `drum-and-bass` | drum and bass and its six spellings, liquid funk, neurofunk, jungle, techstep, hospital records |
|
||||
| `bass` | dubstep, brostep, grime, trip-hop, big beat |
|
||||
| `dance` | house and its variants, trance, techno, electro, rave |
|
||||
| `pop-punk` | pop punk, punk, emo, emocore, easycore, power pop |
|
||||
| `screamo` | screamo, post-hardcore, metalcore, melodic hardcore, trancecore |
|
||||
| `heavy-metal` | heavy metal, thrash, speed, power, death, prog, NWOBHM |
|
||||
| `hair-metal` | hair metal, glam metal, glam rock, arena rock, AOR — 1975-1994 |
|
||||
| `nu-metal` | nu metal, alternative metal, rapcore, industrial |
|
||||
| `classic-rock` | classic rock, prog, psychedelic, blues rock, 70s, 60s |
|
||||
| `80s-synths` | synthpop, electropop, new wave, post-punk — 1975-1992 |
|
||||
| `indie` | indie, indie rock, indie pop, britpop, singer-songwriter |
|
||||
|
||||
Measuring first mattered. `synthwave`, `edm`, `big room` and `hardstyle` are
|
||||
plausible tags that carry **nothing at all** here, while `techstep`, `easycore`
|
||||
and `hospital records` carry real weight. Guessing produces the first list.
|
||||
|
||||
Three kinds of tag are never used, and there is a test enforcing it:
|
||||
|
||||
- **Nationality** — `american` alone spans 241 artists. A passport is not a
|
||||
sound.
|
||||
- **`rock` and `electronic`** — 340 and 275 artists, most of the library. A
|
||||
mood that matches everything is not a mood.
|
||||
- **Artist names** — Last.fm's most popular tag for an artist is frequently
|
||||
their own name. `green day`, `paramore` and `queen` are single-artist
|
||||
playlists waiting to happen.
|
||||
|
||||
`80s-synths` deliberately excludes the bare `80s` tag, which in this library
|
||||
sits on Def Leppard and Bon Jovi rather than on anything with a synthesiser in
|
||||
it. Those belong to `hair-metal`, which is why that mood now exists.
|
||||
|
||||
An artist qualifies when their tag weights inside a mood sum to at least 30 out
|
||||
of Last.fm's 0-100 scale. One low-weight tag is not a genre, it is somebody's
|
||||
|
||||
+65
-17
@@ -1242,49 +1242,97 @@ PLAYLISTS = (
|
||||
# `years` filters on the album's release date, which is what separates eighties
|
||||
# synth records from everything a synthpop tag would otherwise drag in.
|
||||
DEFAULT_VIBES = (
|
||||
# Built from the tag distribution of this library rather than from a general
|
||||
# taxonomy, which is why some obvious-looking tags are absent and some
|
||||
# unobvious ones are here. `synthwave`, `edm`, `big room` and `hardstyle`
|
||||
# carry nothing at all; `techstep`, `easycore` and `hospital records` carry
|
||||
# real weight.
|
||||
#
|
||||
# Three kinds of tag are deliberately never used. Nationality -- american,
|
||||
# british, swedish -- describes a passport, not a sound, and `american`
|
||||
# alone spans 241 artists. `rock` and `electronic` span 340 and 275, which
|
||||
# is most of the library and therefore no mood at all. And Last.fm's most
|
||||
# popular tag for an artist is frequently their own name, so `green day`,
|
||||
# `paramore` and `queen` are single-artist playlists waiting to happen.
|
||||
{
|
||||
"name": "80s-synths",
|
||||
"name": "drum-and-bass",
|
||||
"tags": [
|
||||
"synthpop", "synth pop", "synth-pop", "new wave", "synthwave",
|
||||
"new romantic", "electropop", "80s", "1980s",
|
||||
"drum and bass", "dnb", "drum n bass", "drum'n'bass", "drum & bass",
|
||||
"drum 'n' bass", "liquid funk", "neurofunk", "jungle", "techstep",
|
||||
"darkstep", "drumstep", "breakbeat", "hospital records",
|
||||
],
|
||||
"years": [1975, 1992],
|
||||
},
|
||||
{
|
||||
"name": "high-energy-rock",
|
||||
"name": "bass",
|
||||
"tags": ["dubstep", "brostep", "grime", "trip-hop", "big beat"],
|
||||
},
|
||||
{
|
||||
"name": "dance",
|
||||
"tags": [
|
||||
"hard rock", "punk rock", "pop punk", "punk", "alternative rock",
|
||||
"rock", "garage rock", "skate punk",
|
||||
"house", "electro house", "progressive house", "tech house", "trance",
|
||||
"techno", "electro", "rave", "dance", "minimal",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "pop-punk",
|
||||
"tags": [
|
||||
"pop punk", "pop-punk", "punk rock", "punk", "skate punk", "emo",
|
||||
"emocore", "easycore", "powerpop", "power pop", "post-grunge",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "screamo",
|
||||
"tags": [
|
||||
"screamo", "post-hardcore", "metalcore", "emo", "hardcore",
|
||||
"melodic hardcore", "emocore",
|
||||
"screamo", "post-hardcore", "metalcore", "melodic metalcore",
|
||||
"melodic hardcore", "hardcore", "trancecore", "deathcore",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "drum-and-bass",
|
||||
"name": "heavy-metal",
|
||||
"tags": [
|
||||
"drum and bass", "drum n bass", "dnb", "liquid funk", "neurofunk",
|
||||
"jungle", "breakbeat",
|
||||
"heavy metal", "metal", "thrash metal", "thrash", "speed metal",
|
||||
"power metal", "death metal", "progressive metal", "nwobhm",
|
||||
"classic metal",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "dance",
|
||||
"name": "hair-metal",
|
||||
"tags": [
|
||||
"electro house", "house", "big room", "electronic dance music",
|
||||
"edm", "hardstyle", "trance", "dubstep", "electro",
|
||||
"hair metal", "glam metal", "glam rock", "arena rock", "aor",
|
||||
"rock and roll", "rock n roll",
|
||||
],
|
||||
"years": [1975, 1994],
|
||||
},
|
||||
{
|
||||
"name": "nu-metal",
|
||||
"tags": [
|
||||
"nu metal", "nu-metal", "alternative metal", "rapcore",
|
||||
"industrial metal", "industrial rock", "industrial",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "classic-rock",
|
||||
"tags": [
|
||||
"classic rock", "progressive rock", "psychedelic rock",
|
||||
"blues rock", "70s", "60s",
|
||||
"classic rock", "progressive rock", "psychedelic rock", "psychedelic",
|
||||
"blues rock", "blues", "southern rock", "art rock", "space rock",
|
||||
"british invasion", "folk rock", "70s", "60s",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "80s-synths",
|
||||
# Without the bare `80s` tag, which in this library sits on Def Leppard
|
||||
# and Bon Jovi rather than on anything with a synthesiser in it. The
|
||||
# year window is kept as a second filter, not as the only one.
|
||||
"tags": [
|
||||
"synthpop", "electropop", "new wave", "post-punk",
|
||||
"post-punk revival", "new romantic",
|
||||
],
|
||||
"years": [1975, 1992],
|
||||
},
|
||||
{
|
||||
"name": "indie",
|
||||
"tags": ["indie", "indie rock", "indie pop", "britpop", "singer-songwriter"],
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1198,3 +1198,37 @@ def test_a_real_failure_is_not_recorded_so_the_next_pass_retries(tmp_path):
|
||||
|
||||
# One artist failed hard and must still be pending.
|
||||
assert store.scalar("SELECT COUNT(*) FROM artist_tag_fetched") == 1
|
||||
|
||||
|
||||
# Tags that carry real weight in a real library, against tags that describe a
|
||||
# passport, span most of the collection, or are somebody's artist name.
|
||||
USELESS_TAGS = {
|
||||
"american", "british", "australian", "canadian", "swedish", "dutch", "german",
|
||||
"scottish", "english", "uk", "usa", "canada",
|
||||
"rock", "electronic", "pop", "alternative", "metal ", "all", "heavy",
|
||||
"female vocalists", "male vocalists", "female vocalist",
|
||||
"my top songs", "cover", "covers", "not emo",
|
||||
"green day", "paramore", "queen", "bon jovi", "shinedown", "aerosmith",
|
||||
"journey", "fleetwood mac",
|
||||
}
|
||||
|
||||
|
||||
def test_no_mood_selects_on_a_useless_tag():
|
||||
"""Nationality is not a sound; `rock` and `electronic` span most of the
|
||||
library; and Last.fm's top tag for an artist is often their own name."""
|
||||
for vibe in music_curator.DEFAULT_VIBES:
|
||||
overlap = {tag.casefold() for tag in vibe["tags"]} & USELESS_TAGS
|
||||
assert not overlap, f"{vibe['name']} selects on {overlap}"
|
||||
|
||||
|
||||
def test_mood_names_are_unique():
|
||||
names = [vibe["name"] for vibe in music_curator.DEFAULT_VIBES]
|
||||
assert len(names) == len(set(names))
|
||||
|
||||
|
||||
def test_the_eighties_mood_does_not_lean_on_the_bare_decade_tag():
|
||||
"""In this library `80s` sits on Def Leppard and Bon Jovi, not on
|
||||
synthesisers. The hair-metal mood is where those belong."""
|
||||
synths = next(v for v in music_curator.DEFAULT_VIBES if v["name"] == "80s-synths")
|
||||
assert "80s" not in synths["tags"]
|
||||
assert synths["years"] == [1975, 1992]
|
||||
|
||||
Reference in New Issue
Block a user