diff --git a/subwave/.gitignore b/subwave/.gitignore new file mode 100644 index 0000000..c18dd8d --- /dev/null +++ b/subwave/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/subwave/broadcasts/tunecaster-rock-1995-01-14.json b/subwave/broadcasts/tunecaster-rock-1995-01-14.json new file mode 100644 index 0000000..a814f91 --- /dev/null +++ b/subwave/broadcasts/tunecaster-rock-1995-01-14.json @@ -0,0 +1,36 @@ +{ + "station": "Tunecaster Rock Top 30", + "date": "1995-01-14", + "tracks": [ + {"rank": 1, "artist": "Green Day", "title": "When I Come Around"}, + {"rank": 2, "artist": "Pearl Jam", "title": "Better Man"}, + {"rank": 3, "artist": "The Flaming Lips", "title": "She Don't Use Jelly"}, + {"rank": 4, "artist": "Weezer", "title": "Buddy Holly"}, + {"rank": 5, "artist": "Van Halen", "title": "Don't Tell Me (What Love Can Do)"}, + {"rank": 6, "artist": "The Offspring", "title": "Gotta Get Away"}, + {"rank": 7, "artist": "Bush", "title": "Everything Zen"}, + {"rank": 8, "artist": "Portishead", "title": "Sour Times (Nobody Loves Me)"}, + {"rank": 9, "artist": "Nine Inch Nails", "title": "Piggy"}, + {"rank": 10, "artist": "Alice In Chains", "title": "Got Me Wrong"}, + {"rank": 11, "artist": "Tom Petty", "title": "You Wreck Me"}, + {"rank": 12, "artist": "Queensryche", "title": "Bridge"}, + {"rank": 13, "artist": "Oasis", "title": "Live Forever"}, + {"rank": 14, "artist": "The Stone Roses", "title": "Love Spreads"}, + {"rank": 15, "artist": "Stone Temple Pilots", "title": "Unglued"}, + {"rank": 16, "artist": "Pearl Jam", "title": "Corduroy"}, + {"rank": 17, "artist": "Counting Crows", "title": "A Murder Of One"}, + {"rank": 18, "artist": "Tom Petty", "title": "You Don't Know How It Feels"}, + {"rank": 19, "artist": "R.E.M.", "title": "Bang And Blame"}, + {"rank": 20, "artist": "Jimmy Page & Robert Plant", "title": "Thank You"}, + {"rank": 21, "artist": "Aerosmith", "title": "Blind Man"}, + {"rank": 22, "artist": "Nirvana", "title": "The Man Who Sold The World"}, + {"rank": 23, "artist": "The Cranberries", "title": "Ode To My Family"}, + {"rank": 24, "artist": "Rancid", "title": "Roots Radical"}, + {"rank": 25, "artist": "Pete Droge", "title": "If You Don't Love Me (I'll Kill Myself)"}, + {"rank": 26, "artist": "Soundgarden", "title": "Fell On Black Days"}, + {"rank": 27, "artist": "Sponge", "title": "Plowed"}, + {"rank": 28, "artist": "The Cranberries", "title": "Zombie"}, + {"rank": 29, "artist": "Throwing Muses", "title": "Bright Yellow Gun"}, + {"rank": 30, "artist": "Hole", "title": "Doll Parts"} + ] +} diff --git a/subwave/broadcasts/tunecaster-rock-1995-06-10.json b/subwave/broadcasts/tunecaster-rock-1995-06-10.json new file mode 100644 index 0000000..9b16b03 --- /dev/null +++ b/subwave/broadcasts/tunecaster-rock-1995-06-10.json @@ -0,0 +1,156 @@ +{ + "station": "Tunecaster Rock Top 30", + "date": "1995-06-10", + "tracks": [ + { + "rank": 1, + "artist": "Soul Asylum", + "title": "Runaway Train" + }, + { + "rank": 2, + "artist": "Collective Soul", + "title": "December" + }, + { + "rank": 3, + "artist": "Live", + "title": "All Over You" + }, + { + "rank": 4, + "artist": "U2", + "title": "Hold Me, Thrill Me, Kiss Me, Kill Me" + }, + { + "rank": 5, + "artist": "Green Day", + "title": "She" + }, + { + "rank": 6, + "artist": "R.E.M.", + "title": "Strange Currencies" + }, + { + "rank": 7, + "artist": "Bush", + "title": "Little Things" + }, + { + "rank": 8, + "artist": "Nirvana", + "title": "Lake Of Fire" + }, + { + "rank": 9, + "artist": "White Zombie", + "title": "More Human Than Human" + }, + { + "rank": 10, + "artist": "Sponge", + "title": "Molly (Sixteen Candles)" + }, + { + "rank": 11, + "artist": "The Magnificent Bastards", + "title": "Mockingbird Girl" + }, + { + "rank": 12, + "artist": "Radiohead", + "title": "Fake Plastic Trees" + }, + { + "rank": 13, + "artist": "Blues Traveler", + "title": "Run-Around" + }, + { + "rank": 14, + "artist": "Nine Inch Nails", + "title": "Hurt" + }, + { + "rank": 15, + "artist": "Filter", + "title": "Hey Man, Nice Shot" + }, + { + "rank": 16, + "artist": "Catherine Wheel", + "title": "Waydown" + }, + { + "rank": 17, + "artist": "The Black Crowes", + "title": "Wiser Time" + }, + { + "rank": 18, + "artist": "Weezer", + "title": "Say It Ain't So" + }, + { + "rank": 19, + "artist": "Monster Magnet", + "title": "Negasonic Teenage Warhead" + }, + { + "rank": 20, + "artist": "The Rembrandts", + "title": "I'll Be There For You" + }, + { + "rank": 21, + "artist": "The Offspring", + "title": "Self Esteem" + }, + { + "rank": 22, + "artist": "Van Halen", + "title": "Amsterdam" + }, + { + "rank": 23, + "artist": "Hum", + "title": "Stars" + }, + { + "rank": 24, + "artist": "Mad Season", + "title": "River Of Deceit" + }, + { + "rank": 25, + "artist": "The Cranberries", + "title": "Ridiculous Thoughts" + }, + { + "rank": 26, + "artist": "Better Than Ezra", + "title": "Good" + }, + { + "rank": 27, + "artist": "Pink Floyd", + "title": "What Do You Want From Me" + }, + { + "rank": 28, + "artist": "Tom Petty", + "title": "It's Good To Be King" + }, + { + "rank": 29, + "artist": "Stone Temple Pilots", + "title": "Dancing Days" + }, + { + "rank": 30, + "artist": "Jill Sobule", + "title": "I Kissed A Girl" + } + ] +} \ No newline at end of file diff --git a/subwave/broadcasts/tunecaster-rock-1995-10-28.json b/subwave/broadcasts/tunecaster-rock-1995-10-28.json new file mode 100644 index 0000000..21da7bb --- /dev/null +++ b/subwave/broadcasts/tunecaster-rock-1995-10-28.json @@ -0,0 +1,36 @@ +{ + "station": "Tunecaster Rock Top 30", + "date": "1995-10-28", + "tracks": [ + {"rank": 1, "artist": "The Smashing Pumpkins", "title": "Bullet With Butterfly Wings"}, + {"rank": 2, "artist": "Foo Fighters", "title": "I'll Stick Around"}, + {"rank": 3, "artist": "Red Hot Chili Peppers", "title": "My Friends"}, + {"rank": 4, "artist": "Green Day", "title": "Geek Stink Breath"}, + {"rank": 5, "artist": "Alanis Morissette", "title": "Hand In My Pocket"}, + {"rank": 6, "artist": "Goo Goo Dolls", "title": "Name"}, + {"rank": 7, "artist": "Toadies", "title": "Possum Kingdom"}, + {"rank": 8, "artist": "Ozzy Osbourne", "title": "Perry Mason"}, + {"rank": 9, "artist": "Seven Mary Three", "title": "Cumbersome"}, + {"rank": 10, "artist": "Alice In Chains", "title": "Grind"}, + {"rank": 11, "artist": "The Presidents Of The United States Of America", "title": "Lump"}, + {"rank": 12, "artist": "Toad The Wet Sprocket", "title": "Good Intentions"}, + {"rank": 13, "artist": "Garbage", "title": "Queer"}, + {"rank": 14, "artist": "Melissa Etheridge", "title": "Your Little Secret"}, + {"rank": 15, "artist": "Oasis", "title": "Morning Glory"}, + {"rank": 16, "artist": "Edwyn Collins", "title": "A Girl Like You"}, + {"rank": 17, "artist": "AC/DC", "title": "Hard As A Rock"}, + {"rank": 18, "artist": "Blues Traveler", "title": "Hook"}, + {"rank": 19, "artist": "Folk Implosion", "title": "Natural One"}, + {"rank": 20, "artist": "The Rentals", "title": "Friends Of P."}, + {"rank": 21, "artist": "Candlebox", "title": "Simple Lessons"}, + {"rank": 22, "artist": "Joan Osborne", "title": "One Of Us"}, + {"rank": 23, "artist": "Rancid", "title": "Time Bomb"}, + {"rank": 24, "artist": "Civ", "title": "Can't Wait One Minute More"}, + {"rank": 25, "artist": "Heather Nova", "title": "Walk This World"}, + {"rank": 26, "artist": "Sponge", "title": "Rainin'"}, + {"rank": 27, "artist": "Lenny Kravitz", "title": "Rock And Roll Is Dead"}, + {"rank": 28, "artist": "Deep Blue Something", "title": "Breakfast At Tiffany's"}, + {"rank": 29, "artist": "Silverchair", "title": "Tomorrow"}, + {"rank": 30, "artist": "Lisa Loeb & Nine Stories", "title": "Do You Sleep?"} + ] +} diff --git a/subwave/broadcasts/tunecaster-rock-1995-12-16.json b/subwave/broadcasts/tunecaster-rock-1995-12-16.json new file mode 100644 index 0000000..b6afa80 --- /dev/null +++ b/subwave/broadcasts/tunecaster-rock-1995-12-16.json @@ -0,0 +1,136 @@ +{ + "station": "Tunecaster Rock Top 30", + "date": "1995-12-16", + "tracks": [ + { + "rank": 1, + "artist": "Bush", + "title": "Glycerine" + }, + { + "rank": 2, + "artist": "Oasis", + "title": "Wonderwall" + }, + { + "rank": 3, + "artist": "The Smashing Pumpkins", + "title": "1979" + }, + { + "rank": 4, + "artist": "Pearl Jam", + "title": "I Got ID" + }, + { + "rank": 6, + "artist": "Seven Mary Three", + "title": "Water's Edge" + }, + { + "rank": 7, + "artist": "Collective Soul", + "title": "The World I Know" + }, + { + "rank": 8, + "artist": "Alanis Morissette", + "title": "All I Really Want" + }, + { + "rank": 9, + "artist": "Red Hot Chili Peppers", + "title": "Give It Away" + }, + { + "rank": 10, + "artist": "The Presidents Of The United States Of America", + "title": "Kitty" + }, + { + "rank": 11, + "artist": "Everclear", + "title": "Santa Monica" + }, + { + "rank": 12, + "artist": "Silverchair", + "title": "Pure Massacre" + }, + { + "rank": 14, + "artist": "Alice In Chains", + "title": "Would?" + }, + { + "rank": 15, + "artist": "Foo Fighters", + "title": "This Is A Call" + }, + { + "rank": 17, + "artist": "No Doubt", + "title": "Just A Girl" + }, + { + "rank": 18, + "artist": "Better Than Ezra", + "title": "Circle of Friends" + }, + { + "rank": 19, + "artist": "Tom Petty And The Heartbreakers", + "title": "Waiting For Tonight" + }, + { + "rank": 20, + "artist": "Rancid", + "title": "Ruby Soho" + }, + { + "rank": 21, + "artist": "Green Day", + "title": "Brain Stew" + }, + { + "rank": 22, + "artist": "Candlebox", + "title": "Far Behind" + }, + { + "rank": 23, + "artist": "Spacehog", + "title": "In The Meantime" + }, + { + "rank": 24, + "artist": "Dave Matthews Band", + "title": "What Would You Say" + }, + { + "rank": 25, + "artist": "AC/DC", + "title": "Cover You In Oil" + }, + { + "rank": 26, + "artist": "Goo Goo Dolls", + "title": "Long Way Down" + }, + { + "rank": 27, + "artist": "Natalie Merchant", + "title": "Carnival" + }, + { + "rank": 28, + "artist": "Ruth Ruth", + "title": "Uninvited" + }, + { + "rank": 29, + "artist": "The Beatles", + "title": "Free As A Bird" + } + ] +} \ No newline at end of file diff --git a/subwave/recreate_broadcast.py b/subwave/recreate_broadcast.py index d367654..f629378 100755 --- a/subwave/recreate_broadcast.py +++ b/subwave/recreate_broadcast.py @@ -158,8 +158,28 @@ def similarity(a, b): return difflib.SequenceMatcher(None, normalize(a), normalize(b)).ratio() +def contains_normalized(a, b): + """True if the normalized forms of a/b contain one another as whole words. + + Handles library tags that carry extra baggage a chart title/artist won't -- + reissue composite credits ("Green Day • Billie Joe Armstrong, Mike Dirnt, + & Tre Cool") or a subtitle the library dropped ("Sour Times" vs "Sour Times + (Nobody Loves Me)") -- without this a correct match can score just under + the threshold on artist or title alone even though one string is clearly + the other plus extra text. + """ + na, nb = f" {normalize(a)} ", f" {normalize(b)} " + return bool(na.strip()) and bool(nb.strip()) and (na in nb or nb in na) + + def score_candidate(song, artist, title): - return similarity(song.get("title", ""), title) * 0.6 + similarity(song.get("artist", ""), artist) * 0.4 + title_score = similarity(song.get("title", ""), title) + if contains_normalized(song.get("title", ""), title): + title_score = max(title_score, 0.9) + artist_score = similarity(song.get("artist", ""), artist) + if contains_normalized(song.get("artist", ""), artist): + artist_score = 1.0 + return title_score * 0.6 + artist_score * 0.4 def match_track(nd_cfg, artist, title, min_score):