From e0080fb1d2de2b0751503abd8d0ea5392119e9d1 Mon Sep 17 00:00:00 2001 From: shayaantx Date: Sat, 16 Jan 2021 15:27:20 -0500 Subject: [PATCH] Add matrix chat client support - Remove cancel/lookup torrents commands - Add thread pool for running api commands - Add new config "existing-item-paths-blacklist" - Change default prefix from / to ! - Refactor ConnectionHelper calls to be more generic - Fix log4j config so logs go to their respective files - Change default download notification time --- README.md | 71 ++-- images/search-results.png | Bin 218168 -> 0 bytes sample.properties | 31 +- src/main/java/com/botdarr/Config.java | 43 ++- .../com/botdarr/api/CacheContentStrategy.java | 2 +- .../java/com/botdarr/api/LookupStrategy.java | 8 + .../com/botdarr/api/lidarr/LidarrApi.java | 17 +- .../com/botdarr/api/radarr/RadarrApi.java | 111 +----- .../com/botdarr/api/radarr/RadarrTorrent.java | 364 ------------------ .../com/botdarr/api/sonarr/SonarrApi.java | 30 +- .../clients/ChatClientResponseBuilder.java | 3 - .../com/botdarr/clients/ChatClientType.java | 105 +++-- .../discord/DiscordResponseBuilder.java | 28 -- .../clients/matrix/MatrixChatClient.java | 318 +++++++++++++++ .../clients/matrix/MatrixResponse.java | 30 ++ .../clients/matrix/MatrixResponseBuilder.java | 271 +++++++++++++ .../transactions/MatrixJoinRoomResponse.java | 9 + .../matrix/transactions/MatrixLoginFlow.java | 9 + .../transactions/MatrixLoginInformation.java | 9 + .../transactions/MatrixLoginRequest.java | 15 + .../transactions/MatrixLoginResponse.java | 19 + .../MatrixPreviewUrlResponse.java | 18 + .../transactions/MatrixSendImageRequest.java | 11 + .../MatrixSendMessageRequest.java | 13 + .../MatrixSendMessageResponse.java | 9 + .../filter/MatrixEventFilter.java | 14 + .../filter/MatrixFilterRequest.java | 24 ++ .../filter/MatrixFilterResponse.java | 9 + .../filter/MatrixRoomEventFilter.java | 12 + .../transactions/filter/MatrixRoomFilter.java | 24 ++ .../filter/MatrixStateFilter.java | 19 + .../transactions/sync/MatrixSyncEvent.java | 18 + .../sync/MatrixSyncEventContent.java | 14 + .../transactions/sync/MatrixSyncJoinRoom.java | 9 + .../transactions/sync/MatrixSyncResponse.java | 14 + .../transactions/sync/MatrixSyncRooms.java | 12 + .../transactions/sync/MatrixSyncTimeline.java | 9 + .../clients/slack/SlackResponseBuilder.java | 51 --- .../telegram/TelegramResponseBuilder.java | 27 -- .../botdarr/commands/CommandProcessor.java | 2 +- .../com/botdarr/commands/RadarrCommands.java | 23 -- .../botdarr/connections/ConnectionHelper.java | 113 +++--- .../com/botdarr/scheduling/Scheduler.java | 14 +- src/main/resources/log4j2.xml | 23 +- src/main/resources/version.txt | 2 +- src/test/java/com/botdarr/ConfigTests.java | 2 +- .../java/com/botdarr/TestResponseBuilder.java | 6 - .../com/botdarr/api/LookupStrategyTests.java | 5 + .../commands/CommandProcessorTests.java | 46 --- 49 files changed, 1225 insertions(+), 811 deletions(-) delete mode 100644 images/search-results.png delete mode 100644 src/main/java/com/botdarr/api/radarr/RadarrTorrent.java create mode 100644 src/main/java/com/botdarr/clients/matrix/MatrixChatClient.java create mode 100644 src/main/java/com/botdarr/clients/matrix/MatrixResponse.java create mode 100644 src/main/java/com/botdarr/clients/matrix/MatrixResponseBuilder.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/MatrixJoinRoomResponse.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginFlow.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginInformation.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginRequest.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginResponse.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/MatrixPreviewUrlResponse.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/MatrixSendImageRequest.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/MatrixSendMessageRequest.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/MatrixSendMessageResponse.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixEventFilter.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixFilterRequest.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixFilterResponse.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixRoomEventFilter.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixRoomFilter.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixStateFilter.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncEvent.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncEventContent.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncJoinRoom.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncResponse.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncRooms.java create mode 100644 src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncTimeline.java diff --git a/README.md b/README.md index 43f50cd..a0276c2 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # Summary -Made this simple slack/discord/telegram bot so I could access radarr, sonarr, and lidarr all from a multiple slack/discord/telegram channels without a UI/server. +Made this simple slack/discord/telegram/matrix bot so I could access radarr, sonarr, and lidarr all from a multiple slack/discord/telegram/matrix channels without a UI/server.
@@ -20,6 +20,7 @@ Made this simple slack/discord/telegram bot so I could access radarr, sonarr, an - [x] Discord - [x] Slack - [x] Telegram +- [x] Matrix ## Currently Supported Feature's @@ -34,11 +35,12 @@ Made this simple slack/discord/telegram bot so I could access radarr, sonarr, an - [x] Configurable value for url base for radarr, sonarr, and lidarr - [x] Lookup torrents for movies and force download - [x] (discord/slack only) Thumbs up reaction will add search results -- [x] User requests audited to local database +- [x] User requests audited to local database\ +- [x] Blacklist content by paths from showing up in searches - [ ] Cancel/blacklist existing downloads - [ ] Episode/season search - [ ] Album/song search -- [ ] Run bot in mode where all 3 chat clients work in same process (right now you would need 3 separate processes/containers) +- [ ] Run bot in mode where all 4 chat clients work in same process (right now you would need 4 separate processes/containers) ## Discord Bot Installation @@ -54,6 +56,10 @@ See https://github.com/shayaantx/botdarr/wiki/Install-Slack-Bot See https://github.com/shayaantx/botdarr/wiki/Install-Telegram-Bot +## Matrix bot installation + +See https://github.com/shayaantx/botdarr/wiki/Install-Matrix-Bot + ## Jar installation/Configuration 1. Get latest copy of botdarr botdarr-release.jar @@ -69,26 +75,35 @@ Radarr seems to return a 200 http code, not actually add the movie, and return j the api url with your radarr url base. So MAKE SURE you account for this in your config/setup. ``` # your discord bot token -discord-token= +#discord-token= # the discord channel(s) you want the bot installed on -discord-channels= +#discord-channels= # Your slack bot oauth authentication token -slack-bot-token= +#slack-bot-token= # Your slack user oauth authentication token -slack-user-token= +#slack-user-token= # the slack channel(s) you want the bot installed on -slack-channels= +#slack-channels= # Your telegram bot token -telegram-token= +#telegram-token= # Your actual telegram channels your bot can respond in # this should be a list containing the name and id of the channel, i.e., CHANNEL_NAME:CHANNEL_ID # to get the channel id, right click any post in private channel and copy post link # you should see something like this, https://t.me/c/1408146664/63 # the id is between c// -# example: plex-channel1:id1,plex-channel2:id2 -telegram-private-channels= +# example: channel1:id1,channel2:id2 +#telegram-private-channels= + +# Your matrix bot user +#matrix-username= +# Your matrix bot password +#matrix-password= +# The room your matrix bot will send messages in +#matrix-room= +# The url of your homeserver +#matrix-home-server-url= # your radarr url (i.e., http://SOME-IP:SOME-PORT) radarr-url= @@ -145,9 +160,13 @@ lidarr-url-base= # If you set this to any value less than 0, the bot won't startup #max-results-to-show=20 -# The command prefix (default is /) +# The command prefix (default is !) # Any prefix is allowed (but I haven't tested every single prefix in every client) -command-prefix=/ +command-prefix=! + +# If you want content to NOT appear in searches against your library, you can list blacklisted paths here +# in comma delimited form, and they will be ignored when building up responses +#existing-item-paths-blacklist= ``` 1. Run the jar using java @@ -187,20 +206,18 @@ botdarr: ## Usage -* Type /help in your configured chat client to get information about commands and what is supported +* Type !help in your configured chat client to get information about commands and what is supported * Notifications will appear indicating the current downloads (based on your configuration for max downloads), their status, and their time remaining. -* When you search for content (i.e., /movie title add History of Dumb People) if too many results are returned you will be presented with multiple results. You can either use the thumbs up reaction (in discord or slack) or copy the add command (which will be embedded in the result) into the chat client. - -![](https://raw.githubusercontent.com/shayaantx/botdarr/development/images/search-results.png) -* The success of the bot depends a lot on how diverse your trackers you use in radarr, sonarr, lidarr and your quality profiles. If you have a trackers with little content or very restrictive quality profiles, a lot of content will never actually get added. The bot can't do anything about this. +* When you search for content (i.e., !movie title add History of Dumb People) if too many results are returned you will be presented with multiple results. You can either use the thumbs up reaction (in discord or slack) or copy the add command (which will be embedded in the result) into the chat client. * Example commands: - * /movie title add Lion Fling - * /show title add One Fliece - * /movie find new zombies - * /artist find new Linkin Flarp - * /movie downloads - * /show downloads - * /help - * /shows help - * /movies help + * !movie title add Lion Fling + * !show title add One Fliece + * !movie find new zombies + * !artist find new Linkin Flarp + * !movie downloads + * !show downloads + * !help + * !shows help + * !movies help +* The default command prefix is !. I chose ! because / (original command prefix) is commonly used by many chat clients and has existing functionality with it that leads to some commands not working nicely.
diff --git a/images/search-results.png b/images/search-results.png deleted file mode 100644 index 97e1d638be862d0872d71fedd5c9c8b085444499..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 218168 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

