diff --git a/TODO b/TODO index fed6447..3636cde 100644 --- a/TODO +++ b/TODO @@ -6,10 +6,10 @@ ## bugs -- 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 newer series +- update movies to use tv like search +- write a function to calculate plex dates - 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 ? -- remove dead fields from the tv data types ## done @@ -26,3 +26,5 @@ - add ui for music search - spotify search - bastille is showing "give me the future" as an album. wrong !! +- remove dead fields from the tv data types +- remove links to tv series we already have in plex. eg dont show adventure time series 1 and 2 ? diff --git a/amazon/amazon.go b/amazon/amazon.go index 7e0acd3..153bb42 100644 --- a/amazon/amazon.go +++ b/amazon/amazon.go @@ -19,9 +19,9 @@ const ( amazonURL = "https://www.blu-ray.com/movies/search.php?keyword=" ) -func ScrapeMovies(movieSearchResult *types.SearchResults) (scrapedResults []types.MovieSearchResult) { +func ScrapeTitles(searchResults *types.SearchResults) (scrapedResults []types.MovieSearchResult) { var results, lookups []types.MovieSearchResult - for _, searchResult := range movieSearchResult.MovieSearchResults { + for _, searchResult := range searchResults.MovieSearchResults { if !searchResult.BestMatch { results = append(results, searchResult) } else { @@ -37,7 +37,7 @@ func ScrapeMovies(movieSearchResult *types.SearchResults) (scrapedResults []type go func() { semaphore <- struct{}{} defer func() { <-semaphore }() - scrapeMovie(&lookups[i], movieSearchResult.PlexMovie.DateAdded, ch) + scrapeTitle(&lookups[i], searchResults.PlexMovie.DateAdded, ch) }() } @@ -49,7 +49,7 @@ func ScrapeMovies(movieSearchResult *types.SearchResults) (scrapedResults []type return results } -func scrapeMovie(movie *types.MovieSearchResult, dateAdded time.Time, ch chan<- *types.MovieSearchResult) { +func scrapeTitle(movie *types.MovieSearchResult, dateAdded time.Time, ch chan<- *types.MovieSearchResult) { req, err := http.NewRequestWithContext(context.Background(), "GET", movie.URL, bytes.NewBuffer([]byte{})) movie.ReleaseDate = time.Time{} if err != nil { @@ -78,14 +78,14 @@ func scrapeMovie(movie *types.MovieSearchResult, dateAdded time.Time, ch chan<- return } rawData := string(body) - movie.ReleaseDate = findMovieDetails(rawData) + movie.ReleaseDate = findTitleDetails(rawData) if movie.ReleaseDate.After(dateAdded) { movie.NewRelease = true } ch <- movie } -func findMovieDetails(response string) (releaseDate time.Time) { +func findTitleDetails(response string) (releaseDate time.Time) { r := regexp.MustCompile(`(.*?)`) match := r.FindStringSubmatch(response) @@ -196,7 +196,7 @@ func SearchAmazonTV(plexTVShow *types.PlexTVShow, filter string) (tvSearchResult } func findTitlesInResponse(response string, movie bool) (movieResults []types.MovieSearchResult, tvResults []types.TVSearchResult) { - // Find the start and end index of the movie entry + // Find the start and end index of the entry for { startIndex := strings.Index(response, ``) match := r.FindAllStringSubmatch(response, -1) for i, m := range match { - tvSeries = append(tvSeries, types.TVSeriesResult{Number: i, URL: m[1]}) + tvSeries = append(tvSeries, types.TVSeasonResult{Number: i, URL: m[1]}) } // remove the first entry as it is general information - results := make([]types.TVSeriesResult, 0, len(tvSeries)) + results := make([]types.TVSeasonResult, 0, len(tvSeries)) if len(tvSeries) > 0 { tvSeries = tvSeries[1:] - ch := make(chan *types.TVSeriesResult, len(tvSeries)) + ch := make(chan *types.TVSeasonResult, len(tvSeries)) semaphore := make(chan struct{}, types.ConcurrencyLimit) for i := range tvSeries { @@ -152,7 +152,7 @@ func findTVSeriesInResponse(response string) (tvSeries []types.TVSeriesResult) { return results } -func makeSeriesRequest(tv types.TVSeriesResult, ch chan<- *types.TVSeriesResult) { +func makeSeriesRequest(tv types.TVSeasonResult, ch chan<- *types.TVSeasonResult) { content := []byte(fmt.Sprintf("FilmID=%s", tv.URL)) req, err := http.NewRequestWithContext(context.Background(), "POST", cinemaparadisoSeriesURL, bytes.NewBuffer(content)) if err != nil { diff --git a/cmd/root.go b/cmd/root.go index 0faf915..e42302e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -62,10 +62,10 @@ func initializeFlags() { func initializePlexMovies() []types.PlexMovie { var allMovies []types.PlexMovie - allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexMovieLibraryID, plexToken, "sd", nil)...) - allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexMovieLibraryID, plexToken, "480", nil)...) - allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexMovieLibraryID, plexToken, "576", nil)...) - allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexMovieLibraryID, plexToken, "720", nil)...) + allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexMovieLibraryID, plexToken, types.PlexResolution240, nil)...) + allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexMovieLibraryID, plexToken, types.PlexResolution480, nil)...) + allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexMovieLibraryID, plexToken, types.PlexResolution576, nil)...) + allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexMovieLibraryID, plexToken, types.PlexResolution720, nil)...) fmt.Printf("\nThere are a total of %d movies in the library.\n\nMovies available:\n", len(allMovies)) return allMovies diff --git a/musicbrainz/musicbrainz_test.go b/musicbrainz/musicbrainz_test.go index 990d38e..71a18fa 100644 --- a/musicbrainz/musicbrainz_test.go +++ b/musicbrainz/musicbrainz_test.go @@ -38,7 +38,7 @@ func TestSearchMusicBrainzArtist(t *testing.T) { { Name: "AC/DC", ID: "66c662b6-6e2f-4930-8610-912e24c63ed1", - Albums: make([]types.MusicSearchAlbumResult, 17), + Albums: make([]types.MusicSearchAlbumResult, 18), }, }, }, diff --git a/plex/plex.go b/plex/plex.go index b61021a..dbff20b 100644 --- a/plex/plex.go +++ b/plex/plex.go @@ -518,7 +518,7 @@ func GetPlexMovies(ipAddress, libraryID, plexToken, resolution string, filters [ return movieList } -func GetPlexTV(ipAddress, libraryID, plexToken string, resolutions []string) (tvShowList []types.PlexTVShow) { +func GetPlexTV(ipAddress, libraryID, plexToken string) (tvShowList []types.PlexTVShow) { url := fmt.Sprintf("http://%s:32400/library/sections/%s/all", ipAddress, libraryID) req, err := http.NewRequestWithContext(context.Background(), "GET", url, http.NoBody) @@ -547,7 +547,7 @@ func GetPlexTV(ipAddress, libraryID, plexToken string, resolutions []string) (tv tvShowList = extractTVShows(string(body)) // now we need to get the episodes for each TV show for i := range tvShowList { - tvShowList[i].Seasons = GetPlexTVSeasons(ipAddress, plexToken, tvShowList[i].RatingKey, resolutions) + tvShowList[i].Seasons = GetPlexTVSeasons(ipAddress, plexToken, tvShowList[i].RatingKey) } // remove TV shows with no seasons var filteredTVShows []types.PlexTVShow @@ -677,7 +677,7 @@ func extractMusicArtists(xmlString string) (artists []types.PlexMusicArtist, err return artists, nil } -func GetPlexTVSeasons(ipAddress, plexToken, ratingKey string, resolutions []string) (seasonList []types.PlexTVSeason) { +func GetPlexTVSeasons(ipAddress, plexToken, ratingKey string) (seasonList []types.PlexTVSeason) { url := fmt.Sprintf("http://%s:32400/library/metadata/%s/children?", ipAddress, ratingKey) req, err := http.NewRequestWithContext(context.Background(), "GET", url, http.NoBody) @@ -707,7 +707,7 @@ func GetPlexTVSeasons(ipAddress, plexToken, ratingKey string, resolutions []stri // os.WriteFile("seasons.xml", body, 0644) // now we need to get the episodes for each TV show for i := range seasonList { - episodes := GetPlexTVEpisodes(ipAddress, plexToken, seasonList[i].RatingKey, resolutions) + episodes := GetPlexTVEpisodes(ipAddress, plexToken, seasonList[i].RatingKey) if len(episodes) > 0 { seasonList[i].Episodes = episodes } @@ -715,14 +715,49 @@ func GetPlexTVSeasons(ipAddress, plexToken, ratingKey string, resolutions []stri // remove seasons with no episodes var filteredSeasons []types.PlexTVSeason for i := range seasonList { - if len(seasonList[i].Episodes) > 0 { - filteredSeasons = append(filteredSeasons, seasonList[i]) + if len(seasonList[i].Episodes) < 1 { + continue } + // lets add all of the resolutions for the episodes + var listOfResolutions []string + for j := range seasonList[i].Episodes { + listOfResolutions = append(listOfResolutions, seasonList[i].Episodes[j].Resolution) + } + // now we have all of the resolutions for the episodes + seasonList[i].LowestResolution = findLowestResolution(listOfResolutions) + // get the last episode added date + seasonList[i].LastEpisodeAdded = seasonList[i].Episodes[len(seasonList[i].Episodes)-1].DateAdded + filteredSeasons = append(filteredSeasons, seasonList[i]) } return filteredSeasons } -func GetPlexTVEpisodes(ipAddress, plexToken, ratingKey string, resolutions []string) (episodeList []types.PlexTVEpisode) { +func findLowestResolution(resolutions []string) (lowestResolution string) { + if slices.Contains(resolutions, types.PlexResolutionSD) { + return types.PlexResolutionSD + } + if slices.Contains(resolutions, types.PlexResolution240) { + return types.PlexResolution240 + } + if slices.Contains(resolutions, types.PlexResolution480) { + return types.PlexResolution480 + } + if slices.Contains(resolutions, types.PlexResolution576) { + return types.PlexResolution576 + } + if slices.Contains(resolutions, types.PlexResolution720) { + return types.PlexResolution720 + } + if slices.Contains(resolutions, types.PlexResolution1080) { + return types.PlexResolution1080 + } + if slices.Contains(resolutions, types.PlexResolution4K) { + return types.PlexResolution4K + } + return "" +} + +func GetPlexTVEpisodes(ipAddress, plexToken, ratingKey string) (episodeList []types.PlexTVEpisode) { url := fmt.Sprintf("http://%s:32400/library/metadata/%s/children?", ipAddress, ratingKey) req, err := http.NewRequestWithContext(context.Background(), "GET", url, http.NoBody) @@ -749,16 +784,6 @@ func GetPlexTVEpisodes(ipAddress, plexToken, ratingKey string, resolutions []str } episodeList = extractTVEpisodes(string(body)) - if len(resolutions) > 0 { - // filter out episodes that don't match the resolution - var filteredEpisodes []types.PlexTVEpisode - for i := range episodeList { - if slices.Contains(resolutions, episodeList[i].Resolution) { - filteredEpisodes = append(filteredEpisodes, episodeList[i]) - } - } - episodeList = filteredEpisodes - } return episodeList } @@ -881,8 +906,16 @@ func extractTVEpisodes(xmlString string) (episodeList []types.PlexTVEpisode) { } for i := range container.Video { + intTime, err := strconv.ParseInt(container.Video[i].AddedAt, 10, 64) + var parsedDate time.Time + if err != nil { + parsedDate = time.Time{} + } else { + parsedDate = time.Unix(intTime, 0) + } episodeList = append(episodeList, types.PlexTVEpisode{ - Title: container.Video[i].Title, Resolution: container.Video[i].Media.VideoResolution, Index: container.Video[i].Index}) + Title: container.Video[i].Title, Resolution: container.Video[i].Media.VideoResolution, + Index: container.Video[i].Index, DateAdded: parsedDate}) } return episodeList } diff --git a/plex/plex_test.go b/plex/plex_test.go index 4b7d271..c4eff6b 100644 --- a/plex/plex_test.go +++ b/plex/plex_test.go @@ -63,7 +63,7 @@ func TestGetPlexTV(t *testing.T) { if plexIP == "" || plexTVLibraryID == "" || plexToken == "" { t.Skip("ACCEPTANCE TEST: PLEX environment variables not set") } - result := GetPlexTV(plexIP, plexTVLibraryID, plexToken, []string{}) + result := GetPlexTV(plexIP, plexTVLibraryID, plexToken) if len(result) == 0 { t.Errorf("Expected at least one TV show, but got %d", len(result)) @@ -78,6 +78,21 @@ func TestGetPlexTV(t *testing.T) { } } +func TestDebugGetPlexTVSeasons(t *testing.T) { + if plexIP == "" || plexTVLibraryID == "" || plexToken == "" { + t.Skip("ACCEPTANCE TEST: PLEX environment variables not set") + } + result := GetPlexTVSeasons(plexIP, plexToken, "5383") + + if len(result) == 0 { + t.Errorf("Expected at least one TV show, but got %d", len(result)) + } + + if len(result[0].Episodes) == 0 { + t.Errorf("Expected at least one episode, but got %d", len(result[0].Episodes)) + } +} + func TestGetPlexMusic(t *testing.T) { if plexIP == "" || plexMusicLibraryID == "" || plexToken == "" { t.Skip("ACCEPTANCE TEST: PLEX environment variables not set") @@ -96,3 +111,34 @@ func TestGetPlexMusic(t *testing.T) { t.Errorf("Expected at least one album, but got %d", len(result[0].Albums)) } } + +func Test_findLowestResolution(t *testing.T) { + tests := []struct { + name string + resolutions []string + wantLowestResolution string + }{ + { + name: "SD is lowest", + resolutions: []string{types.PlexResolutionSD, types.PlexResolution240, types.PlexResolution720, types.PlexResolution1080}, + wantLowestResolution: types.PlexResolutionSD, + }, + { + name: "4k is lowest", + resolutions: []string{types.PlexResolution4K, types.PlexResolution4K}, + wantLowestResolution: types.PlexResolution4K, + }, + { + name: "720 is lowest", + resolutions: []string{types.PlexResolution720, types.PlexResolution1080, types.PlexResolution720, types.PlexResolution1080}, + wantLowestResolution: types.PlexResolution720, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotLowestResolution := findLowestResolution(tt.resolutions); gotLowestResolution != tt.wantLowestResolution { + t.Errorf("findLowestResolution() = %v, want %v", gotLowestResolution, tt.wantLowestResolution) + } + }) + } +} diff --git a/types/types.go b/types/types.go index 4a3e706..6e59e53 100644 --- a/types/types.go +++ b/types/types.go @@ -3,11 +3,18 @@ package types import "time" const ( - DiskBluray = "Blu-ray" - DiskDVD = "DVD" - Disk4K = "4K Blu-ray" - PlexMovieType = "Movie" - ConcurrencyLimit = 10 + DiskBluray = "Blu-ray" + DiskDVD = "DVD" + Disk4K = "4K Blu-ray" + PlexMovieType = "Movie" + PlexResolutionSD = "sd" + PlexResolution240 = "240" + PlexResolution480 = "480" + PlexResolution576 = "576" + PlexResolution720 = "720" + PlexResolution1080 = "1080" + PlexResolution4K = "4k" + ConcurrencyLimit = 10 ) type SearchResults struct { @@ -60,16 +67,19 @@ type PlexTVShow struct { } type PlexTVSeason struct { - Title string - Number int - RatingKey string - Episodes []PlexTVEpisode + Title string + Number int + RatingKey string + LowestResolution string + LastEpisodeAdded time.Time + Episodes []PlexTVEpisode } type PlexTVEpisode struct { Title string Index string Resolution string + DateAdded time.Time } type TVSearchResult struct { @@ -82,10 +92,10 @@ type TVSearchResult struct { ReleaseDate time.Time NewRelease bool BoxSet bool - Series []TVSeriesResult + Seasons []TVSeasonResult } -type TVSeriesResult struct { +type TVSeasonResult struct { Number int URL string Format []string diff --git a/web/movies.go b/web/movies.go index 46c8082..69876b4 100644 --- a/web/movies.go +++ b/web/movies.go @@ -39,13 +39,13 @@ func moviesHandler(w http.ResponseWriter, _ *http.Request) { func processMoviesHTML(w http.ResponseWriter, r *http.Request) { lookup := r.FormValue("lookup") // plex resolutions - sd := r.FormValue("sd") + sd := r.FormValue("SD") r240 := r.FormValue("240p") r480 := r.FormValue("480p") r576 := r.FormValue("576p") r720 := r.FormValue("720p") r1080 := r.FormValue("1080p") - r4k := r.FormValue("4k") + r4k := r.FormValue("4K") plexResolutions := []string{sd, r240, r480, r576, r720, r1080, r4k} // remove empty resolutions var filteredResolutions []string @@ -82,7 +82,7 @@ func processMoviesHTML(w http.ResponseWriter, r *http.Request) { } // if we are filtering by newer version, we need to search again if newerVersion == stringTrue { - scrapedResults := amazon.ScrapeMovies(&searchResult) + scrapedResults := amazon.ScrapeTitles(&searchResult) searchResult.MovieSearchResults = scrapedResults } } diff --git a/web/movies.html b/web/movies.html index b52b0a0..f6e88c2 100644 --- a/web/movies.html +++ b/web/movies.html @@ -30,28 +30,28 @@

