From 672567e118f799d2bb644edc2dd605de75ef8a34 Mon Sep 17 00:00:00 2001 From: Louis Vallat Date: Mon, 26 Oct 2020 21:01:06 +0100 Subject: [PATCH] Added support for searching subtitles language availability Signed-off-by: Louis Vallat --- build.gradle | 1 + .../java/xyz/vallat/louis/MovieQuoteBot.java | 8 +- .../xyz/vallat/louis/commands/Command.java | 2 +- .../xyz/vallat/louis/commands/ListLang.java | 74 +++++++++++++++++++ .../vallat/louis/commands/SearchTitle.java | 6 +- .../vallat/louis/subtitles/OpenSubtitles.java | 5 ++ 6 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 src/main/java/xyz/vallat/louis/commands/ListLang.java diff --git a/build.gradle b/build.gradle index 9a200c9..5c172fb 100644 --- a/build.gradle +++ b/build.gradle @@ -33,5 +33,6 @@ repositories { dependencies { implementation 'com.discord4j:discord4j-core:3.1.1' implementation 'com.github.wtekiela:opensub4j:0.3.0' + implementation 'org.apache.commons:commons-lang3:3.11' implementation 'ch.qos.logback:logback-classic:1.2.3' } \ No newline at end of file diff --git a/src/main/java/xyz/vallat/louis/MovieQuoteBot.java b/src/main/java/xyz/vallat/louis/MovieQuoteBot.java index 5b383fc..cd1c884 100644 --- a/src/main/java/xyz/vallat/louis/MovieQuoteBot.java +++ b/src/main/java/xyz/vallat/louis/MovieQuoteBot.java @@ -10,10 +10,7 @@ import discord4j.core.object.presence.Presence; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import reactor.core.publisher.Mono; -import xyz.vallat.louis.commands.Command; -import xyz.vallat.louis.commands.Ping; -import xyz.vallat.louis.commands.Search; -import xyz.vallat.louis.commands.Version; +import xyz.vallat.louis.commands.*; import xyz.vallat.louis.subtitles.OpenSubtitles; import java.util.HashMap; @@ -37,7 +34,8 @@ public class MovieQuoteBot { static { commands.put("ping", new Ping(PREFIX + "ping")); commands.put("version", new Version(PREFIX + "version")); - commands.put("search", new Search(PREFIX + "search")); + commands.put("searchTitle", new SearchTitle(PREFIX + "searchTitle")); + commands.put("listLang", new ListLang(PREFIX + "listLang")); } public static void main(String[] args) { diff --git a/src/main/java/xyz/vallat/louis/commands/Command.java b/src/main/java/xyz/vallat/louis/commands/Command.java index ed7227a..4060d3b 100644 --- a/src/main/java/xyz/vallat/louis/commands/Command.java +++ b/src/main/java/xyz/vallat/louis/commands/Command.java @@ -11,7 +11,7 @@ public abstract class Command { protected final int minArgs; protected final int maxArgs; - Command(String name, String description, String usage, int minArgs, int maxArgs) { + protected Command(String name, String description, String usage, int minArgs, int maxArgs) { this.name = name; this.description = description; this.usage = usage; diff --git a/src/main/java/xyz/vallat/louis/commands/ListLang.java b/src/main/java/xyz/vallat/louis/commands/ListLang.java new file mode 100644 index 0000000..4b3b64d --- /dev/null +++ b/src/main/java/xyz/vallat/louis/commands/ListLang.java @@ -0,0 +1,74 @@ +package xyz.vallat.louis.commands; + +import com.github.wtekiela.opensub4j.response.ListResponse; +import com.github.wtekiela.opensub4j.response.MovieInfo; +import com.github.wtekiela.opensub4j.response.ResponseStatus; +import com.github.wtekiela.opensub4j.response.SubtitleInfo; +import discord4j.core.event.domain.message.MessageCreateEvent; +import discord4j.core.object.entity.Message; +import discord4j.core.object.entity.channel.MessageChannel; +import discord4j.core.object.reaction.ReactionEmoji; +import discord4j.rest.util.Color; +import org.apache.xmlrpc.XmlRpcException; +import reactor.core.publisher.Mono; +import xyz.vallat.louis.subtitles.OpenSubtitles; + +public class ListLang extends Command { + + private static final ReactionEmoji WAITING = ReactionEmoji.unicode("⌛"); + + public ListLang(String name) { + super(name, "List all languages attached to a film.", name + " IMDBid", 1, 2); + } + + @Override + public Mono execute(MessageCreateEvent event) { + String[] args = event.getMessage().getContent().split(" "); + if (args.length < minArgs) + return notEnoughArguments(event); + return event.getMessage().getChannel() + .flatMap(channel -> { + if (OpenSubtitles.isLoggedIn()) { + return event.getMessage().addReaction(WAITING) + .then(event.getMessage().getChannel().flatMap(messageChannel -> + searchAndShowFilms(args[1], channel, messageChannel))) + .then(event.getMessage().removeSelfReaction(WAITING)) + .then(); + } else return channel.createMessage("I cannot search for subtitle languages right now. Sorry."); + }) + .then(); + } + + private Mono notEnoughArguments(MessageCreateEvent event) { + return event.getMessage().getChannel() + .flatMap(channel -> channel.createMessage("Error.\n" + getUsage())) + .then(); + } + + private Mono searchAndShowFilms(String arg, MessageChannel channel, MessageChannel messageChannel) { + try { + ListResponse subtitles = OpenSubtitles.searchSubtitles("", arg); + ListResponse movies = OpenSubtitles.searchImdb(arg); + if (subtitles.getStatus().getCode() == ResponseStatus.OK.getCode()) { + return messageChannel.createEmbed( + embed -> { + embed.setTitle("Results") + .setDescription("Found " + subtitles.getData().size() + " results.") + .setColor(Color.BISMARK); + if (movies.getStatus().getCode() == ResponseStatus.OK.getCode() && !movies.getData().isEmpty()) + embed.addField("Title", movies.getData().get(0).getTitle(), false); + StringBuilder s = new StringBuilder(); + for (SubtitleInfo info : subtitles.getData().subList(0, Math.min(10, subtitles.getData().size()))) + s.append(info.getId()).append(" - ").append(info.getLanguage()).append("\n"); + embed.addField("Languages found", s.toString(), false); + }); + } else if (subtitles.getStatus().getCode() == ResponseStatus.INVALID_IMDB_ID.getCode() || + subtitles.getStatus().getCode() == ResponseStatus.INVALID_PARAMETERS.getCode()) + return messageChannel.createMessage("It looks like this IMDB id is invalid. Try again with a valid one."); + else + return messageChannel.createMessage("An error happened while fetching the results. Try again later, or contact my administrator." + subtitles.getStatus()); + } catch (XmlRpcException e) { + return channel.createMessage("It seems like OpenSubtitles had a stroke."); + } + } +} diff --git a/src/main/java/xyz/vallat/louis/commands/SearchTitle.java b/src/main/java/xyz/vallat/louis/commands/SearchTitle.java index 797dcb5..fc778f4 100644 --- a/src/main/java/xyz/vallat/louis/commands/SearchTitle.java +++ b/src/main/java/xyz/vallat/louis/commands/SearchTitle.java @@ -12,12 +12,12 @@ import org.apache.xmlrpc.XmlRpcException; import reactor.core.publisher.Mono; import xyz.vallat.louis.subtitles.OpenSubtitles; -public class Search extends Command { +public class SearchTitle extends Command { private static final ReactionEmoji WAITING = ReactionEmoji.unicode("⌛"); private static final String FORMAT = "%1$-7s - %2$s\n"; - public Search(String name) { + public SearchTitle(String name) { super(name, "A command to search some subtitles.", name + " ", 1, 1); } @@ -49,7 +49,7 @@ public class Search extends Command { .setDescription("Found " + response.getData().size() + " results.") .setColor(Color.BISMARK); StringBuilder s = new StringBuilder("```txt\n"); - for (MovieInfo info : response.getData().subList(0, 10)) + for (MovieInfo info : response.getData().subList(0, Math.min(10, response.getData().size()))) s.append(String.format(FORMAT, info.getId(), info.getTitle())); s.append("```"); embed.addField("First 10 results:", s.toString(), false); diff --git a/src/main/java/xyz/vallat/louis/subtitles/OpenSubtitles.java b/src/main/java/xyz/vallat/louis/subtitles/OpenSubtitles.java index 2a617b0..54a7960 100644 --- a/src/main/java/xyz/vallat/louis/subtitles/OpenSubtitles.java +++ b/src/main/java/xyz/vallat/louis/subtitles/OpenSubtitles.java @@ -5,6 +5,7 @@ import com.github.wtekiela.opensub4j.impl.OpenSubtitlesClientImpl; import com.github.wtekiela.opensub4j.response.ListResponse; import com.github.wtekiela.opensub4j.response.MovieInfo; import com.github.wtekiela.opensub4j.response.ResponseStatus; +import com.github.wtekiela.opensub4j.response.SubtitleInfo; import org.apache.xmlrpc.XmlRpcException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,6 +53,10 @@ public final class OpenSubtitles { return client.searchMoviesOnImdb(name); } + public static ListResponse searchSubtitles(String lang, String imdbId) throws XmlRpcException { + return client.searchSubtitles(lang, imdbId); + } + public static boolean isLoggedIn() { return client != null && client.isLoggedIn(); }