diff --git a/README.md b/README.md index ea45eae..846a6db 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Made this simple multi chat-client bot to access radarr, sonarr, and lidarr with ## Currently, Supported API's - [x] Radarr (v4) +- [x] Sonarr (v4) - [x] Sonarr (v3) - [x] Lidarr (v1) - [x] Lidarr (v0) @@ -166,6 +167,7 @@ botdarr: | SONARR_DEFAULT_PROFILE | The sonarr quality profile (should be already configured in sonarr) | yes - if you use sonarr | | SONARR_PATH | Where your sonarr shows should go (if you add/update them) | yes - if you use sonarr | | SONARR_URL_BASE | Only populate this if you use a custom sonarr url base (which is configurable in Sonarr->Settings->General->URL Base) don't include prefix/suffix slashes | no | +| SONARR_V4 | Whether you are using sonarr v4 or not | no | no | #### Lidarr | Environment Variable | Description | Required | Default | diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index da16c1d..d0f6bf7 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -39,6 +39,7 @@ if [ ! -e "$propertiesFile" ]; then [[ ! -z "${SONARR_DEFAULT_PROFILE}" ]] && addConfiguration "sonarr-default-profile" "${SONARR_DEFAULT_PROFILE}" "${propertiesFile}" [[ ! -z "${SONARR_PATH}" ]] && addConfiguration "sonarr-path" "${SONARR_PATH}" "${propertiesFile}" [[ ! -z "${SONARR_URL_BASE}" ]] && addConfiguration "sonarr-url-base" "${SONARR_URL_BASE}" "${propertiesFile}" + [[ ! -z "${SONARR_V4}" ]] && addConfiguration "sonarr-v4" "${SONARR_V4}" "${propertiesFile}" [[ ! -z "${LIDARR_URL}" ]] && addConfiguration "lidarr-url" "${LIDARR_URL}" "${propertiesFile}" [[ ! -z "${LIDARR_TOKEN}" ]] && addConfiguration "lidarr-token" "${LIDARR_TOKEN}" "${propertiesFile}" diff --git a/pom.xml b/pom.xml index 2656dde..1c11ddd 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ com.google.code.gson gson - 2.8.5 + 2.8.9 org.apache.logging.log4j @@ -66,7 +66,7 @@ com.fasterxml.jackson.core jackson-databind - 2.13.1 + 2.13.4.1 com.google.guava diff --git a/sample.properties b/sample.properties index dbc7a6c..cb3377f 100644 --- a/sample.properties +++ b/sample.properties @@ -53,6 +53,8 @@ sonarr-path= # Only populate this if you use a custom sonarr url base (which is configurable in Sonarr->Settings->General->URL Base) # don't include prefix/suffix slashes sonarr-url-base= +# Whether your sonarr instance is v4 or not +sonarr-v4 lidarr-url= lidarr-token= diff --git a/src/main/java/com/botdarr/Config.java b/src/main/java/com/botdarr/Config.java index a62e778..9dc8eb7 100644 --- a/src/main/java/com/botdarr/Config.java +++ b/src/main/java/com/botdarr/Config.java @@ -327,6 +327,11 @@ public static final class Constants { */ public static final String SONARR_URL_BASE = "sonarr-url-base"; + /** + * Whether to turn on sonarr v4 support or not + */ + public static final String SONARR_V4 = "sonarr-v4"; + /** * The url to your lidarr instance */ @@ -416,6 +421,7 @@ public static final class Constants { * Config for the log level */ public static final String LOG_LEVEL = "log-level"; + public static final int VALUE_MAX_LENGTH = 1024; } private static String propertiesPath = "config/properties"; diff --git a/src/main/java/com/botdarr/api/Api.java b/src/main/java/com/botdarr/api/Api.java index 3103978..b04c9cc 100644 --- a/src/main/java/com/botdarr/api/Api.java +++ b/src/main/java/com/botdarr/api/Api.java @@ -1,30 +1,12 @@ package com.botdarr.api; -import com.botdarr.Config; -import com.botdarr.clients.ChatClient; import com.botdarr.clients.ChatClientResponse; -import com.botdarr.clients.ChatClientResponseBuilder; -import com.botdarr.clients.discord.DiscordResponse; import com.botdarr.commands.responses.CommandResponse; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.util.Strings; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; import java.util.List; public interface Api { - /** - * The url base for this api (can be null/empty) - */ - String getUrlBase(); - - /** - * Get this api's url endpoint - */ - String getApiUrl(String path); - /** * Gets all the in-progress downloads */ @@ -35,24 +17,9 @@ public interface Api { */ void cacheData(); - /** - * Gets the auth token for this api - */ - String getApiToken(); - - default String getApiUrl(String apiUrlKey, String apiTokenKey, String path) { - try { - String urlBase = Strings.isBlank(getUrlBase()) ? "" : "/" + getUrlBase(); - return Config.getProperty(apiUrlKey) + urlBase + "/api/" + path + "?apikey=" + URLEncoder.encode(Config.getProperty(apiTokenKey), "UTF-8"); - } catch (UnsupportedEncodingException e) { - LOGGER.error("Error encoding api token", e); - throw new RuntimeException("Error calculating the api url", e); - } - } - default List subList(List responses, int max) { return responses.subList(0, responses.size() > max ? max - 1 : responses.size()); } - static final Logger LOGGER = LogManager.getLogger(); + Logger LOGGER = LogManager.getLogger(); } diff --git a/src/main/java/com/botdarr/api/ArrRequestBuilder.java b/src/main/java/com/botdarr/api/ArrRequestBuilder.java new file mode 100644 index 0000000..3aa28dd --- /dev/null +++ b/src/main/java/com/botdarr/api/ArrRequestBuilder.java @@ -0,0 +1,54 @@ +package com.botdarr.api; + +import com.botdarr.Config; +import com.botdarr.connections.RequestBuilder; +import org.apache.logging.log4j.util.Strings; +import java.util.HashMap; +import java.util.Map; + +public class ArrRequestBuilder { + private final String urlConfigName; + private final String urlBaseConfigName; + private final String tokenName; + private final RequestBuilder requestBuilder = new RequestBuilder(); + public ArrRequestBuilder(String urlConfigName, String urlBaseConfigName, String tokenName) { + this.urlConfigName = urlConfigName; + this.urlBaseConfigName = urlBaseConfigName; + this.tokenName = tokenName; + } + + private RequestBuilder tokens(RequestBuilder requestBuilder) { + //TODO: which *arr's actually need the api key in path and headers? (this is likely a side effect from one + //of the apis requiring one or the other and me being lazy) + return requestBuilder.param("apiKey", Config.getProperty(this.tokenName)) + .headers("X-Api-Key", Config.getProperty(this.tokenName)); + } + + private String getRadarrHost() { + String host = Config.getProperty(this.urlConfigName); + String rawUrlBase = Config.getProperty(this.urlBaseConfigName); + String urlBase = Strings.isBlank(rawUrlBase) ? "" : "/" + rawUrlBase; + return host + urlBase + getApiSuffix(); + } + + public String getApiSuffix() { + return "/api/"; + } + + public RequestBuilder buildGet(String path) { + return buildGet(path, new HashMap<>()); + } + + public RequestBuilder buildGet(String path, Map params) { + for (Map.Entry entry : params.entrySet()) { + this.requestBuilder.param(entry.getKey(), entry.getValue()); + } + RequestBuilder requestBuilder = this.requestBuilder.host(getRadarrHost() + path); + return this.tokens(requestBuilder); + } + + public RequestBuilder buildPost(String path, String postBody) { + RequestBuilder requestBuilder = this.requestBuilder.host(getRadarrHost() + path).post(postBody); + return this.tokens(requestBuilder); + } +} \ No newline at end of file diff --git a/src/main/java/com/botdarr/api/CacheContentStrategy.java b/src/main/java/com/botdarr/api/CacheContentStrategy.java index e60eaaa..229d551 100644 --- a/src/main/java/com/botdarr/api/CacheContentStrategy.java +++ b/src/main/java/com/botdarr/api/CacheContentStrategy.java @@ -1,6 +1,7 @@ package com.botdarr.api; import com.botdarr.connections.ConnectionHelper; +import com.botdarr.connections.RequestBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonParser; @@ -11,9 +12,8 @@ import java.util.List; public abstract class CacheContentStrategy { - public CacheContentStrategy(Api api, String url) { - this.api = api; - this.url = url; + public CacheContentStrategy(RequestBuilder requestBuilder) { + this.requestBuilder = requestBuilder; } public abstract void deleteFromCache(List itemsAddedUpdated); @@ -21,7 +21,9 @@ public CacheContentStrategy(Api api, String url) { public void cacheData() { List itemsAddedUpdated = new ArrayList<>(); - ConnectionHelper.makeGetRequest(this.api, this.url, new ConnectionHelper.SimpleEntityResponseHandler>() { + ConnectionHelper.makeGetRequest( + this.requestBuilder, + new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) throws Exception { JsonParser parser = new JsonParser(); @@ -33,10 +35,9 @@ public List onSuccess(String response) throws Exception { } }); deleteFromCache(itemsAddedUpdated); - LOGGER.debug("Finished caching content data for api " + api.getClass().getName()); + LOGGER.debug("Finished caching content data for host " + this.requestBuilder.getHost()); } - private final Api api; - private final String url; + private final RequestBuilder requestBuilder; private static final Logger LOGGER = LogManager.getLogger(); } diff --git a/src/main/java/com/botdarr/api/DownloadsStrategy.java b/src/main/java/com/botdarr/api/DownloadsStrategy.java index 2db384a..2bbb8ac 100644 --- a/src/main/java/com/botdarr/api/DownloadsStrategy.java +++ b/src/main/java/com/botdarr/api/DownloadsStrategy.java @@ -3,6 +3,7 @@ import com.botdarr.commands.responses.CommandResponse; import com.botdarr.commands.responses.InfoResponse; import com.botdarr.connections.ConnectionHelper; +import com.botdarr.connections.RequestBuilder; import com.botdarr.utilities.ListUtils; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @@ -16,13 +17,8 @@ import java.util.List; public abstract class DownloadsStrategy { - public DownloadsStrategy(Api api, - String url) { - this.api = api; - this.url = url; - } - public abstract CommandResponse getResponse(JsonElement rawElement); + public abstract List getContentDownloads(); public List downloads() { if (MAX_DOWNLOADS_TO_SHOW <= 0) { @@ -31,27 +27,9 @@ public List downloads() { return getContentDownloads(); } - public List getContentDownloads() { - return ConnectionHelper.makeGetRequest(this.api, this.url, new ConnectionHelper.SimpleMessageEmbedResponseHandler() { - - @Override - public List onConnectException(HttpHostConnectException e) { - String message = "Error trying to connect to " + DownloadsStrategy.this.api.getApiUrl(DownloadsStrategy.this.url); - LOGGER.error(message); - return Collections.emptyList(); - } - - @Override - public List onSuccess(String response) { - return parseContent(response); - } - }); - } - public List parseContent(String response) { List chatClientResponses = new ArrayList<>(); - JsonParser parser = new JsonParser(); - JsonArray json = parser.parse(response).getAsJsonArray(); + JsonArray json = JsonParser.parseString(response).getAsJsonArray(); boolean tooManyDownloads = json.size() >= MAX_DOWNLOADS_TO_SHOW; for (int i = 0; i < json.size(); i++) { CommandResponse chatClientResponse = getResponse(json.get(i)); @@ -67,8 +45,6 @@ public List parseContent(String response) { return chatClientResponses; } - private final Api api; - private final String url; private final int MAX_DOWNLOADS_TO_SHOW = new ApiRequests().getMaxDownloadsToShow(); private static Logger LOGGER = LogManager.getLogger(); } diff --git a/src/main/java/com/botdarr/api/lidarr/LidarrApi.java b/src/main/java/com/botdarr/api/lidarr/LidarrApi.java index 3dcb4ba..f67d3a5 100644 --- a/src/main/java/com/botdarr/api/lidarr/LidarrApi.java +++ b/src/main/java/com/botdarr/api/lidarr/LidarrApi.java @@ -2,39 +2,27 @@ import com.botdarr.Config; import com.botdarr.api.*; -import com.botdarr.api.sonarr.SonarrUrls; import com.botdarr.commands.CommandContext; import com.botdarr.commands.responses.*; import com.botdarr.connections.ConnectionHelper; +import com.botdarr.connections.RequestBuilder; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.*; import org.apache.commons.io.IOUtils; import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; +import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.logging.log4j.LogManager; import java.io.IOException; -import java.net.URLEncoder; -import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; public class LidarrApi implements Api { - @Override - public String getUrlBase() { - return Config.getProperty(Config.Constants.LIDARR_URL_BASE); - } - - @Override - public String getApiUrl(String path) { - return getApiUrl(Config.Constants.LIDARR_URL, Config.Constants.LIDARR_TOKEN, path); - } - @Override public List downloads() { return getDownloadsStrategy().downloads(); @@ -51,7 +39,9 @@ public void deleteFromCache(List profilesAddUpdated) { @Override public List getProfiles() { - return ConnectionHelper.makeGetRequest(LidarrApi.this, LidarrUrls.PROFILE, new ConnectionHelper.SimpleEntityResponseHandler>() { + return ConnectionHelper.makeGetRequest( + new LidarrUrls.LidarrRequestBuilder().buildGet(LidarrUrls.PROFILE), + new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List lidarrQualityProfiles = new ArrayList<>(); @@ -81,7 +71,9 @@ public void deleteFromCache(List profilesAddUpdated) { @Override public List getProfiles() { - return ConnectionHelper.makeGetRequest(LidarrApi.this, LidarrUrls.METADATA_PROFILE, new ConnectionHelper.SimpleEntityResponseHandler>() { + return ConnectionHelper.makeGetRequest( + new LidarrUrls.LidarrRequestBuilder().buildGet(LidarrUrls.METADATA_PROFILE), + new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List lidarrMetadataProfiles = new ArrayList<>(); @@ -102,7 +94,7 @@ public void addProfile(LidarrMetadataProfile profile) { } }.cacheData(); - new CacheContentStrategy(this, LidarrUrls.ALL_ARTISTS) { + new CacheContentStrategy(new LidarrUrls.LidarrRequestBuilder().buildGet(LidarrUrls.ALL_ARTISTS)) { @Override public void deleteFromCache(List itemsToRetain) { @@ -120,11 +112,6 @@ public String addToCache(JsonElement cacheItem) { //TODO: add album cache } - @Override - public String getApiToken() { - return Config.Constants.LIDARR_TOKEN; - } - public CommandResponse addArtistWithId(String id, String artistName) { return getArtistAddStrategy().addWithSearchId(artistName, id); } @@ -204,7 +191,8 @@ public CommandResponse getResponse(LidarrArtist item) { } private DownloadsStrategy getDownloadsStrategy() { - return new DownloadsStrategy(this, LidarrUrls.DOWNLOAD_BASE) { + RequestBuilder requestBuilder = new LidarrUrls.LidarrRequestBuilder().buildGet(LidarrUrls.DOWNLOAD_BASE); + return new DownloadsStrategy() { @Override public CommandResponse getResponse(JsonElement rawElement) { LidarrQueueRecord lidarrQueueRecord = new Gson().fromJson(rawElement, LidarrQueueRecord.class); @@ -212,11 +200,12 @@ public CommandResponse getResponse(JsonElement rawElement) { } @Override public List getContentDownloads() { - return ConnectionHelper.makeGetRequest(LidarrApi.this, LidarrUrls.DOWNLOAD_BASE, new ConnectionHelper.SimpleMessageEmbedResponseHandler() { + return ConnectionHelper.makeGetRequest( + requestBuilder, + new ConnectionHelper.SimpleCommandResponseHandler() { @Override public List onSuccess(String response) { - JsonParser parser = new JsonParser(); - JsonObject json = parser.parse(response).getAsJsonObject(); + JsonObject json = JsonParser.parseString(response).getAsJsonObject(); return parseContent(json.get("records").toString()); } }); @@ -225,7 +214,10 @@ public List onSuccess(String response) { } private List lookupArtists(String search) throws Exception { - return ConnectionHelper.makeGetRequest(this, LidarrUrls.LOOKUP_ARTISTS, "&term=" + URLEncoder.encode(search, "UTF-8"), + return ConnectionHelper.makeGetRequest( + new LidarrUrls.LidarrRequestBuilder().buildGet(LidarrUrls.LOOKUP_ARTISTS, new HashMap() {{ + put("term", search); + }}), new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { @@ -259,14 +251,12 @@ private CommandResponse addArtist(LidarrArtist lidarrArtist) { lidarrArtist.setMetadataProfileId(lidarrMetadataProfile.getId()); lidarrArtist.setQualityProfileId(lidarrQualityProfile.getId()); try (CloseableHttpClient client = HttpClientBuilder.create().build()) { - HttpPost post = new HttpPost(getApiUrl(SonarrUrls.ARTIST_BASE)); - post.addHeader("content-type", "application/json"); ObjectMapper mapper = new ObjectMapper(); //lidarr for some reason doesn't support raw unicode characters in json parsing (since they should be allowed), so we escape them here mapper.getFactory().configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true); String json = mapper.writeValueAsString(lidarrArtist); - post.setEntity(new StringEntity(json, Charset.forName("UTF-8"))); + HttpRequestBase post = new LidarrUrls.LidarrRequestBuilder().buildPost(LidarrUrls.ARTIST_BASE, json).build(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Client request=" + post); diff --git a/src/main/java/com/botdarr/api/lidarr/LidarrUrls.java b/src/main/java/com/botdarr/api/lidarr/LidarrUrls.java index 5c36eb3..a623b62 100644 --- a/src/main/java/com/botdarr/api/lidarr/LidarrUrls.java +++ b/src/main/java/com/botdarr/api/lidarr/LidarrUrls.java @@ -1,6 +1,15 @@ package com.botdarr.api.lidarr; +import com.botdarr.Config; +import com.botdarr.api.ArrRequestBuilder; + public class LidarrUrls { + public static class LidarrRequestBuilder extends ArrRequestBuilder { + public LidarrRequestBuilder() { + super(Config.Constants.LIDARR_URL, Config.Constants.LIDARR_URL_BASE, Config.Constants.LIDARR_TOKEN); + } + } + /** * The base endpoint prefix for lidarr v1 api, https://github.com/lidarr/Lidarr/wiki/API */ @@ -30,4 +39,5 @@ public class LidarrUrls { * TODO: doc */ public static final String METADATA_PROFILE = VERSION + "metadataprofile"; + public static final String ARTIST_BASE = "v1/artist"; } diff --git a/src/main/java/com/botdarr/api/radarr/RadarrApi.java b/src/main/java/com/botdarr/api/radarr/RadarrApi.java index ea56ef8..7d71147 100644 --- a/src/main/java/com/botdarr/api/radarr/RadarrApi.java +++ b/src/main/java/com/botdarr/api/radarr/RadarrApi.java @@ -8,28 +8,16 @@ import com.google.gson.*; import org.apache.commons.io.IOUtils; import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; +import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.logging.log4j.LogManager; import java.io.IOException; -import java.net.URLEncoder; import java.nio.charset.Charset; import java.util.*; public class RadarrApi implements Api { - @Override - public String getUrlBase() { - return Config.getProperty(Config.Constants.RADARR_URL_BASE); - } - - @Override - public String getApiUrl(String path) { - return getApiUrl(Config.Constants.RADARR_URL, Config.Constants.RADARR_TOKEN, "v3/" + path); - } - public List lookup(String search, boolean findNew) { return new LookupStrategy(ContentType.MOVIE) { @@ -96,7 +84,9 @@ public void deleteFromCache(List profilesAddUpdated) { @Override public List getProfiles() { - return ConnectionHelper.makeGetRequest(RadarrApi.this, RadarrUrls.PROFILE_BASE, new ConnectionHelper.SimpleEntityResponseHandler>() { + return ConnectionHelper.makeGetRequest( + new RadarrUrls.RadarrV3RequestBuilder().buildGet(RadarrUrls.PROFILE_BASE), + new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List radarrProfiles = new ArrayList<>(); @@ -117,7 +107,7 @@ public void addProfile(RadarrProfile profile) { } }.cacheData(); - new CacheContentStrategy(this, RadarrUrls.MOVIE_BASE) { + new CacheContentStrategy(new RadarrUrls.RadarrV3RequestBuilder().buildGet(RadarrUrls.MOVIE_BASE)) { @Override public void deleteFromCache(List itemsAddedUpdated) { RADARR_CACHE.removeDeletedMovies(itemsAddedUpdated); @@ -132,13 +122,12 @@ public Long addToCache(JsonElement cacheItem) { }.cacheData(); } - @Override - public String getApiToken() { - return Config.Constants.RADARR_TOKEN; - } - public List discover() { - return ConnectionHelper.makeGetRequest(this, RadarrUrls.DISCOVER_MOVIES, "&includeRecommendations=true", new ConnectionHelper.SimpleEntityResponseHandler>() { + return ConnectionHelper.makeGetRequest( + new RadarrUrls.RadarrV3RequestBuilder().buildGet(RadarrUrls.DISCOVER_MOVIES, new HashMap() {{ + put("includeRecommendations", "true"); + }}), + new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) throws Exception { List recommendedMovies = new ArrayList<>(); @@ -163,7 +152,7 @@ public List onSuccess(String response) throws Exception { } private DownloadsStrategy getDownloadsStrategy() { - return new DownloadsStrategy(this, RadarrUrls.DOWNLOAD_BASE) { + return new DownloadsStrategy() { @Override public CommandResponse getResponse(JsonElement rawElement) { RadarrQueue radarrQueue = new Gson().fromJson(rawElement, RadarrQueue.class); @@ -186,16 +175,14 @@ public CommandResponse getResponse(JsonElement rawElement) { @Override public List getContentDownloads() { return ConnectionHelper.makeGetRequest( - RadarrApi.this, - RadarrUrls.DOWNLOAD_BASE, - new ConnectionHelper.SimpleMessageEmbedResponseHandler() { + new RadarrUrls.RadarrV3RequestBuilder().buildGet(RadarrUrls.DOWNLOAD_BASE), + new ConnectionHelper.SimpleCommandResponseHandler() { @Override public List onSuccess(String response) { if (response == null || response.isEmpty() || response.equals("{}")) { return new ArrayList<>(); } - JsonParser parser = new JsonParser(); - JsonObject json = parser.parse(response).getAsJsonObject(); + JsonObject json = JsonParser.parseString(response).getAsJsonObject(); return parseContent(json.get("records").toString()); } }); @@ -251,15 +238,12 @@ private CommandResponse addMovie(RadarrMovie radarrMovie) { radarrMovie.setQualityProfileId((int) radarrProfile.getId()); try (CloseableHttpClient client = HttpClientBuilder.create().build()) { - HttpPost post = new HttpPost(getApiUrl(RadarrUrls.MOVIE_BASE)); - - post.addHeader("content-type", "application/json"); String json = new Gson().toJson(radarrMovie, RadarrMovie.class); - post.setEntity(new StringEntity(json, Charset.forName("UTF-8"))); + HttpRequestBase post = new RadarrUrls.RadarrV3RequestBuilder().buildPost(RadarrUrls.MOVIE_BASE, json).build(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Client request=" + post); - LOGGER.debug("Client data=" + (json)); + LOGGER.debug("Client data=" + json); } String username = CommandContext.getConfig().getUsername(); @@ -292,8 +276,11 @@ private CommandResponse addMovie(RadarrMovie radarrMovie) { } private List lookupMovies(String search) throws Exception { - return ConnectionHelper.makeGetRequest(this, RadarrUrls.MOVIE_LOOKUP, "&term=" + URLEncoder.encode(search, "UTF-8"), - new ConnectionHelper.SimpleEntityResponseHandler>() { + return ConnectionHelper.makeGetRequest( + new RadarrUrls.RadarrV3RequestBuilder().buildGet(RadarrUrls.MOVIE_LOOKUP, new HashMap() {{ + put("term", search); + }}), + new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List movies = new ArrayList<>(); @@ -308,8 +295,11 @@ public List onSuccess(String response) { } private List lookupMoviesById(String tmdbid) throws Exception { - return ConnectionHelper.makeGetRequest(this, RadarrUrls.MOVIE_LOOKUP_TMDB, "&tmdbId=" + URLEncoder.encode(tmdbid, "UTF-8"), - new ConnectionHelper.SimpleEntityResponseHandler>() { + return ConnectionHelper.makeGetRequest( + new RadarrUrls.RadarrV3RequestBuilder().buildGet(RadarrUrls.MOVIE_LOOKUP_TMDB, new HashMap() {{ + put("tmdbId", tmdbid); + }}), + new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List movies = new ArrayList<>(); diff --git a/src/main/java/com/botdarr/api/radarr/RadarrUrls.java b/src/main/java/com/botdarr/api/radarr/RadarrUrls.java index 3f3578e..97293b1 100644 --- a/src/main/java/com/botdarr/api/radarr/RadarrUrls.java +++ b/src/main/java/com/botdarr/api/radarr/RadarrUrls.java @@ -1,6 +1,20 @@ package com.botdarr.api.radarr; +import com.botdarr.Config; +import com.botdarr.api.ArrRequestBuilder; + public class RadarrUrls { + public static class RadarrV3RequestBuilder extends ArrRequestBuilder { + public RadarrV3RequestBuilder() { + super(Config.Constants.RADARR_URL, Config.Constants.RADARR_URL_BASE, Config.Constants.RADARR_TOKEN); + } + + @Override + public String getApiSuffix() { + return "/api/v3/"; + } + } + /** * The base download(s) url for get, put, delete requests (which each do different things in radarr) * See https://github.com/Radarr/Radarr/wiki/API:Queue diff --git a/src/main/java/com/botdarr/api/sonarr/SonarrApi.java b/src/main/java/com/botdarr/api/sonarr/SonarrApi.java index 6405db7..6356c86 100644 --- a/src/main/java/com/botdarr/api/sonarr/SonarrApi.java +++ b/src/main/java/com/botdarr/api/sonarr/SonarrApi.java @@ -7,28 +7,17 @@ import com.botdarr.connections.ConnectionHelper; import com.google.gson.*; import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; +import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.logging.log4j.LogManager; import java.io.IOException; -import java.net.URLEncoder; -import java.nio.charset.Charset; import java.util.*; -public class SonarrApi implements Api { - @Override - public String getUrlBase() { - return Config.getProperty(Config.Constants.SONARR_URL_BASE); - } - - @Override - public String getApiUrl(String path) { - return getApiUrl(Config.Constants.SONARR_URL, Config.Constants.SONARR_TOKEN, path); - } +import static com.botdarr.Config.Constants.VALUE_MAX_LENGTH; +public class SonarrApi implements Api { @Override public List downloads() { return getDownloadsStrategy().downloads(); @@ -95,7 +84,9 @@ public void deleteFromCache(List profilesAddUpdated) { @Override public List getProfiles() { - return ConnectionHelper.makeGetRequest(SonarrApi.this, SonarrUrls.PROFILE, new ConnectionHelper.SimpleEntityResponseHandler>() { + return ConnectionHelper.makeGetRequest( + new SonarrUrls.SonarrRequestBuilder().buildGet(SonarrUrls.PROFILE), + new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List sonarrProfiles = new ArrayList<>(); @@ -116,7 +107,7 @@ public void addProfile(SonarrProfile profile) { } }.cacheData(); - new CacheContentStrategy(this, SonarrUrls.SERIES_BASE) { + new CacheContentStrategy(new SonarrUrls.SonarrRequestBuilder().buildGet(SonarrUrls.SERIES_BASE)) { @Override public void deleteFromCache(List itemsAddedUpdated) { SONARR_CACHE.removeDeletedShows(itemsAddedUpdated); @@ -131,11 +122,6 @@ public Long addToCache(JsonElement cacheItem) { }.cacheData(); } - @Override - public String getApiToken() { - return Config.Constants.SONARR_TOKEN; - } - private AddStrategy getAddStrategy() { return new AddStrategy(ContentType.SHOW) { @Override @@ -171,17 +157,77 @@ public CommandResponse getResponse(SonarrShow item) { }; } + private SonarrEpisodeInformation getEpisode(long seriesId, long episodeId) { + return ConnectionHelper.makeGetRequest( + new SonarrUrls.SonarrRequestBuilder().buildGet(SonarrUrls.EPISODES_LOOKUP, new HashMap() {{ + put("seriesId", String.valueOf(seriesId)); + put("episodeIds", String.valueOf(episodeId)); + }}), + new ConnectionHelper.SimpleEntityResponseHandler() { + @Override + public SonarrEpisodeInformation onSuccess(String response) { + if (response == null || response.isEmpty() || response.equals("{}")) { + return null; + } + JsonArray array = JsonParser.parseString(response).getAsJsonArray(); + for (int i = 0; i < array.size(); i++) { + SonarrQueueEpisode episode = new Gson().fromJson(array.get(i), SonarrQueueEpisode.class); + if (episode.getId() != episodeId) { + continue; + } + return new SonarrEpisodeInformation(episode.getSeasonNumber(), episode.getEpisodeNumber(), episode.getTitle(), episode.getOverview()); + } + return null; + } + } + ); + } + private DownloadsStrategy getDownloadsStrategy() { - return new DownloadsStrategy(this, SonarrUrls.DOWNLOAD_BASE) { - @Override - public CommandResponse getResponse(JsonElement rawElement) { - SonarrQueue showQueue = new Gson().fromJson(rawElement, SonarrQueue.class); - SonarQueueEpisode episode = showQueue.getEpisode(); - if (episode == null) { - //something is wrong with the download, skip - LOGGER.error("Series " + showQueue.getSonarrQueueShow().getTitle() + " missing episode info for id " + showQueue.getId()); + return new DownloadsStrategy() { + private ShowDownloadResponse getDownloadBasedApiV3Queue(SonarrQueue showQueue) { + SonarrShow sonarrShow = SONARR_CACHE.getExistingShowFromSonarrId(showQueue.getSeriesId()); + if (sonarrShow == null) { + LOGGER.warn("Could not load sonarr show from cache for id " + showQueue.getSeriesId()); return null; } + if (isPathBlacklisted(sonarrShow)) { + LOGGER.warn("The following show is blacklisted: " + sonarrShow.getTitle() + " from being displayed in downloads"); + return null; + } + SonarrEpisodeInformation episodeInformation = SONARR_CACHE.getEpisode(showQueue.getSeriesId(), showQueue.getEpisodeId()); + if (episodeInformation == null) { + episodeInformation = getEpisode(showQueue.getSeriesId(), showQueue.getEpisodeId()); + if (episodeInformation == null) { + // if episode is still null, we can't display any download data + LOGGER.error("Couldn't find download data in sonarr cache or sonarr api for " + showQueue.getSeriesId() + ", episode " + showQueue.getEpisodeId()); + return null; + } + // cache information for faster lookups since download data is displayed periodically + SONARR_CACHE.addEpisode(showQueue.getSeriesId(), showQueue.getEpisodeId(), episodeInformation); + } + List statusMessages = new ArrayList<>(); + for (SonarrQueueStatusMessages sonarrQueueStatusMessages : showQueue.getStatusMessages()) { + statusMessages.add(sonarrQueueStatusMessages.getTitle()); + } + String overview = episodeInformation.getOverview(); + if (overview.length() > VALUE_MAX_LENGTH) { + overview = overview.substring(0, VALUE_MAX_LENGTH); + } + return new ShowDownloadResponse(new SonarrDownloadActivity( + sonarrShow.getTitle() + ": " + episodeInformation.getTitle(), + episodeInformation.getSeasonNumber(), + episodeInformation.getEpisodeNumber(), + showQueue.getQuality().getQuality().getName(), + showQueue.getStatus(), + showQueue.getTimeleft(), + overview, + statusMessages.toArray(new String[]{}) + )); + } + + private ShowDownloadResponse getDownloadBasedApiQueue(SonarrQueue showQueue) { + SonarrQueueEpisode episode = showQueue.getEpisode(); SonarrShow sonarrShow = SONARR_CACHE.getExistingShowFromSonarrId(showQueue.getEpisode().getSeriesId()); if (sonarrShow == null) { LOGGER.warn("Could not load sonarr show from cache for id " + showQueue.getEpisode().getSeriesId() + " title=" + showQueue.getSonarrQueueShow().getTitle()); @@ -191,7 +237,54 @@ public CommandResponse getResponse(JsonElement rawElement) { LOGGER.warn("The following show is blacklisted: " + sonarrShow.getTitle() + " from being displayed in downloads"); return null; } - return new ShowDownloadResponse(showQueue); + List statusMessages = new ArrayList<>(); + for (SonarrQueueStatusMessages sonarrQueueStatusMessages : showQueue.getStatusMessages()) { + statusMessages.add(sonarrQueueStatusMessages.getTitle()); + } + String overview = episode.getOverview(); + if (overview.length() > VALUE_MAX_LENGTH) { + overview = overview.substring(0, VALUE_MAX_LENGTH); + } + return new ShowDownloadResponse(new SonarrDownloadActivity( + sonarrShow.getTitle() + ": " + episode.getTitle(), + episode.getSeasonNumber(), + episode.getEpisodeNumber(), + showQueue.getQuality().getQuality().getName(), + showQueue.getStatus(), + showQueue.getTimeleft(), + overview, + statusMessages.toArray(new String[]{}) + ) + ); + } + + @Override + public CommandResponse getResponse(JsonElement rawElement) { + SonarrQueue showQueue = new Gson().fromJson(rawElement, SonarrQueue.class); + SonarrQueueEpisode episode = showQueue.getEpisode(); + // api/queue vs /api/v3/queue differ in results which makes the episode object not exist, + // so we support both cause I have no idea why I originally used api/queue and if its still in use and will stay in use... + //TODO: eventually get rid of the api/queue one when you're sure its not anything of value + if (episode == null) { + return getDownloadBasedApiV3Queue(showQueue); + } + return getDownloadBasedApiQueue(showQueue); + } + + @Override + public List getContentDownloads() { + return ConnectionHelper.makeGetRequest( + new SonarrUrls.SonarrRequestBuilder().buildGet(SonarrUrls.DOWNLOAD_BASE), + new ConnectionHelper.SimpleCommandResponseHandler() { + @Override + public List onSuccess(String response) { + if (response == null || response.isEmpty() || response.equals("{}")) { + return new ArrayList<>(); + } + JsonObject json = JsonParser.parseString(response).getAsJsonObject(); + return parseContent(json.get("records").toString()); + } + }); } }; } @@ -219,12 +312,11 @@ private CommandResponse addShow(SonarrShow sonarrShow) { return new ErrorResponse("Could not add show, user " + username + " has exceeded max show requests for " + requestThreshold.getReadableName()); } try (CloseableHttpClient client = HttpClientBuilder.create().build()) { - HttpPost post = new HttpPost(getApiUrl(SonarrUrls.SERIES_BASE)); + String json = new GsonBuilder().addSerializationExclusionStrategy(excludeUnnecessaryFields).create().toJson(sonarrShow, SonarrShow.class); + HttpRequestBase post = new SonarrUrls.SonarrRequestBuilder().buildPost(SonarrUrls.SERIES_BASE, json).build(); + //TODO: why isn't the content type json post.addHeader("content-type", "application/x-www-form-urlencoded"); - post.setEntity( - new StringEntity( - new GsonBuilder().addSerializationExclusionStrategy(excludeUnnecessaryFields).create().toJson(sonarrShow, SonarrShow.class), Charset.forName("UTF-8"))); try (CloseableHttpResponse response = client.execute(post)) { int statusCode = response.getStatusLine().getStatusCode(); @@ -244,16 +336,20 @@ private CommandResponse addShow(SonarrShow sonarrShow) { } private List lookupShows(String search) throws Exception { - return ConnectionHelper.makeGetRequest(this, SonarrUrls.LOOKUP_SERIES, "&term=" + URLEncoder.encode(search, "UTF-8"), new ConnectionHelper.SimpleEntityResponseHandler>() { + return ConnectionHelper.makeGetRequest( + new SonarrUrls.SonarrRequestBuilder().buildGet(SonarrUrls.LOOKUP_SERIES, new HashMap() {{ + put("term", search); + }}), + new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { - List movies = new ArrayList<>(); + List shows = new ArrayList<>(); JsonParser parser = new JsonParser(); JsonArray json = parser.parse(response).getAsJsonArray(); for (int i = 0; i < json.size(); i++) { - movies.add(new Gson().fromJson(json.get(i), SonarrShow.class)); + shows.add(new Gson().fromJson(json.get(i), SonarrShow.class)); } - return movies; + return shows; } }); } diff --git a/src/main/java/com/botdarr/api/sonarr/SonarrCache.java b/src/main/java/com/botdarr/api/sonarr/SonarrCache.java index cf44e2f..16860cc 100644 --- a/src/main/java/com/botdarr/api/sonarr/SonarrCache.java +++ b/src/main/java/com/botdarr/api/sonarr/SonarrCache.java @@ -12,6 +12,22 @@ public SonarrShow getExistingShowFromSonarrId(long sonarrId) { return existingSonarrIdsToShows.get(sonarrId); } + public SonarrEpisodeInformation getEpisode(long seriesId, long episodeNumber) { + if (existingSeriesToEpisodes.get(seriesId) == null) { + return null; + } + return existingSeriesToEpisodes.get(seriesId).get(episodeNumber); + } + + public void addEpisode(long seriesId, long episodeNumber, SonarrEpisodeInformation sonarrEpisodeInformation) { + Map episodeInformationMap = existingSeriesToEpisodes.get(seriesId); + if (episodeInformationMap == null) { + episodeInformationMap = new ConcurrentHashMap<>(); + existingSeriesToEpisodes.put(seriesId, episodeInformationMap); + } + episodeInformationMap.put(episodeNumber, sonarrEpisodeInformation); + } + public boolean doesShowExist(String title) { return existingShowTitlesToSonarrId.containsKey(title.toLowerCase()); } @@ -51,10 +67,12 @@ public void removeDeletedShows(List addUpdatedTvdbShowIds) { existingShowTitlesToSonarrId.keySet().retainAll(existingShowTitles); existingTvdbIdsToShows.keySet().retainAll(addUpdatedTvdbShowIds); existingSonarrIdsToShows.keySet().retainAll(existingShowIds); + existingSeriesToEpisodes.keySet().retainAll(existingShowIds); } private Map existingProfiles = new ConcurrentHashMap<>(); private Map existingShowTitlesToSonarrId = new ConcurrentHashMap<>(); private Map existingTvdbIdsToShows = new ConcurrentHashMap<>(); private Map existingSonarrIdsToShows = new ConcurrentHashMap<>(); + private Map> existingSeriesToEpisodes = new ConcurrentHashMap<>(); } diff --git a/src/main/java/com/botdarr/api/sonarr/SonarrDownloadActivity.java b/src/main/java/com/botdarr/api/sonarr/SonarrDownloadActivity.java new file mode 100644 index 0000000..9b70fb3 --- /dev/null +++ b/src/main/java/com/botdarr/api/sonarr/SonarrDownloadActivity.java @@ -0,0 +1,62 @@ +package com.botdarr.api.sonarr; + +public class SonarrDownloadActivity { + public SonarrDownloadActivity(String title, + long seasonNumber, + long episodeNumber, + String qualityProfileName, + String status, + String timeleft, + String overview, + String[] statusMessages) { + this.title = title; + this.seasonNumber = seasonNumber; + this.episodeNumber = episodeNumber; + this.qualityProfileName = qualityProfileName; + this.status = status; + this.timeleft = timeleft; + this.statusMessages = statusMessages; + this.overview = overview; + } + + public String getTitle() { + return title; + } + + public long getSeasonNumber() { + return seasonNumber; + } + + public long getEpisodeNumber() { + return episodeNumber; + } + + public String getQualityProfileName() { + return qualityProfileName; + } + + public String getStatus() { + return status; + } + + public String getTimeleft() { + return timeleft; + } + + public String[] getStatusMessages() { + return statusMessages; + } + + public String getOverview() { + return overview; + } + + private final String title; + private final String overview; + private final long seasonNumber; + private final long episodeNumber; + private final String qualityProfileName; + private final String status; + private final String timeleft; + private final String[] statusMessages; +} diff --git a/src/main/java/com/botdarr/api/sonarr/SonarrEpisodeInformation.java b/src/main/java/com/botdarr/api/sonarr/SonarrEpisodeInformation.java new file mode 100644 index 0000000..dc89c8e --- /dev/null +++ b/src/main/java/com/botdarr/api/sonarr/SonarrEpisodeInformation.java @@ -0,0 +1,31 @@ +package com.botdarr.api.sonarr; + +public class SonarrEpisodeInformation { + public SonarrEpisodeInformation(long seasonNumber, long episodeNumber, String title, String overview) { + this.seasonNumber = seasonNumber; + this.episodeNumber = episodeNumber; + this.title = title; + this.overview = overview; + } + + public long getSeasonNumber() { + return seasonNumber; + } + + public long getEpisodeNumber() { + return episodeNumber; + } + + public String getTitle() { + return title; + } + + public String getOverview() { + return overview; + } + + private final long seasonNumber; + private final long episodeNumber; + private final String title; + private final String overview; +} diff --git a/src/main/java/com/botdarr/api/sonarr/SonarrProfile.java b/src/main/java/com/botdarr/api/sonarr/SonarrProfile.java index 0c1302e..fdca442 100644 --- a/src/main/java/com/botdarr/api/sonarr/SonarrProfile.java +++ b/src/main/java/com/botdarr/api/sonarr/SonarrProfile.java @@ -14,7 +14,7 @@ public String getName() { return name; } - public SonarrProfileCutoff getCutoff() { + public Integer getCutoff() { return cutoff; } @@ -22,7 +22,7 @@ public void setName(String name) { this.name = name; } - public void setCutoff(SonarrProfileCutoff cutoff) { + public void setCutoff(Integer cutoff) { this.cutoff = cutoff; } @@ -43,7 +43,7 @@ public void setId(long id) { } private String name; - private SonarrProfileCutoff cutoff; + private Integer cutoff; private List items; private long id; } diff --git a/src/main/java/com/botdarr/api/sonarr/SonarrProfileQualityItem.java b/src/main/java/com/botdarr/api/sonarr/SonarrProfileQualityItem.java index 97e84b8..4fc5748 100644 --- a/src/main/java/com/botdarr/api/sonarr/SonarrProfileQualityItem.java +++ b/src/main/java/com/botdarr/api/sonarr/SonarrProfileQualityItem.java @@ -1,5 +1,8 @@ package com.botdarr.api.sonarr; +import java.util.ArrayList; +import java.util.List; + public class SonarrProfileQualityItem { public SonarrProfileQuality getQuality() { return quality; @@ -17,6 +20,24 @@ public void setAllowed(boolean allowed) { this.allowed = allowed; } + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + private int id; + private List items = new ArrayList<>(); private SonarrProfileQuality quality; private boolean allowed; } diff --git a/src/main/java/com/botdarr/api/sonarr/SonarrQueue.java b/src/main/java/com/botdarr/api/sonarr/SonarrQueue.java index 4f6bd03..a99a1bc 100644 --- a/src/main/java/com/botdarr/api/sonarr/SonarrQueue.java +++ b/src/main/java/com/botdarr/api/sonarr/SonarrQueue.java @@ -46,23 +46,41 @@ public SonarrQueueShow getSonarrQueueShow() { return series; } - public void setRadarrQueueMovie(SonarrQueueShow radarrQueueMovie) { - this.series = radarrQueueMovie; + public void setSeries(SonarrQueueShow series) { + this.series = series; } - public SonarQueueEpisode getEpisode() { + public SonarrQueueEpisode getEpisode() { return episode; } - public void setEpisode(SonarQueueEpisode episode) { + public void setEpisode(SonarrQueueEpisode episode) { this.episode = episode; } - private String status; - private String timeleft; + public long getSeriesId() { + return seriesId; + } + + public void setSeriesId(long seriesId) { + this.seriesId = seriesId; + } + + public long getEpisodeId() { + return episodeId; + } + + public void setEpisodeId(long episodeId) { + this.episodeId = episodeId; + } + private SonarrProfileQualityItem quality; - private long id; private SonarrQueueStatusMessages[] statusMessages; private SonarrQueueShow series; - private SonarQueueEpisode episode; + private SonarrQueueEpisode episode; + private String status; + private String timeleft; + private long seriesId; + private long episodeId; + private long id; } diff --git a/src/main/java/com/botdarr/api/sonarr/SonarQueueEpisode.java b/src/main/java/com/botdarr/api/sonarr/SonarrQueueEpisode.java similarity index 84% rename from src/main/java/com/botdarr/api/sonarr/SonarQueueEpisode.java rename to src/main/java/com/botdarr/api/sonarr/SonarrQueueEpisode.java index 268361b..ae40a55 100644 --- a/src/main/java/com/botdarr/api/sonarr/SonarQueueEpisode.java +++ b/src/main/java/com/botdarr/api/sonarr/SonarrQueueEpisode.java @@ -1,6 +1,6 @@ package com.botdarr.api.sonarr; -public class SonarQueueEpisode { +public class SonarrQueueEpisode { public int getSeasonNumber() { return seasonNumber; } @@ -37,9 +37,18 @@ public long getSeriesId() { return seriesId; } + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + private int seasonNumber; private int episodeNumber; private String title; private String overview; private long seriesId; + private long id; } diff --git a/src/main/java/com/botdarr/api/sonarr/SonarrUrls.java b/src/main/java/com/botdarr/api/sonarr/SonarrUrls.java index 3812e06..129f709 100644 --- a/src/main/java/com/botdarr/api/sonarr/SonarrUrls.java +++ b/src/main/java/com/botdarr/api/sonarr/SonarrUrls.java @@ -1,9 +1,32 @@ package com.botdarr.api.sonarr; +import com.botdarr.Config; +import com.botdarr.api.ArrRequestBuilder; +import org.apache.logging.log4j.util.Strings; + public class SonarrUrls { + public static class SonarrRequestBuilder extends ArrRequestBuilder { + public SonarrRequestBuilder() { + super(Config.Constants.SONARR_URL, Config.Constants.SONARR_URL_BASE, Config.Constants.SONARR_TOKEN); + } + + //TODO: do i even need this? + private boolean isV4Enabled() { + String isSonarrV4 = Config.getProperty(Config.Constants.SONARR_V4); + return !Strings.isEmpty(isSonarrV4) && Boolean.parseBoolean(isSonarrV4); + } + + @Override + public String getApiSuffix() { + if (isV4Enabled()) { + return "/api/v3/"; + } + return super.getApiSuffix(); + } + } public static final String DOWNLOAD_BASE = "queue"; public static final String LOOKUP_SERIES = "series/lookup"; public static final String SERIES_BASE = "series"; - public static final String PROFILE = "profile"; - public static final String ARTIST_BASE = "v1/artist"; + public static final String PROFILE = "qualityprofile"; + public static final String EPISODES_LOOKUP = "episode"; } diff --git a/src/main/java/com/botdarr/clients/discord/DiscordResponseBuilder.java b/src/main/java/com/botdarr/clients/discord/DiscordResponseBuilder.java index b73b596..9724a87 100644 --- a/src/main/java/com/botdarr/clients/discord/DiscordResponseBuilder.java +++ b/src/main/java/com/botdarr/clients/discord/DiscordResponseBuilder.java @@ -31,7 +31,6 @@ import static com.botdarr.api.sonarr.SonarrApi.SHOW_LOOKUP_FIELD; import static com.botdarr.commands.StatusCommand.STATUS_COMMAND; import static com.botdarr.commands.StatusCommand.STATUS_COMMAND_DESCRIPTION; -import static net.dv8tion.jda.api.entities.MessageEmbed.VALUE_MAX_LENGTH; public class DiscordResponseBuilder implements ChatClientResponseBuilder { @Override @@ -107,23 +106,15 @@ public DiscordResponse build(MusicArtistResponse musicArtistResponse) { @Override public DiscordResponse build(ShowDownloadResponse showDownloadResponse) { EmbedBuilder embedBuilder = new EmbedBuilder(); - SonarrQueue showQueue = showDownloadResponse.getShowQueue(); - SonarQueueEpisode episode = showQueue.getEpisode(); - embedBuilder.setTitle(showQueue.getSonarrQueueShow().getTitle()); - embedBuilder.addField("Season/Episode", "S" + episode.getSeasonNumber() + "E" + episode.getEpisodeNumber(), true); - embedBuilder.addField("Quality", showQueue.getQuality().getQuality().getName(), true); - embedBuilder.addField("Status", showQueue.getStatus(), true); - embedBuilder.addField("Time Left", showQueue.getTimeleft() == null ? "unknown" : showQueue.getTimeleft(), true); - String overview = episode.getTitle() + ": " + episode.getOverview(); - if (overview.length() > VALUE_MAX_LENGTH) { - overview = overview.substring(0, VALUE_MAX_LENGTH); - } - embedBuilder.addField("Overview", overview, false); - if (showQueue.getStatusMessages() != null) { - for (SonarrQueueStatusMessages statusMessage : showQueue.getStatusMessages()) { - for (String message : statusMessage.getMessages()) { - embedBuilder.addField("Download message", message, true); - } + embedBuilder.setTitle(showDownloadResponse.getShowQueue().getTitle()); + embedBuilder.addField("Season/Episode", "S" + showDownloadResponse.getShowQueue().getSeasonNumber() + "E" + showDownloadResponse.getShowQueue().getEpisodeNumber(), true); + embedBuilder.addField("Quality", showDownloadResponse.getShowQueue().getQualityProfileName(), true); + embedBuilder.addField("Status", showDownloadResponse.getShowQueue().getStatus(), true); + embedBuilder.addField("Time Left", showDownloadResponse.getShowQueue().getTimeleft() == null ? "unknown" : showDownloadResponse.getShowQueue().getTimeleft(), true); + embedBuilder.addField("Overview", showDownloadResponse.getShowQueue().getOverview(), true); + if (showDownloadResponse.getShowQueue().getStatusMessages() != null) { + for (String statusMessage : showDownloadResponse.getShowQueue().getStatusMessages()) { + embedBuilder.addField("Download message", statusMessage, true); } } return new DiscordResponse(embedBuilder.build()); @@ -164,21 +155,31 @@ public DiscordResponse build(MusicArtistDownloadResponse musicArtistDownloadResp return new DiscordResponse(embedBuilder.build()); } + private void addQualityItem(EmbedBuilder embedBuilder, SonarrProfileQualityItem sonarrProfileQualityItem) { + embedBuilder.addField( + "Quality", + "name=" + sonarrProfileQualityItem.getQuality().getName() + ", resolution=" + sonarrProfileQualityItem.getQuality().getResolution(), + true); + } + @Override public DiscordResponse build(ShowProfileResponse showProfileResponse) { EmbedBuilder embedBuilder = new EmbedBuilder(); embedBuilder.setTitle("Profile"); SonarrProfile sonarrProfile = showProfileResponse.getShowProfile(); embedBuilder.addField("Name", sonarrProfile.getName(), false); - embedBuilder.addField("Cutoff", sonarrProfile.getCutoff().getName(), false); + embedBuilder.addField("Cutoff", "" + sonarrProfile.getCutoff(), false); embedBuilder.addBlankField(false); for (int k = 0; k < sonarrProfile.getItems().size(); k++) { SonarrProfileQualityItem sonarrProfileQualityItem = sonarrProfile.getItems().get(k); if (sonarrProfileQualityItem.isAllowed()) { - embedBuilder.addField( - "Quality", - "name=" + sonarrProfileQualityItem.getQuality().getName() + ", resolution=" + sonarrProfileQualityItem.getQuality().getResolution(), - true); + if (sonarrProfileQualityItem.getQuality() == null) { + for(SonarrProfileQualityItem qualityItem : sonarrProfileQualityItem.getItems()) { + addQualityItem(embedBuilder, qualityItem); + } + } else { + addQualityItem(embedBuilder, sonarrProfileQualityItem); + } } } return new DiscordResponse(embedBuilder.build()); diff --git a/src/main/java/com/botdarr/clients/matrix/MatrixResponseBuilder.java b/src/main/java/com/botdarr/clients/matrix/MatrixResponseBuilder.java index 83c003a..407d1c2 100644 --- a/src/main/java/com/botdarr/clients/matrix/MatrixResponseBuilder.java +++ b/src/main/java/com/botdarr/clients/matrix/MatrixResponseBuilder.java @@ -104,24 +104,16 @@ public MatrixResponse build(MovieResponse movieResponse) { @Override public MatrixResponse build(ShowDownloadResponse showDownloadResponse) { - SonarrQueue sonarrQueue = showDownloadResponse.getShowQueue(); MatrixResponse matrixResponse = new MatrixResponse(); - SonarQueueEpisode episode = sonarrQueue.getEpisode(); - matrixResponse.addContent("Title - " + sonarrQueue.getSonarrQueueShow().getTitle()); - matrixResponse.addContent("Season/Episode - " + "S" + episode.getSeasonNumber() + "E" + episode.getEpisodeNumber()); - matrixResponse.addContent("Quality - " + sonarrQueue.getQuality().getQuality().getName()); - matrixResponse.addContent("Status - " + sonarrQueue.getStatus()); - matrixResponse.addContent("Time Left - " + (sonarrQueue.getTimeleft() == null ? "unknown" : sonarrQueue.getTimeleft()) + ""); - String overview = episode.getTitle() + ": " + episode.getOverview(); - if (overview.length() > 1024) { - overview = overview.substring(0, 1024); - } - matrixResponse.addContent("Overview - " + overview); - if (sonarrQueue.getStatusMessages() != null) { - for (SonarrQueueStatusMessages statusMessage : sonarrQueue.getStatusMessages()) { - for (String message : statusMessage.getMessages()) { - matrixResponse.addContent("Download message - " + message); - } + matrixResponse.addContent("Title - " + showDownloadResponse.getShowQueue().getTitle()); + matrixResponse.addContent("Season/Episode - " + "S" + showDownloadResponse.getShowQueue().getSeasonNumber() + "E" + showDownloadResponse.getShowQueue().getEpisodeNumber()); + matrixResponse.addContent("Quality - " + showDownloadResponse.getShowQueue().getQualityProfileName()); + matrixResponse.addContent("Status - " + showDownloadResponse.getShowQueue().getStatus()); + matrixResponse.addContent("Time Left - " + (showDownloadResponse.getShowQueue().getTimeleft() == null ? "unknown" : showDownloadResponse.getShowQueue().getTimeleft()) + ""); + matrixResponse.addContent("Overview - " + showDownloadResponse.getShowQueue().getOverview()); + if (showDownloadResponse.getShowQueue().getStatusMessages() != null) { + for (String statusMessage : showDownloadResponse.getShowQueue().getStatusMessages()) { + matrixResponse.addContent("Download message - " + statusMessage); } } return matrixResponse; @@ -183,17 +175,27 @@ public MatrixResponse build(SuccessResponse successResponse) { return matrixResponse; } + private String addQualityItem(SonarrProfileQualityItem sonarrProfileQualityItem) { + return "Quality - Name: " + sonarrProfileQualityItem.getQuality().getName() + ", Resolution: " + sonarrProfileQualityItem.getQuality().getResolution(); + } + @Override public MatrixResponse build(ShowProfileResponse showProfileResponse) { SonarrProfile sonarrProfile = showProfileResponse.getShowProfile(); MatrixResponse matrixResponse = new MatrixResponse(); matrixResponse.addContent("Profile"); matrixResponse.addContent("Name - " + sonarrProfile.getName()); - matrixResponse.addContent("Cutoff - " + sonarrProfile.getCutoff().getName()); + matrixResponse.addContent("Cutoff - " + sonarrProfile.getCutoff()); for (int k = 0; k < sonarrProfile.getItems().size(); k++) { SonarrProfileQualityItem sonarrProfileQualityItem = sonarrProfile.getItems().get(k); if (sonarrProfileQualityItem.isAllowed()) { - matrixResponse.addContent("Quality - Name: " + sonarrProfileQualityItem.getQuality().getName() + ", Resolution: " + sonarrProfileQualityItem.getQuality().getResolution()); + if (sonarrProfileQualityItem.getQuality() == null) { + for(SonarrProfileQualityItem qualityItem : sonarrProfileQualityItem.getItems()) { + matrixResponse.addContent(addQualityItem(qualityItem)); + } + } else { + matrixResponse.addContent(addQualityItem(sonarrProfileQualityItem)); + } } } return matrixResponse; diff --git a/src/main/java/com/botdarr/clients/slack/SlackResponseBuilder.java b/src/main/java/com/botdarr/clients/slack/SlackResponseBuilder.java index d1b3776..efcb8d4 100644 --- a/src/main/java/com/botdarr/clients/slack/SlackResponseBuilder.java +++ b/src/main/java/com/botdarr/clients/slack/SlackResponseBuilder.java @@ -25,7 +25,6 @@ import static com.botdarr.api.sonarr.SonarrApi.ADD_SHOW_COMMAND_FIELD_PREFIX; import static com.botdarr.commands.StatusCommand.STATUS_COMMAND; import static com.botdarr.commands.StatusCommand.STATUS_COMMAND_DESCRIPTION; -import static net.dv8tion.jda.api.entities.MessageEmbed.VALUE_MAX_LENGTH; public class SlackResponseBuilder implements ChatClientResponseBuilder { @Override @@ -146,17 +145,16 @@ public SlackResponse build(MusicArtistResponse musicArtistResponse) { @Override public SlackResponse build(ShowDownloadResponse showDownloadResponse) { - SonarrQueue showQueue = showDownloadResponse.getShowQueue(); - SonarQueueEpisode episode = showQueue.getEpisode(); + SonarrDownloadActivity showQueue = showDownloadResponse.getShowQueue(); SlackResponse slackResponse = new SlackResponse(); slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("*Title* - " + showQueue.getSonarrQueueShow().getTitle()).build()) + .text(MarkdownTextObject.builder().text("*Title* - " + showQueue.getTitle()).build()) .build()); slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("Season/Episode - " + "S" + episode.getSeasonNumber() + "E" + episode.getEpisodeNumber()).build()) + .text(MarkdownTextObject.builder().text("Season/Episode - " + "S" + showQueue.getSeasonNumber() + "E" + showQueue.getEpisodeNumber()).build()) .build()); slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("Quality - " + showQueue.getQuality().getQuality().getName()).build()) + .text(MarkdownTextObject.builder().text("Quality - " + showQueue.getQualityProfileName()).build()) .build()); slackResponse.addBlock(SectionBlock.builder() .text(MarkdownTextObject.builder().text("Status - " + showQueue.getStatus()).build()) @@ -164,19 +162,13 @@ public SlackResponse build(ShowDownloadResponse showDownloadResponse) { slackResponse.addBlock(SectionBlock.builder() .text(MarkdownTextObject.builder().text("Time Left - *" + (showQueue.getTimeleft() == null ? "unknown" : showQueue.getTimeleft()) + "*").build()) .build()); - String overview = episode.getTitle() + ": " + episode.getOverview(); - if (overview.length() > VALUE_MAX_LENGTH) { - overview = overview.substring(0, VALUE_MAX_LENGTH); - } slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("Overview - " + overview).build()) - .build()); + .text(MarkdownTextObject.builder().text("Overview - " + showQueue.getOverview()).build()) + .build()); if (showQueue.getStatusMessages() != null) { List contextBlockElements = new ArrayList<>(); - for (SonarrQueueStatusMessages statusMessage : showQueue.getStatusMessages()) { - for (String message : statusMessage.getMessages()) { - contextBlockElements.add(PlainTextObject.builder().text(message).build()); - } + for (String statusMessage : showQueue.getStatusMessages()) { + contextBlockElements.add(PlainTextObject.builder().text(statusMessage).build()); } if (showQueue.getStatusMessages() != null && showQueue.getStatusMessages().length > 0) { slackResponse.addBlock(ContextBlock.builder() @@ -275,6 +267,10 @@ public SlackResponse build(SuccessResponse successResponse) { return slackResponse; } + private String addQualityItem(SonarrProfileQualityItem sonarrProfileQualityItem) { + return "Quality - name=" + sonarrProfileQualityItem.getQuality().getName() + ", resolution=" + sonarrProfileQualityItem.getQuality().getResolution(); + } + @Override public SlackResponse build(ShowProfileResponse showProfileResponse) { SonarrProfile sonarrProfile = showProfileResponse.getShowProfile(); @@ -286,16 +282,24 @@ public SlackResponse build(ShowProfileResponse showProfileResponse) { .text(MarkdownTextObject.builder().text("Name - " + sonarrProfile.getName()).build()) .build()); slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("Cutoff - " + sonarrProfile.getCutoff().getName()).build()) + .text(MarkdownTextObject.builder().text("Cutoff - " + sonarrProfile.getCutoff()).build()) .build()); List contextBlockElements = new ArrayList<>(); for (int k = 0; k < sonarrProfile.getItems().size(); k++) { SonarrProfileQualityItem sonarrProfileQualityItem = sonarrProfile.getItems().get(k); if (sonarrProfileQualityItem.isAllowed()) { - contextBlockElements.add(PlainTextObject.builder() - .text("Quality - name=" + sonarrProfileQualityItem.getQuality().getName() + ", resolution=" + sonarrProfileQualityItem.getQuality().getResolution()) - .build()); + if (sonarrProfileQualityItem.getQuality() == null) { + for(SonarrProfileQualityItem qualityItem : sonarrProfileQualityItem.getItems()) { + contextBlockElements.add(PlainTextObject.builder() + .text(addQualityItem(qualityItem)) + .build()); + } + } else { + contextBlockElements.add(PlainTextObject.builder() + .text(addQualityItem(sonarrProfileQualityItem)) + .build()); + } } } slackResponse.addBlock(ContextBlock.builder() diff --git a/src/main/java/com/botdarr/clients/telegram/TelegramResponseBuilder.java b/src/main/java/com/botdarr/clients/telegram/TelegramResponseBuilder.java index 06b3da8..8a54a45 100644 --- a/src/main/java/com/botdarr/clients/telegram/TelegramResponseBuilder.java +++ b/src/main/java/com/botdarr/clients/telegram/TelegramResponseBuilder.java @@ -24,7 +24,6 @@ import static com.botdarr.commands.StatusCommand.STATUS_COMMAND; import static com.botdarr.commands.StatusCommand.STATUS_COMMAND_DESCRIPTION; import static j2html.TagCreator.*; -import static net.dv8tion.jda.api.entities.MessageEmbed.VALUE_MAX_LENGTH; import java.io.IOException; import java.util.ArrayList; @@ -101,28 +100,19 @@ public TelegramResponse build(MusicArtistResponse musicArtistResponse) { @Override public TelegramResponse build(ShowDownloadResponse showDownloadResponse) { - SonarrQueue showQueue = showDownloadResponse.getShowQueue(); - SonarQueueEpisode episode = showQueue.getEpisode(); - List domContents = new ArrayList<>(); - domContents.add(b(showQueue.getSonarrQueueShow().getTitle())); - String queueDetails = "Season/Episode - " + "S" + episode.getSeasonNumber() + "E" + episode.getEpisodeNumber() + "\n" + - "Quality - " + showQueue.getQuality().getQuality().getName() + "\n" + - "Status - " + showQueue.getStatus() + "\n" + - "Time Left - " + (showQueue.getTimeleft() == null ? "unknown" : showQueue.getTimeleft()) + "\n"; + domContents.add(b(showDownloadResponse.getShowQueue().getTitle())); + String queueDetails = "Season/Episode - " + "S" + showDownloadResponse.getShowQueue().getSeasonNumber() + "E" + showDownloadResponse.getShowQueue().getEpisodeNumber() + "\n" + + "Quality - " + showDownloadResponse.getShowQueue().getQualityProfileName() + "\n" + + "Status - " + showDownloadResponse.getShowQueue().getStatus() + "\n" + + "Time Left - " + (showDownloadResponse.getShowQueue().getTimeleft() == null ? "unknown" : showDownloadResponse.getShowQueue().getTimeleft()) + "\n" + + "Overview - " + showDownloadResponse.getShowQueue().getOverview() + "\n"; domContents.add(code(queueDetails)); - String overview = episode.getTitle() + ": " + episode.getOverview(); - if (overview.length() > VALUE_MAX_LENGTH) { - overview = overview.substring(0, VALUE_MAX_LENGTH); - } - domContents.add(b("Overview - " + overview)); - if (showQueue.getStatusMessages() != null) { + if (showDownloadResponse.getShowQueue().getStatusMessages() != null) { StringBuilder statusMessageBuilder = new StringBuilder(); - for (SonarrQueueStatusMessages statusMessage : showQueue.getStatusMessages()) { - for (String message : statusMessage.getMessages()) { - statusMessageBuilder.append("Download Message - ").append(message).append("\n"); - } + for (String statusMessage : showDownloadResponse.getShowQueue().getStatusMessages()) { + statusMessageBuilder.append("Download Message - ").append(statusMessage).append("\n"); } domContents.add(code(statusMessageBuilder.toString())); } @@ -190,19 +180,38 @@ public TelegramResponse build(SuccessResponse successResponse) { return new TelegramResponse(domContents); } + private StringBuilder appendQualityItem(SonarrProfileQualityItem qualityItem) { + StringBuilder qualityItems = new StringBuilder(); + qualityItems.append("Quality - ") + .append("id=") + .append(qualityItem.getQuality().getId()) + .append(", name=") + .append(qualityItem.getQuality().getName()) + .append(", resolution=") + .append(qualityItem.getQuality().getResolution()) + .append("\n"); + return qualityItems; + } + @Override public TelegramResponse build(ShowProfileResponse showProfileResponse) { SonarrProfile sonarrProfile = showProfileResponse.getShowProfile(); List domContents = new ArrayList<>(); domContents.add(b("Profile")); domContents.add(text("Name - " + sonarrProfile.getName())); - domContents.add(text("Cutoff - " + sonarrProfile.getCutoff().getName())); + domContents.add(text("Cutoff - " + sonarrProfile.getCutoff())); if (sonarrProfile.getItems() != null) { StringBuilder qualityItems = new StringBuilder(); for (int k = 0; k < sonarrProfile.getItems().size(); k++) { SonarrProfileQualityItem sonarrProfileQualityItem = sonarrProfile.getItems().get(k); if (sonarrProfileQualityItem.isAllowed()) { - qualityItems.append("Quality - name=").append(sonarrProfileQualityItem.getQuality().getName()).append(", resolution=").append(sonarrProfileQualityItem.getQuality().getResolution()).append("\n"); + if (sonarrProfileQualityItem.getQuality() == null) { + for(SonarrProfileQualityItem qualityItem : sonarrProfileQualityItem.getItems()) { + qualityItems.append(appendQualityItem(qualityItem)); + } + } else { + qualityItems.append(appendQualityItem(sonarrProfileQualityItem)); + } } } domContents.add(code(qualityItems.toString())); diff --git a/src/main/java/com/botdarr/commands/responses/ShowDownloadResponse.java b/src/main/java/com/botdarr/commands/responses/ShowDownloadResponse.java index 8ead06b..d8cfebf 100644 --- a/src/main/java/com/botdarr/commands/responses/ShowDownloadResponse.java +++ b/src/main/java/com/botdarr/commands/responses/ShowDownloadResponse.java @@ -1,15 +1,15 @@ package com.botdarr.commands.responses; -import com.botdarr.api.sonarr.SonarrQueue; +import com.botdarr.api.sonarr.SonarrDownloadActivity; import com.botdarr.clients.ChatClientResponse; import com.botdarr.clients.ChatClientResponseBuilder; public class ShowDownloadResponse implements CommandResponse { - private final SonarrQueue showQueue; - public ShowDownloadResponse(SonarrQueue showQueue) { + private final SonarrDownloadActivity showQueue; + public ShowDownloadResponse(SonarrDownloadActivity showQueue) { this.showQueue = showQueue; } - public SonarrQueue getShowQueue() { + public SonarrDownloadActivity getShowQueue() { return showQueue; } diff --git a/src/main/java/com/botdarr/connections/ConnectionHelper.java b/src/main/java/com/botdarr/connections/ConnectionHelper.java index 08d2edb..d017d30 100644 --- a/src/main/java/com/botdarr/connections/ConnectionHelper.java +++ b/src/main/java/com/botdarr/connections/ConnectionHelper.java @@ -1,6 +1,5 @@ package com.botdarr.connections; -import com.botdarr.api.Api; import com.botdarr.Config; import com.botdarr.commands.responses.CommandResponse; import com.botdarr.commands.responses.ErrorResponse; @@ -18,17 +17,11 @@ import java.util.List; public class ConnectionHelper { - public static T makeGetRequest(Api api, String path, ResponseHandler responseHandler) { - return makeGetRequest(api, path, "", responseHandler); - } - - public static T makeGetRequest(Api api, String path, String params, ResponseHandler responseHandler) { + public static T makeGetRequest(RequestBuilder builder, ResponseHandler responseHandler) { return makeRequest(new RequestHandler() { @Override public HttpRequestBase buildRequest() throws Exception { - HttpGet get = new HttpGet(api.getApiUrl(path) + params); - get.setHeader("X-Api-Key", Config.getProperty(api.getApiToken())); - return get; + return builder.build(); } @Override @@ -58,6 +51,7 @@ public static T makeRequest(RequestHandler requestHandler, ResponseHandler entry : headers.entrySet()) { + post.addHeader(entry.getKey(), entry.getValue()); + } + post.addHeader("content-type", "application/json"); + post.setEntity(new StringEntity(postBody, StandardCharsets.UTF_8)); + return post; + } + HttpGet get = new HttpGet(builder.build()); + for (Map.Entry entry : headers.entrySet()) { + get.addHeader(entry.getKey(), entry.getValue()); + } + return get; + } catch (URISyntaxException e) { + LOGGER.error("Error trying to build get request", e); + } + throw new RuntimeException("Could not build get or post request"); + } + private static final Logger LOGGER = LogManager.getLogger(); +} diff --git a/src/main/resources/version.txt b/src/main/resources/version.txt index c7ba1e8..4cc0e35 100644 --- a/src/main/resources/version.txt +++ b/src/main/resources/version.txt @@ -1 +1 @@ -5.5.0 \ No newline at end of file +5.6.0 \ No newline at end of file diff --git a/src/test/java/com/botdarr/api/DownloadsStrategyTests.java b/src/test/java/com/botdarr/api/DownloadsStrategyTests.java index 833ebdd..dd5191e 100644 --- a/src/test/java/com/botdarr/api/DownloadsStrategyTests.java +++ b/src/test/java/com/botdarr/api/DownloadsStrategyTests.java @@ -4,6 +4,7 @@ import com.botdarr.TestCommandResponse; import com.botdarr.commands.responses.CommandResponse; import com.botdarr.commands.responses.InfoResponse; +import com.botdarr.connections.RequestBuilder; import com.google.gson.JsonElement; import mockit.*; import org.apache.commons.lang3.builder.EqualsBuilder; @@ -36,6 +37,7 @@ public void beforeEachTest() throws Exception { properties.put("telegram-token", "%H$$54j45i"); properties.put("telegram-private-channels", "channel1:459349"); writeFakePropertiesFile(properties); + requestBuilder = new RequestBuilder().host("http://localhost"); } @Test @@ -71,27 +73,8 @@ public void parseContent_tooManyDownloads_infoMessageIncluded() { responses.get(0))); } - @Test - public void getContentDownloads_endpointUnavailable_emptyResponse() { - DownloadsStrategy downloadsStrategy = new DownloadsStrategy(api, "") { - @Override - public CommandResponse getResponse(JsonElement rawElement) { - return null; - } - }; - Deencapsulation.setField(downloadsStrategy, "LOGGER", logger); - new Expectations(downloadsStrategy) {{ - api.getApiUrl(""); result = "http://localhost"; times = 2; - api.getApiToken(); result = "token1"; times = 1; - logger.error("Error trying to connect to http://localhost"); times = 1; - }}; - - //confirm even tho we failed to connect we don't return error notifications that could flood chat clients - Assert.assertTrue(downloadsStrategy.getContentDownloads().isEmpty()); - } - private DownloadsStrategy getMockDownloadsStrategy(int maxDownloadsToShow) { - DownloadsStrategy mockDownloadsStrategy = new MockDownloadsStrategy(api, ""); + DownloadsStrategy mockDownloadsStrategy = new MockDownloadsStrategy(); Deencapsulation.setField(mockDownloadsStrategy, "MAX_DOWNLOADS_TO_SHOW", maxDownloadsToShow); return mockDownloadsStrategy; } @@ -113,15 +96,10 @@ private void writeFakePropertiesFile(Properties properties) throws Exception { @Mocked private Logger logger; - @Injectable - private Api api; + private RequestBuilder requestBuilder; private static class MockDownloadsStrategy extends DownloadsStrategy { - public MockDownloadsStrategy(Api api, String url) { - super(api, url); - } - @Override public CommandResponse getResponse(JsonElement rawElement) { return null; diff --git a/src/test/java/com/botdarr/api/radarr/RadarrApiTests.java b/src/test/java/com/botdarr/api/radarr/RadarrApiTests.java index 29d4159..6cc2dd1 100644 --- a/src/test/java/com/botdarr/api/radarr/RadarrApiTests.java +++ b/src/test/java/com/botdarr/api/radarr/RadarrApiTests.java @@ -9,6 +9,7 @@ import org.junit.*; import org.junit.rules.TemporaryFolder; import org.mockserver.junit.MockServerRule; +import org.mockserver.model.Header; import org.mockserver.model.HttpRequest; import org.mockserver.model.HttpResponse; import org.mockserver.model.MediaType; @@ -219,7 +220,10 @@ public void downloads_noDownloadsFound() { HttpRequest request = HttpRequest.request() .withMethod("GET") .withPath("/api/v3/queue") - .withQueryStringParameter("apiKey", "FSJDkjmf#$Kf3"); + .withQueryStringParameter("apiKey", "FSJDkjmf#$Kf3") + .withHeaders(new ArrayList
() {{ + add(new Header("content-length", "0")); + }}); //setup expected response in mock server mockServerRule.getClient()