Movies

Plex Filter: only compare movies that match the following criteria.
diff --git a/web/tv.go b/web/tv.go index ed416d0..845234b 100644 --- a/web/tv.go +++ b/web/tv.go @@ -6,7 +6,6 @@ import ( "html/template" "net/http" "slices" - "strings" "time" "github.com/tphoney/plex-lookup/amazon" @@ -15,6 +14,11 @@ import ( "github.com/tphoney/plex-lookup/types" ) +type FilteringOptions struct { + AudioLanguage string + NewerVersion bool +} + var ( //go:embed tv.html tvPage string @@ -22,7 +26,9 @@ var ( numberOfTVProcessed int = 0 tvJobRunning bool = false totalTV int = 0 + plexTV []types.PlexTVShow tvSearchResults []types.SearchResults + filters FilteringOptions ) func tvHandler(w http.ResponseWriter, _ *http.Request) { @@ -34,30 +40,16 @@ func tvHandler(w http.ResponseWriter, _ *http.Request) { } } -// nolint: lll, nolintlint func processTVHTML(w http.ResponseWriter, r *http.Request) { lookup := r.FormValue("lookup") - // plex resolutions - sd := r.FormValue("sd") - r240 := r.FormValue("240p") - r480 := r.FormValue("480p") - r576 := r.FormValue("576p") - r720 := r.FormValue("720p") - r1080 := r.FormValue("1080p") - r4k := r.FormValue("4k") - plexResolutions := []string{sd, r240, r480, r576, r720, r1080, r4k} - // remove empty resolutions - var filteredResolutions []string - for _, resolution := range plexResolutions { - if resolution != "" { - filteredResolutions = append(filteredResolutions, resolution) - } - } // lookup filters - german := r.FormValue("german") - // newerVersion := r.FormValue("newerVersion") - // Prepare table plexTV - plexTV := plex.GetPlexTV(config.PlexIP, config.PlexTVLibraryID, config.PlexToken, filteredResolutions) + filters.AudioLanguage = r.FormValue("german") + filters.NewerVersion = r.FormValue("newerVersion") == stringTrue + + if len(plexTV) == 0 { + plexTV = plex.GetPlexTV(config.PlexIP, config.PlexTVLibraryID, config.PlexToken) + } + var searchResult types.SearchResults tvJobRunning = true numberOfTVProcessed = 0 @@ -73,16 +65,12 @@ func processTVHTML(w http.ResponseWriter, r *http.Request) { if lookup == "cinemaParadiso" { searchResult, _ = cinemaparadiso.SearchCinemaParadisoTV(&plexTV[i]) } else { - if german == stringTrue { - searchResult, _ = amazon.SearchAmazonTV(&plexTV[i], "&audio=german") + if filters.AudioLanguage == "german" { + searchResult, _ = amazon.SearchAmazonTV(&plexTV[i], fmt.Sprintf("&audio=%s", filters.AudioLanguage)) } else { searchResult, _ = amazon.SearchAmazonTV(&plexTV[i], "") } - // if we are filtering by newer version, we need to search again - // if newerVersion == stringTrue { - // scrapedResults := amazon.ScrapeMovies(&searchResult) - // searchResult.MovieSearchResults = scrapedResults - // } + // ADD CALL TO GET TV SHOW DETAILS } tvSearchResults = append(tvSearchResults, searchResult) numberOfTVProcessed = i @@ -110,11 +98,18 @@ func tvProgressBarHTML(w http.ResponseWriter, _ *http.Request) { } func renderTVTable(searchResults []types.SearchResults) (tableRows string) { + searchResults = filterTVSearchResults(searchResults) tableRows = `Plex TitleBlu-ray Seasons4K-ray SeasonsDisc` //nolint: lll for i := range searchResults { + // build up plex season / resolution row + seasony := "Season:" + for _, season := range searchResults[i].PlexTVShow.Seasons { + seasony += fmt.Sprintf(" %d@%s,", season.Number, season.LowestResolution) + } + seasony = seasony[:len(seasony)-1] // remove trailing comma tableRows += fmt.Sprintf( - `%s [%v]%d%d`, - searchResults[i].SearchURL, searchResults[i].PlexTVShow.Title, searchResults[i].PlexTVShow.Year, + `%s [%v]
%s
%d%d`, + searchResults[i].SearchURL, searchResults[i].PlexTVShow.Title, searchResults[i].PlexTVShow.Year, seasony, searchResults[i].MatchesBluray, searchResults[i].Matches4k) if (searchResults[i].MatchesBluray + searchResults[i].Matches4k) > 0 { tableRows += "" @@ -124,16 +119,12 @@ func renderTVTable(searchResults []types.SearchResults) (tableRows string) { tableRows += fmt.Sprintf(`%s Box Set
`, searchResults[i].TVSearchResults[j].URL, searchResults[i].TVSearchResults[j].Format[0]) } else { - for _, series := range searchResults[i].TVSearchResults[j].Series { - if slices.Contains(series.Format, types.DiskBluray) || slices.Contains(series.Format, types.Disk4K) { - // remove the dvd format - disks := fmt.Sprintf("%v", series.Format) - disks = strings.ReplaceAll(disks, "DVD ", "") - tableRows += fmt.Sprintf( - `Season %d: %v`, - searchResults[i].TVSearchResults[j].URL, series.Number, disks) - tableRows += "
" - } + for _, season := range searchResults[i].TVSearchResults[j].Seasons { + disks := fmt.Sprintf("%v", season.Format) + tableRows += fmt.Sprintf( + `Season %d: %v`, + searchResults[i].TVSearchResults[j].URL, season.Number, disks) + tableRows += "
" } } } @@ -146,3 +137,82 @@ func renderTVTable(searchResults []types.SearchResults) (tableRows string) { } return tableRows // Return the generated HTML for table rows } + +func filterTVSearchResults(searchResults []types.SearchResults) []types.SearchResults { + searchResults = removeOwnedTVSeasons(searchResults) + if filters.NewerVersion { + searchResults = removeOldDiscReleases(searchResults) + } + return searchResults +} + +func removeOwnedTVSeasons(searchResults []types.SearchResults) []types.SearchResults { + for i := range searchResults { + if len(searchResults[i].TVSearchResults) > 0 { + tvSeasonsToRemove := make([]types.TVSeasonResult, 0) + // iterate over plex tv season + for _, plexSeasons := range searchResults[i].PlexTVShow.Seasons { + // iterate over search results + for _, searchSeasons := range searchResults[i].TVSearchResults[0].Seasons { + if searchSeasons.Number == plexSeasons.Number && !discBeatsPlexResolution(plexSeasons.LowestResolution, searchSeasons.Format) { + tvSeasonsToRemove = append(tvSeasonsToRemove, searchSeasons) + } + } + } + searchResults[i].TVSearchResults[0].Seasons = cleanTVSeasons(searchResults[i].TVSearchResults[0].Seasons, tvSeasonsToRemove) + } + } + return searchResults +} + +func removeOldDiscReleases(searchResults []types.SearchResults) []types.SearchResults { + for i := range searchResults { + if len(searchResults[i].TVSearchResults) > 0 { + tvSeasonsToRemove := make([]types.TVSeasonResult, 0) + // iterate over plex tv season + for _, plexSeasons := range searchResults[i].PlexTVShow.Seasons { + // iterate over search results + for _, searchSeasons := range searchResults[i].TVSearchResults[0].Seasons { + if searchSeasons.ReleaseDate.Compare(plexSeasons.LastEpisodeAdded) == 1 { + tvSeasonsToRemove = append(tvSeasonsToRemove, searchSeasons) + } + } + } + searchResults[i].TVSearchResults[0].Seasons = cleanTVSeasons(searchResults[i].TVSearchResults[0].Seasons, tvSeasonsToRemove) + } + } + return searchResults +} + +func cleanTVSeasons(original, toRemove []types.TVSeasonResult) []types.TVSeasonResult { + cleaned := make([]types.TVSeasonResult, 0) + for _, season := range original { + found := false + for _, remove := range toRemove { + if season.Number == remove.Number { + found = true + break + } + } + if !found { + cleaned = append(cleaned, season) + } + } + return cleaned +} + +func discBeatsPlexResolution(lowestPlexResolution string, format []string) bool { + for i := range format { + switch format[i] { + case types.Disk4K: + return true // 4K beats everything + case types.DiskBluray: + if slices.Contains([]string{types.PlexResolution1080, types.PlexResolution720, // HD + types.PlexResolution576, types.PlexResolution480, types.PlexResolution240, types.PlexResolutionSD}, // SD + lowestPlexResolution) { + return true + } + } // DVD is not considered + } + return false +} diff --git a/web/tv.html b/web/tv.html index 1278f7c..e665156 100644 --- a/web/tv.html +++ b/web/tv.html @@ -27,33 +27,6 @@

TV

-
- Plex Filter: only compare TV series that match the following criteria. - - - - - - -
Lookup: