mirror of
https://github.com/JasonHHouse/gaps.git
synced 2026-05-01 06:01:28 -05:00
Merge pull request #288 from JasonHHouse/improvement/Gaps_currently_reports_future_releases_as_missing#257
Initial work to implement and remove unreleased movies or show all
This commit is contained in:
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>Gaps</artifactId>
|
||||
<groupId>com.jasonhhouse</groupId>
|
||||
<version>0.9.13</version>
|
||||
<version>0.10.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.jasonhhouse.gaps;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.jasonhhouse.gaps.json.MovieStatusDeserializer;
|
||||
import com.jasonhhouse.gaps.json.MovieStatusSerializer;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@JsonSerialize(using = MovieStatusSerializer.class)
|
||||
@JsonDeserialize(using = MovieStatusDeserializer.class)
|
||||
public enum MovieStatus {
|
||||
ALL("All", 0),
|
||||
RELEASED("Released", 1);
|
||||
|
||||
public static final String ID_LABEL = "id";
|
||||
public static final String MESSAGE_LABEL = "message";
|
||||
|
||||
@NotNull
|
||||
private final String message;
|
||||
|
||||
@NotNull
|
||||
private final Integer id;
|
||||
|
||||
MovieStatus(@NotNull String message, @NotNull Integer id) {
|
||||
this.message = message;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static MovieStatus getMovieStatus(@NotNull Integer id) {
|
||||
if (RELEASED.getId().equals(id)) {
|
||||
return RELEASED;
|
||||
} else {
|
||||
return ALL;
|
||||
}
|
||||
}
|
||||
|
||||
public static @NotNull List<MovieStatus> getAllMovieStatuses() {
|
||||
return Arrays.asList(ALL, RELEASED);
|
||||
}
|
||||
|
||||
public @NotNull String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public @NotNull Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String toString() {
|
||||
return "MovieStatus{" +
|
||||
"message='" + message + '\'' +
|
||||
", id=" + id +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.jasonhhouse.gaps;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public final class MovieStatusPayload {
|
||||
private final Integer status;
|
||||
|
||||
@JsonCreator
|
||||
public MovieStatusPayload(@JsonProperty("status") Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MovieStatusPayload{" +
|
||||
"status=" + status +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,11 @@ public enum Payload {
|
||||
DISCORD_NOTIFICATION_UPDATE_SUCCEEDED(140, "Discord Notification Update Succeeded."),
|
||||
DISCORD_NOTIFICATION_UPDATE_FAILED(141, "Discord Notification Update Failed."),
|
||||
DISCORD_NOTIFICATION_FOUND(142, "Discord Notification Found."),
|
||||
DISCORD_NOTIFICATION_NOT_FOUND(143, "Discord Notification Not Found.");
|
||||
DISCORD_NOTIFICATION_NOT_FOUND(143, "Discord Notification Not Found."),
|
||||
MOVIE_STATUS_FOUND(150, "Movie status found."),
|
||||
MOVIE_STATUS_NOT_FOUND(151, "Movie status not found."),
|
||||
MOVIE_STATUS_UPDATED(152, "Movie status updated successfully."),
|
||||
MOVIE_STATUS_NOT_UPDATED(153, "Movie status update failed.");
|
||||
|
||||
private final int code;
|
||||
private final String reason;
|
||||
|
||||
@@ -65,7 +65,7 @@ public enum Schedule {
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Schedule> getAllSchedules() {
|
||||
public static @NotNull List<Schedule> getAllSchedules() {
|
||||
return Arrays.asList(HOURLY, DAILY_4AM, EVERY_MONDAY, EVERY_TWO_WEEKS, EVERY_MONTH);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.jasonhhouse.gaps.json;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||
import com.jasonhhouse.gaps.MovieStatus;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MovieStatusDeserializer extends StdDeserializer<MovieStatus> {
|
||||
public MovieStatusDeserializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
protected MovieStatusDeserializer(Class<?> vc) {
|
||||
super(vc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MovieStatus deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
|
||||
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
|
||||
int id = node.get(MovieStatus.ID_LABEL).numberValue().intValue();
|
||||
return MovieStatus.getMovieStatus(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2020 Jason H House
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.jasonhhouse.gaps.json;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
import com.jasonhhouse.gaps.MovieStatus;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MovieStatusSerializer extends StdSerializer<MovieStatus> {
|
||||
|
||||
public MovieStatusSerializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
protected MovieStatusSerializer(Class<MovieStatus> t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(MovieStatus value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
|
||||
jsonGenerator.writeStartObject();
|
||||
jsonGenerator.writeNumberField(MovieStatus.ID_LABEL, value.getId());
|
||||
jsonGenerator.writeStringField(MovieStatus.MESSAGE_LABEL, value.getMessage());
|
||||
jsonGenerator.writeEndObject();
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.jasonhhouse.gaps.MovieStatus;
|
||||
import com.jasonhhouse.gaps.PlexServer;
|
||||
import com.jasonhhouse.gaps.Schedule;
|
||||
import java.util.ArrayList;
|
||||
@@ -47,6 +48,8 @@ public final class PlexProperties {
|
||||
private DiscordProperties discordProperties;
|
||||
@NotNull
|
||||
private Schedule schedule;
|
||||
@NotNull
|
||||
private MovieStatus movieStatus;
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
|
||||
public PlexProperties(@JsonProperty(value = "plexServers") @Nullable List<PlexServer> plexServers,
|
||||
@@ -59,7 +62,8 @@ public final class PlexProperties {
|
||||
@JsonProperty(value = "discordProperties") @Nullable DiscordProperties discordProperties,
|
||||
@JsonProperty(value = "movieDbApiKey") @Nullable String movieDbApiKey,
|
||||
@JsonProperty(value = "password") @Nullable String password,
|
||||
@JsonProperty(value = "schedule") @Nullable Schedule schedule) {
|
||||
@JsonProperty(value = "schedule") @Nullable Schedule schedule,
|
||||
@JsonProperty(value = "movieStatus") @Nullable MovieStatus movieStatus) {
|
||||
this.plexServers = plexServers == null ? new ArrayList<>() : plexServers;
|
||||
this.telegramProperties = telegramProperties == null ? TelegramProperties.getDefault() : telegramProperties;
|
||||
this.pushBulletProperties = pushBulletProperties == null ? PushBulletProperties.getDefault() : pushBulletProperties;
|
||||
@@ -71,6 +75,7 @@ public final class PlexProperties {
|
||||
this.movieDbApiKey = movieDbApiKey == null ? "" : movieDbApiKey;
|
||||
this.password = password == null ? "" : password;
|
||||
this.schedule = schedule == null ? Schedule.EVERY_MONDAY : schedule;
|
||||
this.movieStatus = movieStatus == null ? MovieStatus.ALL : movieStatus;
|
||||
}
|
||||
|
||||
public PlexProperties() {
|
||||
@@ -85,6 +90,7 @@ public final class PlexProperties {
|
||||
this.movieDbApiKey = "";
|
||||
this.password = "";
|
||||
this.schedule = Schedule.EVERY_MONDAY;
|
||||
this.movieStatus = MovieStatus.ALL;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -185,6 +191,14 @@ public final class PlexProperties {
|
||||
this.discordProperties = discordProperties;
|
||||
}
|
||||
|
||||
public @NotNull MovieStatus getMovieStatus() {
|
||||
return movieStatus;
|
||||
}
|
||||
|
||||
public void setMovieStatus(@NotNull MovieStatus movieStatus) {
|
||||
this.movieStatus = movieStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PlexProperties{" +
|
||||
@@ -199,6 +213,7 @@ public final class PlexProperties {
|
||||
", pushOverProperties=" + pushOverProperties +
|
||||
", discordProperties=" + discordProperties +
|
||||
", schedule=" + schedule +
|
||||
", movieStatus=" + movieStatus +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ RUN mkdir -p /usr/app && chmod 777 /usr/app
|
||||
|
||||
WORKDIR /usr/app
|
||||
|
||||
COPY GapsWeb/target/GapsWeb-0.9.13.jar /usr/app/gaps.jar
|
||||
COPY GapsWeb/target/GapsWeb-0.10.0.jar /usr/app/gaps.jar
|
||||
|
||||
COPY start.sh /usr/app/
|
||||
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ RUN mkdir -p /usr/app && chmod 777 /usr/app
|
||||
|
||||
WORKDIR /usr/app
|
||||
|
||||
COPY GapsWeb/target/GapsWeb-0.9.13.jar /usr/app/gaps.jar
|
||||
COPY GapsWeb/target/GapsWeb-0.10.0.jar /usr/app/gaps.jar
|
||||
|
||||
COPY start.sh /usr/app/
|
||||
|
||||
|
||||
+1
-1
@@ -48,4 +48,4 @@ RMDIR /r $INSTDIR
|
||||
SectionEnd
|
||||
|
||||
# name the installer
|
||||
OutFile "gaps-0.9.13-installer.exe"
|
||||
OutFile "gaps-0.10.0-installer.exe"
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>Gaps</artifactId>
|
||||
<groupId>com.jasonhhouse</groupId>
|
||||
<version>0.9.13</version>
|
||||
<version>0.10.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.jasonhhouse.gaps.Payload;
|
||||
import com.jasonhhouse.gaps.PlexServer;
|
||||
import com.jasonhhouse.gaps.properties.PlexProperties;
|
||||
import com.jasonhhouse.gaps.service.FileIoService;
|
||||
import com.jasonhhouse.gaps.service.MovieStatusService;
|
||||
import com.jasonhhouse.gaps.service.PlexQueryImpl;
|
||||
import com.jasonhhouse.gaps.service.SchedulerService;
|
||||
import com.jasonhhouse.gaps.service.TmdbService;
|
||||
@@ -22,6 +23,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import javax.validation.Valid;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -50,18 +52,31 @@ public class ConfigurationController {
|
||||
private static final String CONFIGURATION_PLEX = "/configuration/plex";
|
||||
private static final String CONFIGURATION_PLEX_COMPLETE = CONFIGURATION_PLEX + "/complete";
|
||||
|
||||
@NotNull
|
||||
private final TmdbService tmdbService;
|
||||
@NotNull
|
||||
private final SimpMessagingTemplate template;
|
||||
@NotNull
|
||||
private final PlexQueryImpl plexQuery;
|
||||
@NotNull
|
||||
private final FileIoService fileIoService;
|
||||
@NotNull
|
||||
private final SchedulerService schedulerService;
|
||||
@NotNull
|
||||
private final MovieStatusService movieStatusService;
|
||||
|
||||
public ConfigurationController(TmdbService tmdbService, SimpMessagingTemplate template, PlexQueryImpl plexQuery, FileIoService fileIoService, SchedulerService schedulerService) {
|
||||
public ConfigurationController(@NotNull TmdbService tmdbService,
|
||||
@NotNull SimpMessagingTemplate template,
|
||||
@NotNull PlexQueryImpl plexQuery,
|
||||
@NotNull FileIoService fileIoService,
|
||||
@NotNull SchedulerService schedulerService,
|
||||
@NotNull MovieStatusService movieStatusService) {
|
||||
this.tmdbService = tmdbService;
|
||||
this.template = template;
|
||||
this.plexQuery = plexQuery;
|
||||
this.fileIoService = fileIoService;
|
||||
this.schedulerService = schedulerService;
|
||||
this.movieStatusService = movieStatusService;
|
||||
}
|
||||
|
||||
@GetMapping(produces = MediaType.TEXT_HTML_VALUE)
|
||||
@@ -72,6 +87,7 @@ public class ConfigurationController {
|
||||
ModelAndView modelAndView = new ModelAndView("configuration");
|
||||
modelAndView.addObject("plexProperties", plexProperties);
|
||||
modelAndView.addObject("schedules", schedulerService.getAllSchedules());
|
||||
modelAndView.addObject("movieStatuses", movieStatusService.getAllMovieStatuses());
|
||||
modelAndView.addObject("configurationPage", true);
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.jasonhhouse.gaps.controller;
|
||||
|
||||
import com.jasonhhouse.gaps.MovieStatusPayload;
|
||||
import com.jasonhhouse.gaps.Payload;
|
||||
import com.jasonhhouse.gaps.service.MovieStatusService;
|
||||
import java.io.IOException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "/movieStatus")
|
||||
public class MovieStatusController {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MovieStatusController.class);
|
||||
|
||||
private final MovieStatusService movieStatusService;
|
||||
|
||||
@Autowired
|
||||
public MovieStatusController(MovieStatusService movieStatusService) {
|
||||
this.movieStatusService = movieStatusService;
|
||||
}
|
||||
|
||||
@PutMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Payload> putMovieStatus(@RequestBody final MovieStatusPayload movieStatusPayload) {
|
||||
LOGGER.info("putMovieStatus( {} )", movieStatusPayload);
|
||||
|
||||
try {
|
||||
movieStatusService.setMovieStatus(movieStatusPayload);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Failed to update Movie Status", e);
|
||||
ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Payload.MOVIE_STATUS_NOT_UPDATED);
|
||||
}
|
||||
|
||||
return ResponseEntity.ok().body(Payload.MOVIE_STATUS_UPDATED);
|
||||
}
|
||||
|
||||
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResponseEntity<String> getSchedule() {
|
||||
LOGGER.info("getSchedule()");
|
||||
try {
|
||||
return ResponseEntity.ok().body(movieStatusService.getJsonMovieStatus());
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Failed to parse schedule into JSON", e);
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to parse schedule into JSON");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeType;
|
||||
import com.jasonhhouse.gaps.BasicMovie;
|
||||
import com.jasonhhouse.gaps.MovieFromCollection;
|
||||
import com.jasonhhouse.gaps.MovieStatus;
|
||||
import com.jasonhhouse.gaps.Payload;
|
||||
import com.jasonhhouse.gaps.PlexServer;
|
||||
import com.jasonhhouse.gaps.SearchCancelledException;
|
||||
@@ -31,7 +32,6 @@ import java.nio.charset.StandardCharsets;
|
||||
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;
|
||||
@@ -98,15 +98,17 @@ public class GapsSearchService implements GapsSearch {
|
||||
|
||||
private final NotificationService notificationService;
|
||||
|
||||
private final MovieStatusService movieStatusService;
|
||||
|
||||
@Autowired
|
||||
public GapsSearchService(@Qualifier("real") UrlGenerator urlGenerator,
|
||||
SimpMessagingTemplate template, FileIoService fileIoService, TmdbService tmdbService, NotificationService notificationService) {
|
||||
SimpMessagingTemplate template, FileIoService fileIoService, TmdbService tmdbService, NotificationService notificationService, MovieStatusService movieStatusService) {
|
||||
this.template = template;
|
||||
this.tmdbService = tmdbService;
|
||||
this.urlGenerator = urlGenerator;
|
||||
this.fileIoService = fileIoService;
|
||||
this.notificationService = notificationService;
|
||||
this.movieStatusService = movieStatusService;
|
||||
|
||||
tempTmdbCounter = new AtomicInteger();
|
||||
cancelSearch = new AtomicBoolean(true);
|
||||
@@ -627,6 +629,13 @@ public class GapsSearchService implements GapsSearch {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(movieStatusService.getRawMovieStatus().equals(MovieStatus.RELEASED) &&
|
||||
movieDet.has("status") &&
|
||||
!movieDet.get("status").textValue().equalsIgnoreCase("Released")) {
|
||||
LOGGER.warn("Movie '{} ({})' not released yet. Not adding the movie to recommended list.", title, movieDet.get(RELEASE_DATE));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (collection.has(NAME)) {
|
||||
basicMovie.setCollectionTitle(collection.get(NAME).textValue());
|
||||
basicMovieFromCollection.setCollectionTitle(collection.get(NAME).textValue());
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.jasonhhouse.gaps.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.jasonhhouse.gaps.MovieStatus;
|
||||
import com.jasonhhouse.gaps.MovieStatusPayload;
|
||||
import com.jasonhhouse.gaps.properties.PlexProperties;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class MovieStatusService {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MovieStatus.class);
|
||||
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final FileIoService fileIoService;
|
||||
|
||||
public MovieStatusService(FileIoService fileIoService) {
|
||||
this.fileIoService = fileIoService;
|
||||
}
|
||||
|
||||
public void setMovieStatus(MovieStatusPayload movieStatusPayload) {
|
||||
LOGGER.info("setMovieStatus( {} )", movieStatusPayload);
|
||||
PlexProperties plexProperties = fileIoService.readProperties();
|
||||
MovieStatus movieStatus = MovieStatus.getMovieStatus(movieStatusPayload.getStatus());
|
||||
plexProperties.setMovieStatus(movieStatus);
|
||||
fileIoService.writeProperties(plexProperties);
|
||||
}
|
||||
|
||||
public List<MovieStatus> getAllMovieStatuses() {
|
||||
LOGGER.info("getAllMovieStatus()");
|
||||
return MovieStatus.getAllMovieStatuses();
|
||||
}
|
||||
|
||||
public MovieStatus getRawMovieStatus() {
|
||||
LOGGER.info("getRawMovieStatus()");
|
||||
return fileIoService.readProperties().getMovieStatus();
|
||||
}
|
||||
|
||||
public String getJsonMovieStatus() throws IOException {
|
||||
LOGGER.info("getJsonMovieStatus()");
|
||||
return objectMapper.writeValueAsString(fileIoService.readProperties().getMovieStatus());
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ info:
|
||||
app:
|
||||
name: Gaps
|
||||
description: Gaps searches through your Plex Server 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.13
|
||||
version: 0.10.0
|
||||
storageFolder: /usr/data
|
||||
properties:
|
||||
rssFeed: rssFeed.json
|
||||
|
||||
@@ -27,6 +27,11 @@ function hideScheduleAlertsAndSpinners() {
|
||||
document.getElementById('scheduleSaveError').style.display = 'none';
|
||||
}
|
||||
|
||||
function hideMovieStatusAlertsAndSpinners() {
|
||||
document.getElementById('movieStatusSaveSuccess').style.display = 'none';
|
||||
document.getElementById('movieStatusSaveError').style.display = 'none';
|
||||
}
|
||||
|
||||
function hidePlexAlertsAndSpinners() {
|
||||
document.getElementById('plexSpinner').style.display = 'none';
|
||||
document.getElementById('plexSaveSuccess').style.display = 'none';
|
||||
@@ -98,6 +103,7 @@ export default function hideAllAlertsAndSpinners() {
|
||||
hideTmdbAlertsAndSpinners();
|
||||
hideDeleteAlertsAndSpinners();
|
||||
hideScheduleAlertsAndSpinners();
|
||||
hideMovieStatusAlertsAndSpinners();
|
||||
hidePlexAlertsAndSpinners();
|
||||
hideTelegramAlertsAndSpinners();
|
||||
hideSlackAlertsAndSpinners();
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2022 Jason H House
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
import hideAllAlertsAndSpinners from './alerts-manager.min.js';
|
||||
import Payload from './payload.min.js';
|
||||
import { getContextPath } from './common.min.js';
|
||||
|
||||
export default async function saveMovieStatus() {
|
||||
hideAllAlertsAndSpinners();
|
||||
|
||||
const body = {};
|
||||
body.status = document.getElementById('setMovieStatus').value;
|
||||
|
||||
const response = await fetch(getContextPath('/movieStatus'), {
|
||||
method: 'put',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
const put = await response.json();
|
||||
if (put && put.code && put.code === Payload.MOVIE_STATUS_UPDATED) {
|
||||
hideAllAlertsAndSpinners();
|
||||
document.getElementById('movieStatusSaveSuccess').style.display = 'block';
|
||||
} else {
|
||||
hideAllAlertsAndSpinners();
|
||||
document.getElementById('movieStatusSaveError').style.display = 'block';
|
||||
}
|
||||
}
|
||||
@@ -64,4 +64,8 @@ export default Object.freeze({
|
||||
DISCORD_NOTIFICATION_UPDATE_FAILED: 141,
|
||||
DISCORD_NOTIFICATION_FOUND: 142,
|
||||
DISCORD_NOTIFICATION_NOT_FOUND: 143,
|
||||
MOVIE_STATUS_FOUND: 150,
|
||||
MOVIE_STATUS_NOT_FOUND: 151,
|
||||
MOVIE_STATUS_UPDATED: 152,
|
||||
MOVIE_STATUS_NOT_UPDATED: 153,
|
||||
});
|
||||
|
||||
@@ -29,7 +29,7 @@ export default async function saveSchedule() {
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
const put = await response.json();
|
||||
if (put.code && put.code === Payload.SCHEDULE_UPDATED) {
|
||||
if (put && put.code && put.code === Payload.SCHEDULE_UPDATED) {
|
||||
hideAllAlertsAndSpinners();
|
||||
document.getElementById('scheduleSaveSuccess').style.display = 'block';
|
||||
} else {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
import hideAllAlertsAndSpinners from '../modules/alerts-manager.min.js';
|
||||
import saveSchedule from '../modules/schedule.min.js';
|
||||
import saveMovieStatus from '../modules/movieStatus.min.js';
|
||||
import Payload from '../modules/payload.min.js';
|
||||
import { getContextPath } from '../modules/common.min.js';
|
||||
import { saveTelegramNotifications, testTelegramNotifications } from '../modules/telegram-notifications.min.js';
|
||||
@@ -308,6 +309,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
window.testPushOver = testPushOverNotifications;
|
||||
window.savePushOver = savePushOverNotifications;
|
||||
window.saveSchedule = saveSchedule;
|
||||
window.saveMovieStatus = saveMovieStatus;
|
||||
window.openPlexLibraryConfigurationModel = openPlexLibraryConfigurationModel;
|
||||
window.savePlexLibraryConfiguration = savePlexLibraryConfiguration;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<img loading="lazy" th:src="@{/images/final-2.svg}" alt="Gaps Logo" style="width:50%;height:50%;" class="center">
|
||||
|
||||
<h3 class="top-margin">About</h3>
|
||||
<h4 class="top-margin text-primary">v0.9.13</h4>
|
||||
<h4 class="top-margin text-primary">v0.10.0</h4>
|
||||
|
||||
<p class="text-muted">Gaps searches through your Plex Server. It then queries
|
||||
for known
|
||||
|
||||
@@ -30,17 +30,16 @@
|
||||
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="nav-item">
|
||||
<span class="badge badge-pill badge-primary" style="float:right;margin-bottom:-10px;">New</span>
|
||||
<a class="nav-link active" data-toggle="tab" href="#tmdb" id="tmdbTab">TMDB</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#plex" id="plexTab">Plex</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<span class="badge badge-pill badge-primary" style="float:right;margin-bottom:-10px;">New</span>
|
||||
<a class="nav-link" data-toggle="tab" href="#schedule" id="scheduleTab">Schedule</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<span class="badge badge-pill badge-primary" style="float:right;margin-bottom:-10px;">New</span>
|
||||
<a class="nav-link" data-toggle="tab" href="#notification" id="notificationTab">Notifications</a>
|
||||
</li>
|
||||
<li class="nav-item" hidden>
|
||||
@@ -60,6 +59,15 @@
|
||||
create an account, and make an API Key. Copy that key and paste it below.</p>
|
||||
|
||||
<form class="needs-validation" id="tmdbConfiguration" novalidate th:object="${plexProperties}">
|
||||
<div class="form-group">
|
||||
<label for="setMovieStatus">Show missing movies</label>
|
||||
<select class="form-control" id="setMovieStatus" onChange="saveMovieStatus();">
|
||||
<div th:each="movieStatus : ${movieStatuses}" th:remove="tag">
|
||||
<option th:value="${movieStatus.id}" th:text="${movieStatus.message}" th:selected="${plexProperties?.movieStatus?.getId().equals(movieStatus.id)?: false}"></option>
|
||||
</div>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="movieDbApiKey">Movie Database Api Key</label>
|
||||
<div class="input-group">
|
||||
@@ -102,6 +110,19 @@
|
||||
<h4 class="alert-heading">Success!</h4>
|
||||
<p class="mb-0">Your MovieDB key saved successfully.</p>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-dismissible alert-danger gaps-hide top-margin" id="movieStatusSaveError">
|
||||
<button class="close" data-hide="alert" type="button">×</button>
|
||||
<h4 class="alert-heading">Error!</h4>
|
||||
<p class="mb-0">Could not save your movie status. Check the logs and try again.</p>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-dismissible alert-success gaps-hide top-margin" id="movieStatusSaveSuccess">
|
||||
<button class="close" data-hide="alert" type="button">×</button>
|
||||
<h4 class="alert-heading">Success!</h4>
|
||||
<p class="mb-0">Your movie status saved successfully.</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="tab-pane fade top-margin" id="plex">
|
||||
<form class="needs-validation" id="plexConfiguration" novalidate>
|
||||
@@ -269,7 +290,6 @@
|
||||
<h4 class="alert-heading">Success!</h4>
|
||||
<p class="mb-0">Your schedule saved successfully.</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="tab-pane fade top-margin" id="notification">
|
||||
<div th:insert="fragments/notifications :: discord"></div>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<div class="container bottom-margin">
|
||||
<img loading="lazy" th:src="@{/images/final-2.svg}" alt="Gaps Logo" style="width:50%;height:50%;" class="center">
|
||||
|
||||
<h3 class="top-margin">v0.9.13</h3>
|
||||
<h3 class="top-margin">v0.10.0</h3>
|
||||
|
||||
<p class="text-muted">Gaps searches through your Plex Server. It then queries
|
||||
for known
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
<img loading="lazy" th:src="@{/images/final-2.svg}" alt="Gaps Logo" style="width:50%;height:50%;" class="center">
|
||||
|
||||
<h3 class="top-margin">Updates</h3>
|
||||
<h4 class="top-margin text-primary">v0.10.0</h4>
|
||||
<ul class="text-muted">
|
||||
<li>Adding option to only show released movies</li>
|
||||
</ul>
|
||||
|
||||
<h4 class="top-margin text-primary">v0.9.13</h4>
|
||||
<ul class="text-muted">
|
||||
<li>NPM and Maven Version Updates</li>
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>Gaps</artifactId>
|
||||
<groupId>com.jasonhhouse</groupId>
|
||||
<version>0.9.13</version>
|
||||
<version>0.10.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>Gaps</artifactId>
|
||||
<groupId>com.jasonhhouse</groupId>
|
||||
<version>0.9.13</version>
|
||||
<version>0.10.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ info:
|
||||
app:
|
||||
name: Gaps
|
||||
description: Gaps searches through your Plex Server 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.13
|
||||
version: 0.10.0
|
||||
storageFolder: /{CUSTOM_FOLDER} #Change to folder that gaps has permission to read, write, and delete in.
|
||||
properties:
|
||||
rssFeed: rssFeed.json
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
##
|
||||
|
||||
set -e
|
||||
VERSION=0.9.13
|
||||
VERSION=0.10.0
|
||||
JAR_VERSION="GapsWeb/target/GapsWeb-$VERSION.jar"
|
||||
ZIP_VERSION="GapsAsJar-$VERSION.zip"
|
||||
npm ci
|
||||
|
||||
@@ -21,7 +21,7 @@ describe('Verify About Page', () => {
|
||||
.should('have.text', 'About');
|
||||
|
||||
cy.get('.container > :nth-child(3)')
|
||||
.should('have.text', 'v0.9.13');
|
||||
.should('have.text', 'v0.10.0');
|
||||
|
||||
cy.get('.container > :nth-child(6)')
|
||||
.should('have.text', 'Software');
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "gaps",
|
||||
"version": "0.9.13",
|
||||
"version": "0.10.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "gaps",
|
||||
"version": "0.9.13",
|
||||
"version": "0.10.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cssnano": "^5.0.14",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gaps",
|
||||
"version": "0.9.13",
|
||||
"version": "0.10.0",
|
||||
"description": "Gaps searches through your Plex Server 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.",
|
||||
"main": "/",
|
||||
"dependencies": {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</parent>
|
||||
<groupId>com.jasonhhouse</groupId>
|
||||
<artifactId>Gaps</artifactId>
|
||||
<version>0.9.13</version>
|
||||
<version>0.10.0</version>
|
||||
<name>Gaps</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<apache.commons.lang3>3.9</apache.commons.lang3>
|
||||
<apache.commons.text>1.9</apache.commons.text>
|
||||
<commons.io>2.11.0</commons.io>
|
||||
<gaps.version>0.9.13</gaps.version>
|
||||
<gaps.version>0.10.0</gaps.version>
|
||||
<google.findbugs>3.0.0</google.findbugs>
|
||||
<guava>31.0.1-jre</guava>
|
||||
<hibernate.validator>6.1.5.Final</hibernate.validator>
|
||||
|
||||
Reference in New Issue
Block a user