Added support for searching subtitles language availability

Signed-off-by: Louis Vallat <louis@louis-vallat.xyz>
This commit is contained in:
Louis Vallat 2020-10-26 21:01:06 +01:00
parent 1587f5f1d6
commit 672567e118
6 changed files with 87 additions and 9 deletions

View File

@ -33,5 +33,6 @@ repositories {
dependencies { dependencies {
implementation 'com.discord4j:discord4j-core:3.1.1' implementation 'com.discord4j:discord4j-core:3.1.1'
implementation 'com.github.wtekiela:opensub4j:0.3.0' 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' implementation 'ch.qos.logback:logback-classic:1.2.3'
} }

View File

@ -10,10 +10,7 @@ import discord4j.core.object.presence.Presence;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import xyz.vallat.louis.commands.Command; import xyz.vallat.louis.commands.*;
import xyz.vallat.louis.commands.Ping;
import xyz.vallat.louis.commands.Search;
import xyz.vallat.louis.commands.Version;
import xyz.vallat.louis.subtitles.OpenSubtitles; import xyz.vallat.louis.subtitles.OpenSubtitles;
import java.util.HashMap; import java.util.HashMap;
@ -37,7 +34,8 @@ public class MovieQuoteBot {
static { static {
commands.put("ping", new Ping(PREFIX + "ping")); commands.put("ping", new Ping(PREFIX + "ping"));
commands.put("version", new Version(PREFIX + "version")); 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) { public static void main(String[] args) {

View File

@ -11,7 +11,7 @@ public abstract class Command {
protected final int minArgs; protected final int minArgs;
protected final int maxArgs; 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.name = name;
this.description = description; this.description = description;
this.usage = usage; this.usage = usage;

View File

@ -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<Void> 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<Void> notEnoughArguments(MessageCreateEvent event) {
return event.getMessage().getChannel()
.flatMap(channel -> channel.createMessage("Error.\n" + getUsage()))
.then();
}
private Mono<? extends Message> searchAndShowFilms(String arg, MessageChannel channel, MessageChannel messageChannel) {
try {
ListResponse<SubtitleInfo> subtitles = OpenSubtitles.searchSubtitles("", arg);
ListResponse<MovieInfo> 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.");
}
}
}

View File

@ -12,12 +12,12 @@ import org.apache.xmlrpc.XmlRpcException;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import xyz.vallat.louis.subtitles.OpenSubtitles; 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 ReactionEmoji WAITING = ReactionEmoji.unicode("");
private static final String FORMAT = "%1$-7s - %2$s\n"; 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 + " <name>", 1, 1); super(name, "A command to search some subtitles.", name + " <name>", 1, 1);
} }
@ -49,7 +49,7 @@ public class Search extends Command {
.setDescription("Found " + response.getData().size() + " results.") .setDescription("Found " + response.getData().size() + " results.")
.setColor(Color.BISMARK); .setColor(Color.BISMARK);
StringBuilder s = new StringBuilder("```txt\n"); 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(String.format(FORMAT, info.getId(), info.getTitle()));
s.append("```"); s.append("```");
embed.addField("First 10 results:", s.toString(), false); embed.addField("First 10 results:", s.toString(), false);

View File

@ -5,6 +5,7 @@ import com.github.wtekiela.opensub4j.impl.OpenSubtitlesClientImpl;
import com.github.wtekiela.opensub4j.response.ListResponse; import com.github.wtekiela.opensub4j.response.ListResponse;
import com.github.wtekiela.opensub4j.response.MovieInfo; import com.github.wtekiela.opensub4j.response.MovieInfo;
import com.github.wtekiela.opensub4j.response.ResponseStatus; import com.github.wtekiela.opensub4j.response.ResponseStatus;
import com.github.wtekiela.opensub4j.response.SubtitleInfo;
import org.apache.xmlrpc.XmlRpcException; import org.apache.xmlrpc.XmlRpcException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -52,6 +53,10 @@ public final class OpenSubtitles {
return client.searchMoviesOnImdb(name); return client.searchMoviesOnImdb(name);
} }
public static ListResponse<SubtitleInfo> searchSubtitles(String lang, String imdbId) throws XmlRpcException {
return client.searchSubtitles(lang, imdbId);
}
public static boolean isLoggedIn() { public static boolean isLoggedIn() {
return client != null && client.isLoggedIn(); return client != null && client.isLoggedIn();
} }