B5`tcu!z;J#6e~ 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 z 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�B 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

gRa6bmvof|q6j88d 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

S)7iuUcQr{wu0QqKk-<=0qYUW=GC)h1?cC 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/ # example: plex-channel1:id1,plex-channel2:id2 -telegram-private-channels= +#telegram-private-channels= + +# Your matrix bot user +#matrix-username= +# Your matrix bot password +#matrix-password= +# The room your matrix bot will send messages in +#matrix-room= +# The url of your homeserver +#matrix-home-server-url= # Your various media tool urls/keys go here radarr-url= @@ -67,6 +76,10 @@ max-downloads-to-show=20 # If you set this to any value less than 0, the bot won't startup max-results-to-show=20 -# The command prefix (default is /) +# The command prefix (default is !) # Any prefix is allowed (but I haven't tested every single prefix in every client) -command-prefix=/ \ No newline at end of file +command-prefix=! + +# If you want content to NOT appear in searches against your library, you can list blacklisted paths here +# in comma delimited form, and they will be ignored when building up responses +existing-item-paths-blacklist= \ No newline at end of file diff --git a/src/main/java/com/botdarr/Config.java b/src/main/java/com/botdarr/Config.java index 15cc798..3f3246a 100644 --- a/src/main/java/com/botdarr/Config.java +++ b/src/main/java/com/botdarr/Config.java @@ -7,9 +7,7 @@ import java.io.FileInputStream; import java.io.InputStream; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Properties; +import java.util.*; import java.util.stream.Collectors; public class Config { @@ -84,6 +82,12 @@ private Config() { if (!Strings.isEmpty(configuredPrefix) && configuredPrefix.length() > 1) { throw new RuntimeException("Command prefix must be a single character"); } + if (chatClientType == ChatClientType.SLACK && configuredPrefix.equals("/")) { + throw new RuntimeException("Cannot use / command prefix in slack since /help command was deprecated by slack"); + } + if (chatClientType == ChatClientType.MATRIX && configuredPrefix.equals("/")) { + throw new RuntimeException("Cannot use / command prefix in matrix since /help command is used by element by default"); + } } catch (Exception ex) { LOGGER.error("Error loading properties file", ex); throw new RuntimeException(ex); @@ -110,7 +114,35 @@ public static ChatClientType getChatClientType() { return getConfig().chatClientType; } + public static List getExistingItemBlacklistPaths() { + String paths = getProperty(Constants.EXISTING_ITEMS_PATHS_BLACKLIST); + if (paths != null && paths.contains(",")) { + return Arrays.asList(paths.split(",")); + } + return new ArrayList() {{add(paths);}}; + } + public static final class Constants { + /** + * The matrix bot username + */ + public static final String MATRIX_USERNAME = "matrix-username"; + + /** + * The matrix bot password + */ + public static final String MATRIX_PASSWORD = "matrix-password"; + + /** + * The matrix room for the bot + */ + public static final String MATRIX_ROOM = "matrix-room"; + + /** + * The matrix home server for the bot + */ + public static final String MATRIX_HOME_SERVER = "matrix-home-server-url"; + /** * The telegram auth token */ @@ -267,6 +299,11 @@ public static final class Constants { * The prefix for all commands */ public static final String COMMAND_PREFIX = "command-prefix"; + + /** + * The paths of items to blacklist from searches + */ + public static final String EXISTING_ITEMS_PATHS_BLACKLIST = "existing-item-paths-blacklist"; } private static String propertiesPath = "config/properties"; diff --git a/src/main/java/com/botdarr/api/CacheContentStrategy.java b/src/main/java/com/botdarr/api/CacheContentStrategy.java index 3e49ec3..e60eaaa 100644 --- a/src/main/java/com/botdarr/api/CacheContentStrategy.java +++ b/src/main/java/com/botdarr/api/CacheContentStrategy.java @@ -21,7 +21,7 @@ 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.api, this.url, new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) throws Exception { JsonParser parser = new JsonParser(); diff --git a/src/main/java/com/botdarr/api/LookupStrategy.java b/src/main/java/com/botdarr/api/LookupStrategy.java index 8f28f29..eb69eab 100644 --- a/src/main/java/com/botdarr/api/LookupStrategy.java +++ b/src/main/java/com/botdarr/api/LookupStrategy.java @@ -19,14 +19,22 @@ public LookupStrategy(ChatClientResponseBuilder ch public abstract T lookupExistingItem(T lookupItem); public abstract List lookup(String searchTerm) throws Exception; public abstract ChatClientResponse getNewOrExistingItem(T lookupItem, T existingItem, boolean findNew); + public abstract boolean isPathBlacklisted(T item); public List lookup(String search, boolean findNew) { try { List responses = new ArrayList<>(); List lookupItems = lookup(search); + if (lookupItems == null) { + return Arrays.asList(chatClientResponseBuilder.createErrorMessage("Something failed during lookup for search term=" + search)); + } for (T lookupItem : lookupItems) { T existingItem = lookupExistingItem(lookupItem); boolean isExistingItem = existingItem != null; + if (isExistingItem && isPathBlacklisted(existingItem)) { + //skip any items that have blacklisted paths + continue; + } boolean skip = findNew ? isExistingItem : !isExistingItem; if (skip) { continue; diff --git a/src/main/java/com/botdarr/api/lidarr/LidarrApi.java b/src/main/java/com/botdarr/api/lidarr/LidarrApi.java index cd51252..9d5eb96 100644 --- a/src/main/java/com/botdarr/api/lidarr/LidarrApi.java +++ b/src/main/java/com/botdarr/api/lidarr/LidarrApi.java @@ -2,6 +2,7 @@ import com.botdarr.Config; import com.botdarr.api.*; +import com.botdarr.api.sonarr.SonarrShow; import com.botdarr.api.sonarr.SonarrUrls; import com.botdarr.clients.ChatClient; import com.botdarr.clients.ChatClientResponse; @@ -65,7 +66,7 @@ public void deleteFromCache(List profilesAddUpdated) { @Override public List getProfiles() { - return ConnectionHelper.makeGetRequest(LidarrApi.this, LidarrUrls.PROFILE, new ConnectionHelper.SimpleEntityResponseHandler() { + return ConnectionHelper.makeGetRequest(LidarrApi.this, LidarrUrls.PROFILE, new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List lidarrQualityProfiles = new ArrayList<>(); @@ -95,7 +96,7 @@ public void deleteFromCache(List profilesAddUpdated) { @Override public List getProfiles() { - return ConnectionHelper.makeGetRequest(LidarrApi.this, LidarrUrls.METADATA_PROFILE, new ConnectionHelper.SimpleEntityResponseHandler() { + return ConnectionHelper.makeGetRequest(LidarrApi.this, LidarrUrls.METADATA_PROFILE, new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List lidarrMetadataProfiles = new ArrayList<>(); @@ -164,6 +165,16 @@ public List lookup(String searchTerm) throws Exception { public ChatClientResponse getNewOrExistingItem(LidarrArtist lookupItem, LidarrArtist existingItem, boolean findNew) { return chatClientResponseBuilder.getNewOrExistingArtist(lookupItem, existingItem, findNew); } + + @Override + public boolean isPathBlacklisted(LidarrArtist item) { + for (String path : Config.getExistingItemBlacklistPaths()) { + if (item.getPath() != null && item.getPath().startsWith(path)) { + return true; + } + } + return false; + } }.lookup(search, findNew); } @@ -226,7 +237,7 @@ 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"), - new ConnectionHelper.SimpleEntityResponseHandler() { + new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List artists = new ArrayList<>(); diff --git a/src/main/java/com/botdarr/api/radarr/RadarrApi.java b/src/main/java/com/botdarr/api/radarr/RadarrApi.java index 68df357..b90feb7 100644 --- a/src/main/java/com/botdarr/api/radarr/RadarrApi.java +++ b/src/main/java/com/botdarr/api/radarr/RadarrApi.java @@ -53,6 +53,16 @@ public List lookup(String searchTerm) throws Exception { public ChatClientResponse getNewOrExistingItem(RadarrMovie lookupItem, RadarrMovie existingItem, boolean findNew) { return chatClientResponseBuilder.getNewOrExistingMovie(lookupItem, existingItem, findNew); } + + @Override + public boolean isPathBlacklisted(RadarrMovie item) { + for (String path : Config.getExistingItemBlacklistPaths()) { + if (item.getPath() != null && item.getPath().startsWith(path)) { + return true; + } + } + return false; + } }.lookup(search, findNew); } @@ -82,74 +92,6 @@ public List getProfiles() { return profileMessages; } - public List forceDownload(String command) { - String decodedKey = new String(Base64.getDecoder().decode(command.getBytes())); - //the hash format is guid:title - //title couldn't contain : so we find the first occurrence - int titleIndex = decodedKey.indexOf("title="); - String[] decodedKeyArray = {decodedKey.substring(0, titleIndex - 1), decodedKey.substring(titleIndex + 6)}; - if (decodedKeyArray.length != 2) { - return Arrays.asList(chatClientResponseBuilder.createErrorMessage("Invalid key=" + decodedKey)); - } - - String guid = decodedKeyArray[0]; - String title = decodedKeyArray[1]; - List radarrTorrents = lookupTorrents(title); - - if (radarrTorrents.isEmpty()) { - return Arrays.asList(chatClientResponseBuilder.createErrorMessage("Found no movies to force download, title=" + title)); - } - - for (RadarrTorrent radarrTorrent : radarrTorrents) { - if (radarrTorrent.getGuid().equalsIgnoreCase(guid)) { - return ConnectionHelper.makePostRequest(this, RadarrUrls.RELEASE_BASE, radarrTorrent, new ConnectionHelper.SimpleMessageEmbedResponseHandler(chatClientResponseBuilder) { - @Override - public List onSuccess(String response) throws Exception { - return Arrays.asList(chatClientResponseBuilder.createSuccessMessage("Forced the download for " + title)); - } - }); - } - } - return Arrays.asList(chatClientResponseBuilder.createErrorMessage("Could not force download movie for title=" + title + ", guid=" + guid)); - } - - public List lookupTorrents(String movieTitle, boolean showRejected) { - List radarrTorrents = lookupTorrents(movieTitle); - if (radarrTorrents.isEmpty()) { - return Arrays.asList(chatClientResponseBuilder.createErrorMessage("No downloads available for " + movieTitle + ", make sure you have exact film name.")); - } - - List responses = new ArrayList<>(); - for (RadarrTorrent radarrTorrent : radarrTorrents) { - if (!showRejected && radarrTorrent.isRejected()) { - //dont show rejected torrents - continue; - } - responses.add(chatClientResponseBuilder.getTorrentResponses(radarrTorrent, movieTitle)); - } - - if (responses.isEmpty()) { - responses.add(chatClientResponseBuilder.createErrorMessage("Torrents were found but all of them were rejected based on your profiles/indexer settings for movie " + movieTitle)); - } - - return responses; - } - - public List cancelDownload(String command) { - try { - Long id = Long.valueOf(command); - return ConnectionHelper.makeDeleteRequest(this, RadarrUrls.DOWNLOAD_BASE + "/" + id, "&blacklist=true", new ConnectionHelper.SimpleMessageEmbedResponseHandler(chatClientResponseBuilder) { - @Override - public List onSuccess(String response) throws Exception { - //TODO: implement - return Arrays.asList(chatClientResponseBuilder.createErrorMessage("Not implemented yet")); - } - }); - } catch (NumberFormatException e) { - return Arrays.asList(chatClientResponseBuilder.createErrorMessage("Require an id value to cancel a download, e=" + e.getMessage())); - } - } - @Override public void sendPeriodicNotifications(ChatClient chatClient) { new PeriodicNotificationStrategy(ContentType.MOVIE, getDownloadsStrategy()) { @@ -170,7 +112,7 @@ public void deleteFromCache(List profilesAddUpdated) { @Override public List getProfiles() { - return ConnectionHelper.makeGetRequest(RadarrApi.this, RadarrUrls.PROFILE_BASE, new ConnectionHelper.SimpleEntityResponseHandler() { + return ConnectionHelper.makeGetRequest(RadarrApi.this, RadarrUrls.PROFILE_BASE, new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List radarrProfiles = new ArrayList<>(); @@ -212,7 +154,7 @@ public String getApiToken() { } public List discover() { - return ConnectionHelper.makeGetRequest(this, RadarrUrls.DISCOVER_MOVIES, new ConnectionHelper.SimpleEntityResponseHandler() { + return ConnectionHelper.makeGetRequest(this, RadarrUrls.DISCOVER_MOVIES, new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) throws Exception { List recommendedMovies = new ArrayList<>(); @@ -334,34 +276,9 @@ private ChatClientResponse addMovie(RadarrMovie radarrMovie) { } } - private List lookupTorrents(String title) { - Long id = RADARR_CACHE.getMovieSonarrId(title); - if (id == null) { - LOGGER.warn("Could not find title id for title " + title); - return Collections.emptyList(); - } - return ConnectionHelper.makeGetRequest(this, RadarrUrls.RELEASE_BASE, "&movieId=" + id + "&sort_by=releaseWeight&order=asc", new ConnectionHelper.SimpleEntityResponseHandler() { - @Override - public List onSuccess(String response) throws Exception { - List radarrTorrents = new ArrayList<>(); - if (response == null || response.isEmpty() || response.equalsIgnoreCase("[]")) { - LOGGER.warn("Found no response when looking for radarr torrents"); - return Collections.emptyList(); - } - JsonParser parser = new JsonParser(); - JsonArray json = parser.parse(response).getAsJsonArray(); - - for (int i = 0; i < json.size(); i++) { - radarrTorrents.add(new Gson().fromJson(json.get(i), RadarrTorrent.class)); - } - return radarrTorrents; - } - }); - } - private List lookupMovies(String search) throws Exception { return ConnectionHelper.makeGetRequest(this, RadarrUrls.MOVIE_LOOKUP, "&term=" + URLEncoder.encode(search, "UTF-8"), - new ConnectionHelper.SimpleEntityResponseHandler() { + new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List movies = new ArrayList<>(); @@ -377,7 +294,7 @@ 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() { + new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List movies = new ArrayList<>(); diff --git a/src/main/java/com/botdarr/api/radarr/RadarrTorrent.java b/src/main/java/com/botdarr/api/radarr/RadarrTorrent.java deleted file mode 100644 index 2e9592b..0000000 --- a/src/main/java/com/botdarr/api/radarr/RadarrTorrent.java +++ /dev/null @@ -1,364 +0,0 @@ -package com.botdarr.api.radarr; - -public class RadarrTorrent { - public String getGuid() { - return guid; - } - - public void setGuid(String guid) { - this.guid = guid; - } - - public RadarrProfileQualityItem getQuality() { - return quality; - } - - public void setQuality(RadarrProfileQualityItem quality) { - this.quality = quality; - } - - public String getIndexer() { - return indexer; - } - - public void setIndexer(String indexer) { - this.indexer = indexer; - } - - public boolean isRejected() { - return rejected; - } - - public void setRejected(boolean rejected) { - this.rejected = rejected; - } - - public String getDownloadUrl() { - return downloadUrl; - } - - public void setDownloadUrl(String downloadUrl) { - this.downloadUrl = downloadUrl; - } - - public int getSeeders() { - return seeders; - } - - public void setSeeders(int seeders) { - this.seeders = seeders; - } - - public int getLeechers() { - return leechers; - } - - public void setLeechers(int leechers) { - this.leechers = leechers; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String[] getRejections() { - return rejections; - } - - public void setRejections(String[] rejections) { - this.rejections = rejections; - } - - public long getAge() { - return age; - } - - public void setAge(long age) { - this.age = age; - } - - public double getAgeHours() { - return ageHours; - } - - public void setAgeHours(double ageHours) { - this.ageHours = ageHours; - } - - public double getAgeMinutes() { - return ageMinutes; - } - - public void setAgeMinutes(double ageMinutes) { - this.ageMinutes = ageMinutes; - } - - public boolean isApproved() { - return approved; - } - - public void setApproved(boolean approved) { - this.approved = approved; - } - - public String getCommentUrl() { - return commentUrl; - } - - public void setCommentUrl(String commentUrl) { - this.commentUrl = commentUrl; - } - - public String getEdition() { - return edition; - } - - public void setEdition(String edition) { - this.edition = edition; - } - - public boolean isFullSeason() { - return fullSeason; - } - - public void setFullSeason(boolean fullSeason) { - this.fullSeason = fullSeason; - } - - public String[] getIndexerFlags() { - return indexerFlags; - } - - public void setIndexerFlags(String[] indexerFlags) { - this.indexerFlags = indexerFlags; - } - - public int getIndexerId() { - return indexerId; - } - - public void setIndexerId(int indexerId) { - this.indexerId = indexerId; - } - - public String getInfoHash() { - return infoHash; - } - - public void setInfoHash(String infoHash) { - this.infoHash = infoHash; - } - - public String getInfoUrl() { - return infoUrl; - } - - public void setInfoUrl(String infoUrl) { - this.infoUrl = infoUrl; - } - - public boolean isAbsoluteNumbering() { - return isAbsoluteNumbering; - } - - public void setAbsoluteNumbering(boolean absoluteNumbering) { - isAbsoluteNumbering = absoluteNumbering; - } - - public boolean isDaily() { - return isDaily; - } - - public void setDaily(boolean daily) { - isDaily = daily; - } - - public boolean isPossibleSpecialEpisode() { - return isPossibleSpecialEpisode; - } - - public void setPossibleSpecialEpisode(boolean possibleSpecialEpisode) { - isPossibleSpecialEpisode = possibleSpecialEpisode; - } - - public String[] getLanguages() { - return languages; - } - - public void setLanguages(String[] languages) { - this.languages = languages; - } - - public String getMagnetUrl() { - return magnetUrl; - } - - public void setMagnetUrl(String magnetUrl) { - this.magnetUrl = magnetUrl; - } - - public String getMappingResult() { - return mappingResult; - } - - public void setMappingResult(String mappingResult) { - this.mappingResult = mappingResult; - } - - public String getMovieTitle() { - return movieTitle; - } - - public void setMovieTitle(String movieTitle) { - this.movieTitle = movieTitle; - } - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public String getPublishDate() { - return publishDate; - } - - public void setPublishDate(String publishDate) { - this.publishDate = publishDate; - } - - public int getQualityWeight() { - return qualityWeight; - } - - public void setQualityWeight(int qualityWeight) { - this.qualityWeight = qualityWeight; - } - - public String getReleaseGroup() { - return releaseGroup; - } - - public void setReleaseGroup(String releaseGroup) { - this.releaseGroup = releaseGroup; - } - - public int getReleaseWeight() { - return releaseWeight; - } - - public void setReleaseWeight(int releaseWeight) { - this.releaseWeight = releaseWeight; - } - - public int getSeasonNumber() { - return seasonNumber; - } - - public void setSeasonNumber(int seasonNumber) { - this.seasonNumber = seasonNumber; - } - - public long getSize() { - return size; - } - - public void setSize(long size) { - this.size = size; - } - - public boolean isSpecial() { - return special; - } - - public void setSpecial(boolean special) { - this.special = special; - } - - public long getSuspectedMovieId() { - return suspectedMovieId; - } - - public void setSuspectedMovieId(long suspectedMovieId) { - this.suspectedMovieId = suspectedMovieId; - } - - public boolean isTemporarilyRejected() { - return temporarilyRejected; - } - - public void setTemporarilyRejected(boolean temporarilyRejected) { - this.temporarilyRejected = temporarilyRejected; - } - - public int getTvRageId() { - return tvRageId; - } - - public void setTvRageId(int tvRageId) { - this.tvRageId = tvRageId; - } - - public long getTvdbId() { - return tvdbId; - } - - public void setTvdbId(long tvdbId) { - this.tvdbId = tvdbId; - } - - public int getYear() { - return year; - } - - public void setYear(int year) { - this.year = year; - } - - private String[] rejections; - private String guid; - private RadarrProfileQualityItem quality; - private String indexer; - private boolean rejected; - private String downloadUrl; - private int seeders; - private int leechers; - private String title; - private long age; - private double ageHours; - private double ageMinutes; - private boolean approved; - private String commentUrl; - private String edition; - private boolean fullSeason; - private String[] indexerFlags; - private int indexerId; - private String infoHash; - private String infoUrl; - private boolean isAbsoluteNumbering; - private boolean isDaily; - private boolean isPossibleSpecialEpisode; - private String[] languages; - private String magnetUrl; - private String mappingResult; - private String movieTitle; - private String protocol; - private String publishDate; - private int qualityWeight; - private String releaseGroup; - private int releaseWeight; - private int seasonNumber; - private long size; - private boolean special; - private long suspectedMovieId; - private boolean temporarilyRejected; - private int tvRageId; - private long tvdbId; - private int year; -} diff --git a/src/main/java/com/botdarr/api/sonarr/SonarrApi.java b/src/main/java/com/botdarr/api/sonarr/SonarrApi.java index 25daec6..7555756 100644 --- a/src/main/java/com/botdarr/api/sonarr/SonarrApi.java +++ b/src/main/java/com/botdarr/api/sonarr/SonarrApi.java @@ -2,6 +2,7 @@ import com.botdarr.Config; import com.botdarr.api.*; +import com.botdarr.api.radarr.RadarrMovie; import com.botdarr.clients.ChatClient; import com.botdarr.clients.ChatClientResponse; import com.botdarr.clients.ChatClientResponseBuilder; @@ -64,17 +65,17 @@ public List lookup(String searchTerm) throws Exception { public ChatClientResponse getNewOrExistingItem(SonarrShow lookupItem, SonarrShow existingItem, boolean findNew) { return chatClientResponseBuilder.getNewOrExistingShow(lookupItem, existingItem, findNew); } - }.lookup(search, findNew); - } - - public List lookupTorrents(String command, boolean showRejected) { - //TODO: implement - return null; - } - public List cancelDownload(long id) { - //TODO: implement - return null; + @Override + public boolean isPathBlacklisted(SonarrShow item) { + for (String path : Config.getExistingItemBlacklistPaths()) { + if (item.getPath() != null && item.getPath().startsWith(path)) { + return true; + } + } + return false; + } + }.lookup(search, findNew); } public List getProfiles() { @@ -90,11 +91,6 @@ public List getProfiles() { return profileMessages; } - public List forceDownload(String command) { - //TODO: implement - return null; - } - @Override public void sendPeriodicNotifications(ChatClient chatClient) { new PeriodicNotificationStrategy(ContentType.SHOW, getDownloadsStrategy()) { @@ -115,7 +111,7 @@ public void deleteFromCache(List profilesAddUpdated) { @Override public List getProfiles() { - return ConnectionHelper.makeGetRequest(SonarrApi.this, SonarrUrls.PROFILE, new ConnectionHelper.SimpleEntityResponseHandler() { + return ConnectionHelper.makeGetRequest(SonarrApi.this, SonarrUrls.PROFILE, new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List sonarrProfiles = new ArrayList<>(); @@ -253,7 +249,7 @@ private ChatClientResponse 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(this, SonarrUrls.LOOKUP_SERIES, "&term=" + URLEncoder.encode(search, "UTF-8"), new ConnectionHelper.SimpleEntityResponseHandler>() { @Override public List onSuccess(String response) { List movies = new ArrayList<>(); diff --git a/src/main/java/com/botdarr/clients/ChatClientResponseBuilder.java b/src/main/java/com/botdarr/clients/ChatClientResponseBuilder.java index e74f19b..46400ea 100644 --- a/src/main/java/com/botdarr/clients/ChatClientResponseBuilder.java +++ b/src/main/java/com/botdarr/clients/ChatClientResponseBuilder.java @@ -1,12 +1,10 @@ package com.botdarr.clients; import com.botdarr.api.lidarr.LidarrArtist; -import com.botdarr.api.lidarr.LidarrQueue; import com.botdarr.api.lidarr.LidarrQueueRecord; import com.botdarr.api.radarr.RadarrMovie; import com.botdarr.api.radarr.RadarrProfile; import com.botdarr.api.radarr.RadarrQueue; -import com.botdarr.api.radarr.RadarrTorrent; import com.botdarr.api.sonarr.SonarrProfile; import com.botdarr.api.sonarr.SonarrQueue; import com.botdarr.api.sonarr.SonarrShow; @@ -34,7 +32,6 @@ public interface ChatClientResponseBuilder { T createErrorMessage(String message); T createInfoMessage(String message); T createSuccessMessage(String message); - T getTorrentResponses(RadarrTorrent radarrTorrent, String movieTitle); T getShowProfile(SonarrProfile sonarrProfile); T getMovieProfile(RadarrProfile radarrProfile); T getNewOrExistingShow(SonarrShow sonarrShow, SonarrShow existingShow, boolean findNew); diff --git a/src/main/java/com/botdarr/clients/ChatClientType.java b/src/main/java/com/botdarr/clients/ChatClientType.java index f508172..1bb66d4 100644 --- a/src/main/java/com/botdarr/clients/ChatClientType.java +++ b/src/main/java/com/botdarr/clients/ChatClientType.java @@ -5,6 +5,9 @@ import com.botdarr.api.lidarr.LidarrApi; import com.botdarr.api.radarr.RadarrApi; import com.botdarr.api.sonarr.SonarrApi; +import com.botdarr.clients.matrix.MatrixChatClient; +import com.botdarr.clients.matrix.MatrixResponse; +import com.botdarr.clients.matrix.MatrixResponseBuilder; import com.botdarr.commands.*; import com.botdarr.clients.discord.DiscordChatClient; import com.botdarr.clients.discord.DiscordResponse; @@ -43,12 +46,47 @@ import javax.annotation.Nonnull; import java.util.*; +import java.util.concurrent.Callable; import static com.botdarr.api.lidarr.LidarrApi.ADD_ARTIST_COMMAND_FIELD_PREFIX; import static com.botdarr.api.radarr.RadarrApi.ADD_MOVIE_COMMAND_FIELD_PREFIX; import static com.botdarr.api.sonarr.SonarrApi.ADD_SHOW_COMMAND_FIELD_PREFIX; public enum ChatClientType { + MATRIX() { + @Override + public void init() throws Exception { + MatrixChatClient chatClient = new MatrixChatClient(); + ChatClientResponseBuilder responseChatClientResponseBuilder = new MatrixResponseBuilder(); + ApisAndCommandConfig config = buildConfig(responseChatClientResponseBuilder); + initScheduling(chatClient, config.apis); + chatClient.addListener((roomId, sender, content) -> { + Scheduler.getScheduler().executeCommand(() -> { + CommandResponse commandResponse = + commandProcessor.processMessage(config.commands, content, sender, responseChatClientResponseBuilder); + if (commandResponse != null) { + chatClient.sendMessage(commandResponse, roomId); + } + return null; + }); + }); + chatClient.listen(); + } + + @Override + public boolean isConfigured(Properties properties) { + return + !Strings.isBlank(properties.getProperty(Config.Constants.MATRIX_USERNAME)) && + !Strings.isBlank(properties.getProperty(Config.Constants.MATRIX_PASSWORD)) && + !Strings.isBlank(properties.getProperty(Config.Constants.MATRIX_ROOM)) && + !Strings.isBlank(properties.getProperty(Config.Constants.MATRIX_HOME_SERVER)); + } + + @Override + public String getReadableName() { + return "Matrix"; + } + }, TELEGRAM() { @Override public void init() throws Exception { @@ -66,11 +104,14 @@ public void init() throws Exception { //TODO: the telegram api doesn't seem return "from" field in channel posts for some reason //for now we leave the author as "telegram" till a better solution arises String author = "telegram"; - CommandResponse commandResponse = - commandProcessor.processMessage(config.commands, text, author, responseChatClientResponseBuilder); - if (commandResponse != null) { - telegramChatClient.sendMessage(commandResponse, message.chat()); - } + Scheduler.getScheduler().executeCommand(() -> { + CommandResponse commandResponse = + commandProcessor.processMessage(config.commands, text, author, responseChatClientResponseBuilder); + if (commandResponse != null) { + telegramChatClient.sendMessage(commandResponse, message.chat()); + } + return null; + }); } } } catch (Throwable t) { @@ -108,7 +149,7 @@ public void onGenericEvent(@Nonnull GenericEvent event) { @Override public void onReady(@Nonnull ReadyEvent event) { - LogManager.getLogger("DiscordLog").info("Connected to discord"); + LogManager.getLogger("com.botdarr.clients.discord").info("Connected to discord"); ChatClient chatClient = new DiscordChatClient(event.getJDA()); //start the scheduler threads that send notifications and cache data periodically initScheduling(chatClient, config.apis); @@ -143,7 +184,7 @@ public void onGuildMessageReactionAdd(@Nonnull GuildMessageReactionAddEvent even @Override public void onMessageReceived(@Nonnull MessageReceivedEvent event) { handleCommand(event.getJDA(), event.getMessage().getContentStripped(), event.getAuthor().getName(), event.getChannel().getName()); - LogManager.getLogger("DiscordLog").debug(event.getMessage().getContentRaw()); + LogManager.getLogger("com.botdarr.clients.discord").debug(event.getMessage().getContentRaw()); super.onMessageReceived(event); } @@ -152,22 +193,25 @@ private void handleCommand(JDA jda, String message, String author, String channe DiscordChatClient discordChatClient = new DiscordChatClient(jda); //capture/process command - CommandResponse commandResponse = commandProcessor.processMessage( - config.commands, - message, - author, - responseChatClientResponseBuilder); - if (commandResponse != null) { - //then send the response - discordChatClient.sendMessage(commandResponse, channelName); - } + Scheduler.getScheduler().executeCommand(() -> { + CommandResponse commandResponse = commandProcessor.processMessage( + config.commands, + message, + author, + responseChatClientResponseBuilder); + if (commandResponse != null) { + //then send the response + discordChatClient.sendMessage(commandResponse, channelName); + } + return null; + }); } private static final String THUMBS_UP_EMOTE = "\uD83D\uDC4D"; }).build(); jda.awaitReady(); } catch (Throwable e) { - LogManager.getLogger("DiscordLog").error("Error caught during main", e); + LogManager.getLogger("com.botdarr.clients.discord").error("Error caught during main", e); throw e; } } @@ -232,24 +276,27 @@ public void handle(String message) { } } } catch (Exception e) { - LogManager.getLogger("SlackLog").error("Error fetching conversation history", e); + LogManager.getLogger("com.botdarr.clients.slack").error("Error fetching conversation history", e); } } } - LogManager.getLogger("SlackLog").debug(json); + LogManager.getLogger("com.botdarr.clients.slack").debug(json); } private void handleCommand(String text, String userId, String channel) { - //capture/process the command - CommandResponse commandResponse = commandProcessor.processMessage( - config.commands, - text, - userId, - responseChatClientResponseBuilder); - if (commandResponse != null) { - //then send the response - slackChatClient.sendMessage(commandResponse, channel); - } + Scheduler.getScheduler().executeCommand(() -> { + //capture/process the command + CommandResponse commandResponse = commandProcessor.processMessage( + config.commands, + text, + userId, + responseChatClientResponseBuilder); + if (commandResponse != null) { + //then send the response + slackChatClient.sendMessage(commandResponse, channel); + } + return null; + }); } }); diff --git a/src/main/java/com/botdarr/clients/discord/DiscordResponseBuilder.java b/src/main/java/com/botdarr/clients/discord/DiscordResponseBuilder.java index 262dd82..2c7a75f 100644 --- a/src/main/java/com/botdarr/clients/discord/DiscordResponseBuilder.java +++ b/src/main/java/com/botdarr/clients/discord/DiscordResponseBuilder.java @@ -11,14 +11,12 @@ import com.botdarr.utilities.ListUtils; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.MessageEmbed; -import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.util.Strings; import java.awt.*; import java.io.IOException; -import java.util.Base64; import java.util.List; import static com.botdarr.api.lidarr.LidarrApi.ADD_ARTIST_COMMAND_FIELD_PREFIX; @@ -113,7 +111,6 @@ public DiscordResponse getShowDownloadResponses(SonarrQueue showQueue) { } } } - embedBuilder.addField("Cancel download command", "show cancel download " + showQueue.getId(), true); return new DiscordResponse(embedBuilder.build()); } @@ -131,8 +128,6 @@ public DiscordResponse getMovieDownloadResponses(RadarrQueue radarrQueue) { } } } - //TODO: implement - //embedBuilder.addField("Cancel download command", "movie cancel download " + radarrQueue.getId(), true); return new DiscordResponse(embedBuilder.build()); } @@ -152,29 +147,6 @@ public DiscordResponse getArtistDownloadResponses(LidarrQueueRecord lidarrQueueR return new DiscordResponse(embedBuilder.build()); } - @Override - public DiscordResponse getTorrentResponses(RadarrTorrent radarrTorrent, String movieTitle) { - EmbedBuilder embedBuilder = new EmbedBuilder(); - embedBuilder.addField("Title", radarrTorrent.getTitle(), false); - embedBuilder.addField("Torrent", radarrTorrent.getGuid(), false); - embedBuilder.addField("Quality", radarrTorrent.getQuality().getQuality().getName(), true); - embedBuilder.addField("Indexer", radarrTorrent.getIndexer(), true); - embedBuilder.addField("Seeders", "" + radarrTorrent.getSeeders(), true); - embedBuilder.addField("Leechers", "" + radarrTorrent.getLeechers(), true); - embedBuilder.addField("Size", "" + FileUtils.byteCountToDisplaySize(radarrTorrent.getSize()), true); - String[] rejections = radarrTorrent.getRejections(); - if (rejections != null) { - embedBuilder.addBlankField(false); - for (String rejection : rejections) { - embedBuilder.addField("Rejection Reason", rejection, false); - } - } - String key = radarrTorrent.getGuid() + ":title=" + movieTitle; - byte[] encodedBytes = Base64.getEncoder().encode(key.getBytes()); - embedBuilder.addField("Download hash command", "movie hash download " + new String(encodedBytes), true); - return new DiscordResponse(embedBuilder.build()); - } - @Override public DiscordResponse getShowProfile(SonarrProfile sonarrProfile) { EmbedBuilder embedBuilder = new EmbedBuilder(); diff --git a/src/main/java/com/botdarr/clients/matrix/MatrixChatClient.java b/src/main/java/com/botdarr/clients/matrix/MatrixChatClient.java new file mode 100644 index 0000000..124b312 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/MatrixChatClient.java @@ -0,0 +1,318 @@ +package com.botdarr.clients.matrix; + +import com.botdarr.Config; +import com.botdarr.clients.ChatClient; +import com.botdarr.clients.matrix.transactions.*; +import com.botdarr.clients.matrix.transactions.filter.*; +import com.botdarr.clients.matrix.transactions.sync.MatrixSyncEvent; +import com.botdarr.clients.matrix.transactions.sync.MatrixSyncJoinRoom; +import com.botdarr.clients.matrix.transactions.sync.MatrixSyncResponse; +import com.botdarr.clients.matrix.transactions.sync.MatrixSyncRooms; +import com.botdarr.commands.CommandResponse; +import com.botdarr.connections.ConnectionHelper; +import com.google.gson.Gson; +import org.apache.http.client.methods.*; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.net.URLEncoder; +import java.util.*; + +public class MatrixChatClient implements ChatClient { + public MatrixChatClient() { + if (!isPasswordLoginSupported()) { + throw new RuntimeException("Password login not supported on homeserver"); + } + MatrixLoginResponse loginResponse = getAccessToken(); + if (loginResponse == null) { + throw new RuntimeException("Could not get login response"); + } + this.accessToken = loginResponse.getAccessToken(); + this.userId = loginResponse.getUserId(); + if (this.accessToken == null || this.accessToken.isEmpty()) { + throw new RuntimeException("Could not get access token"); + } + if (this.userId == null || this.userId.isEmpty()) { + throw new RuntimeException("Could not get user id"); + } + for (String room : getRooms()) { + if (!this.joinRoom(room)) { + throw new RuntimeException("Could not join room " + room); + } + } + this.messageFilterId = this.addMessageFilter(); + if (this.messageFilterId == null || this.messageFilterId.isEmpty()) { + throw new RuntimeException("Could not add/get matrix filter"); + } + } + + @Override + public void sendToConfiguredChannels(List chatClientResponses) { + for (MatrixResponse response : chatClientResponses) { + for (String room : getRooms()) { + sendMatrixResponse(response, room); + } + } + } + + public void sendMessage(CommandResponse commandResponse, String roomId) { + if (commandResponse.getSingleChatClientResponse() != null) { + sendMatrixResponse(commandResponse.getSingleChatClientResponse(), roomId); + + } else if (commandResponse.getMultipleChatClientResponses() != null) { + for (MatrixResponse response : commandResponse.getMultipleChatClientResponses()) { + sendMatrixResponse(response, roomId); + } + } else { + //TODO: err + } + } + + public void addListener(MatrixMessageListener listener) { + this.listeners.add(listener); + } + + public void listen() { + String nextBatch = null; + while (true) { + try { + //TODO: handle invalid access token + MatrixSyncResponse syncResponse = sync(nextBatch); + nextBatch = syncResponse.getNextBatch(); + MatrixSyncRooms syncRooms = syncResponse.getRooms(); + for (Map.Entry entry : syncRooms.getJoin().entrySet()) { + String roomId = entry.getKey(); + MatrixSyncJoinRoom joinRoom = entry.getValue(); + for (MatrixSyncEvent event : joinRoom.getTimeline().getEvents()) { + if (event.getContent().getMsgtype() != null && event.getContent().getMsgtype().equals("m.text")) { + for (MatrixMessageListener matrixMessageListener : this.listeners) { + matrixMessageListener.process(roomId, event.getSender(), event.getContent().getBody()); + } + } + } + } + } catch (Throwable t) { + LOGGER.error("Error during event listener", t); + } + } + } + + private List getRooms() { + String rawRoomsStr = Config.getProperty(Config.Constants.MATRIX_ROOM); + if (rawRoomsStr.contains(",")) { + return Arrays.asList(rawRoomsStr.split(",")); + } + return new ArrayList() {{add(rawRoomsStr);}}; + } + + private MatrixPreviewUrlResponse getPreviewUrl(String url) { + return ConnectionHelper.makeRequest(() -> new HttpGet( + Config.getProperty(Config.Constants.MATRIX_HOME_SERVER) + + Constants.API_PREVIEW_URL + + "?access_token=" + MatrixChatClient.this.accessToken + + "&url=" + URLEncoder.encode(url, "UTF-8")), new MatrixResponseHandler() { + @Override + public MatrixPreviewUrlResponse onSuccess(String response) throws Exception { + return new Gson().fromJson(response, MatrixPreviewUrlResponse.class); + } + }); + } + + private void sendMatrixResponse(MatrixResponse response, String roomId) { + List mxcUrls = new ArrayList<>(); + //image previews urls seem to have sporadic behavior across clients in matrix ecosystem + //so I just use the preview url api to get images in a format that works fine + if (!response.getImageUrls().isEmpty()) { + for (String imageUrl : response.getImageUrls()) { + MatrixPreviewUrlResponse previewUrlResponse = getPreviewUrl(imageUrl); + if (previewUrlResponse == null) { + LOGGER.warn("Could not find image " + imageUrl); + continue; + } + mxcUrls.add(previewUrlResponse.getMxcUri()); + } + } + MatrixSendMessageRequest sendMessageRequest = new MatrixSendMessageRequest(); + sendMessageRequest.setBody(response.getContent()); + sendMessage(roomId, sendMessageRequest); + for (String mxcUrl : mxcUrls) { + MatrixSendImageRequest sendImageRequest = new MatrixSendImageRequest(); + sendImageRequest.setUrl(mxcUrl); + sendMessage(roomId, sendImageRequest); + } + } + + private void sendMessage(String roomId, T message) { + MatrixSendMessageResponse response = ConnectionHelper.makeRequest(() -> { + HttpPost post = new HttpPost(Config.getProperty(Config.Constants.MATRIX_HOME_SERVER) + + String.format(Constants.API_SEND_MESSAGE, roomId) + + "?access_token=" + MatrixChatClient.this.accessToken); + post.setEntity(new StringEntity(new Gson().toJson(message), ContentType.APPLICATION_JSON)); + return post; + }, + new MatrixResponseHandler() { + @Override + public MatrixSendMessageResponse onSuccess(String response) throws Exception { + return new Gson().fromJson(response, MatrixSendMessageResponse.class); + } + }); + if (response == null || response.getEventId() == null || response.getEventId().isEmpty()) { + LOGGER.error("Missing event id for room " + roomId + " and message " + message); + } + } + + private String addMessageFilter() { + return ConnectionHelper.makeRequest(() -> { + HttpPost post = new HttpPost(Config.getProperty(Config.Constants.MATRIX_HOME_SERVER) + + String.format(Constants.API_ADD_FILTER, this.userId) + "?access_token=" + this.accessToken); + MatrixFilterRequest matrixFilterRequest = new MatrixFilterRequest(); + + String[] excludeAll = new String[]{"*"}; + String[] rooms = getRooms().toArray(new String[0]); + MatrixEventFilter accountData = new MatrixEventFilter(); + //don't need account data + accountData.setNotTypes(excludeAll); + MatrixEventFilter presenceData = new MatrixEventFilter(); + // no presence data either + presenceData.setNotTypes(excludeAll); + MatrixRoomFilter roomFilter = new MatrixRoomFilter(); + MatrixRoomEventFilter accountDataRoom = new MatrixRoomEventFilter(); + //no account data for the room events + accountDataRoom.setNotTypes(excludeAll); + MatrixStateFilter stateFilter = new MatrixStateFilter(); + stateFilter.setRooms(rooms); + //only message events for the room + stateFilter.setTypes(new String[] {"m.room.message"}); + //ignore events from the bot user itself + stateFilter.setNotSenders(new String[] {this.userId}); + roomFilter.setAccountData(accountDataRoom); + roomFilter.setRooms(rooms); + roomFilter.setState(stateFilter); + roomFilter.setTimeline(new MatrixRoomEventFilter()); + + matrixFilterRequest.setRoom(roomFilter); + matrixFilterRequest.setPresence(presenceData); + matrixFilterRequest.setAccountData(accountData); + matrixFilterRequest.setEventFields(new String[]{"content", "sender", "room_id", "event_id"}); + + post.setEntity(new StringEntity(new Gson().toJson(matrixFilterRequest), ContentType.APPLICATION_JSON)); + return post; + }, new MatrixResponseHandler() { + @Override + public String onSuccess(String response) throws Exception { + MatrixFilterResponse filterResponse = + new Gson().fromJson(response, MatrixFilterResponse.class); + return filterResponse.getFilterId(); + } + }); + } + + private MatrixSyncResponse sync(String nextBatch) { + return ConnectionHelper.makeRequest(() -> new HttpGet( + Config.getProperty(Config.Constants.MATRIX_HOME_SERVER) + + Constants.API_SYNC + + "?access_token=" + MatrixChatClient.this.accessToken + + "&timeout=" + POLL_TIMEOUT + + (nextBatch != null && !nextBatch.isEmpty() ? "&since=" + nextBatch : "") + + "&filter=" + MatrixChatClient.this.messageFilterId + + "&set_presence=online"), new MatrixResponseHandler() { + @Override + public MatrixSyncResponse onSuccess(String response) throws Exception { + return new Gson().fromJson(response, MatrixSyncResponse.class); + } + }); + } + + private boolean joinRoom(String room) { + Boolean joinedRoom = ConnectionHelper.makeRequest(() -> new HttpPost( + Config.getProperty(Config.Constants.MATRIX_HOME_SERVER) + + Constants.API_JOIN_ROOM + + URLEncoder.encode(room, "UTF-8") + + "/join?access_token=" + MatrixChatClient.this.accessToken), new MatrixResponseHandler() { + @Override + public Boolean onSuccess(String response) throws Exception { + MatrixJoinRoomResponse joinRoomResponse = + new Gson().fromJson(response, MatrixJoinRoomResponse.class); + return !joinRoomResponse.getRoomId().isEmpty(); + } + }); + return joinedRoom != null && joinedRoom; + } + + private MatrixLoginResponse getAccessToken() { + return ConnectionHelper.makeRequest(() -> { + HttpPost post = new HttpPost(Config.getProperty(Config.Constants.MATRIX_HOME_SERVER) + Constants.API_LOGIN); + MatrixLoginRequest matrixLoginRequest = new MatrixLoginRequest(); + matrixLoginRequest.setUser(Config.getProperty(Config.Constants.MATRIX_USERNAME)); + matrixLoginRequest.setPassword(Config.getProperty(Config.Constants.MATRIX_PASSWORD)); + post.setEntity(new StringEntity(new Gson().toJson(matrixLoginRequest), ContentType.APPLICATION_JSON)); + return post; + }, new MatrixResponseHandler() { + @Override + public MatrixLoginResponse onSuccess(String response) throws Exception { + return new Gson().fromJson(response, MatrixLoginResponse.class); + } + }); + } + + private boolean isPasswordLoginSupported() { + Boolean isPasswordLoginSupported = ConnectionHelper.makeRequest(() -> + new HttpGet(Config.getProperty(Config.Constants.MATRIX_HOME_SERVER) + Constants.API_LOGIN), new MatrixResponseHandler() { + @Override + public Boolean onSuccess(String response) throws Exception { + MatrixLoginInformation matrixLoginType = + new Gson().fromJson(response, MatrixLoginInformation.class); + for (MatrixLoginFlow flow : matrixLoginType.getFlows()) { + if (flow.getType().equals("m.login.password")) { + return true; + } + } + return false; + } + }); + return isPasswordLoginSupported != null && isPasswordLoginSupported; + } + + private static abstract class MatrixResponseHandler implements ConnectionHelper.ResponseHandler { + + @Override + public T onFailure(int statusCode, String reason) { + LOGGER.error("Error from matrix response, code=" + statusCode + ", reason=" + reason); + if (statusCode == 429) { + LOGGER.error("Rate limited from matrix"); + } + return null; + } + + @Override + public T onException(Exception e) { + LOGGER.error("Error trying to make matrix request", e); + return null; + } + } + + protected static class Constants { + private static final String API_BASE = "/_matrix/client/r0"; + private static final String API_LOGIN = API_BASE + "/login"; + private static final String API_JOIN_ROOM = API_BASE + "/rooms/"; + private static final String API_SYNC = API_BASE + "/sync"; + /** 1 == user_id */ + private static final String API_ADD_FILTER = API_BASE + "/user/%s/filter"; + /** 1 == room id*/ + private static final String API_SEND_MESSAGE = API_BASE + "/rooms/%s/send/m.room.message"; + private static final String API_PREVIEW_URL = "/_matrix/media/r0/preview_url"; + } + + public interface MatrixMessageListener { + void process(String roomId, String sender, String content); + } + + private final List listeners = new ArrayList<>(); + private final String messageFilterId; + private final String accessToken; + private final String userId; + private static final int POLL_TIMEOUT = 60000; + private static final Logger LOGGER = LogManager.getLogger(); +} diff --git a/src/main/java/com/botdarr/clients/matrix/MatrixResponse.java b/src/main/java/com/botdarr/clients/matrix/MatrixResponse.java new file mode 100644 index 0000000..42d1d78 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/MatrixResponse.java @@ -0,0 +1,30 @@ +package com.botdarr.clients.matrix; + +import com.botdarr.clients.ChatClientResponse; + +import java.util.ArrayList; +import java.util.List; + +public class MatrixResponse implements ChatClientResponse { + public void addContent(String content) { + this.content.append(content + "
"); + } + + public void addImage(String imageUrl) { + if (imageUrl == null || imageUrl.isEmpty()) { + return; + } + this.imageUrls.add(imageUrl); + } + + public String getContent() { + return this.content.toString(); + } + + public List getImageUrls() { + return imageUrls; + } + + private List imageUrls = new ArrayList<>(); + private StringBuilder content = new StringBuilder(); +} diff --git a/src/main/java/com/botdarr/clients/matrix/MatrixResponseBuilder.java b/src/main/java/com/botdarr/clients/matrix/MatrixResponseBuilder.java new file mode 100644 index 0000000..0f27f35 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/MatrixResponseBuilder.java @@ -0,0 +1,271 @@ +package com.botdarr.clients.matrix; + +import com.botdarr.Config; +import com.botdarr.api.lidarr.LidarrArtist; +import com.botdarr.api.lidarr.LidarrQueueRecord; +import com.botdarr.api.lidarr.LidarrQueueStatusMessage; +import com.botdarr.api.radarr.*; +import com.botdarr.api.sonarr.*; +import com.botdarr.clients.ChatClientResponseBuilder; +import com.botdarr.commands.*; +import com.botdarr.utilities.ListUtils; +import org.apache.logging.log4j.util.Strings; + +import java.util.List; + +import static com.botdarr.api.lidarr.LidarrApi.ADD_ARTIST_COMMAND_FIELD_PREFIX; +import static com.botdarr.api.radarr.RadarrApi.ADD_MOVIE_COMMAND_FIELD_PREFIX; +import static com.botdarr.api.sonarr.SonarrApi.ADD_SHOW_COMMAND_FIELD_PREFIX; + +public class MatrixResponseBuilder implements ChatClientResponseBuilder { + @Override + public MatrixResponse getHelpResponse() { + try { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("Version: " + ChatClientResponseBuilder.getVersion() + ""); + boolean radarrEnabled = Config.isRadarrEnabled(); + boolean sonarrEnabled = Config.isSonarrEnabled(); + boolean lidarrEnabled = Config.isLidarrEnabled(); + if (radarrEnabled) { + matrixResponse.addContent("" + RadarrCommands.getHelpMovieCommandStr() + " - Shows all the commands for movies"); + } + + if (sonarrEnabled) { + matrixResponse.addContent("" + SonarrCommands.getHelpShowCommandStr() + " - Shows all the commands for shows"); + } + + if (lidarrEnabled) { + matrixResponse.addContent("" + LidarrCommands.getHelpCommandStr() + " - Shows all the commands for music"); + } + + if (!radarrEnabled && !sonarrEnabled && !lidarrEnabled) { + matrixResponse.addContent("No radarr or sonarr or lidarr commands configured, check your properties file and logs"); + } + return matrixResponse; + } catch (Exception e) { + throw new RuntimeException("Error getting botdarr version", e); + } + } + + @Override + public MatrixResponse getMusicHelpResponse(List lidarCommands) { + return getListOfCommands(lidarCommands); + } + + @Override + public MatrixResponse getMoviesHelpResponse(List radarrCommands) { + return getListOfCommands(radarrCommands); + } + + @Override + public MatrixResponse getShowsHelpResponse(List sonarrCommands) { + return getListOfCommands(sonarrCommands); + } + + @Override + public MatrixResponse getShowResponse(SonarrShow show) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("Title - " + show.getTitle()); + matrixResponse.addContent("TvdbId - " + String.valueOf(show.getTvdbId())); + matrixResponse.addContent("" + ADD_SHOW_COMMAND_FIELD_PREFIX + " - " + SonarrCommands.getAddShowCommandStr(show.getTitle(), show.getTvdbId())); + matrixResponse.addImage(show.getRemotePoster()); + return matrixResponse; + } + + @Override + public MatrixResponse getArtistResponse(LidarrArtist lidarrArtist) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("Artist Name - " + lidarrArtist.getArtistName()); + matrixResponse.addContent("Id - " + String.valueOf(lidarrArtist.getForeignArtistId())); + matrixResponse.addContent("" + ADD_ARTIST_COMMAND_FIELD_PREFIX + " - " + LidarrCommands.getAddArtistCommandStr(lidarrArtist.getArtistName(), lidarrArtist.getForeignArtistId())); + return matrixResponse; + } + + @Override + public MatrixResponse getMovieResponse(RadarrMovie radarrMovie) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("Movie Title - " + radarrMovie.getTitle()); + matrixResponse.addContent("TmdbId - " + radarrMovie.getTmdbId()); + matrixResponse.addContent("" + ADD_MOVIE_COMMAND_FIELD_PREFIX + " - " + RadarrCommands.getAddMovieCommandStr(radarrMovie.getTitle(), radarrMovie.getTmdbId())); + return matrixResponse; + } + + @Override + public MatrixResponse getShowDownloadResponses(SonarrQueue sonarrShow) { + MatrixResponse matrixResponse = new MatrixResponse(); + SonarQueueEpisode episode = sonarrShow.getEpisode(); + matrixResponse.addContent("Season/Episode - " + "S" + episode.getSeasonNumber() + "E" + episode.getEpisodeNumber()); + matrixResponse.addContent("Quality - " + sonarrShow.getQuality().getQuality().getName()); + matrixResponse.addContent("Status - " + sonarrShow.getStatus()); + matrixResponse.addContent("Time Left - " + (sonarrShow.getTimeleft() == null ? "unknown" : sonarrShow.getTimeleft()) + ""); + String overview = episode.getTitle() + ": " + episode.getOverview(); + if (overview.length() > 1024) { + overview = overview.substring(0, 1024); + } + matrixResponse.addContent("Overview - " + overview); + if (sonarrShow.getStatusMessages() != null) { + for (SonarrQueueStatusMessages statusMessage : sonarrShow.getStatusMessages()) { + for (String message : statusMessage.getMessages()) { + matrixResponse.addContent("Download message - " + message); + } + } + } + return matrixResponse; + } + + @Override + public MatrixResponse getMovieDownloadResponses(RadarrQueue radarrQueue) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("Title - " + radarrQueue.getRadarrQueueMovie().getTitle()); + matrixResponse.addContent("Quality - " + radarrQueue.getQuality().getQuality().getName()); + matrixResponse.addContent("Status - " + radarrQueue.getStatus()); + matrixResponse.addContent("Time Left - " + (radarrQueue.getTimeleft() == null ? "unknown" : radarrQueue.getTimeleft()) + ""); + if (radarrQueue.getStatusMessages() != null) { + for (RadarrQueueStatusMessages statusMessage : radarrQueue.getStatusMessages()) { + for (String message : statusMessage.getMessages()) { + matrixResponse.addContent("Download message - " + message); + } + } + } + return matrixResponse; + } + + @Override + public MatrixResponse getArtistDownloadResponses(LidarrQueueRecord lidarrQueue) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("Title - " + lidarrQueue.getTitle()); + matrixResponse.addContent("Time Left - " + (lidarrQueue.getTimeleft() == null ? "unknown" : lidarrQueue.getTimeleft()) + "
"); + matrixResponse.addContent("Status - " + lidarrQueue.getStatus()); + if (lidarrQueue.getStatusMessages() != null) { + for (LidarrQueueStatusMessage statusMessage : ListUtils.subList(lidarrQueue.getStatusMessages(), 5)) { + for (String message : statusMessage.getMessages()) { + matrixResponse.addContent("Download message - " + message); + } + } + } + return matrixResponse; + } + + @Override + public MatrixResponse createErrorMessage(String message) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("" + message + ""); + return matrixResponse; + } + + @Override + public MatrixResponse createInfoMessage(String message) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("" + message + ""); + return matrixResponse; + } + + @Override + public MatrixResponse createSuccessMessage(String message) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("" + message + ""); + return matrixResponse; + } + + @Override + public MatrixResponse getShowProfile(SonarrProfile sonarrProfile) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("Profile"); + matrixResponse.addContent("Name - " + sonarrProfile.getName()); + matrixResponse.addContent("Cutoff - " + sonarrProfile.getCutoff().getName()); + 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()); + } + } + return matrixResponse; + } + + @Override + public MatrixResponse getMovieProfile(RadarrProfile radarrProfile) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("Profile"); + matrixResponse.addContent("Name - " + radarrProfile.getName()); + matrixResponse.addContent("Cutoff - " + radarrProfile.getCutoff().getName()); + for (int k = 0; k < radarrProfile.getItems().size(); k++) { + RadarrProfileQualityItem sonarrProfileQualityItem = radarrProfile.getItems().get(k); + if (sonarrProfileQualityItem.isAllowed()) { + matrixResponse.addContent("Quality - Name: " + sonarrProfileQualityItem.getQuality().getName() + ", Resolution: " + sonarrProfileQualityItem.getQuality().getResolution()); + } + } + return matrixResponse; + } + + @Override + public MatrixResponse getNewOrExistingShow(SonarrShow sonarrShow, SonarrShow existingShow, boolean findNew) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("Title - " + sonarrShow.getTitle()); + matrixResponse.addContent("TvdbId - " + sonarrShow.getTvdbId()); + if (findNew) { + matrixResponse.addContent("" + ADD_SHOW_COMMAND_FIELD_PREFIX + " - " + SonarrCommands.getAddShowCommandStr(sonarrShow.getTitle(), sonarrShow.getTvdbId())); + } else { + matrixResponse.addContent("Id - " + existingShow.getId()); + if (existingShow.getSeasons() != null) { + matrixResponse.addContent("Number of seasons - " + existingShow.getSeasons().size()); + for (SonarrSeason sonarrSeason : existingShow.getSeasons()) { + matrixResponse.addContent( + "Season#" + sonarrSeason.getSeasonNumber() + + ",Available Epsiodes=" + sonarrSeason.getStatistics().getEpisodeCount() + + ",Total Epsiodes=" + sonarrSeason.getStatistics().getTotalEpisodeCount()); + } + } + } + matrixResponse.addImage(sonarrShow.getRemotePoster()); + return matrixResponse; + } + + @Override + public MatrixResponse getNewOrExistingMovie(RadarrMovie lookupMovie, RadarrMovie existingMovie, boolean findNew) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("Title - " + lookupMovie.getTitle()); + matrixResponse.addContent("TmdbId - " + String.valueOf(lookupMovie.getTmdbId())); + if (findNew) { + matrixResponse.addContent("" + ADD_MOVIE_COMMAND_FIELD_PREFIX + " - " + RadarrCommands.getAddMovieCommandStr(lookupMovie.getTitle(), lookupMovie.getTmdbId())); + } else { + matrixResponse.addContent("Id - " + existingMovie.getId()); + matrixResponse.addContent("Downloaded - " + String.valueOf(existingMovie.isDownloaded())); + matrixResponse.addContent("Has File - " + String.valueOf(existingMovie.isHasFile())); + } + matrixResponse.addImage(lookupMovie.getRemotePoster()); + return matrixResponse; + } + + @Override + public MatrixResponse getNewOrExistingArtist(LidarrArtist lookupArtist, LidarrArtist existingArtist, boolean findNew) { + MatrixResponse matrixResponse = new MatrixResponse(); + String artistDetail = " (" + lookupArtist.getDisambiguation() + ")"; + matrixResponse.addContent("Title - " + (lookupArtist.getArtistName() + (Strings.isEmpty(lookupArtist.getDisambiguation()) ? "" : artistDetail))); + if (findNew) { + matrixResponse.addContent("" + ADD_ARTIST_COMMAND_FIELD_PREFIX + " - " + LidarrCommands.getAddArtistCommandStr(lookupArtist.getArtistName(), lookupArtist.getForeignArtistId())); + } + matrixResponse.addImage(lookupArtist.getRemotePoster()); + return matrixResponse; + } + + @Override + public MatrixResponse getDiscoverableMovies(RadarrMovie radarrMovie) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("Title - " + radarrMovie.getTitle()); + matrixResponse.addContent("TmdbId - " + radarrMovie.getTmdbId()); + matrixResponse.addContent("" + ADD_MOVIE_COMMAND_FIELD_PREFIX + " - " + RadarrCommands.getAddMovieCommandStr(radarrMovie.getTitle(), radarrMovie.getTmdbId())); + if (radarrMovie.getRemotePoster() != null && !radarrMovie.getRemotePoster().isEmpty()) { + matrixResponse.addImage(radarrMovie.getRemotePoster()); + } + return matrixResponse; + } + + private MatrixResponse getListOfCommands(List commands) { + MatrixResponse matrixResponse = new MatrixResponse(); + matrixResponse.addContent("Commands"); + for (Command command : commands) { + matrixResponse.addContent("" + new CommandProcessor().getPrefix() + command.getCommandUsage() + "" + " - " + command.getDescription()); + } + return matrixResponse; + } +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/MatrixJoinRoomResponse.java b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixJoinRoomResponse.java new file mode 100644 index 0000000..33478b4 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixJoinRoomResponse.java @@ -0,0 +1,9 @@ +package com.botdarr.clients.matrix.transactions; + +public class MatrixJoinRoomResponse { + public String getRoomId() { + return room_id; + } + + private String room_id = ""; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginFlow.java b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginFlow.java new file mode 100644 index 0000000..4a8b301 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginFlow.java @@ -0,0 +1,9 @@ +package com.botdarr.clients.matrix.transactions; + +public class MatrixLoginFlow { + public String getType() { + return type; + } + + private String type; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginInformation.java b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginInformation.java new file mode 100644 index 0000000..344db8b --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginInformation.java @@ -0,0 +1,9 @@ +package com.botdarr.clients.matrix.transactions; + +public class MatrixLoginInformation { + public MatrixLoginFlow[] getFlows() { + return flows; + } + + private MatrixLoginFlow[] flows = new MatrixLoginFlow[]{}; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginRequest.java b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginRequest.java new file mode 100644 index 0000000..2ddc713 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginRequest.java @@ -0,0 +1,15 @@ +package com.botdarr.clients.matrix.transactions; + +public class MatrixLoginRequest { + public void setUser(String user) { + this.user = user; + } + + public void setPassword(String password) { + this.password = password; + } + + private String user; + private String password; + private String type = "m.login.password"; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginResponse.java b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginResponse.java new file mode 100644 index 0000000..45b82ef --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixLoginResponse.java @@ -0,0 +1,19 @@ +package com.botdarr.clients.matrix.transactions; + +public class MatrixLoginResponse { + public String getUserId() { + return user_id; + } + + public String getHomeServer() { + return home_server; + } + + public String getAccessToken() { + return access_token; + } + + private String user_id; + private String home_server; + private String access_token; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/MatrixPreviewUrlResponse.java b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixPreviewUrlResponse.java new file mode 100644 index 0000000..e599510 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixPreviewUrlResponse.java @@ -0,0 +1,18 @@ +package com.botdarr.clients.matrix.transactions; + +import com.google.gson.annotations.SerializedName; + +public class MatrixPreviewUrlResponse { + public Integer getSize() { + return size; + } + + public String getMxcUri() { + return mxcUri; + } + + @SerializedName("matrix:image:size") + private Integer size; + @SerializedName("og:image") + private String mxcUri; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/MatrixSendImageRequest.java b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixSendImageRequest.java new file mode 100644 index 0000000..6d7b086 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixSendImageRequest.java @@ -0,0 +1,11 @@ +package com.botdarr.clients.matrix.transactions; + +public class MatrixSendImageRequest { + public void setUrl(String url) { + this.url = url; + } + + private String msgtype = "m.image"; + private String url; + private String body = "image-text"; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/MatrixSendMessageRequest.java b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixSendMessageRequest.java new file mode 100644 index 0000000..7053f2c --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixSendMessageRequest.java @@ -0,0 +1,13 @@ +package com.botdarr.clients.matrix.transactions; + +public class MatrixSendMessageRequest { + public void setBody(String body) { + this.body = body; + this.formatted_body = body; + } + + private String msgtype = "m.text"; + private String format = "org.matrix.custom.html"; + private String formatted_body; + private String body; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/MatrixSendMessageResponse.java b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixSendMessageResponse.java new file mode 100644 index 0000000..0287747 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/MatrixSendMessageResponse.java @@ -0,0 +1,9 @@ +package com.botdarr.clients.matrix.transactions; + +public class MatrixSendMessageResponse { + public String getEventId() { + return event_id; + } + + private String event_id; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixEventFilter.java b/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixEventFilter.java new file mode 100644 index 0000000..fc58d58 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixEventFilter.java @@ -0,0 +1,14 @@ +package com.botdarr.clients.matrix.transactions.filter; + +public class MatrixEventFilter { + public void setTypes(String[] types) { + this.types = types; + } + + public void setNotTypes(String[] not_types) { + this.not_types = not_types; + } + + private String[] types; + private String[] not_types; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixFilterRequest.java b/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixFilterRequest.java new file mode 100644 index 0000000..621130c --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixFilterRequest.java @@ -0,0 +1,24 @@ +package com.botdarr.clients.matrix.transactions.filter; + +public class MatrixFilterRequest { + public void setEventFields(String[] event_fields) { + this.event_fields = event_fields; + } + + public void setAccountData(MatrixEventFilter account_data) { + this.account_data = account_data; + } + + public void setPresence(MatrixEventFilter presence) { + this.presence = presence; + } + + public void setRoom(MatrixRoomFilter room) { + this.room = room; + } + + private String[] event_fields; + private MatrixEventFilter presence; + private MatrixEventFilter account_data; + private MatrixRoomFilter room; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixFilterResponse.java b/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixFilterResponse.java new file mode 100644 index 0000000..ec78578 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixFilterResponse.java @@ -0,0 +1,9 @@ +package com.botdarr.clients.matrix.transactions.filter; + +public class MatrixFilterResponse { + public String getFilterId() { + return filter_id; + } + + private String filter_id; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixRoomEventFilter.java b/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixRoomEventFilter.java new file mode 100644 index 0000000..067b625 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixRoomEventFilter.java @@ -0,0 +1,12 @@ +package com.botdarr.clients.matrix.transactions.filter; + +public class MatrixRoomEventFilter { + public void setNotTypes(String[] not_types) { + this.not_types = not_types; + } + + private String[] not_types; + //this setting makes it so we never receive historical events from the server + //be careful reusing this type outside of MatrixRoomFilter + private int limit = 0; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixRoomFilter.java b/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixRoomFilter.java new file mode 100644 index 0000000..77c7c14 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixRoomFilter.java @@ -0,0 +1,24 @@ +package com.botdarr.clients.matrix.transactions.filter; + +public class MatrixRoomFilter { + public void setRooms(String[] rooms) { + this.rooms = rooms; + } + + public void setState(MatrixStateFilter state) { + this.state = state; + } + + public void setAccountData(MatrixRoomEventFilter account_data) { + this.account_data = account_data; + } + + public void setTimeline(MatrixRoomEventFilter timeline) { + this.timeline = timeline; + } + + private String[] rooms; + private MatrixStateFilter state; + private MatrixRoomEventFilter account_data; + private MatrixRoomEventFilter timeline; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixStateFilter.java b/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixStateFilter.java new file mode 100644 index 0000000..caaa566 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/filter/MatrixStateFilter.java @@ -0,0 +1,19 @@ +package com.botdarr.clients.matrix.transactions.filter; + +public class MatrixStateFilter { + public void setTypes(String[] types) { + this.types = types; + } + + public void setRooms(String[] rooms) { + this.rooms = rooms; + } + + public void setNotSenders(String[] not_senders) { + this.not_senders = not_senders; + } + + private String[] types; + private String[] rooms; + private String[] not_senders; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncEvent.java b/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncEvent.java new file mode 100644 index 0000000..ef221d1 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncEvent.java @@ -0,0 +1,18 @@ +package com.botdarr.clients.matrix.transactions.sync; + +public class MatrixSyncEvent { + public String getSender() { + return sender; + } + + public String getEvent_id() { + return event_id; + } + + public MatrixSyncEventContent getContent() { + return content; + } + private String sender; + private String event_id; + private MatrixSyncEventContent content; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncEventContent.java b/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncEventContent.java new file mode 100644 index 0000000..592ff6f --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncEventContent.java @@ -0,0 +1,14 @@ +package com.botdarr.clients.matrix.transactions.sync; + +public class MatrixSyncEventContent { + public String getMsgtype() { + return msgtype; + } + + public String getBody() { + return body; + } + + private String msgtype; + private String body; +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncJoinRoom.java b/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncJoinRoom.java new file mode 100644 index 0000000..4878727 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncJoinRoom.java @@ -0,0 +1,9 @@ +package com.botdarr.clients.matrix.transactions.sync; + +public class MatrixSyncJoinRoom { + public MatrixSyncTimeline getTimeline() { + return timeline; + } + + private MatrixSyncTimeline timeline = new MatrixSyncTimeline(); +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncResponse.java b/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncResponse.java new file mode 100644 index 0000000..c0f6d3d --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncResponse.java @@ -0,0 +1,14 @@ +package com.botdarr.clients.matrix.transactions.sync; + +public class MatrixSyncResponse { + public String getNextBatch() { + return next_batch; + } + + public MatrixSyncRooms getRooms() { + return rooms; + } + + private String next_batch; + private MatrixSyncRooms rooms = new MatrixSyncRooms(); +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncRooms.java b/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncRooms.java new file mode 100644 index 0000000..ee5e9f6 --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncRooms.java @@ -0,0 +1,12 @@ +package com.botdarr.clients.matrix.transactions.sync; + +import java.util.HashMap; +import java.util.Map; + +public class MatrixSyncRooms { + public Map getJoin() { + return join; + } + + private Map join = new HashMap<>(); +} diff --git a/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncTimeline.java b/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncTimeline.java new file mode 100644 index 0000000..c895dcb --- /dev/null +++ b/src/main/java/com/botdarr/clients/matrix/transactions/sync/MatrixSyncTimeline.java @@ -0,0 +1,9 @@ +package com.botdarr.clients.matrix.transactions.sync; + +public class MatrixSyncTimeline { + public MatrixSyncEvent[] getEvents() { + return events; + } + + private MatrixSyncEvent[] events = new MatrixSyncEvent[]{}; +} diff --git a/src/main/java/com/botdarr/clients/slack/SlackResponseBuilder.java b/src/main/java/com/botdarr/clients/slack/SlackResponseBuilder.java index 4b65fad..d49de46 100644 --- a/src/main/java/com/botdarr/clients/slack/SlackResponseBuilder.java +++ b/src/main/java/com/botdarr/clients/slack/SlackResponseBuilder.java @@ -15,13 +15,11 @@ import com.github.seratch.jslack.api.model.block.SectionBlock; import com.github.seratch.jslack.api.model.block.composition.MarkdownTextObject; import com.github.seratch.jslack.api.model.block.composition.PlainTextObject; -import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.util.Strings; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Base64; import java.util.List; import static com.botdarr.api.lidarr.LidarrApi.ADD_ARTIST_COMMAND_FIELD_PREFIX; @@ -171,9 +169,6 @@ public SlackResponse getShowDownloadResponses(SonarrQueue showQueue) { .build()); } } - slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("Cancel download command - " + "show cancel download " + showQueue.getId()).build()) - .build()); return slackResponse; } @@ -205,9 +200,6 @@ public SlackResponse getMovieDownloadResponses(RadarrQueue radarrQueue) { .build()); } } - slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("Cancel download command - " + "movie cancel download " + radarrQueue.getId()).build()) - .build()); return slackResponse; } @@ -266,49 +258,6 @@ public SlackResponse createSuccessMessage(String message) { return slackResponse; } - @Override - public SlackResponse getTorrentResponses(RadarrTorrent radarrTorrent, String movieTitle) { - SlackResponse slackResponse = new SlackResponse(); - slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("*Title* - " + radarrTorrent.getTitle()).build()) - .build()); - slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("Torrent - " + radarrTorrent.getGuid()).build()) - .build()); - slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("Quality - " + radarrTorrent.getQuality().getQuality().getName()).build()) - .build()); - slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("Indexer - " + radarrTorrent.getIndexer()).build()) - .build()); - slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("Seeders - " + radarrTorrent.getSeeders()).build()) - .build()); - slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("Leechers - " + radarrTorrent.getLeechers()).build()) - .build()); - slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("Size - " + FileUtils.byteCountToDisplaySize(radarrTorrent.getSize())).build()) - .build()); - - String[] rejections = radarrTorrent.getRejections(); - if (rejections != null) { - List contextBlockElements = new ArrayList<>(); - for (String rejection : rejections) { - contextBlockElements.add(PlainTextObject.builder().text("Rejection Reason - " + rejection).build()); - } - slackResponse.addBlock(ContextBlock.builder() - .elements(contextBlockElements) - .build()); - } - String key = radarrTorrent.getGuid() + ":title=" + movieTitle; - byte[] encodedBytes = Base64.getEncoder().encode(key.getBytes()); - slackResponse.addBlock(SectionBlock.builder() - .text(MarkdownTextObject.builder().text("Download hash command - " + "movie hash download " + new String(encodedBytes)).build()) - .build()); - return slackResponse; - } - @Override public SlackResponse getShowProfile(SonarrProfile sonarrProfile) { SlackResponse slackResponse = new SlackResponse(); diff --git a/src/main/java/com/botdarr/clients/telegram/TelegramResponseBuilder.java b/src/main/java/com/botdarr/clients/telegram/TelegramResponseBuilder.java index ff7d86f..710ce00 100644 --- a/src/main/java/com/botdarr/clients/telegram/TelegramResponseBuilder.java +++ b/src/main/java/com/botdarr/clients/telegram/TelegramResponseBuilder.java @@ -10,7 +10,6 @@ import com.botdarr.commands.*; import com.botdarr.utilities.ListUtils; import j2html.tags.DomContent; -import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.util.Strings; import static com.botdarr.api.lidarr.LidarrApi.ADD_ARTIST_COMMAND_FIELD_PREFIX; @@ -21,7 +20,6 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.Base64; import java.util.List; public class TelegramResponseBuilder implements ChatClientResponseBuilder { @@ -114,7 +112,6 @@ public TelegramResponse getShowDownloadResponses(SonarrQueue showQueue) { } domContents.add(code(statusMessageBuilder.toString())); } - domContents.add(b("Cancel download command - " + "show cancel download " + showQueue.getId())); return new TelegramResponse(domContents); } @@ -177,30 +174,6 @@ public TelegramResponse createSuccessMessage(String message) { return new TelegramResponse(domContents); } - @Override - public TelegramResponse getTorrentResponses(RadarrTorrent radarrTorrent, String movieTitle) { - List domContents = new ArrayList<>(); - domContents.add(b("Title - " + radarrTorrent.getTitle())); - domContents.add(text("Torrent - " + radarrTorrent.getGuid())); - domContents.add(text("Quality - " + radarrTorrent.getQuality().getQuality().getName())); - domContents.add(text("Indexer - " + radarrTorrent.getIndexer())); - domContents.add(text("Seeders - " + radarrTorrent.getSeeders())); - domContents.add(text("Leechers - " + radarrTorrent.getLeechers())); - domContents.add(text("Size - " + FileUtils.byteCountToDisplaySize(radarrTorrent.getSize()))); - String[] rejections = radarrTorrent.getRejections(); - if (rejections != null) { - StringBuilder rejectionReasons = new StringBuilder(); - for (String rejection : rejections) { - rejectionReasons.append("Rejection Reason - " + rejection + "\n"); - } - domContents.add(code(rejectionReasons.toString())); - } - String key = radarrTorrent.getGuid() + ":title=" + movieTitle; - byte[] encodedBytes = Base64.getEncoder().encode(key.getBytes()); - domContents.add(u(b("Download hash command - " + "movie hash download " + new String(encodedBytes)))); - return new TelegramResponse(domContents); - } - @Override public TelegramResponse getShowProfile(SonarrProfile sonarrProfile) { List domContents = new ArrayList<>(); diff --git a/src/main/java/com/botdarr/commands/CommandProcessor.java b/src/main/java/com/botdarr/commands/CommandProcessor.java index ecc695c..75cd3c2 100644 --- a/src/main/java/com/botdarr/commands/CommandProcessor.java +++ b/src/main/java/com/botdarr/commands/CommandProcessor.java @@ -52,7 +52,7 @@ public String getPrefix() { if (!Strings.isEmpty(configuredPrefix)) { return configuredPrefix; } - return "/"; + return "!"; } private static final Logger LOGGER = LogManager.getLogger(CommandProcessor.class); diff --git a/src/main/java/com/botdarr/commands/RadarrCommands.java b/src/main/java/com/botdarr/commands/RadarrCommands.java index 622563b..13c5f25 100644 --- a/src/main/java/com/botdarr/commands/RadarrCommands.java +++ b/src/main/java/com/botdarr/commands/RadarrCommands.java @@ -70,29 +70,6 @@ public CommandResponse execute(String searchText) return new CommandResponse(radarrApi.lookup(searchText, false)); } }); - add(new BaseCommand("movie find downloads", "movie find downloads ", "Lists all the available (not rejected) torrents for a movie (i.e., movie find downloads TITLE OF MOVIE). " + - "You can get the title by using \"movie find existing\". This can be a SLOW operation depending on the number of indexers configured" + - " in your Radarr settings and particularly how fast each indexer is. Also these are torrents that have not been marked as rejected based" + - " on whatever quality/profile settings are configured in Radarr") { - @Override - public CommandResponse execute(String searchText) { - validateMovieTitle(searchText); - return new CommandResponse(radarrApi.lookupTorrents(searchText, false)); - } - }); - add(new BaseCommand("movie find all downloads", "movie find all downloads ","List all the available torrents for a movie whether they are rejected by radarr or not") { - @Override - public CommandResponse execute(String searchText) { - validateMovieTitle(searchText); - return new CommandResponse(radarrApi.lookupTorrents(searchText, true)); - } - }); - add(new BaseCommand("movie hash download", "movie hash download ", "Force downloads a movie using a hash string, you can only get from the command 'movie find all downloads'") { - @Override - public CommandResponse execute(String command) { - return new CommandResponse(radarrApi.forceDownload(command)); - } - }); add(new BaseCommand("movie downloads", "Shows all the active movies downloading in radarr") { @Override public boolean hasArguments() { diff --git a/src/main/java/com/botdarr/connections/ConnectionHelper.java b/src/main/java/com/botdarr/connections/ConnectionHelper.java index d7cea05..38bdd8d 100644 --- a/src/main/java/com/botdarr/connections/ConnectionHelper.java +++ b/src/main/java/com/botdarr/connections/ConnectionHelper.java @@ -5,12 +5,8 @@ import com.botdarr.clients.ChatClientResponse; import com.botdarr.clients.ChatClientResponseBuilder; import com.google.gson.Gson; -import com.sun.jndi.toolkit.url.Uri; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpDelete; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.utils.URIBuilder; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.*; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; @@ -21,85 +17,62 @@ import java.io.IOException; import java.util.Arrays; -import java.util.Collections; import java.util.List; public class ConnectionHelper { - public static List makeGetRequest(Api api, String path, ResponseHandler responseHandler) { + public static T makeGetRequest(Api api, String path, ResponseHandler responseHandler) { return makeGetRequest(api, path, "", responseHandler); } - public static List makePostRequest(Api api, String path, K params, ResponseHandler responseHandler) { - try (CloseableHttpClient client = HttpClientBuilder.create().build()) { - HttpPost post = new HttpPost(api.getApiUrl(path) + params); - post.setHeader("X-Api-Key", Config.getProperty(api.getApiToken())); - post.setEntity(new StringEntity(new Gson().toJson(params), ContentType.APPLICATION_JSON)); - try (CloseableHttpResponse response = client.execute(post)) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode == 200) { - try { - return responseHandler.onSuccess(EntityUtils.toString(response.getEntity())); - } catch (Exception e) { - LOGGER.error("Error trying to make post request", e); - return responseHandler.onException(e); - } - } else { - return responseHandler.onFailure(statusCode, response.getStatusLine().getReasonPhrase()); - } + public static T makeGetRequest(Api api, String path, String params, 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; } - } catch (IOException e) { - LOGGER.error("Error trying to make connection during post request", e); - return responseHandler.onException(e); - } - } - public static List makeGetRequest(Api api, String path, String params, ResponseHandler responseHandler) { - try (CloseableHttpClient client = HttpClientBuilder.create().build()) { - HttpGet get = new HttpGet(api.getApiUrl(path) + params); - get.setHeader("X-Api-Key", Config.getProperty(api.getApiToken())); - try (CloseableHttpResponse response = client.execute(get)) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode == 200) { - try { - return responseHandler.onSuccess(EntityUtils.toString(response.getEntity())); - } catch (Exception e) { - LOGGER.error("Error trying to make get request", e); - return responseHandler.onException(e); - } - } else { - return responseHandler.onFailure(statusCode, response.getStatusLine().getReasonPhrase()); - } + @Override + public boolean turnOnTimeouts() { + // all api requests should use timeouts + return true; } - } catch (IOException e) { - LOGGER.error("Error trying to make connection during get request", e); - return responseHandler.onException(e); - } + }, responseHandler); } - public static List makeDeleteRequest(Api api, String path, String params, ResponseHandler responseHandler) { - try (CloseableHttpClient client = HttpClientBuilder.create().build()) { - HttpDelete delete = new HttpDelete(api.getApiUrl(path) + params); - delete.setHeader("X-Api-Key", Config.getProperty(api.getApiToken())); - try (CloseableHttpResponse response = client.execute(delete)) { + public static T makeRequest(RequestHandler requestHandler, ResponseHandler responseHandler) { + RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); + if (requestHandler.turnOnTimeouts()) { + int timeout = 5000; + requestConfigBuilder.setConnectTimeout(timeout); + requestConfigBuilder.setSocketTimeout(timeout); + requestConfigBuilder.setConnectionRequestTimeout(timeout); + } + try (CloseableHttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfigBuilder.build()).build()) { + try (CloseableHttpResponse response = client.execute(requestHandler.buildRequest())) { int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == 200) { try { return responseHandler.onSuccess(EntityUtils.toString(response.getEntity())); } catch (Exception e) { - LOGGER.error("Error trying to make delete request", e); + LOGGER.error("Error trying to process response", e); return responseHandler.onException(e); } } else { return responseHandler.onFailure(statusCode, response.getStatusLine().getReasonPhrase()); } + } catch (Exception e) { + LOGGER.error("Error trying to execute connection during post request", e); + return responseHandler.onException(e); } } catch (IOException e) { - LOGGER.error("Error trying to make connection during delete request", e); + LOGGER.error("Error trying to make connection during post request", e); return responseHandler.onException(e); } } - public static abstract class SimpleMessageEmbedResponseHandler implements ResponseHandler { + public static abstract class SimpleMessageEmbedResponseHandler implements ResponseHandler> { public SimpleMessageEmbedResponseHandler(ChatClientResponseBuilder chatClientResponseBuilder) { this.chatClientResponseBuilder = chatClientResponseBuilder; } @@ -116,26 +89,32 @@ public List onException(Exception e) { private ChatClientResponseBuilder chatClientResponseBuilder; } - //TODO: add ability to return any object (instead of just a list) public static abstract class SimpleEntityResponseHandler implements ResponseHandler { @Override - public List onFailure(int statusCode, String reason) { - return Collections.emptyList(); + public T onFailure(int statusCode, String reason) { + return null; } @Override - public List onException(Exception e) { - return Collections.emptyList(); + public T onException(Exception e) { + return null; + } + } + + public interface RequestHandler { + HttpRequestBase buildRequest() throws Exception; + default boolean turnOnTimeouts() { + return false; } } - public static interface ResponseHandler { - List onSuccess(String response) throws Exception; + public interface ResponseHandler { + T onSuccess(String response) throws Exception; - List onFailure(int statusCode, String reason); + T onFailure(int statusCode, String reason); - List onException(Exception e); + T onException(Exception e); } private static final Logger LOGGER = LogManager.getLogger(); diff --git a/src/main/java/com/botdarr/scheduling/Scheduler.java b/src/main/java/com/botdarr/scheduling/Scheduler.java index 6ea445a..236710c 100644 --- a/src/main/java/com/botdarr/scheduling/Scheduler.java +++ b/src/main/java/com/botdarr/scheduling/Scheduler.java @@ -6,9 +6,7 @@ import org.apache.logging.log4j.Logger; import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; public class Scheduler { public static Scheduler getScheduler() { @@ -33,7 +31,7 @@ public void initApiNotifications(List apis, ChatClient chatClient) { } catch (Throwable e) { LOGGER.error("Error during api notification", e); } - }, 0, 1, TimeUnit.HOURS); + }, 0, 5, TimeUnit.MINUTES); } } @@ -57,8 +55,16 @@ public void initApiCaching(List apis) { } } + public void executeCommand(Callable callable) { + if (commandThreadPool == null) { + commandThreadPool = Executors.newFixedThreadPool(10); + } + commandThreadPool.submit(callable); + } + private ScheduledFuture notificationFuture; private ScheduledFuture cacheFuture; + private ExecutorService commandThreadPool; private static volatile Scheduler instance; private static final Logger LOGGER = LogManager.getLogger(); } diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index 417d7ca..8691a33 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -89,6 +89,18 @@ + + logs/matrix.log + logs/%d{yyyy-MM-dd-hh-mm}.log.zip + + %d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n + + + + + + + logs/telegram.log logs/%d{yyyy-MM-dd-hh-mm}.log.zip @@ -125,18 +137,22 @@ - + - + - + + + + + @@ -146,6 +162,7 @@ + \ No newline at end of file diff --git a/src/main/resources/version.txt b/src/main/resources/version.txt index c20c645..831446c 100644 --- a/src/main/resources/version.txt +++ b/src/main/resources/version.txt @@ -1 +1 @@ -5.0.6 +5.1.0 diff --git a/src/test/java/com/botdarr/ConfigTests.java b/src/test/java/com/botdarr/ConfigTests.java index f7c234e..25a4503 100644 --- a/src/test/java/com/botdarr/ConfigTests.java +++ b/src/test/java/com/botdarr/ConfigTests.java @@ -33,7 +33,7 @@ public void getConfig_invalidCommandPrefixConfigured() throws Exception { public void getConfig_noChatClientsConfigured() throws Exception { writeFakePropertiesFile(new Properties()); expectedException.expect(RuntimeException.class); - expectedException.expectMessage("You don't have Discord, Slack, Telegram configured, please configure one"); + expectedException.expectMessage("You don't have Discord, Matrix, Slack, Telegram configured, please configure one"); Config.getProperty(""); } diff --git a/src/test/java/com/botdarr/TestResponseBuilder.java b/src/test/java/com/botdarr/TestResponseBuilder.java index 5a234dd..95dab48 100644 --- a/src/test/java/com/botdarr/TestResponseBuilder.java +++ b/src/test/java/com/botdarr/TestResponseBuilder.java @@ -5,7 +5,6 @@ import com.botdarr.api.radarr.RadarrMovie; import com.botdarr.api.radarr.RadarrProfile; import com.botdarr.api.radarr.RadarrQueue; -import com.botdarr.api.radarr.RadarrTorrent; import com.botdarr.api.sonarr.SonarrProfile; import com.botdarr.api.sonarr.SonarrQueue; import com.botdarr.api.sonarr.SonarrShow; @@ -76,11 +75,6 @@ public TestResponse createSuccessMessage(String message) { return new TestResponse(message); } - @Override - public TestResponse getTorrentResponses(RadarrTorrent radarrTorrent, String movieTitle) { - return new TestResponse(); - } - @Override public TestResponse getShowProfile(SonarrProfile sonarrProfile) { return new TestResponse(); diff --git a/src/test/java/com/botdarr/api/LookupStrategyTests.java b/src/test/java/com/botdarr/api/LookupStrategyTests.java index 44b1f9a..f7b33cb 100644 --- a/src/test/java/com/botdarr/api/LookupStrategyTests.java +++ b/src/test/java/com/botdarr/api/LookupStrategyTests.java @@ -129,5 +129,10 @@ public List lookup(String searchTerm) throws Exception { public ChatClientResponse getNewOrExistingItem(Object lookupItem, Object existingItem, boolean findNew) { return null; } + + @Override + public boolean isPathBlacklisted(Object item) { + return false; + } } } diff --git a/src/test/java/com/botdarr/commands/CommandProcessorTests.java b/src/test/java/com/botdarr/commands/CommandProcessorTests.java index 153f914..ddb15a1 100644 --- a/src/test/java/com/botdarr/commands/CommandProcessorTests.java +++ b/src/test/java/com/botdarr/commands/CommandProcessorTests.java @@ -175,52 +175,6 @@ public void processMessage_validMovieTitleWithSpacesForFindExistingMovieCommand( validateValidCommand("!movie find existing Princess 5"); } - @Test - public void processMessage_invalidMovieTitleForFindDownloadsCommand() { - validateInvalidCommand("!movie find downloads", - "Error trying to parse command !movie find downloads, " + - "error=Movie title is missing"); - } - - @Test - public void processMessage_validMovieTitleForFindDownloadsCommand() { - new Expectations() {{ - radarrApi.lookupTorrents("princess5", false); times = 1; result = new TestResponse(); - }}; - validateValidCommand("!movie find downloads Princess5"); - } - - @Test - public void processMessage_validMovieTitleWithSpacesForFindDownloadsCommand() { - new Expectations() {{ - radarrApi.lookupTorrents("princess 5", false); times = 1; result = new TestResponse(); - }}; - validateValidCommand("!movie find downloads Princess 5"); - } - - @Test - public void processMessage_invalidMovieTitleForFindAllDownloadsCommand() { - validateInvalidCommand("!movie find all downloads", - "Error trying to parse command !movie find all downloads, " + - "error=Movie title is missing"); - } - - @Test - public void processMessage_validMovieTitleForFindAllDownloadsCommand() { - new Expectations() {{ - radarrApi.lookupTorrents("princess5", true); times = 1; result = new TestResponse(); - }}; - validateValidCommand("!movie find all downloads Princess5"); - } - - @Test - public void processMessage_validMovieTitleWithSpacesForFindAllDownloadsCommand() { - new Expectations() {{ - radarrApi.lookupTorrents("princess 5", true); times = 1; result = new TestResponse(); - }}; - validateValidCommand("!movie find all downloads Princess 5"); - } - @Test public void processMessage_missingShowTitleAndIdForAddCommand() { validateInvalidCommand("!show id add",