From 3410b0470e551fb5c176b413ce31a0ae586bd4fb Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 31 May 2021 21:16:09 +0900 Subject: [PATCH 1/4] Adding genres to recommended movies --- .../java/com/jasonhhouse/gaps/BasicMovie.java | 33 ++++++++++++++++--- .../gaps/service/GapsSearchService.java | 33 +++++++++++++++++-- .../main/resources/templates/recommended.html | 13 +++----- 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/Core/src/main/java/com/jasonhhouse/gaps/BasicMovie.java b/Core/src/main/java/com/jasonhhouse/gaps/BasicMovie.java index e8cc4bc8..bdee30c7 100755 --- a/Core/src/main/java/com/jasonhhouse/gaps/BasicMovie.java +++ b/Core/src/main/java/com/jasonhhouse/gaps/BasicMovie.java @@ -51,6 +51,8 @@ public final class BasicMovie implements Comparable { private String backdropPathUrl; @NotNull private Integer tmdbId; + @NotNull + private List genres; private BasicMovie(@NotNull String name, @NotNull Integer year, @@ -64,7 +66,8 @@ private BasicMovie(@NotNull String name, @NotNull String overview, @NotNull List moviesInCollection, @NotNull Integer ratingKey, - @NotNull String key) { + @NotNull String key, + @NotNull List genres) { this.name = name; this.nameWithoutBadCharacters = name.replaceAll("[<>`~\\[\\]()*&^%$#@!|{}.,?\\-_=+:;]", ""); this.year = year; @@ -79,6 +82,7 @@ private BasicMovie(@NotNull String name, this.moviesInCollection = moviesInCollection; this.ratingKey = ratingKey; this.key = key; + this.genres = genres; } public @NotNull Integer getCollectionId() { @@ -137,12 +141,20 @@ public void setTmdbId(@NotNull Integer tmdbId) { return moviesInCollection; } + public @NotNull String getBackdropPathUrl() { + return backdropPathUrl; + } + public void setBackdropPathUrl(@NotNull String backdropPathUrl) { this.backdropPathUrl = backdropPathUrl; } - public @NotNull String getBackdropPathUrl() { - return backdropPathUrl; + public @NotNull List getGenres() { + return genres; + } + + public void setGenres(@NotNull List genres) { + this.genres = genres; } @JsonIgnore @@ -198,7 +210,6 @@ public String toString() { ", year=" + year + ", nameWithoutBadCharacters='" + nameWithoutBadCharacters + '\'' + ", posterUrl='" + posterUrl + '\'' + - ", backdropPathUrl='" + backdropPathUrl + '\'' + ", language='" + language + '\'' + ", overview='" + overview + '\'' + ", moviesInCollection=" + moviesInCollection + @@ -207,7 +218,9 @@ public String toString() { ", imdbId='" + imdbId + '\'' + ", collectionTitle='" + collectionTitle + '\'' + ", collectionId=" + collectionId + + ", backdropPathUrl='" + backdropPathUrl + '\'' + ", tmdbId=" + tmdbId + + ", genres=" + genres + '}'; } @@ -268,6 +281,10 @@ public static class Builder { @JsonProperty private String key; + @NotNull + @JsonProperty + private List genres; + @JsonCreator public Builder(@JsonProperty(value = "name") @NotNull String name, @JsonProperty(value = "year") @NotNull Integer year) { @@ -284,10 +301,11 @@ public Builder(@JsonProperty(value = "name") @NotNull String name, this.moviesInCollection = new ArrayList<>(); this.ratingKey = -1; this.key = ""; + this.genres = new ArrayList<>(); } public @NotNull BasicMovie build() { - return new BasicMovie(name, year, posterUrl, backdropPathUrl, collectionTitle, collectionId, tmdbId, imdbId, language, overview, moviesInCollection, ratingKey, key); + return new BasicMovie(name, year, posterUrl, backdropPathUrl, collectionTitle, collectionId, tmdbId, imdbId, language, overview, moviesInCollection, ratingKey, key, genres); } public @NotNull Builder setPosterUrl(@NotNull String posterUrl) { @@ -344,5 +362,10 @@ public Builder(@JsonProperty(value = "name") @NotNull String name, this.key = key; return this; } + + public @NotNull Builder setGenres(@NotNull List genres) { + this.genres = genres; + return this; + } } } diff --git a/GapsWeb/src/main/java/com/jasonhhouse/gaps/service/GapsSearchService.java b/GapsWeb/src/main/java/com/jasonhhouse/gaps/service/GapsSearchService.java index 8325b406..14e3b0e2 100755 --- a/GapsWeb/src/main/java/com/jasonhhouse/gaps/service/GapsSearchService.java +++ b/GapsWeb/src/main/java/com/jasonhhouse/gaps/service/GapsSearchService.java @@ -39,6 +39,7 @@ import java.util.Date; import java.util.GregorianCalendar; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; @@ -71,6 +72,7 @@ public class GapsSearchService implements GapsSearch { public static final String COLLECTION_ID = "belongs_to_collection"; public static final String BACKDROP_PATH = "backdrop_path"; + public static final String GENRES = "genres"; public static final String TITLE = "title"; public static final String NAME = "name"; public static final String ID = "id"; @@ -78,6 +80,7 @@ public class GapsSearchService implements GapsSearch { public static final String PARTS = "parts"; public static final String MOVIE_RESULTS = "movie_results"; public static final String FINISHED_SEARCHING_URL = "/finishedSearching"; + private static final String languageCode = "en-US"; private static final Logger LOGGER = LoggerFactory.getLogger(GapsSearchService.class); private static final ObjectMapper objectMapper = new ObjectMapper(); @@ -95,8 +98,10 @@ public class GapsSearchService implements GapsSearch { private final NotificationService notificationService; + @Autowired - public GapsSearchService(@Qualifier("real") UrlGenerator urlGenerator, SimpMessagingTemplate template, FileIoService fileIoService, TmdbService tmdbService, NotificationService notificationService) { + public GapsSearchService(@Qualifier("real") UrlGenerator urlGenerator, + SimpMessagingTemplate template, FileIoService fileIoService, TmdbService tmdbService, NotificationService notificationService) { this.template = template; this.tmdbService = tmdbService; this.urlGenerator = urlGenerator; @@ -108,7 +113,7 @@ public GapsSearchService(@Qualifier("real") UrlGenerator urlGenerator, SimpMessa } @Override - public void run(@NotNull String machineIdentifier,@NotNull Integer key) { + public void run(@NotNull String machineIdentifier, @NotNull Integer key) { LOGGER.info("run( {}, {} )", machineIdentifier, key); PlexProperties plexProperties = fileIoService.readProperties(); @@ -228,7 +233,6 @@ private void searchForMovies(PlexProperties plexProperties, String machineIdenti } for (BasicMovie basicMovie : ownedBasicMovies) { - String languageCode = "en-US"; //Cancel search if needed if (cancelSearch.get()) { @@ -397,6 +401,9 @@ private void searchMovieDetails(PlexProperties plexProperties, String machineIde basicMovie.setCollectionTitle(collectionName); basicMovie.setBackdropPathUrl(backdropPath); + List genres = getGenres(movieDetails); + basicMovie.setGenres(genres); + int indexOfMovie = everyBasicMovie.indexOf(basicMovie); if (indexOfMovie != -1) { LOGGER.info("Merging movie data"); @@ -404,6 +411,7 @@ private void searchMovieDetails(PlexProperties plexProperties, String machineIde everyBasicMovie.get(indexOfMovie).setCollectionId(basicMovie.getCollectionId()); everyBasicMovie.get(indexOfMovie).setCollectionTitle(basicMovie.getCollectionTitle()); everyBasicMovie.get(indexOfMovie).setBackdropPathUrl(basicMovie.getBackdropPathUrl()); + everyBasicMovie.get(indexOfMovie).setGenres(genres); } else { BasicMovie newBasicMovie = new BasicMovie.Builder(basicMovie.getName(), basicMovie.getYear()) .setTmdbId(basicMovie.getTmdbId()) @@ -411,6 +419,7 @@ private void searchMovieDetails(PlexProperties plexProperties, String machineIde .setCollectionTitle(basicMovie.getCollectionTitle()) .setCollectionId(basicMovie.getCollectionId()) .setBackdropPathUrl(basicMovie.getBackdropPathUrl()) + .setGenres(basicMovie.getGenres()) .build(); everyBasicMovie.add(newBasicMovie); } @@ -422,6 +431,19 @@ private void searchMovieDetails(PlexProperties plexProperties, String machineIde } } + private @NotNull List getGenres(@NotNull JsonNode movieDetails) { + List genres = new ArrayList<>(); + + Iterator jsonNodeIterator = movieDetails.get(GENRES).elements(); + + while (jsonNodeIterator.hasNext()) { + JsonNode genre = jsonNodeIterator.next(); + genres.add(genre.get(NAME).textValue()); + } + + return genres; + } + private void handleCollection(PlexProperties plexProperties, String machineIdentifier, Integer key, List ownedBasicMovies, List everyBasicMovie, Set recommended, List searched, AtomicInteger searchedMovieCount, BasicMovie basicMovie, OkHttpClient client, String languageCode) { LOGGER.debug("handleCollection()"); @@ -506,6 +528,7 @@ private void handleCollection(PlexProperties plexProperties, String machineIdent .setOverview(basicMovie.getOverview()) .setPosterUrl(basicMovie.getPosterUrl()) .setBackdropPathUrl(basicMovie.getBackdropPathUrl()) + .setGenres(basicMovie.getGenres()) .build(); everyBasicMovie.add(newBasicMovie); @@ -547,6 +570,7 @@ private void handleCollection(PlexProperties plexProperties, String machineIdent .setPosterUrl(posterUrl) .setMoviesInCollection(moviesInCollection) .setBackdropPathUrl(basicMovie.getBackdropPathUrl()) + .setGenres(basicMovie.getGenres()) .build(); if (ownedBasicMovies.contains(basicMovieFromCollection)) { @@ -608,6 +632,8 @@ private void handleCollection(PlexProperties plexProperties, String machineIdent basicMovieFromCollection.setCollectionTitle(collection.get(NAME).textValue()); } + List genres = getGenres(movieDet); + // Add movie with imbd_id and other details for RSS to recommended list BasicMovie recommendedBasicMovie = new BasicMovie.Builder(movieDet.get(TITLE).textValue(), year) .setTmdbId(movieDet.get(ID).intValue()) @@ -618,6 +644,7 @@ private void handleCollection(PlexProperties plexProperties, String machineIdent .setBackdropPathUrl("https://image.tmdb.org/t/p/original/" + movieDet.get(COLLECTION_ID).get(BACKDROP_PATH).textValue()) .setOverview(movieDet.get("overview").textValue()) .setMoviesInCollection(moviesInCollection) + .setGenres(genres) .build(); if (ownedBasicMovies.contains(recommendedBasicMovie)) { diff --git a/GapsWeb/src/main/resources/templates/recommended.html b/GapsWeb/src/main/resources/templates/recommended.html index 3fd38fbb..52deedaa 100755 --- a/GapsWeb/src/main/resources/templates/recommended.html +++ b/GapsWeb/src/main/resources/templates/recommended.html @@ -137,7 +137,11 @@

Searching for Movies

{{name}} ({{year}})
{{collectionTitle}}

{{overview}}

-

English

+

+ {{#each genres}} + {{this}} + {{/each}} +

@@ -148,17 +152,10 @@
Owned
{{#each moviesInCollection}} {{#if this.owned}} - {{#if (isEqual this.tmdbId @root.tmdbId)}} - {{this.title}} - {{else}} {{this.title}} - {{/if}} {{/if}} {{/each}}
From 7d928a31effd500b897d15b7c663ed89b8c5fb62 Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 31 May 2021 21:59:22 +0900 Subject: [PATCH 2/4] Adding genre to both libraries and recommended --- .../gaps/service/GapsSearchService.java | 1 + .../gaps/service/PlexQueryImpl.java | 34 ++++++++++++++----- .../main/resources/templates/libraries.html | 4 ++- .../main/resources/templates/recommended.html | 6 ++-- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/GapsWeb/src/main/java/com/jasonhhouse/gaps/service/GapsSearchService.java b/GapsWeb/src/main/java/com/jasonhhouse/gaps/service/GapsSearchService.java index 14e3b0e2..684ac14a 100755 --- a/GapsWeb/src/main/java/com/jasonhhouse/gaps/service/GapsSearchService.java +++ b/GapsWeb/src/main/java/com/jasonhhouse/gaps/service/GapsSearchService.java @@ -36,6 +36,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; +import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashSet; diff --git a/GapsWeb/src/main/java/com/jasonhhouse/gaps/service/PlexQueryImpl.java b/GapsWeb/src/main/java/com/jasonhhouse/gaps/service/PlexQueryImpl.java index cefc50ca..22fe72c7 100755 --- a/GapsWeb/src/main/java/com/jasonhhouse/gaps/service/PlexQueryImpl.java +++ b/GapsWeb/src/main/java/com/jasonhhouse/gaps/service/PlexQueryImpl.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -268,7 +269,7 @@ public PlexQueryImpl(@Qualifier("real") UrlGenerator urlGenerator) { public void findAllMovieIds(@NotNull List basicMovies, @NotNull PlexServer plexServer, @NotNull PlexLibrary plexLibrary) { LOGGER.info("findAllMovieIds( {}, {} )", plexServer, plexLibrary); - if(plexLibrary.getScanner().equals("Plex Movie Scanner")) { + if (plexLibrary.getScanner().equals("Plex Movie Scanner")) { LOGGER.info("PlexLibrary {} uses old scanner", plexLibrary.getTitle()); return; } @@ -348,10 +349,10 @@ public void findAllMovieIds(@NotNull List basicMovies, @NotNull Plex } @Override - public @NotNull PlexServer getPlexServerFromMachineIdentifier(@NotNull PlexProperties plexProperties, @NotNull String machineIdentifier) throws IllegalArgumentException{ + public @NotNull PlexServer getPlexServerFromMachineIdentifier(@NotNull PlexProperties plexProperties, @NotNull String machineIdentifier) throws IllegalArgumentException { LOGGER.info("generatePlexUrl( {} )", machineIdentifier); - for(PlexServer plexServer : plexProperties.getPlexServers()) { - if(plexServer.getMachineIdentifier().equals(machineIdentifier)) { + for (PlexServer plexServer : plexProperties.getPlexServers()) { + if (plexServer.getMachineIdentifier().equals(machineIdentifier)) { return plexServer; } } @@ -360,9 +361,9 @@ public void findAllMovieIds(@NotNull List basicMovies, @NotNull Plex } @Override - public @NotNull PlexLibrary getPlexLibraryFromKey(@NotNull PlexServer plexServer,@NotNull Integer key) throws IllegalArgumentException { - for(PlexLibrary plexLibrary : plexServer.getPlexLibraries()) { - if(plexLibrary.getKey().equals(key)) { + public @NotNull PlexLibrary getPlexLibraryFromKey(@NotNull PlexServer plexServer, @NotNull Integer key) throws IllegalArgumentException { + for (PlexLibrary plexLibrary : plexServer.getPlexLibraries()) { + if (plexLibrary.getKey().equals(key)) { return plexLibrary; } } @@ -460,7 +461,17 @@ public void findAllMovieIds(@NotNull List basicMovies, @NotNull Plex ratingKey = Integer.valueOf(node.getAttributes().getNamedItem("ratingKey").getNodeValue()); } - BasicMovie basicMovie = getOrCreateOwnedMovie(previousMovies, title, year, tmdbId, imdbId, thumbnail, summary, ratingKey, key); + List genres = new ArrayList<>(); + if (node.hasChildNodes()) { + for (int j = 0; j < node.getChildNodes().getLength(); j++) { + Node childNode = node.getChildNodes().item(j); + if (childNode.getNodeName().equalsIgnoreCase("genre")) { + genres.add(childNode.getAttributes().getNamedItem("tag").getNodeValue()); + } + } + } + + BasicMovie basicMovie = getOrCreateOwnedMovie(previousMovies, title, year, tmdbId, imdbId, thumbnail, summary, ratingKey, key, genres); ownedBasicMovies.add(basicMovie); } LOGGER.info("{} movies found in plex", ownedBasicMovies.size()); @@ -483,7 +494,10 @@ public void findAllMovieIds(@NotNull List basicMovies, @NotNull Plex return ownedBasicMovies; } - private BasicMovie getOrCreateOwnedMovie(Map, BasicMovie> previousMovies, @NotNull String title, int year, @NotNull Integer tmdbId, @NotNull String imdbId, @NotNull String thumbnail, @NotNull String summary, @NotNull Integer ratingKey, @NotNull String key) { + private BasicMovie getOrCreateOwnedMovie(Map, BasicMovie> previousMovies, @NotNull String title, int year, + @NotNull Integer tmdbId, @NotNull String imdbId, @NotNull String thumbnail, + @NotNull String summary, @NotNull Integer ratingKey, @NotNull String key, + @NotNull List genres) { Pair moviePair = new Pair<>(title, year); if (previousMovies.containsKey(moviePair)) { BasicMovie previousBasicMovie = previousMovies.get(moviePair); @@ -497,6 +511,7 @@ private BasicMovie getOrCreateOwnedMovie(Map, BasicMovie> .setLanguage(previousBasicMovie.getLanguage()) .setTmdbId(previousBasicMovie.getTmdbId()) .setCollectionId(previousBasicMovie.getCollectionId()) + .setGenres(genres) .build(); } else { return new BasicMovie.Builder(title, year) @@ -506,6 +521,7 @@ private BasicMovie getOrCreateOwnedMovie(Map, BasicMovie> .setRatingKey(ratingKey) .setTmdbId(tmdbId) .setImdbId(imdbId) + .setGenres(genres) .build(); } } diff --git a/GapsWeb/src/main/resources/templates/libraries.html b/GapsWeb/src/main/resources/templates/libraries.html index 5b0bc0ec..b06aa399 100755 --- a/GapsWeb/src/main/resources/templates/libraries.html +++ b/GapsWeb/src/main/resources/templates/libraries.html @@ -122,7 +122,9 @@
Your movies are really missing
{{name}} ({{year}})

{{overview}}

-

English

+ {{#each genres}} +
{{this}}
+ {{/each}}
diff --git a/GapsWeb/src/main/resources/templates/recommended.html b/GapsWeb/src/main/resources/templates/recommended.html index 52deedaa..6860180d 100755 --- a/GapsWeb/src/main/resources/templates/recommended.html +++ b/GapsWeb/src/main/resources/templates/recommended.html @@ -137,11 +137,11 @@

Searching for Movies

{{name}} ({{year}})
{{collectionTitle}}

{{overview}}

-

+

{{#each genres}} - {{this}} +
{{this}}
{{/each}} -

+
From 21e4b51336b129fbc9c6d63e85e2f164513ea5c5 Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 1 Jun 2021 10:33:00 +0900 Subject: [PATCH 3/4] Adding E2E tests --- .../main/resources/templates/libraries.html | 4 ++-- .../main/resources/templates/recommended.html | 5 +++-- .../libraries/searchOwnedMovies.spec.js | 18 +++++++++++++++ .../searchRecommendedMovies.spec.js | 22 ++++++++++++++++++- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/GapsWeb/src/main/resources/templates/libraries.html b/GapsWeb/src/main/resources/templates/libraries.html index b06aa399..d7dd0fd0 100755 --- a/GapsWeb/src/main/resources/templates/libraries.html +++ b/GapsWeb/src/main/resources/templates/libraries.html @@ -114,7 +114,7 @@
Your movies are really missing
- Plex Poster
@@ -123,7 +123,7 @@
Your movies are really missing
{{name}} ({{year}})

{{overview}}

{{#each genres}} -
{{this}}
+
{{this}}
{{/each}}
diff --git a/GapsWeb/src/main/resources/templates/recommended.html b/GapsWeb/src/main/resources/templates/recommended.html index 6860180d..8e88e045 100755 --- a/GapsWeb/src/main/resources/templates/recommended.html +++ b/GapsWeb/src/main/resources/templates/recommended.html @@ -123,12 +123,13 @@

Searching for Movies