mirror of
https://github.com/JasonHHouse/gaps.git
synced 2026-05-08 09:59:15 -05:00
Fixing bad char issue and adding new tests to catch
This commit is contained in:
@@ -14,9 +14,13 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.jasonhhouse.gaps.json.MovieDeserializer;
|
||||
import com.jasonhhouse.gaps.json.MovieSerializer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -142,6 +146,10 @@ public final class Movie implements Comparable<Movie> {
|
||||
return moviesInCollection;
|
||||
}
|
||||
|
||||
public @NotNull String getNameWithoutBadCharacters() {
|
||||
return nameWithoutBadCharacters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@@ -170,7 +178,7 @@ public final class Movie implements Comparable<Movie> {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, year);
|
||||
return Objects.hash(nameWithoutBadCharacters, year);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -183,18 +191,20 @@ public final class Movie implements Comparable<Movie> {
|
||||
return "Movie{" +
|
||||
"name='" + name + '\'' +
|
||||
", year=" + year +
|
||||
", nameWithoutBadCharacters='" + nameWithoutBadCharacters + '\'' +
|
||||
", posterUrl='" + posterUrl + '\'' +
|
||||
", collection='" + collection + '\'' +
|
||||
", collectionId=" + collectionId +
|
||||
", tvdbId=" + tvdbId +
|
||||
", imdbId='" + imdbId + '\'' +
|
||||
", language='" + language + '\'' +
|
||||
", overview='" + overview + '\'' +
|
||||
", collection='" + collection + '\'' +
|
||||
", collectionId=" + collectionId +
|
||||
", tvdbId=" + tvdbId +
|
||||
", moviesInCollection=" + moviesInCollection +
|
||||
'}';
|
||||
}
|
||||
|
||||
public int compareTo(Movie o) {
|
||||
return getName().compareTo(o.getName());
|
||||
return getNameWithoutBadCharacters().compareTo(o.getNameWithoutBadCharacters());
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
@@ -24,21 +24,20 @@ import com.jasonhhouse.gaps.SearchCancelledException;
|
||||
import com.jasonhhouse.gaps.SearchResults;
|
||||
import com.jasonhhouse.gaps.UrlGenerator;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.Year;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
@@ -154,7 +153,7 @@ public class GapsSearchService implements GapsSearch {
|
||||
|
||||
@Override
|
||||
public void cancelSearch() {
|
||||
LOGGER.debug("cancelSearch()");
|
||||
LOGGER.info("cancelSearch()");
|
||||
cancelSearch.set(true);
|
||||
}
|
||||
|
||||
@@ -277,8 +276,8 @@ public class GapsSearchService implements GapsSearch {
|
||||
}
|
||||
|
||||
if (results.size() > 1) {
|
||||
LOGGER.debug("Results for " + movie + " came back with " + results.size() + " results. Using first result.");
|
||||
LOGGER.debug(movie + " URL: " + searchMovieUrl);
|
||||
LOGGER.info("Results for " + movie + " came back with " + results.size() + " results. Using first result.");
|
||||
LOGGER.info(movie + " URL: " + searchMovieUrl);
|
||||
}
|
||||
|
||||
JsonNode result = results.get(0);
|
||||
@@ -287,7 +286,7 @@ public class GapsSearchService implements GapsSearch {
|
||||
|
||||
int indexOfMovie = everyMovie.indexOf(movie);
|
||||
if (indexOfMovie != -1) {
|
||||
LOGGER.debug("Merging movie data");
|
||||
LOGGER.info("Merging movie data");
|
||||
everyMovie.get(indexOfMovie).setTvdbId(movie.getTvdbId());
|
||||
} else {
|
||||
Movie newMovie = new Movie.Builder(movie.getName(), movie.getYear())
|
||||
@@ -369,7 +368,7 @@ public class GapsSearchService implements GapsSearch {
|
||||
|
||||
int indexOfMovie = everyMovie.indexOf(movie);
|
||||
if (indexOfMovie != -1) {
|
||||
LOGGER.debug("Merging movie data");
|
||||
LOGGER.info("Merging movie data");
|
||||
everyMovie.get(indexOfMovie).setTvdbId(movie.getTvdbId());
|
||||
everyMovie.get(indexOfMovie).setCollectionId(movie.getCollectionId());
|
||||
everyMovie.get(indexOfMovie).setCollection(movie.getCollection());
|
||||
@@ -425,19 +424,32 @@ public class GapsSearchService implements GapsSearch {
|
||||
JsonNode parts = collection.get("parts");
|
||||
parts.iterator().forEachRemaining(jsonNode -> {
|
||||
String title = jsonNode.get("title").asText();
|
||||
int year = -1;
|
||||
if(jsonNode.has("year")) {
|
||||
year = jsonNode.get("year").asInt(-1);
|
||||
int year = 0;
|
||||
if (jsonNode.has("release_date")) {
|
||||
String oldDate = jsonNode.get("release_date").asText("0000-01-01");
|
||||
|
||||
try {
|
||||
Date date = new SimpleDateFormat("yyyy-MM-dd").parse(oldDate);
|
||||
Calendar calendar = new GregorianCalendar();
|
||||
calendar.setTime(date);
|
||||
year = calendar.get(Calendar.YEAR);
|
||||
} catch (ParseException e) {
|
||||
LOGGER.warn("Could not parse date");
|
||||
}
|
||||
}
|
||||
String id = jsonNode.get("id").asText();
|
||||
Boolean owned = ownedMovies.contains(new Movie.Builder(title, year).build());
|
||||
|
||||
Movie collectionMovie = new Movie.Builder(title, year).build();
|
||||
LOGGER.info(collectionMovie.toString());
|
||||
|
||||
Boolean owned = ownedMovies.contains(collectionMovie);
|
||||
moviesInCollection.add(new MovieFromCollection(title, id, owned));
|
||||
});
|
||||
}
|
||||
|
||||
LOGGER.info("MoviesInCollection: " + Arrays.toString(moviesInCollection.toArray()));
|
||||
|
||||
if (indexOfMovie != -1) {
|
||||
if (indexOfMovie != -1) {
|
||||
int id = collection.get("id").asInt(-1);
|
||||
String name = collection.get("name").asText();
|
||||
everyMovie.get(indexOfMovie).setCollectionId(id);
|
||||
@@ -485,7 +497,7 @@ public class GapsSearchService implements GapsSearch {
|
||||
try {
|
||||
posterUrl = part.get("poster_url").asText();
|
||||
} catch (Exception e) {
|
||||
LOGGER.debug("No poster found for" + title + ".");
|
||||
LOGGER.info("No poster found for" + title + ".");
|
||||
}
|
||||
|
||||
Movie movieFromCollection = new Movie.Builder(title, year)
|
||||
@@ -496,21 +508,27 @@ public class GapsSearchService implements GapsSearch {
|
||||
.setMoviesInCollection(moviesInCollection)
|
||||
.build();
|
||||
|
||||
Movie ownedMovieFromCollection = new Movie.Builder(title, year).build();
|
||||
if (ownedMovies.contains(movieFromCollection)) {
|
||||
LOGGER.info("Skip owned movie: " + movieFromCollection);
|
||||
continue;
|
||||
}
|
||||
|
||||
indexOfMovie = everyMovie.indexOf(new Movie.Builder(title, year).build());
|
||||
indexOfMovie = everyMovie.indexOf(movieFromCollection);
|
||||
if (indexOfMovie == -1) {
|
||||
LOGGER.debug("Adding collection movie");
|
||||
LOGGER.info("Adding collection movie");
|
||||
everyMovie.add(movieFromCollection);
|
||||
} else {
|
||||
LOGGER.debug("Merging collection movie");
|
||||
LOGGER.info("Merging collection movie");
|
||||
everyMovie.get(indexOfMovie).setTvdbId(tvdbId);
|
||||
}
|
||||
|
||||
if (ownedMovies.contains(ownedMovieFromCollection)) {
|
||||
if (ownedMovies.contains(movieFromCollection)) {
|
||||
LOGGER.info("Owned movie found: " + movieFromCollection);
|
||||
searched.add(movieFromCollection);
|
||||
sendEmptySearchUpdate(ownedMovies.size(), searchedMovieCount);
|
||||
} else if (!searched.contains(movieFromCollection) && year != 0 && year < Year.now().getValue()) {
|
||||
LOGGER.info("Missing movie found: " + movieFromCollection);
|
||||
|
||||
// Get recommended Movie details from MovieDB API
|
||||
HttpUrl movieDetailUrl = urlGenerator.generateMovieDetailUrl(gapsService.getPlexSearch().getMovieDbApiKey(), String.valueOf(movieFromCollection.getTvdbId()), languageCode);
|
||||
|
||||
@@ -560,6 +578,14 @@ public class GapsSearchService implements GapsSearch {
|
||||
.setMoviesInCollection(moviesInCollection)
|
||||
.build();
|
||||
|
||||
LOGGER.info("ownedMovies");
|
||||
ownedMovies.forEach(movie1 -> LOGGER.info(movie1.toString()));
|
||||
|
||||
if (ownedMovies.contains(recommendedMovie)) {
|
||||
LOGGER.info("Skip owned movie: " + recommendedMovie);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (recommended.add(recommendedMovie)) {
|
||||
// Write current list of recommended movies to file.
|
||||
ioService.writeRssFile(machineIdentifier, key, recommended);
|
||||
|
||||
@@ -218,7 +218,7 @@ public class IoService {
|
||||
fullFile.append(line);
|
||||
}
|
||||
|
||||
return objectMapper.readValue(fullFile.toString(), new TypeReference<List<Movie>>() {
|
||||
return objectMapper.readValue(fullFile.toString(), new TypeReference<>() {
|
||||
});
|
||||
} catch (FileNotFoundException e) {
|
||||
LOGGER.error("Can't find file " + ownedMovieFile, e);
|
||||
|
||||
@@ -392,7 +392,7 @@ public class PlexQueryImpl implements PlexQuery {
|
||||
|
||||
ownedMovies.add(movie);
|
||||
}
|
||||
LOGGER.debug(ownedMovies.size() + " movies found in plex");
|
||||
LOGGER.info(ownedMovies.size() + " movies found in plex");
|
||||
|
||||
} catch (IOException e) {
|
||||
String reason = "Error connecting to Plex to get Movie list: " + url;
|
||||
|
||||
@@ -15,7 +15,7 @@ export function spyOnAddEventListener(win) {
|
||||
};
|
||||
}
|
||||
|
||||
export function searchPlexForMovies(cy) {
|
||||
export function searchPlexForMoviesFromSaw(cy) {
|
||||
cy.get('#dropdownMenuLink')
|
||||
.click();
|
||||
|
||||
@@ -33,6 +33,25 @@ export function searchPlexForMovies(cy) {
|
||||
.should('have.text', 'Showing 1 to 1 of 1 entries');
|
||||
}
|
||||
|
||||
|
||||
export function searchPlexForMoviesFromMovies(cy) {
|
||||
cy.get('#dropdownMenuLink')
|
||||
.click();
|
||||
|
||||
cy.get('[data-key="1"]')
|
||||
.click();
|
||||
|
||||
cy.get('.card-body > .btn')
|
||||
.click();
|
||||
|
||||
cy.get('label > input')
|
||||
.clear()
|
||||
.type('2001 A Space');
|
||||
|
||||
cy.get('#movies_info')
|
||||
.should('have.text', 'Showing 1 to 1 of 1 entries (filtered from 4 total entries)');
|
||||
}
|
||||
|
||||
export function nuke() {
|
||||
cy.request('PUT', '/nuke')
|
||||
.then((response) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {nuke, redLibraryBefore, searchPlexForMovies, spyOnAddEventListener} from "../common";
|
||||
import {nuke, redLibraryBefore, searchPlexForMoviesFromSaw, spyOnAddEventListener} from "../common";
|
||||
|
||||
describe('Library API', function () {
|
||||
|
||||
@@ -53,7 +53,7 @@ describe('Plex Movie List API', function () {
|
||||
function searchSawLibrary(cy) {
|
||||
cy.visit('/libraries', {onBeforeLoad: spyOnAddEventListener});
|
||||
|
||||
searchPlexForMovies(cy);
|
||||
searchPlexForMoviesFromSaw(cy);
|
||||
|
||||
cy.visit('/recommended', {onBeforeLoad: spyOnAddEventListener});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {jokerLibraryBefore, redLibraryBefore, searchPlexForMovies, spyOnAddEventListener} from "../common";
|
||||
import {jokerLibraryBefore, redLibraryBefore, searchPlexForMoviesFromSaw, spyOnAddEventListener} from "../common";
|
||||
|
||||
describe('Find owned movies', function () {
|
||||
before(redLibraryBefore);
|
||||
@@ -6,7 +6,7 @@ describe('Find owned movies', function () {
|
||||
it('Find Movies', () => {
|
||||
cy.visit('/libraries', {onBeforeLoad: spyOnAddEventListener});
|
||||
|
||||
searchPlexForMovies(cy);
|
||||
searchPlexForMoviesFromSaw(cy);
|
||||
});
|
||||
|
||||
it('Refresh Movies', () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {nuke, redLibraryBefore, searchPlexForMovies, spyOnAddEventListener} from "../common";
|
||||
import {nuke, redLibraryBefore, searchPlexForMoviesFromSaw, spyOnAddEventListener} from "../common";
|
||||
|
||||
describe('Recommended API', function () {
|
||||
|
||||
@@ -30,7 +30,7 @@ describe('Recommended API', function () {
|
||||
function searchSawLibrary(cy) {
|
||||
cy.visit('/libraries', {onBeforeLoad: spyOnAddEventListener});
|
||||
|
||||
searchPlexForMovies(cy);
|
||||
searchPlexForMoviesFromSaw(cy);
|
||||
|
||||
cy.visit('/recommended', {onBeforeLoad: spyOnAddEventListener});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import {redLibraryBefore, searchPlexForMoviesFromMovies, spyOnAddEventListener} from "../common";
|
||||
|
||||
describe('Search for Recommended Best Movies', function () {
|
||||
beforeEach(redLibraryBefore);
|
||||
|
||||
it('Clean configuration page load', () => {
|
||||
searchMoviesLibrary(cy);
|
||||
|
||||
cy.get('#libraryTitle').then( ($libraryTitle) => {
|
||||
if($libraryTitle.text() !== "Movies") {
|
||||
cy.get('#dropdownMenuLink')
|
||||
.click();
|
||||
cy.get('[data-key="1"]')
|
||||
.click();
|
||||
}
|
||||
});
|
||||
|
||||
cy.get('#noMovieContainer > .card > .card-img-top')
|
||||
.should('not.be.visible');
|
||||
|
||||
});
|
||||
|
||||
it('Search Movies with bad chars', () => {
|
||||
searchMoviesLibrary(cy);
|
||||
|
||||
cy.get('#dropdownMenuLink')
|
||||
.click();
|
||||
|
||||
cy.get('[data-key="1"]')
|
||||
.click();
|
||||
|
||||
cy.get('.card-body > .btn')
|
||||
.click();
|
||||
|
||||
cy.wait(5000);
|
||||
|
||||
cy.get('#movies_info')
|
||||
.should('have.text', 'Showing 1 to 7 of 7 entries');
|
||||
});
|
||||
|
||||
it('Research Movies with bad chars', () => {
|
||||
searchMoviesLibrary(cy);
|
||||
|
||||
cy.get('#dropdownMenuLink')
|
||||
.click();
|
||||
|
||||
cy.get('[data-key="1"]')
|
||||
.click();
|
||||
|
||||
cy.get('.card-body > .btn')
|
||||
.click();
|
||||
|
||||
cy.wait(5000);
|
||||
|
||||
cy.get('#movies_info')
|
||||
.should('have.text', 'Showing 1 to 7 of 7 entries');
|
||||
|
||||
cy.get('#movieContainer > [onclick="searchForMovies()"]')
|
||||
.click();
|
||||
|
||||
cy.wait(5000);
|
||||
|
||||
cy.get('#movies_info')
|
||||
.should('have.text', 'Showing 1 to 7 of 7 entries');
|
||||
|
||||
cy.get(':nth-child(1) > td > .card > .row > .col-md > .card-body > h5.card-title')
|
||||
.should('have.text', '2010 (1984)');
|
||||
});
|
||||
});
|
||||
|
||||
function searchMoviesLibrary(cy) {
|
||||
cy.visit('/libraries', {onBeforeLoad: spyOnAddEventListener});
|
||||
|
||||
searchPlexForMoviesFromMovies(cy);
|
||||
|
||||
cy.visit('/recommended', {onBeforeLoad: spyOnAddEventListener});
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import {redLibraryBefore, searchPlexForMovies, spyOnAddEventListener} from "../common";
|
||||
import {redLibraryBefore, searchPlexForMoviesFromSaw, spyOnAddEventListener} from "../common";
|
||||
|
||||
describe('Search for Recommended', function () {
|
||||
beforeEach(redLibraryBefore);
|
||||
@@ -66,7 +66,7 @@ describe('Search for Recommended', function () {
|
||||
function searchSawLibrary(cy) {
|
||||
cy.visit('/libraries', {onBeforeLoad: spyOnAddEventListener});
|
||||
|
||||
searchPlexForMovies(cy);
|
||||
searchPlexForMoviesFromSaw(cy);
|
||||
|
||||
cy.visit('/recommended', {onBeforeLoad: spyOnAddEventListener});
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import {nuke, redLibraryBefore, searchPlexForMovies, spyOnAddEventListener} from "../common";
|
||||
import {nuke, redLibraryBefore, searchPlexForMoviesFromSaw, spyOnAddEventListener} from "../common";
|
||||
|
||||
describe('Searched RSS', function () {
|
||||
before(nuke)
|
||||
@@ -35,7 +35,7 @@ describe('Searched RSS', function () {
|
||||
function searchSawLibrary(cy) {
|
||||
cy.visit('/libraries', {onBeforeLoad: spyOnAddEventListener});
|
||||
|
||||
searchPlexForMovies(cy);
|
||||
searchPlexForMoviesFromSaw(cy);
|
||||
|
||||
cy.visit('/recommended', {onBeforeLoad: spyOnAddEventListener});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user