Initial commit — AllMusicGuide scraper and music metadata tagger

This commit is contained in:
2026-05-10 02:49:16 +00:00
commit 4a541ca04b
194 changed files with 46364 additions and 0 deletions
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess;
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Scraper;
using MusicMetaTagger.Client.AllMusicGuide.Services;
using MusicMetaTagger.Core.Queries;
using NUnit.Framework;
namespace MusicMetaTagger.Client.AllMusicGuide.Tests.Services
{
[TestFixture]
public class MusicGuideSearcherTests
{
[Test, Explicit]
public void SearchTrackTests()
{
var trackSearcher = new TrackSearcher(
new MusicGuideScraper(
new AlbumScraper(), new AlbumResultPageScraper(),
new ArtistScraper(), new ArtistResultPageScraper(), new ArtistDiscographyScraper(),
new SongResultPageScraper(), new SongScraper()));
trackSearcher.SearchStatusUpdate += status => Debug.WriteLine(status.Status);
var trackQueries =
new List<TrackQuery>
{
//new TrackQuery { ArtistName = "The Beach Boys", AlbumTitle = "The Smile Sessions", TrackTitle = "Gee", TrackLength = new TimeSpan(0,0,0,52), TrackNumber = 2},
//new TrackQuery { ArtistName = "Wipers", AlbumTitle = "Wipers Box Set (disc 2: Youth of America)", TrackTitle = "When It's Over", TrackLength = new TimeSpan(0,0,6,36), TrackNumber = 6},
//new TrackQuery { ArtistName = "Bonnie 'Prince' Billy & Matt Sweeney", AlbumTitle = "Superwolf", TrackTitle = "My Home Is the Sea", TrackLength = new TimeSpan(0,0,5,49), TrackNumber = 1},
//new TrackQuery { ArtistName = "Aimee Mann & Michael Penn", AlbumTitle = "I Am Sam", TrackTitle = "Two of Us", TrackLength = new TimeSpan(0,0,3,31), TrackNumber = 1},
//new TrackQuery { ArtistName = "rufus wainwright", AlbumTitle = "I Am Sam", TrackTitle = "Across the Universe", TrackLength = new TimeSpan(0,0,4,08), TrackNumber = 3},
//new TrackQuery { ArtistName = "T.I.", AlbumTitle = "Pitchfork - Best of 2006", TrackTitle = "What You Know", TrackLength = new TimeSpan(0,0,4,34), AlbumPartOfCompilation = true},
//new TrackQuery { ArtistName = "Dios", AlbumTitle = "Dios", TrackTitle = "Nobody's Perfect", TrackLength = new TimeSpan(0,0,5,27), TrackNumber = 1},
//new TrackQuery {ArtistName = "Jan Hammer", TrackTitle = "Crockett's Theme"}
//new TrackQuery { AlbumTitle = "Magnolia", TrackTitle = "One"},
//new TrackQuery {ArtistName = "!!!", TrackTitle = "Myth Takes"},
//new TrackQuery {ArtistName = "!!!", AlbumTitle = "Myth Takes", TrackTitle = "Myth Takes", TrackNumber = 1},
//new TrackQuery {ArtistName = "Queen", TrackTitle = "Another One Bites the Dust"},
//new TrackQuery {ArtistName = "Radiohad", TrackTitle = "Paranod Androd"},
//new TrackQuery{ArtistName = "Modest Mouse", AlbumTitle = "The Lonely Crowded West", TrackTitle = "Cowboy Dan"},
//new TrackQuery("Ruling the World") {ArtistName = "Jarvis Cocker"},
//new TrackQuery {ArtistName = "Radiohead", TrackTitle = "Melatonin"}
//new TrackQuery {ArtistName = "Flying Lotus feat. Thom Yorke", TrackTitle = "...and the World Laughs With You", AlbumArtistName = "Flying Lotus"},
//new TrackQuery {ArtistName = "Flying Lotus", TrackTitle = "...and the World Laughs With You", AlbumArtistName = "Flying Lotus"}
//new TrackQuery {ArtistName = "Bill Frisell", TrackTitle = "I Heard It Through the Grapevine", AlbumTitle = "East/West"}
//new TrackQuery {ArtistName = "Christopher O'Riley", TrackTitle = "Everything In It's Right Place", AlbumTitle = "True Love Waits: Christopher O'Riley Plays Radiohead"}
//new TrackQuery {ArtistName = "Roger Waters", TrackTitle = "Comfortably Numb (live) (feat. Van Morrison & The Band)", AlbumTitle = "The Departed", AlbumPartOfCompilation = true, TrackLength = new TimeSpan(0,0,8,0), TrackNumber = 1}
//new TrackQuery {ArtistName = "Sharon Phillips", TrackTitle = "Want 2 / Need 2 (Trentemøller remix)", AlbumTitle = "The Trentemøller Chronicles (disc 2)", AlbumPartOfCompilation = false, TrackLength = new TimeSpan(0,0,6,03), TrackNumber = 8},
//new TrackQuery {ArtistName = "Cozy Powell", TrackTitle = "Dance with the Devil", AlbumTitle = "Hot Fuzz", AlbumPartOfCompilation = false, TrackLength = new TimeSpan(0,0,3,17), TrackNumber = 5}
new TrackQuery {ArtistName = "Alice in Chains", TrackTitle = "Rooster", AlbumTitle = "Dirt", AlbumPartOfCompilation = false, TrackLength = new TimeSpan(0,0,6,15), TrackNumber = 5}
};
foreach (var track in trackQueries.Select(trackQuery => trackSearcher.SearchTrack(trackQuery, new CancellationToken())))
{
Assert.IsNotNull(track);
}
}
}
}
@@ -0,0 +1,94 @@
using System.Xml;
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser;
using MusicMetaTagger.Client.AllMusicGuide.Services;
using MusicMetaTagger.Core.Model;
using MusicMetaTagger.Core.Services;
using NSubstitute;
using NUnit.Framework;
namespace MusicMetaTagger.Client.AllMusicGuide.Tests.Services
{
[TestFixture]
public class TrackRaterTests
{
private IMusicGuide _musicGuide;
private Album _abbeyRoad;
private Artist _beatles;
private Album _killTheMoonLight;
private Album _girlsCanTell;
private Artist _spoon;
private Album _reactor;
private Artist _neilYoung;
private Album _pulpFiction;
private Album _wipersBoxSet;
private Artist _wipers;
private static TEntity LoadObj<TEntity, TParser>(string filename) where TParser : IParser<TEntity>, new()
{
var xml = new XmlDocument();
xml.Load(filename);
return new TParser().Parse(xml);
}
private static Artist LoadArtist(string filename)
{
var xml = new XmlDocument();
xml.Load(filename);
var artist = new ArtistParser().Parse(xml);
artist.Discography = new ArtistDiscographyPageParser().Parse(xml);
return artist;
}
[TestFixtureSetUp]
public void SetUp()
{
_abbeyRoad = LoadObj<Album, AlbumParser>("Album-AbbeyRoad.xml");
_killTheMoonLight = LoadObj<Album, AlbumParser>("Album-KillTheMoonLight.xml");
_girlsCanTell = LoadObj<Album, AlbumParser>("Album-GirlsCanTell.xml");
_reactor = LoadObj<Album, AlbumParser>("Album-Reactor.xml");
_pulpFiction = LoadObj<Album, AlbumParser>("Album-PulpFiction.xml");
_wipersBoxSet = LoadObj<Album, AlbumParser>("Album-WipersBoxSet.xml");
_beatles = LoadArtist("Artist-Beatles.xml");
_spoon = LoadArtist("Artist-Spoon.xml");
_neilYoung = LoadArtist("Artist-NeilYoung.xml");
var wipers = new XmlDocument();
wipers.Load("Artist-Wipers.xml");
_wipers = new ArtistParser().Parse(wipers);
_wipers.Discography = new ArtistDiscographyPageParser().Parse(wipers);
var wipersCompilations = new XmlDocument();
wipersCompilations.Load("ArtistCompilations-Wipers.xml");
_wipers.Discography.AddRange(new ArtistDiscographyPageParser().Parse(wipersCompilations));
_musicGuide = Substitute.For<IMusicGuide>();
_musicGuide.GetAlbum(_abbeyRoad.AlbumId).Returns(_abbeyRoad);
_musicGuide.GetArtist(_beatles.ArtistId).Returns(_beatles);
_musicGuide.GetAlbum(_girlsCanTell.AlbumId).Returns(_girlsCanTell);
_musicGuide.GetAlbum(_killTheMoonLight.AlbumId).Returns(_killTheMoonLight);
_musicGuide.GetArtist(_spoon.ArtistId).Returns(_spoon);
_musicGuide.GetAlbum(_reactor.AlbumId).Returns(_reactor);
_musicGuide.GetArtist(_neilYoung.ArtistId).Returns(_neilYoung);
_musicGuide.GetAlbum(_pulpFiction.AlbumId).Returns(_pulpFiction);
_musicGuide.GetAlbum(_wipersBoxSet.AlbumId).Returns(_wipersBoxSet);
_musicGuide.GetArtist(_wipers.ArtistId).Returns(_wipers);
}
[Test]
public void RateTrackTest()
{
var trackRater = new TrackRater(_musicGuide);
Assert.That(trackRater.RateTrack(_abbeyRoad.Tracks[0]), Is.EqualTo(10));
Assert.That(trackRater.RateTrack(_abbeyRoad.Tracks[1]), Is.EqualTo(10));
Assert.That(trackRater.RateTrack(_abbeyRoad.Tracks[2]), Is.EqualTo(9));
Assert.That(trackRater.RateTrack(_girlsCanTell.Tracks[0]), Is.EqualTo(10));
Assert.That(trackRater.RateTrack(_girlsCanTell.Tracks[1]), Is.EqualTo(9));
Assert.That(trackRater.RateTrack(_killTheMoonLight.Tracks[2]), Is.EqualTo(8));
Assert.That(trackRater.RateTrack(_reactor.Tracks[0]), Is.EqualTo(6));
Assert.That(trackRater.RateTrack(_reactor.Tracks[1]), Is.EqualTo(4));
Assert.That(trackRater.RateTrack(_pulpFiction.Tracks[2]), Is.EqualTo(10));
Assert.That(trackRater.RateTrack(_wipersBoxSet.Tracks[0]), Is.EqualTo(9));
}
}
}
@@ -0,0 +1,49 @@
using System;
using MusicMetaTagger.Client.AllMusicGuide.Services;
using MusicMetaTagger.Core.Model;
using MusicMetaTagger.Core.Queries;
using MusicMetaTagger.Core.Services;
using NUnit.Framework;
namespace MusicMetaTagger.Client.AllMusicGuide.Tests.Services
{
[TestFixture]
public class TrackSimilarityTests
{
[Test]
public void Similarity_Identical()
{
var trackQuery = new TrackQuery { TrackTitle = "track", TrackNumber = 3, TrackLength = new TimeSpan(0, 0, 2, 34) };
var track = new Track {TrackTitle = "track", TrackNumber = 3, TrackLength = new TimeSpan(0, 0, 2, 34)};
Assert.AreEqual(1, TrackSimilarity.Similarity(trackQuery, track));
}
[Test]
public void Similarity_TitleSlightlyDifferent()
{
var trackQuery = new TrackQuery { TrackTitle = "track", TrackNumber = 3, TrackLength = new TimeSpan(0, 0, 2, 34) };
var track = new Track {TrackTitle = "tracker", TrackNumber = 3, TrackLength = new TimeSpan(0, 0, 2, 34)};
Assert.That(TrackSimilarity.Similarity(trackQuery, track), Is.InRange(.8, .99));
}
[Test]
public void Similarity_TimeSlightlyOff()
{
var trackQuery = new TrackQuery { TrackTitle = "track", TrackNumber = 3, TrackLength = new TimeSpan(0, 0, 2, 34) };
var track = new Track {TrackTitle = "track", TrackNumber = 3, TrackLength = new TimeSpan(0, 0, 2, 30)};
Assert.That(TrackSimilarity.Similarity(trackQuery, track), Is.InRange(.95, .995));
}
[Test]
public void Similarity_TrackNumberWrong()
{
var trackQuery = new TrackQuery { TrackTitle = "track", TrackNumber = 3, TrackLength = new TimeSpan(0, 0, 2, 34) };
var track = new Track {TrackTitle = "track", TrackNumber = 2, TrackLength = new TimeSpan(0, 0, 2, 34)};
Assert.That(TrackSimilarity.Similarity(trackQuery, track), Is.InRange(.7, .9));
}
}
}