diff --git a/Core/pom.xml b/Core/pom.xml index 5916eb62..10d210fb 100755 --- a/Core/pom.xml +++ b/Core/pom.xml @@ -5,7 +5,7 @@ Gaps com.jasonhhouse - 0.9.3 + 0.9.4 4.0.0 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/Dockerfile b/Dockerfile index 998ddbfb..a588bbe8 100755 --- a/Dockerfile +++ b/Dockerfile @@ -32,7 +32,7 @@ RUN mkdir -p /usr/app && chmod 777 /usr/data WORKDIR /usr/app -COPY GapsWeb/target/GapsWeb-0.9.3.jar /usr/app/gaps.jar +COPY GapsWeb/target/GapsWeb-0.9.4.jar /usr/app/gaps.jar COPY start.sh /usr/app/ diff --git a/Dockerfile.arm64 b/Dockerfile.arm64 index 9986f4a4..e53a7820 100755 --- a/Dockerfile.arm64 +++ b/Dockerfile.arm64 @@ -36,7 +36,7 @@ RUN mkdir -p /usr/app && chmod 777 /usr/data WORKDIR /usr/app -COPY GapsWeb/target/GapsWeb-0.9.3.jar /usr/app/gaps.jar +COPY GapsWeb/target/GapsWeb-0.9.4.jar /usr/app/gaps.jar COPY start.sh /usr/app/ diff --git a/Dockerfile.ppc64le b/Dockerfile.ppc64le index b44c5883..6c7db07c 100755 --- a/Dockerfile.ppc64le +++ b/Dockerfile.ppc64le @@ -32,7 +32,7 @@ RUN mkdir -p /usr/app && chmod 777 /usr/data WORKDIR /usr/app -COPY GapsWeb/target/GapsWeb-0.9.3.jar /usr/app/gaps.jar +COPY GapsWeb/target/GapsWeb-0.9.4.jar /usr/app/gaps.jar COPY start.sh /usr/app/ diff --git a/Dockerfile.raspbian b/Dockerfile.raspbian index e0e6fc8b..396d7b1d 100755 --- a/Dockerfile.raspbian +++ b/Dockerfile.raspbian @@ -32,7 +32,7 @@ RUN mkdir -p /usr/app && chmod 777 /usr/data WORKDIR /usr/app -COPY GapsWeb/target/GapsWeb-0.9.3.jar /usr/app/gaps.jar +COPY GapsWeb/target/GapsWeb-0.9.4.jar /usr/app/gaps.jar COPY start.sh /usr/app/ diff --git a/Dockerfile.riscv64 b/Dockerfile.riscv64 index 8c6cfd0f..f203d7b4 100755 --- a/Dockerfile.riscv64 +++ b/Dockerfile.riscv64 @@ -36,7 +36,7 @@ RUN mkdir -p /usr/app && chmod 777 /usr/data WORKDIR /usr/app -COPY GapsWeb/target/GapsWeb-0.9.3.jar /usr/app/gaps.jar +COPY GapsWeb/target/GapsWeb-0.9.4.jar /usr/app/gaps.jar COPY start.sh /usr/app/ diff --git a/GapsAsJar/gaps.nsi b/GapsAsJar/gaps.nsi index 84ddce6a..21181449 100644 --- a/GapsAsJar/gaps.nsi +++ b/GapsAsJar/gaps.nsi @@ -48,4 +48,4 @@ RMDIR /r $INSTDIR SectionEnd # name the installer -OutFile "gaps-0.9.3-installer.exe" \ No newline at end of file +OutFile "gaps-0.9.4-installer.exe" \ No newline at end of file diff --git a/GapsWeb/pom.xml b/GapsWeb/pom.xml index dd0e2f2a..8b2a46c5 100755 --- a/GapsWeb/pom.xml +++ b/GapsWeb/pom.xml @@ -5,7 +5,7 @@ Gaps com.jasonhhouse - 0.9.3 + 0.9.4 4.0.0 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..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,9 +36,11 @@ 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; +import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; @@ -71,6 +73,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 +81,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 +99,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 +114,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 +234,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 +402,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 +412,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 +420,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 +432,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 +529,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 +571,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 +633,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 +645,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/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/application.yaml b/GapsWeb/src/main/resources/application.yaml index af465855..58be7927 100755 --- a/GapsWeb/src/main/resources/application.yaml +++ b/GapsWeb/src/main/resources/application.yaml @@ -50,7 +50,7 @@ info: app: name: Gaps description: Gaps searches through your Plex Server or local folders for all movies, then queries for known movies in the same collection. If those movies don't exist in your library, Gaps will recommend getting those movies, legally of course. - version: 0.9.3 + version: 0.9.4 storageFolder: /usr/data properties: rssFeed: rssFeed.json diff --git a/GapsWeb/src/main/resources/templates/about.html b/GapsWeb/src/main/resources/templates/about.html index eb7780a1..c482d1e1 100755 --- a/GapsWeb/src/main/resources/templates/about.html +++ b/GapsWeb/src/main/resources/templates/about.html @@ -29,7 +29,7 @@ Gaps Logo

About

-

v0.9.3

+

v0.9.4

Gaps searches through your Plex Server. It then queries for known diff --git a/GapsWeb/src/main/resources/templates/index.html b/GapsWeb/src/main/resources/templates/index.html index 8c39848e..3b25989c 100755 --- a/GapsWeb/src/main/resources/templates/index.html +++ b/GapsWeb/src/main/resources/templates/index.html @@ -27,7 +27,7 @@

Gaps Logo -

v0.9.3

+

v0.9.4

Gaps searches through your Plex Server. It then queries for known diff --git a/GapsWeb/src/main/resources/templates/libraries.html b/GapsWeb/src/main/resources/templates/libraries.html index 5b0bc0ec..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
@@ -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 3fd38fbb..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