Adding backend support

This commit is contained in:
Jason House
2020-09-23 22:31:59 +09:00
parent 3ae80aafa6
commit e2dca22cf9
44 changed files with 335 additions and 1107 deletions
@@ -14,7 +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.PlexServer;
import com.jasonhhouse.gaps.plex.PlexServer;
import com.jasonhhouse.gaps.Schedule;
import java.util.HashSet;
import java.util.Set;
@@ -14,10 +14,10 @@ package com.jasonhhouse.gaps.service;
import com.jasonhhouse.gaps.BasicMovie;
import com.jasonhhouse.gaps.Pair;
import com.jasonhhouse.gaps.Payload;
import com.jasonhhouse.gaps.PlexServer;
import com.jasonhhouse.gaps.plex.PlexServer;
import com.jasonhhouse.gaps.properties.PlexProperties;
import com.jasonhhouse.plex.libs.PlexLibrary;
import com.jasonhhouse.plex.video.MediaContainer;
import com.jasonhhouse.gaps.plex.PlexLibrary;
import com.jasonhhouse.gaps.plex.video.MediaContainer;
import java.util.List;
import java.util.Map;
import okhttp3.HttpUrl;
@@ -34,7 +34,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
* Search for all missing movies in your plex collection by MovieDB collection.
*/
@SpringBootApplication
@EntityScan("com.jasonhhouse.plex")
@EntityScan("com.jasonhhouse.gaps.plex")
@EnableAsync
@EnableConfigurationProperties
@ConfigurationPropertiesScan
@@ -10,7 +10,8 @@
package com.jasonhhouse.gaps;
import com.jasonhhouse.plex.libs.PlexLibrary;
import com.jasonhhouse.gaps.plex.PlexLibrary;
import com.jasonhhouse.gaps.plex.PlexServer;
import okhttp3.HttpUrl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -103,7 +104,7 @@ public class GapsUrlGenerator implements UrlGenerator {
}
@Override
public @Nullable HttpUrl generatePlexLibraryUrl(@NotNull PlexServer plexServer,@NotNull PlexLibrary plexLibrary) {
public @Nullable HttpUrl generatePlexLibraryUrl(@NotNull PlexServer plexServer, @NotNull PlexLibrary plexLibrary) {
return new HttpUrl.Builder()
.scheme(HTTP)
.host(plexServer.getAddress())
@@ -11,6 +11,7 @@ package com.jasonhhouse.gaps;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jasonhhouse.gaps.plex.PlexServer;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -10,13 +10,14 @@
package com.jasonhhouse.gaps;
import com.jasonhhouse.gaps.plex.PlexLibrary;
import com.jasonhhouse.gaps.plex.PlexServer;
import com.jasonhhouse.gaps.properties.PlexProperties;
import com.jasonhhouse.gaps.service.GapsSearch;
import com.jasonhhouse.gaps.service.FileIoService;
import com.jasonhhouse.gaps.service.NotificationService;
import com.jasonhhouse.gaps.service.PlexQuery;
import com.jasonhhouse.gaps.service.TmdbService;
import com.jasonhhouse.plex.libs.PlexLibrary;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -91,7 +92,8 @@ public class SearchGapsTask implements Runnable {
for (PlexServer plexServer : plexProperties.getPlexServers()) {
Payload payload = plexQuery.queryPlexServer(plexServer);
if (payload.getCode() == Payload.PLEX_CONNECTION_SUCCEEDED.getCode()) {
notificationService.plexServerConnectSuccessful(plexServer);
plexProperties.addPlexServer((PlexServer) payload.getExtras());
notificationService.plexServerConnectSuccessful((PlexServer) payload.getExtras());
} else {
notificationService.plexServerConnectFailed(plexServer, payload.getReason());
}
@@ -9,7 +9,8 @@
*/
package com.jasonhhouse.gaps;
import com.jasonhhouse.plex.libs.PlexLibrary;
import com.jasonhhouse.gaps.plex.PlexLibrary;
import com.jasonhhouse.gaps.plex.PlexServer;
import okhttp3.HttpUrl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -70,7 +71,7 @@ public interface UrlGenerator {
* @param plexLibrary The PlexLibrary to query
* @return query
*/
@Nullable HttpUrl generatePlexLibraryUrl(@NotNull PlexServer plexServer,@NotNull PlexLibrary plexLibrary);
@Nullable HttpUrl generatePlexLibraryUrl(@NotNull PlexServer plexServer, @NotNull PlexLibrary plexLibrary);
@NotNull HttpUrl generatePlexMetadataUrl(@NotNull PlexServer plexServer, @NotNull PlexLibrary plexLibrary,@NotNull Integer ratingKey);
@@ -12,7 +12,7 @@ package com.jasonhhouse.gaps.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.jasonhhouse.gaps.Payload;
import com.jasonhhouse.gaps.PlexServer;
import com.jasonhhouse.gaps.plex.PlexServer;
import com.jasonhhouse.gaps.properties.PlexProperties;
import com.jasonhhouse.gaps.service.FileIoService;
import com.jasonhhouse.gaps.service.PlexQueryImpl;
@@ -20,6 +20,7 @@ import com.jasonhhouse.gaps.service.SchedulerService;
import com.jasonhhouse.gaps.service.TmdbService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import java.util.Collections;
import javax.validation.Valid;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@@ -80,13 +81,20 @@ public class ConfigurationController {
@PostMapping(value = "/add/plex",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@ResponseStatus(value = HttpStatus.OK)
public void postAddPlexServer(@Parameter(description = "The details of the Plex Server to add.") @Valid final PlexServer plexServer) {
LOGGER.info("postAddPlexServer( {} )", plexServer);
public void postAddPlexServer(@Parameter(description = "The details of the Plex Server to add.") @Valid final PlexServer sentPlexServer) {
LOGGER.info("postAddPlexServer( {} )", sentPlexServer);
PlexProperties plexProperties = fileIoService.readProperties();
try {
plexQuery.queryPlexServer(plexServer);
PlexServer plexServer;
Payload plexServerPayload = plexQuery.queryPlexServer(sentPlexServer);
if (plexServerPayload.getCode() == Payload.PLEX_CONNECTION_SUCCEEDED.getCode()) {
plexServer = (PlexServer) plexServerPayload.getExtras();
} else {
plexServer = sentPlexServer;
}
Payload payload = plexQuery.getLibraries(plexServer);
if (payload.getCode() == Payload.PLEX_LIBRARIES_FOUND.getCode()) {
@@ -135,7 +143,8 @@ public class ConfigurationController {
PlexProperties plexProperties = fileIoService.readProperties();
ObjectNode objectNode = objectMapper.createObjectNode();
PlexServer returnedPlexServer = plexProperties.getPlexServers().stream().filter(plexServer -> plexServer.getMachineIdentifier().equals(machineIdentifier)).findFirst().orElse(new PlexServer());
PlexServer returnedPlexServer = plexProperties.getPlexServers().stream().filter(plexServer ->
plexServer.getMachineIdentifier().equals(machineIdentifier)).findFirst().orElse(new PlexServer("", "", "", "", -1, Collections.emptySet()));
if (StringUtils.isEmpty(returnedPlexServer.getMachineIdentifier())) {
//Failed to find and delete
@@ -157,7 +166,8 @@ public class ConfigurationController {
PlexProperties plexProperties = fileIoService.readProperties();
ObjectNode objectNode = objectMapper.createObjectNode();
PlexServer returnedPlexServer = plexProperties.getPlexServers().stream().filter(plexServer -> plexServer.getMachineIdentifier().equals(machineIdentifier)).findFirst().orElse(new PlexServer());
PlexServer returnedPlexServer = plexProperties.getPlexServers().stream().filter(plexServer ->
plexServer.getMachineIdentifier().equals(machineIdentifier)).findFirst().orElse(new PlexServer("", "", "", "", -1, Collections.emptySet()));
if (StringUtils.isEmpty(returnedPlexServer.getMachineIdentifier())) {
//Failed to find and delete
objectNode.put(SUCCESS, false);
@@ -11,10 +11,11 @@ package com.jasonhhouse.gaps.controller;
import com.jasonhhouse.gaps.BasicMovie;
import com.jasonhhouse.gaps.Payload;
import com.jasonhhouse.gaps.PlexServer;
import com.jasonhhouse.gaps.plex.PlexServer;
import com.jasonhhouse.gaps.properties.PlexProperties;
import com.jasonhhouse.gaps.service.FileIoService;
import com.jasonhhouse.plex.libs.PlexLibrary;
import com.jasonhhouse.gaps.plex.PlexLibrary;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@@ -56,12 +57,12 @@ public class LibraryController {
PlexLibrary plexLibrary;
if (CollectionUtils.isNotEmpty(plexProperties.getPlexServers())) {
//Read first plex servers movies
plexServer = plexProperties.getPlexServers().stream().findFirst().orElse(new PlexServer());
plexLibrary = plexServer.getPlexLibraries().stream().findFirst().orElse(new PlexLibrary());
plexServer = plexProperties.getPlexServers().stream().findFirst().orElse(new PlexServer("", "","", "",-1, Collections.emptySet()));
plexLibrary = plexServer.getPlexLibraries().stream().findFirst().orElse(new PlexLibrary(-1, "","","",false, false));
plexServersFound = true;
} else {
plexServer = new PlexServer();
plexLibrary = new PlexLibrary();
plexServer = new PlexServer("", "","", "",-1, Collections.emptySet());
plexLibrary = new PlexLibrary(-1, "","","",false, false);
plexServersFound = false;
}
@@ -15,7 +15,7 @@ import com.jasonhhouse.gaps.properties.PlexProperties;
import com.jasonhhouse.gaps.service.FileIoService;
import com.jasonhhouse.gaps.service.MediaContainerService;
import com.jasonhhouse.gaps.service.MislabeledService;
import com.jasonhhouse.plex.video.MediaContainer;
import com.jasonhhouse.gaps.plex.video.MediaContainer;
import java.util.List;
import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
@@ -13,11 +13,11 @@ package com.jasonhhouse.gaps.controller;
import com.jasonhhouse.gaps.GapsUrlGenerator;
import com.jasonhhouse.gaps.BasicMovie;
import com.jasonhhouse.gaps.Pair;
import com.jasonhhouse.gaps.plex.PlexLibrary;
import com.jasonhhouse.gaps.service.PlexQuery;
import com.jasonhhouse.gaps.PlexServer;
import com.jasonhhouse.gaps.plex.PlexServer;
import com.jasonhhouse.gaps.properties.PlexProperties;
import com.jasonhhouse.gaps.service.FileIoService;
import com.jasonhhouse.plex.libs.PlexLibrary;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -10,11 +10,11 @@
package com.jasonhhouse.gaps.controller;
import com.jasonhhouse.gaps.PlexServer;
import com.jasonhhouse.gaps.plex.PlexLibrary;
import com.jasonhhouse.gaps.plex.PlexServer;
import com.jasonhhouse.gaps.properties.PlexProperties;
import com.jasonhhouse.gaps.service.FileIoService;
import com.jasonhhouse.gaps.service.RssService;
import com.jasonhhouse.plex.libs.PlexLibrary;
import java.util.Map;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
@@ -12,10 +12,11 @@ package com.jasonhhouse.gaps.controller;
import com.jasonhhouse.gaps.service.GapsSearch;
import com.jasonhhouse.gaps.BasicMovie;
import com.jasonhhouse.gaps.Payload;
import com.jasonhhouse.gaps.PlexServer;
import com.jasonhhouse.gaps.plex.PlexServer;
import com.jasonhhouse.gaps.properties.PlexProperties;
import com.jasonhhouse.gaps.service.FileIoService;
import com.jasonhhouse.plex.libs.PlexLibrary;
import com.jasonhhouse.gaps.plex.PlexLibrary;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@@ -63,11 +64,11 @@ public class RecommendedController {
if (CollectionUtils.isNotEmpty(plexProperties.getPlexServers())) {
//Read first plex servers movies
plexServer = plexProperties.getPlexServers().stream().findFirst().orElse(new PlexServer());
plexLibrary = plexServer.getPlexLibraries().stream().findFirst().orElse(new PlexLibrary());
plexServer = plexProperties.getPlexServers().stream().findFirst().orElse(new PlexServer("", "","", "",-1, Collections.emptySet()));
plexLibrary = plexServer.getPlexLibraries().stream().findFirst().orElse(new PlexLibrary(-1, "","","",false, false));
} else {
plexServer = new PlexServer();
plexLibrary = new PlexLibrary();
plexServer = new PlexServer("", "","", "",-1, Collections.emptySet());
plexLibrary = new PlexLibrary(-1, "","","",false, false);
}
Map<String, PlexServer> plexServerMap = plexProperties.getPlexServers().stream().collect(Collectors.toMap(PlexServer::getMachineIdentifier, Function.identity()));
@@ -18,12 +18,12 @@ import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.jasonhhouse.gaps.BasicMovie;
import com.jasonhhouse.gaps.MovieFromCollection;
import com.jasonhhouse.gaps.Payload;
import com.jasonhhouse.gaps.PlexServer;
import com.jasonhhouse.gaps.plex.PlexServer;
import com.jasonhhouse.gaps.SearchCancelledException;
import com.jasonhhouse.gaps.SearchResults;
import com.jasonhhouse.gaps.UrlGenerator;
import com.jasonhhouse.gaps.properties.PlexProperties;
import com.jasonhhouse.plex.libs.PlexLibrary;
import com.jasonhhouse.gaps.plex.PlexLibrary;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import java.net.URLEncoder;
@@ -1,7 +1,7 @@
package com.jasonhhouse.gaps.service;
import com.jasonhhouse.gaps.sql.MediaContainerRepository;
import com.jasonhhouse.plex.video.MediaContainer;
import com.jasonhhouse.gaps.plex.video.MediaContainer;
import java.util.List;
import org.springframework.stereotype.Service;
@@ -10,8 +10,8 @@
package com.jasonhhouse.gaps.service;
import com.jasonhhouse.gaps.Mislabeled;
import com.jasonhhouse.plex.video.MediaContainer;
import com.jasonhhouse.plex.video.Video;
import com.jasonhhouse.gaps.plex.video.MediaContainer;
import com.jasonhhouse.gaps.plex.video.Video;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.text.similarity.LevenshteinDistance;
@@ -1,7 +1,7 @@
package com.jasonhhouse.gaps.service;
import com.jasonhhouse.gaps.PlexServer;
import com.jasonhhouse.plex.libs.PlexLibrary;
import com.jasonhhouse.gaps.plex.PlexServer;
import com.jasonhhouse.gaps.plex.PlexLibrary;
public interface Notification {
@@ -10,10 +10,10 @@
package com.jasonhhouse.gaps.service;
import com.jasonhhouse.gaps.NotificationType;
import com.jasonhhouse.gaps.PlexServer;
import com.jasonhhouse.gaps.plex.PlexServer;
import com.jasonhhouse.gaps.notifications.NotificationAgent;
import com.jasonhhouse.gaps.properties.NotificationProperties;
import com.jasonhhouse.plex.libs.PlexLibrary;
import com.jasonhhouse.gaps.plex.PlexLibrary;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -13,11 +13,10 @@ package com.jasonhhouse.gaps.service;
import com.jasonhhouse.gaps.BasicMovie;
import com.jasonhhouse.gaps.Pair;
import com.jasonhhouse.gaps.Payload;
import com.jasonhhouse.gaps.PlexServer;
import com.jasonhhouse.gaps.plex.PlexServer;
import com.jasonhhouse.gaps.UrlGenerator;
import com.jasonhhouse.gaps.properties.PlexProperties;
import com.jasonhhouse.plex.libs.MediaContainer;
import com.jasonhhouse.plex.libs.PlexLibrary;
import com.jasonhhouse.gaps.plex.PlexLibrary;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -26,7 +25,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
@@ -60,8 +58,6 @@ import org.xml.sax.SAXException;
@Service
public class PlexQueryImpl implements PlexQuery {
public static final String ID_IDX_START = "://";
public static final String ID_IDX_END = "?";
private static final long TIMEOUT = 2500;
private static final Logger LOGGER = LoggerFactory.getLogger(PlexQueryImpl.class);
@@ -76,6 +72,8 @@ public class PlexQueryImpl implements PlexQuery {
public @NotNull Payload getLibraries(@NotNull PlexServer plexServer) {
LOGGER.info("queryPlexLibraries()");
List<PlexLibrary> plexLibraries = new ArrayList<>();
HttpUrl url = new HttpUrl.Builder()
.scheme("http")
.host(plexServer.getAddress())
@@ -97,22 +95,53 @@ public class PlexQueryImpl implements PlexQuery {
.build();
try (Response response = client.newCall(request).execute()) {
String body = response.body() != null ? response.body().string() : null;
NodeList directories = parseXml(response, url, "/MediaContainer/Directory");
if (StringUtils.isBlank(body)) {
String reason = "Body returned empty from Plex";
LOGGER.error(reason);
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, reason);
if (directories.getLength() == 0) {
LOGGER.warn("No movies found in url: {}", url);
return Payload.PARSING_PLEX_FAILED.setExtras("url:" + url);
}
InputStream inputStream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
JAXBContext jaxbContext = JAXBContext.newInstance(MediaContainer.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
MediaContainer mediaContainer = (MediaContainer) jaxbUnmarshaller.unmarshal(inputStream);
for (int i = 0; i < directories.getLength(); i++) {
Node directory = directories.item(i);
Node nodeKey = directory.getAttributes().getNamedItem("key");
Node nodeScanner = directory.getAttributes().getNamedItem("scanner");
Node nodeTitle = directory.getAttributes().getNamedItem("title");
Node nodeType = directory.getAttributes().getNamedItem("type");
if (nodeTitle == null) {
String reason = "Missing title from Video element in Plex";
LOGGER.warn(reason);
continue;
}
if(nodeType == null || !"movie".equalsIgnoreCase(nodeType.getNodeValue())) {
LOGGER.info("Skipping library {}, not of type movie",nodeTitle.getNodeValue());
continue;
}
if(nodeKey == null) {
LOGGER.warn("Skipping library {}, key missing",nodeTitle.getNodeValue());
continue;
}
if(nodeScanner == null) {
LOGGER.warn("Skipping library {}, scanner missing",nodeTitle.getNodeValue());
continue;
}
Integer key = Integer.valueOf(nodeKey.getNodeValue());
String scanner = nodeScanner.getNodeValue();
String title = nodeTitle.getNodeValue();
String type = nodeType.getNodeValue();
PlexLibrary plexLibrary = new PlexLibrary(key, scanner, title, type, true, false);
plexLibraries.add(plexLibrary);
}
LOGGER.info("{} libraries found on server", plexLibraries.size());
//Remove everything except movie folders
List<PlexLibrary> plexLibraries = mediaContainer.getPlexLibraries().stream().filter(plexLibrary -> plexLibrary.getType().equalsIgnoreCase("movie")).collect(Collectors.toList());
LOGGER.info("{} Plex libraries found", plexLibraries.size());
plexServer.getPlexLibraries().addAll(plexLibraries);
return Payload.PLEX_LIBRARIES_FOUND.setExtras("size():" + plexLibraries.size());
@@ -120,7 +149,7 @@ public class PlexQueryImpl implements PlexQuery {
String reason = String.format("Error connecting to Plex to get library list: %s", url);
LOGGER.error(reason, e);
return Payload.PLEX_CONNECTION_FAILED.setExtras("url:" + url);
} catch (JAXBException e) {
} catch (SAXException|XPathExpressionException|ParserConfigurationException e) {
String reason = "Error parsing XML from Plex: " + url;
LOGGER.error(reason, e);
return Payload.PARSING_PLEX_FAILED.setExtras("url:" + url);
@@ -188,10 +217,16 @@ public class PlexQueryImpl implements PlexQuery {
String machineIdentifier = machineIdentifierNode.getNodeValue().trim();
LOGGER.info("machineIdentifier:{}", machineIdentifier);
plexServer.setFriendlyName(friendlyName);
plexServer.setMachineIdentifier(machineIdentifier);
//ToDo
//Do I need this anymore
plexServer = new PlexServer(friendlyName,
machineIdentifier,
plexServer.getPlexToken(),
plexServer.getAddress(),
plexServer.getPort(),
plexServer.getPlexLibraries());
return Payload.PLEX_CONNECTION_SUCCEEDED.setExtras("url:" + url);
return Payload.PLEX_CONNECTION_SUCCEEDED.setExtras(plexServer);
} catch (IOException e) {
String reason = String.format("Error connecting to Plex to get library list: %s", url);
LOGGER.error(reason, e);
@@ -209,7 +244,7 @@ public class PlexQueryImpl implements PlexQuery {
}
@Override
public @NotNull com.jasonhhouse.plex.video.MediaContainer findAllPlexVideos(@NotNull String url) {
public @NotNull com.jasonhhouse.gaps.plex.video.MediaContainer findAllPlexVideos(@NotNull String url) {
LOGGER.info("findAllPlexVideos()");
OkHttpClient client = new OkHttpClient.Builder()
@@ -220,10 +255,10 @@ public class PlexQueryImpl implements PlexQuery {
if (StringUtils.isEmpty(url)) {
LOGGER.info("No URL added to findAllPlexVideos().");
return new com.jasonhhouse.plex.video.MediaContainer();
return new com.jasonhhouse.gaps.plex.video.MediaContainer();
}
com.jasonhhouse.plex.video.MediaContainer mediaContainer;
com.jasonhhouse.gaps.plex.video.MediaContainer mediaContainer;
try {
HttpUrl httpUrl = urlGenerator.generatePlexUrl(url);
@@ -241,9 +276,9 @@ public class PlexQueryImpl implements PlexQuery {
}
InputStream inputStream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
JAXBContext jaxbContext = JAXBContext.newInstance(com.jasonhhouse.plex.video.MediaContainer.class);
JAXBContext jaxbContext = JAXBContext.newInstance(com.jasonhhouse.gaps.plex.video.MediaContainer.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
mediaContainer = (com.jasonhhouse.plex.video.MediaContainer) jaxbUnmarshaller.unmarshal(inputStream);
mediaContainer = (com.jasonhhouse.gaps.plex.video.MediaContainer) jaxbUnmarshaller.unmarshal(inputStream);
} catch (IOException e) {
String reason = String.format("Error connecting to Plex to get Movie list: %s", url);
@@ -9,9 +9,9 @@
*/
package com.jasonhhouse.gaps.service;
import com.jasonhhouse.gaps.PlexServer;
import com.jasonhhouse.gaps.plex.PlexLibrary;
import com.jasonhhouse.gaps.plex.PlexServer;
import com.jasonhhouse.gaps.properties.PlexProperties;
import com.jasonhhouse.plex.libs.PlexLibrary;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -1,6 +1,6 @@
package com.jasonhhouse.gaps.sql;
import com.jasonhhouse.plex.video.MediaContainer;
import com.jasonhhouse.gaps.plex.video.MediaContainer;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MediaContainerRepository extends JpaRepository<MediaContainer, Long> {
@@ -10,7 +10,7 @@
package com.jasonhhouse.gaps.validator;
import com.jasonhhouse.gaps.PlexServer;
import com.jasonhhouse.gaps.plex.PlexServer;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
@@ -71,6 +71,14 @@
margin-right: auto;
}
.material-icons.green600 {
color: #43A047;
}
.skip-searching-library {
text-decoration: line-through;
}
.list-ul-default {
background-color: #fafafa; /* defines the background color of the image */
mask: url(/images/list-ul.svg) no-repeat center / contain;
@@ -44,6 +44,21 @@ window.addEventListener('load', function () {
document.addEventListener('DOMContentLoaded', function () {
Handlebars.registerHelper({
isEnabled: function (value) {
return value.enabled && !value.defaultLibrary;
},
isDefaultLibrary: function (value) {
return !value.enabled && value.defaultLibrary;
},
isBoth: function (value) {
return value.enabled && value.defaultLibrary;
},
isNone: function (value) {
return !value.enabled && !value.defaultLibrary;
}
});
plexSpinner = $('#plexSpinner');
plexSaveSuccess = $('#plexSaveSuccess');
plexSaveError = $('#plexSaveError');
@@ -16,6 +16,7 @@
<link href="images/gaps.ico" rel="shortcut icon"/>
<link href="css/libraries/bootstrap.min.css" rel="stylesheet"/>
<link href="css/input.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Let browser know website is optimized for mobile-->
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
@@ -421,7 +422,18 @@
<div class="card-header">{{friendlyName}}</div>
<ul class="list-group list-group-flush">
{{#each plexLibraries}}
<li class="list-group-item">{{title}}</li>
{{#if (isEnabled this)}}
<li class="list-group-item">{{title}}</li>
{{/if}}
{{#if (isDefaultLibrary this)}}
<li class="list-group-item skip-searching-library">{{title}} <i class="material-icons green600">check</i></li>
{{/if}}
{{#if (isBoth this)}}
<li class="list-group-item">{{title}} <i class="material-icons green600">check</i></li>
{{/if}}
{{#if (isNone this)}}
<li class="list-group-item skip-searching-library">{{title}}</li>
{{/if}}
{{/each}}
</ul>
<div class="card-body">
+6
View File
@@ -12,6 +12,12 @@
<artifactId>Plex</artifactId>
<dependencies>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
@@ -0,0 +1,112 @@
/*
* 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.plex;
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 java.util.Objects;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class PlexLibrary {
@NotNull
private final Integer key;
@NotNull
private final String scanner;
@NotNull
private final String title;
@NotNull
private final String type;
@NotNull
private final Boolean enabled;
@NotNull
private final Boolean defaultLibrary;
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
public PlexLibrary(@JsonProperty(value = "key") @Nullable Integer key,
@JsonProperty(value = "scanner") @Nullable String scanner,
@JsonProperty(value = "title") @Nullable String title,
@JsonProperty(value = "type") @Nullable String type,
@JsonProperty(value = "enabled") @Nullable Boolean enabled,
@JsonProperty(value = "defaultLibrary") @Nullable Boolean defaultLibrary) {
this.key = key == null ? -1 : key;
this.scanner = scanner == null ? "" : scanner;
this.title = title == null ? "" : title;
this.type = type == null ? "" : type;
this.enabled = enabled == null || enabled;
this.defaultLibrary = defaultLibrary != null && defaultLibrary;
}
public @NotNull Integer getKey() {
return key;
}
public @NotNull String getScanner() {
return scanner;
}
public @NotNull String getTitle() {
return title;
}
public @NotNull String getType() {
return type;
}
public @NotNull Boolean getEnabled() {
return enabled;
}
public @NotNull Boolean getDefaultLibrary() {
return defaultLibrary;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PlexLibrary that = (PlexLibrary) o;
return Objects.equals(key, that.key) &&
Objects.equals(scanner, that.scanner) &&
Objects.equals(title, that.title) &&
Objects.equals(type, that.type) &&
Objects.equals(enabled, that.enabled) &&
Objects.equals(defaultLibrary, that.defaultLibrary);
}
@Override
public int hashCode() {
return Objects.hash(key, scanner, title, type, enabled, defaultLibrary);
}
@Override
public String toString() {
return "PlexLibrary{" +
"key=" + key +
", scanner='" + scanner + '\'' +
", title='" + title + '\'' +
", type='" + type + '\'' +
", enabled=" + enabled +
", defaultLibrary=" + defaultLibrary +
'}';
}
}
@@ -3,94 +3,92 @@
*
* 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 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.
*
* 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;
package com.jasonhhouse.gaps.plex;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.jasonhhouse.plex.libs.PlexLibrary;
import io.swagger.v3.oas.annotations.media.Schema;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class PlexServer {
@NotNull
@Schema(description = "Libraries that are of type movie in your Plex Server")
private final Set<PlexLibrary> plexLibraries;
@NotNull
@Schema(description = "Human readable way to identify your Plex Server")
private String friendlyName;
private final String friendlyName;
@NotNull
@Schema(description = "UID to identify the Plex Server")
private String machineIdentifier;
private final String machineIdentifier;
@NotNull
@Schema(required = true, description = "Token for your Plex Server. Found via Plex docs.")
private String plexToken;
private final String plexToken;
@NotNull
@Schema(required = true, defaultValue = "localhost", description = "Address of your Plex Server")
private String address;
private final String address;
@NotNull
@Schema(required = true, defaultValue = "32400", description = "Port of your Plex Server")
private Integer port;
private final Integer port;
public PlexServer() {
plexLibraries = new LinkedHashSet<>();
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
public PlexServer(@JsonProperty(value = "friendlyName") @Nullable String friendlyName,
@JsonProperty(value = "machineIdentifier") @Nullable String machineIdentifier,
@JsonProperty(value = "plexToken") @Nullable String plexToken,
@JsonProperty(value = "address") @Nullable String address,
@JsonProperty(value = "port") @Nullable Integer port,
@JsonProperty(value = "plexLibraries") @Nullable Set<PlexLibrary> plexLibraries) {
this.friendlyName = friendlyName == null ? "" : friendlyName;
this.machineIdentifier = machineIdentifier == null ? "" : machineIdentifier;
this.plexToken = plexToken == null ? "" : plexToken;
this.address = address == null ? "": address;
this.port = port == null ? -1 : port;
this.plexLibraries = plexLibraries == null ? new LinkedHashSet<>() : plexLibraries;
}
public PlexServer(String friendlyName, String machineIdentifier, String plexToken, String address, Integer port) {
this.friendlyName = friendlyName;
this.machineIdentifier = machineIdentifier;
this.plexToken = plexToken;
this.address = address;
this.port = port;
plexLibraries = new LinkedHashSet<>();
}
public String getFriendlyName() {
public @NotNull String getFriendlyName() {
return friendlyName;
}
public void setFriendlyName(String friendlyName) {
this.friendlyName = friendlyName;
}
public String getMachineIdentifier() {
public @NotNull String getMachineIdentifier() {
return machineIdentifier;
}
public void setMachineIdentifier(String machineIdentifier) {
this.machineIdentifier = machineIdentifier;
}
public Set<PlexLibrary> getPlexLibraries() {
public @NotNull Set<PlexLibrary> getPlexLibraries() {
return plexLibraries;
}
public String getPlexToken() {
public @NotNull String getPlexToken() {
return plexToken;
}
public void setPlexToken(String plexToken) {
this.plexToken = plexToken;
}
public String getAddress() {
public @NotNull String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Integer getPort() {
public @NotNull Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -7,7 +7,7 @@
*
* 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.plex.video;
package com.jasonhhouse.gaps.plex.video;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@@ -7,7 +7,7 @@
*
* 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.plex.video;
package com.jasonhhouse.gaps.plex.video;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@@ -7,7 +7,7 @@
*
* 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.plex.video;
package com.jasonhhouse.gaps.plex.video;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@@ -7,7 +7,7 @@
*
* 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.plex.video;
package com.jasonhhouse.gaps.plex.video;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@@ -7,7 +7,7 @@
*
* 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.plex.video;
package com.jasonhhouse.gaps.plex.video;
import java.util.List;
import java.util.Objects;
@@ -7,7 +7,7 @@
*
* 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.plex.video;
package com.jasonhhouse.gaps.plex.video;
import java.util.List;
import javax.persistence.CascadeType;
@@ -7,7 +7,7 @@
*
* 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.plex.video;
package com.jasonhhouse.gaps.plex.video;
import java.util.Objects;
import javax.persistence.Entity;
@@ -7,7 +7,7 @@
*
* 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.plex.video;
package com.jasonhhouse.gaps.plex.video;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@@ -7,7 +7,7 @@
*
* 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.plex.video;
package com.jasonhhouse.gaps.plex.video;
import java.util.List;
import java.util.Objects;
@@ -7,7 +7,7 @@
*
* 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.plex.video;
package com.jasonhhouse.gaps.plex.video;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@@ -1,128 +0,0 @@
package com.jasonhhouse.plex.libs;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType>
* &lt;simpleContent>
* &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
* &lt;attribute name="id" type="{http://www.w3.org/2001/XMLSchema}byte" />
* &lt;attribute name="path" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/extension>
* &lt;/simpleContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"value"
})
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@XmlRootElement(name = "Location")
public class Location {
@XmlValue
protected String value;
@XmlAttribute(name = "id")
protected Byte id;
@XmlAttribute(name = "path")
protected String path;
/**
* Gets the value of the value property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getValue() {
return value;
}
/**
* Sets the value of the value property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setValue(String value) {
this.value = value;
}
/**
* Gets the value of the id property.
*
* @return
* possible object is
* {@link Byte }
*
*/
public Byte getId() {
return id;
}
/**
* Sets the value of the id property.
*
* @param value
* allowed object is
* {@link Byte }
*
*/
public void setId(Byte value) {
this.id = value;
}
/**
* Gets the value of the path property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getPath() {
return path;
}
/**
* Sets the value of the path property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setPath(String value) {
this.path = value;
}
@Override
public String toString() {
return "Location{" +
"value='" + value + '\'' +
", id=" + id +
", path='" + path + '\'' +
'}';
}
}
@@ -1,246 +0,0 @@
package com.jasonhhouse.plex.libs;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType>
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element ref="{}Directory" maxOccurs="unbounded" minOccurs="0"/>
* &lt;/sequence>
* &lt;attribute name="size" type="{http://www.w3.org/2001/XMLSchema}byte" />
* &lt;attribute name="allowSync" type="{http://www.w3.org/2001/XMLSchema}byte" />
* &lt;attribute name="identifier" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="mediaTagPrefix" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="mediaTagVersion" type="{http://www.w3.org/2001/XMLSchema}int" />
* &lt;attribute name="title1" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"plexLibrary"
})
@XmlRootElement(name = "MediaContainer")
public class MediaContainer {
@XmlElement(name = "Directory")
protected List<PlexLibrary> plexLibrary;
@XmlAttribute(name = "size")
protected Byte size;
@XmlAttribute(name = "allowSync")
protected Byte allowSync;
@XmlAttribute(name = "identifier")
protected String identifier;
@XmlAttribute(name = "mediaTagPrefix")
protected String mediaTagPrefix;
@XmlAttribute(name = "mediaTagVersion")
protected Integer mediaTagVersion;
@XmlAttribute(name = "title1")
protected String title1;
/**
* Gets the value of the directory property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the directory property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getDirectory().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link PlexLibrary }
*
*
*/
public List<PlexLibrary> getPlexLibraries() {
if (plexLibrary == null) {
plexLibrary = new ArrayList<>();
}
return this.plexLibrary;
}
/**
* Gets the value of the size property.
*
* @return
* possible object is
* {@link Byte }
*
*/
public Byte getSize() {
return size;
}
/**
* Sets the value of the size property.
*
* @param value
* allowed object is
* {@link Byte }
*
*/
public void setSize(Byte value) {
this.size = value;
}
/**
* Gets the value of the allowSync property.
*
* @return
* possible object is
* {@link Byte }
*
*/
public Byte getAllowSync() {
return allowSync;
}
/**
* Sets the value of the allowSync property.
*
* @param value
* allowed object is
* {@link Byte }
*
*/
public void setAllowSync(Byte value) {
this.allowSync = value;
}
/**
* Gets the value of the identifier property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getIdentifier() {
return identifier;
}
/**
* Sets the value of the identifier property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setIdentifier(String value) {
this.identifier = value;
}
/**
* Gets the value of the mediaTagPrefix property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getMediaTagPrefix() {
return mediaTagPrefix;
}
/**
* Sets the value of the mediaTagPrefix property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setMediaTagPrefix(String value) {
this.mediaTagPrefix = value;
}
/**
* Gets the value of the mediaTagVersion property.
*
* @return
* possible object is
* {@link Integer }
*
*/
public Integer getMediaTagVersion() {
return mediaTagVersion;
}
/**
* Sets the value of the mediaTagVersion property.
*
* @param value
* allowed object is
* {@link Integer }
*
*/
public void setMediaTagVersion(Integer value) {
this.mediaTagVersion = value;
}
/**
* Gets the value of the title1 property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getTitle1() {
return title1;
}
/**
* Sets the value of the title1 property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setTitle1(String value) {
this.title1 = value;
}
@Override
public String toString() {
return "MediaContainer{" +
"plexLibrary=" + plexLibrary +
", size=" + size +
", allowSync=" + allowSync +
", identifier='" + identifier + '\'' +
", mediaTagPrefix='" + mediaTagPrefix + '\'' +
", mediaTagVersion=" + mediaTagVersion +
", title1='" + title1 + '\'' +
'}';
}
}
@@ -1,549 +0,0 @@
package com.jasonhhouse.plex.libs;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType>
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element ref="{}Location"/>
* &lt;/sequence>
* &lt;attribute name="allowSync" type="{http://www.w3.org/2001/XMLSchema}byte" />
* &lt;attribute name="art" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="composite" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="filters" type="{http://www.w3.org/2001/XMLSchema}byte" />
* &lt;attribute name="refreshing" type="{http://www.w3.org/2001/XMLSchema}byte" />
* &lt;attribute name="thumb" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="key" type="{http://www.w3.org/2001/XMLSchema}byte" />
* &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="agent" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="scanner" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="language" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="uuid" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="updatedAt" type="{http://www.w3.org/2001/XMLSchema}int" />
* &lt;attribute name="createdAt" type="{http://www.w3.org/2001/XMLSchema}int" />
* &lt;attribute name="scannedAt" type="{http://www.w3.org/2001/XMLSchema}int" />
* &lt;attribute name="content" type="{http://www.w3.org/2001/XMLSchema}byte" />
* &lt;attribute name="directory" type="{http://www.w3.org/2001/XMLSchema}byte" />
* &lt;attribute name="contentChangedAt" type="{http://www.w3.org/2001/XMLSchema}short" />
* &lt;attribute name="hidden" type="{http://www.w3.org/2001/XMLSchema}byte" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"location"
})
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@XmlRootElement(name = "Directory")
public class PlexLibrary {
@XmlElement(name = "Location", required = true)
protected Location location;
@XmlAttribute(name = "allowSync")
protected Integer allowSync;
@XmlAttribute(name = "art")
protected String art;
@XmlAttribute(name = "composite")
protected String composite;
@XmlAttribute(name = "filters")
protected Integer filters;
@XmlAttribute(name = "refreshing")
protected Integer refreshing;
@XmlAttribute(name = "thumb")
protected String thumb;
@XmlAttribute(name = "key")
protected Integer key;
@XmlAttribute(name = "type")
protected String type;
@XmlAttribute(name = "title")
protected String title;
@XmlAttribute(name = "agent")
protected String agent;
@XmlAttribute(name = "scanner")
protected String scanner;
@XmlAttribute(name = "language")
protected String language;
@XmlAttribute(name = "uuid")
protected String uuid;
@XmlAttribute(name = "updatedAt")
protected Integer updatedAt;
@XmlAttribute(name = "createdAt")
protected Integer createdAt;
@XmlAttribute(name = "scannedAt")
protected Integer scannedAt;
@XmlAttribute(name = "content")
protected Integer content;
@XmlAttribute(name = "directory")
protected Integer directory;
@XmlAttribute(name = "contentChangedAt")
protected Short contentChangedAt;
@XmlAttribute(name = "hidden")
protected Integer hidden;
/**
* Gets the value of the location property.
*
* @return possible object is
* {@link Location }
*/
public Location getLocation() {
return location;
}
/**
* Sets the value of the location property.
*
* @param value allowed object is
* {@link Location }
*/
public void setLocation(Location value) {
this.location = value;
}
/**
* Gets the value of the allowSync property.
*
* @return possible object is
* {@link Integer }
*/
public Integer getAllowSync() {
return allowSync;
}
/**
* Sets the value of the allowSync property.
*
* @param value allowed object is
* {@link Integer }
*/
public void setAllowSync(Integer value) {
this.allowSync = value;
}
/**
* Gets the value of the art property.
*
* @return possible object is
* {@link String }
*/
public String getArt() {
return art;
}
/**
* Sets the value of the art property.
*
* @param value allowed object is
* {@link String }
*/
public void setArt(String value) {
this.art = value;
}
/**
* Gets the value of the composite property.
*
* @return possible object is
* {@link String }
*/
public String getComposite() {
return composite;
}
/**
* Sets the value of the composite property.
*
* @param value allowed object is
* {@link String }
*/
public void setComposite(String value) {
this.composite = value;
}
/**
* Gets the value of the filters property.
*
* @return possible object is
* {@link Integer }
*/
public Integer getFilters() {
return filters;
}
/**
* Sets the value of the filters property.
*
* @param value allowed object is
* {@link Integer }
*/
public void setFilters(Integer value) {
this.filters = value;
}
/**
* Gets the value of the refreshing property.
*
* @return possible object is
* {@link Integer }
*/
public Integer getRefreshing() {
return refreshing;
}
/**
* Sets the value of the refreshing property.
*
* @param value allowed object is
* {@link Integer }
*/
public void setRefreshing(Integer value) {
this.refreshing = value;
}
/**
* Gets the value of the thumb property.
*
* @return possible object is
* {@link String }
*/
public String getThumb() {
return thumb;
}
/**
* Sets the value of the thumb property.
*
* @param value allowed object is
* {@link String }
*/
public void setThumb(String value) {
this.thumb = value;
}
/**
* Gets the value of the key property.
*
* @return possible object is
* {@link Integer }
*/
public Integer getKey() {
return key;
}
/**
* Sets the value of the key property.
*
* @param value allowed object is
* {@link Integer }
*/
public void setKey(Integer value) {
this.key = value;
}
/**
* Gets the value of the type property.
*
* @return possible object is
* {@link String }
*/
public String getType() {
return type;
}
/**
* Sets the value of the type property.
*
* @param value allowed object is
* {@link String }
*/
public void setType(String value) {
this.type = value;
}
/**
* Gets the value of the title property.
*
* @return possible object is
* {@link String }
*/
public String getTitle() {
return title;
}
/**
* Sets the value of the title property.
*
* @param value allowed object is
* {@link String }
*/
public void setTitle(String value) {
this.title = value;
}
/**
* Gets the value of the agent property.
*
* @return possible object is
* {@link String }
*/
public String getAgent() {
return agent;
}
/**
* Sets the value of the agent property.
*
* @param value allowed object is
* {@link String }
*/
public void setAgent(String value) {
this.agent = value;
}
/**
* Gets the value of the scanner property.
*
* @return possible object is
* {@link String }
*/
public String getScanner() {
return scanner;
}
/**
* Sets the value of the scanner property.
*
* @param value allowed object is
* {@link String }
*/
public void setScanner(String value) {
this.scanner = value;
}
/**
* Gets the value of the language property.
*
* @return possible object is
* {@link String }
*/
public String getLanguage() {
return language;
}
/**
* Sets the value of the language property.
*
* @param value allowed object is
* {@link String }
*/
public void setLanguage(String value) {
this.language = value;
}
/**
* Gets the value of the uuid property.
*
* @return possible object is
* {@link String }
*/
public String getUuid() {
return uuid;
}
/**
* Sets the value of the uuid property.
*
* @param value allowed object is
* {@link String }
*/
public void setUuid(String value) {
this.uuid = value;
}
/**
* Gets the value of the updatedAt property.
*
* @return possible object is
* {@link Integer }
*/
public Integer getUpdatedAt() {
return updatedAt;
}
/**
* Sets the value of the updatedAt property.
*
* @param value allowed object is
* {@link Integer }
*/
public void setUpdatedAt(Integer value) {
this.updatedAt = value;
}
/**
* Gets the value of the createdAt property.
*
* @return possible object is
* {@link Integer }
*/
public Integer getCreatedAt() {
return createdAt;
}
/**
* Sets the value of the createdAt property.
*
* @param value allowed object is
* {@link Integer }
*/
public void setCreatedAt(Integer value) {
this.createdAt = value;
}
/**
* Gets the value of the scannedAt property.
*
* @return possible object is
* {@link Integer }
*/
public Integer getScannedAt() {
return scannedAt;
}
/**
* Sets the value of the scannedAt property.
*
* @param value allowed object is
* {@link Integer }
*/
public void setScannedAt(Integer value) {
this.scannedAt = value;
}
/**
* Gets the value of the content property.
*
* @return possible object is
* {@link Integer }
*/
public Integer getContent() {
return content;
}
/**
* Sets the value of the content property.
*
* @param value allowed object is
* {@link Integer }
*/
public void setContent(Integer value) {
this.content = value;
}
/**
* Gets the value of the directory property.
*
* @return possible object is
* {@link Integer }
*/
public Integer getDirectory() {
return directory;
}
/**
* Sets the value of the directory property.
*
* @param value allowed object is
* {@link Integer }
*/
public void setDirectory(Integer value) {
this.directory = value;
}
/**
* Gets the value of the contentChangedAt property.
*
* @return possible object is
* {@link Short }
*/
public Short getContentChangedAt() {
return contentChangedAt;
}
/**
* Sets the value of the contentChangedAt property.
*
* @param value allowed object is
* {@link Short }
*/
public void setContentChangedAt(Short value) {
this.contentChangedAt = value;
}
/**
* Gets the value of the hidden property.
*
* @return possible object is
* {@link Integer }
*/
public Integer getHidden() {
return hidden;
}
/**
* Sets the value of the hidden property.
*
* @param value allowed object is
* {@link Integer }
*/
public void setHidden(Integer value) {
this.hidden = value;
}
@Override
public String toString() {
return "PlexLibrary{" +
"location=" + location +
", allowSync=" + allowSync +
", art='" + art + '\'' +
", composite='" + composite + '\'' +
", filters=" + filters +
", refreshing=" + refreshing +
", thumb='" + thumb + '\'' +
", key=" + key +
", type='" + type + '\'' +
", title='" + title + '\'' +
", agent='" + agent + '\'' +
", scanner='" + scanner + '\'' +
", language='" + language + '\'' +
", uuid='" + uuid + '\'' +
", updatedAt=" + updatedAt +
", createdAt=" + createdAt +
", scannedAt=" + scannedAt +
", content=" + content +
", directory=" + directory +
", contentChangedAt=" + contentChangedAt +
", hidden=" + hidden +
'}';
}
}
@@ -1,52 +0,0 @@
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Location">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:byte" name="id" use="optional"/>
<xs:attribute type="xs:string" name="path" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="Directory">
<xs:complexType>
<xs:sequence>
<xs:element ref="Location"/>
</xs:sequence>
<xs:attribute type="xs:byte" name="allowSync" use="optional"/>
<xs:attribute type="xs:string" name="art" use="optional"/>
<xs:attribute type="xs:string" name="composite" use="optional"/>
<xs:attribute type="xs:byte" name="filters" use="optional"/>
<xs:attribute type="xs:byte" name="refreshing" use="optional"/>
<xs:attribute type="xs:string" name="thumb" use="optional"/>
<xs:attribute type="xs:byte" name="key" use="optional"/>
<xs:attribute type="xs:string" name="type" use="optional"/>
<xs:attribute type="xs:string" name="title" use="optional"/>
<xs:attribute type="xs:string" name="agent" use="optional"/>
<xs:attribute type="xs:string" name="scanner" use="optional"/>
<xs:attribute type="xs:string" name="language" use="optional"/>
<xs:attribute type="xs:string" name="uuid" use="optional"/>
<xs:attribute type="xs:int" name="updatedAt" use="optional"/>
<xs:attribute type="xs:int" name="createdAt" use="optional"/>
<xs:attribute type="xs:int" name="scannedAt" use="optional"/>
<xs:attribute type="xs:byte" name="content" use="optional"/>
<xs:attribute type="xs:byte" name="directory" use="optional"/>
<xs:attribute type="xs:short" name="contentChangedAt" use="optional"/>
<xs:attribute type="xs:byte" name="hidden" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="MediaContainer">
<xs:complexType>
<xs:sequence>
<xs:element ref="Directory" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
<xs:attribute type="xs:byte" name="size"/>
<xs:attribute type="xs:byte" name="allowSync"/>
<xs:attribute type="xs:string" name="identifier"/>
<xs:attribute type="xs:string" name="mediaTagPrefix"/>
<xs:attribute type="xs:int" name="mediaTagVersion"/>
<xs:attribute type="xs:string" name="title1"/>
</xs:complexType>
</xs:element>
</xs:schema>
@@ -7,9 +7,9 @@
*
* 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.plex;
package com.jasonhhouse.gaps.plex;
import com.jasonhhouse.plex.video.MediaContainer;
import com.jasonhhouse.gaps.plex.video.MediaContainer;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;