From 9e1aa338cf89a232c847520be9643bb898ebb205 Mon Sep 17 00:00:00 2001 From: nasvidia Date: Sun, 5 May 2024 15:05:17 +0100 Subject: [PATCH 1/2] (maint) filter music search results. --- TODO | 1 + spotify/spotify.go | 4 +- spotify/spotify_test.go | 4 +- utils/utils.go | 32 +++++- utils/utils_test.go | 89 ++++++++++++++ web/music.go | 73 +++++++++++- web/music.html | 2 +- web/music_test.go | 249 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 441 insertions(+), 13 deletions(-) create mode 100644 web/music_test.go diff --git a/TODO b/TODO index 3452ae8..a9f3104 100644 --- a/TODO +++ b/TODO @@ -6,6 +6,7 @@ ## bugs +- bastille is showing "give me the future" as an album. wrong !! - add plex name hover over for tv/movies/music, so we can identify if there is a mismatch between the plex name and the search name - allow amazon tv search for indivdual series - remove links to tv series we already have in plex. eg dont show adventure time series 1 and 2 ? diff --git a/spotify/spotify.go b/spotify/spotify.go index 2bc2abb..acd7fb4 100644 --- a/spotify/spotify.go +++ b/spotify/spotify.go @@ -174,11 +174,13 @@ func SearchSpotifyAlbums(artistID, clientID, clientSecret string) (albums []type _ = json.Unmarshal(body, &albumsResponse) for i := range albumsResponse.Items { + // convert "2022-06-03" to "2022" + year := strings.Split(albumsResponse.Items[i].ReleaseDate, "-")[0] albums = append(albums, types.MusicSearchAlbumResult{ Title: albumsResponse.Items[i].Name, ID: albumsResponse.Items[i].ID, URL: albumsResponse.Items[i].ExternalUrls.Spotify, - Year: albumsResponse.Items[i].ReleaseDate, + Year: year, }) } diff --git a/spotify/spotify_test.go b/spotify/spotify_test.go index e1ee187..8e6e5fe 100644 --- a/spotify/spotify_test.go +++ b/spotify/spotify_test.go @@ -76,7 +76,7 @@ func TestSearchSpotifyArtistDebug(t *testing.T) { if spotifyClientID == "" || spotifyClientSecret == "" { t.Skip("SPOTIFY_CLIENT_ID and SPOTIFY_CLIENT_SECRET not set") } - artist := &types.PlexMusicArtist{Name: "Aaliyah"} + artist := &types.PlexMusicArtist{Name: "Angel Olsen"} artistSearchResult, err := SearchSpotifyArtist(artist, spotifyClientID, spotifyClientSecret) if err != nil { t.Errorf("SearchSpotifyArtist() error = %v", err) @@ -88,7 +88,7 @@ func TestSearchSpotifyAlbumsDebug(t *testing.T) { if spotifyClientID == "" || spotifyClientSecret == "" { t.Skip("SPOTIFY_CLIENT_ID and SPOTIFY_CLIENT_SECRET not set") } - artistID := "0urTpYCsixqZwgNTkPJOJ4" + artistID := "6mKqFxGMS5TGDZI3XkT5Rt" artistSearchResult, err := SearchSpotifyAlbums(artistID, spotifyClientID, spotifyClientSecret) if err != nil { t.Errorf("SearchSpotifyAlbum() error = %v", err) diff --git a/utils/utils.go b/utils/utils.go index 0f5669f..e54caa3 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,8 +1,10 @@ package utils import ( + "regexp" "slices" "strconv" + "strings" "time" "github.com/tphoney/plex-lookup/types" @@ -13,8 +15,7 @@ func MarkBestMatch(search *types.SearchResults) types.SearchResults { for i := range search.MovieSearchResults { // normally a match if the year is within 1 year of each other resultYear := YearToDate(search.MovieSearchResults[i].Year) - if search.MovieSearchResults[i].FoundTitle == search.PlexMovie.Title && (resultYear.Year() == expectedYear.Year() || - resultYear.Year() == expectedYear.Year()-1 || resultYear.Year() == expectedYear.Year()+1) { + if search.MovieSearchResults[i].FoundTitle == search.PlexMovie.Title && WitinOneYear(resultYear.Year(), expectedYear.Year()) { search.MovieSearchResults[i].BestMatch = true if search.MovieSearchResults[i].Format == types.DiskBluray { search.MatchesBluray++ @@ -26,9 +27,7 @@ func MarkBestMatch(search *types.SearchResults) types.SearchResults { } for i := range search.TVSearchResults { resultYear := YearToDate(search.TVSearchResults[i].Year) - if search.TVSearchResults[i].FoundTitle == search.PlexTVShow.Title && - // normally a match if the year is within 1 year of each other - (resultYear.Year() == expectedYear.Year() || resultYear.Year() == expectedYear.Year()-1 || resultYear.Year() == expectedYear.Year()+1) { + if search.TVSearchResults[i].FoundTitle == search.PlexTVShow.Title && WitinOneYear(resultYear.Year(), expectedYear.Year()) { search.TVSearchResults[i].BestMatch = true if slices.Contains(search.TVSearchResults[i].Format, types.DiskBluray) { search.MatchesBluray++ @@ -48,3 +47,26 @@ func YearToDate(yearString string) time.Time { } return time.Date(year, 1, 1, 0, 0, 0, 0, time.UTC) } + +func CompareTitles(title1, title2 string) bool { + // remove anything between () + r := regexp.MustCompile(`\((.*?)\)`) + title1 = r.ReplaceAllString(title1, "") + title2 = r.ReplaceAllString(title2, "") + // remove anything between [] + r = regexp.MustCompile(`\[(.*?)\]`) + title1 = r.ReplaceAllString(title1, "") + title2 = r.ReplaceAllString(title2, "") + // remove anything between {} + r = regexp.MustCompile(`\{(.*?)\}`) + title1 = r.ReplaceAllString(title1, "") + title2 = r.ReplaceAllString(title2, "") + // strip whitespace + title1 = strings.TrimSpace(title1) + title2 = strings.TrimSpace(title2) + return title1 == title2 +} + +func WitinOneYear(year1, year2 int) bool { + return year1 == year2 || year1 == year2-1 || year1 == year2+1 +} diff --git a/utils/utils_test.go b/utils/utils_test.go index d18c2bf..b9fca7a 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -1,6 +1,7 @@ package utils import ( + "fmt" "testing" "time" @@ -116,3 +117,91 @@ func TestMarkBestMatch(t *testing.T) { } } } + +func Test_albumTitlesMatch(t *testing.T) { + tests := []struct { + title1 string + title2 string + want bool + }{ + { + title1: "Test Album", + title2: "Test Album", + want: true, + }, + { + title1: "Test Album (Deluxe Edition)", + title2: "Test Album", + want: true, + }, + { + title1: "Test Album [Remastered]", + title2: "Test Album", + want: true, + }, + { + title1: "Test Album {Special Edition}", + title2: "Test Album", + want: true, + }, + { + title1: "Test Album (Deluxe Edition) [Remastered] {Special Edition}", + title2: "Test Album", + want: true, + }, + { + title1: "Test Album (Live)", + title2: "Test Album (Studio)", + want: true, + }, + { + title1: "Test Album [Remastered]", + title2: "Test Album2 [Deluxe Edition]", + want: false, + }, + } + for _, tt := range tests { + t.Run(fmt.Sprintf("title1=%s, title2=%s", tt.title1, tt.title2), func(t *testing.T) { + if got := CompareTitles(tt.title1, tt.title2); got != tt.want { + t.Errorf("albumTitlesMatch() = %v, want %v", got, tt.want) + } + }) + } +} +func TestWitinOneYear(t *testing.T) { + // Test case 1: Same year + year1 := 2022 + year2 := 2022 + expectedResult := true + result := WitinOneYear(year1, year2) + if result != expectedResult { + t.Errorf("Expected %v, but got %v", expectedResult, result) + } + + // Test case 2: Year difference of 1 + year1 = 2022 + year2 = 2021 + expectedResult = true + result = WitinOneYear(year1, year2) + if result != expectedResult { + t.Errorf("Expected %v, but got %v", expectedResult, result) + } + + // Test case 3: Year difference of -1 + year1 = 2022 + year2 = 2023 + expectedResult = true + result = WitinOneYear(year1, year2) + if result != expectedResult { + t.Errorf("Expected %v, but got %v", expectedResult, result) + } + + // Test case 4: Year difference greater than 1 + year1 = 2022 + year2 = 2020 + expectedResult = false + result = WitinOneYear(year1, year2) + if result != expectedResult { + t.Errorf("Expected %v, but got %v", expectedResult, result) + } +} diff --git a/web/music.go b/web/music.go index c35b514..705ac84 100644 --- a/web/music.go +++ b/web/music.go @@ -5,12 +5,14 @@ import ( "fmt" "html/template" "net/http" + "strconv" "time" "github.com/tphoney/plex-lookup/musicbrainz" "github.com/tphoney/plex-lookup/plex" "github.com/tphoney/plex-lookup/spotify" "github.com/tphoney/plex-lookup/types" + "github.com/tphoney/plex-lookup/utils" ) var ( @@ -22,6 +24,7 @@ var ( totalArtists int = 0 plexMusic []types.PlexMusicArtist artistsSearchResults []types.SearchResults + albumReleaseYearCutoff int = 2 ) func musicHandler(w http.ResponseWriter, _ *http.Request) { @@ -44,7 +47,7 @@ func processArtistHTML(w http.ResponseWriter, r *http.Request) { var searchResult types.SearchResults artistsJobRunning = true numberOfArtistsProcessed = 0 - totalArtists = 49 // len(plexMusic) - 1 + totalArtists = len(plexMusic) - 1 fmt.Fprintf(w, `
`, numberOfArtistsProcessed, totalArtists) @@ -67,7 +70,7 @@ func processArtistHTML(w http.ResponseWriter, r *http.Request) { // search spotify go func() { startTime := time.Now() - for i := 0; i < 50; i++ { + for i := range plexMusic { fmt.Print(".") searchResult, _ = spotify.SearchSpotifyArtist(&plexMusic[i], config.SpotifyClientID, config.SpotifyClientSecret) artistsSearchResults = append(artistsSearchResults, searchResult) @@ -104,15 +107,16 @@ func artistProgressBarHTML(w http.ResponseWriter, _ *http.Request) { } func renderArtistsTable(searchResults []types.SearchResults) (tableRows string) { + searchResults = filterMusicSearchResults(searchResults) tableRows = `Plex ArtistAlbumsAlbum` //nolint: lll for i := range searchResults { if len(searchResults[i].MusicSearchResults) > 0 { - tableRows += fmt.Sprintf("%s%d