Added OpenSubtitles basic search capability

Signed-off-by: Louis Vallat <louis@louis-vallat.xyz>
This commit is contained in:
Louis Vallat 2020-10-26 15:04:42 +01:00
parent 83279129bf
commit e9be061576
3 changed files with 126 additions and 58 deletions

View File

@ -1,8 +1,5 @@
package xyz.vallat.louis; package xyz.vallat.louis;
import com.github.wtekiela.opensub4j.api.OpenSubtitlesClient;
import com.github.wtekiela.opensub4j.impl.OpenSubtitlesClientImpl;
import com.github.wtekiela.opensub4j.response.ResponseStatus;
import discord4j.core.DiscordClientBuilder; import discord4j.core.DiscordClientBuilder;
import discord4j.core.GatewayDiscordClient; import discord4j.core.GatewayDiscordClient;
import discord4j.core.event.domain.lifecycle.ReadyEvent; import discord4j.core.event.domain.lifecycle.ReadyEvent;
@ -10,18 +7,15 @@ import discord4j.core.event.domain.message.MessageCreateEvent;
import discord4j.core.object.entity.User; import discord4j.core.object.entity.User;
import discord4j.core.object.presence.Activity; import discord4j.core.object.presence.Activity;
import discord4j.core.object.presence.Presence; import discord4j.core.object.presence.Presence;
import org.apache.xmlrpc.XmlRpcException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import xyz.vallat.louis.commands.Command; import xyz.vallat.louis.commands.Command;
import xyz.vallat.louis.commands.Ping; import xyz.vallat.louis.commands.Ping;
import xyz.vallat.louis.commands.Search; import xyz.vallat.louis.commands.Search;
import xyz.vallat.louis.commands.Version; import xyz.vallat.louis.commands.Version;
import xyz.vallat.louis.subtitles.OpenSubtitles;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -39,11 +33,6 @@ public class MovieQuoteBot {
private static final Logger logger = LoggerFactory.getLogger(MovieQuoteBot.class.getCanonicalName()); private static final Logger logger = LoggerFactory.getLogger(MovieQuoteBot.class.getCanonicalName());
private static final Map<String, Command> commands = new HashMap<>(); private static final Map<String, Command> commands = new HashMap<>();
private static GatewayDiscordClient discordClient; private static GatewayDiscordClient discordClient;
private static OpenSubtitlesClient openSubtitlesClient;
private static String discordToken;
private static String osUsername;
private static String osPassword;
private static String osUa;
static { static {
commands.put("ping", new Ping()); commands.put("ping", new Ping());
@ -61,9 +50,23 @@ public class MovieQuoteBot {
System.exit(1); System.exit(1);
} }
setVariables(args); String discordToken = System.getenv(DISCORD_TOKEN_ENVIRONMENT) == null ?
osLogin(); args[0] :
discordLogin(); System.getenv(DISCORD_TOKEN_ENVIRONMENT);
OpenSubtitles.login(
System.getenv(OS_USERNAME_ENVIRONMENT) == null ?
args[1] :
System.getenv(OS_USERNAME_ENVIRONMENT),
System.getenv(OS_PASSWORD_ENVIRONMENT) == null ?
args[2] :
System.getenv(OS_PASSWORD_ENVIRONMENT),
"en",
System.getenv(OS_UA_ENVIRONMENT) == null ?
args[3] :
System.getenv(OS_UA_ENVIRONMENT)
);
discordLogin(discordToken);
registerDiscordCommands(); registerDiscordCommands();
Runtime.getRuntime().addShutdownHook(new Thread(() -> { Runtime.getRuntime().addShutdownHook(new Thread(() -> {
@ -75,17 +78,16 @@ public class MovieQuoteBot {
} }
private static void registerDiscordCommands() { private static void registerDiscordCommands() {
for (Map.Entry<String, Command> command : commands.entrySet())
discordClient.getEventDispatcher().on(MessageCreateEvent.class) discordClient.getEventDispatcher().on(MessageCreateEvent.class)
.flatMap(event -> Mono.just(event.getMessage().getContent()) .filter(event -> event.getMessage().getAuthor().map(user -> !user.isBot()).orElse(false))
.flatMap(content -> Flux.fromIterable(commands.entrySet()) .filter(event -> event.getMessage().getContent().split(" ")[0].equals(PREFIX + command.getKey()))
.filter(entry -> content.split(" ")[0].equals(PREFIX + entry.getKey())) .flatMap(event -> command.getValue().execute(event).then())
.flatMap(entry -> entry.getValue().execute(event))
.next()))
.subscribe(); .subscribe();
} }
private static void discordLogin() { private static void discordLogin(String token) {
discordClient = DiscordClientBuilder.create(discordToken).build().login().block(); discordClient = DiscordClientBuilder.create(token).build().login().block();
assert discordClient != null; assert discordClient != null;
discordClient.updatePresence(Presence.online(Activity.watching("some more films"))).subscribe(); discordClient.updatePresence(Presence.online(Activity.watching("some more films"))).subscribe();
discordClient.getEventDispatcher().on(ReadyEvent.class) discordClient.getEventDispatcher().on(ReadyEvent.class)
@ -95,40 +97,6 @@ public class MovieQuoteBot {
}); });
} }
private static void setVariables(String[] args) {
discordToken = System.getenv(DISCORD_TOKEN_ENVIRONMENT) == null ?
args[0] :
System.getenv(DISCORD_TOKEN_ENVIRONMENT);
osUsername = System.getenv(OS_USERNAME_ENVIRONMENT) == null ?
args[1] :
System.getenv(OS_USERNAME_ENVIRONMENT);
osPassword = System.getenv(OS_PASSWORD_ENVIRONMENT) == null ?
args[2] :
System.getenv(OS_PASSWORD_ENVIRONMENT);
osUa = System.getenv(OS_UA_ENVIRONMENT) == null ?
args[3] :
System.getenv(OS_UA_ENVIRONMENT);
}
public static void osLogin() {
try {
URL serverUrl = new URL("https", "api.opensubtitles.org", 443, "/xml-rpc");
openSubtitlesClient = new OpenSubtitlesClientImpl(serverUrl);
ResponseStatus status = openSubtitlesClient.login(osUsername, osPassword, "en", osUa).getStatus();
if (!openSubtitlesClient.isLoggedIn()) {
logger.error("Cannot login on OpenSubtitles.org.");
logger.error("Message: [{}] - {}", status.getCode(), status.getMessage());
} else logger.info("Logged in on OpenSubtitles.org.");
} catch (MalformedURLException | XmlRpcException e) {
logger.error(e.getMessage());
System.exit(3);
}
}
public static boolean isOsLoggedIn() {
return openSubtitlesClient != null && openSubtitlesClient.isLoggedIn();
}
public static Mono<Long> getGuilds() { public static Mono<Long> getGuilds() {
return discordClient.getGuilds().count(); return discordClient.getGuilds().count();
} }

View File

@ -0,0 +1,41 @@
package xyz.vallat.louis.commands;
import com.github.wtekiela.opensub4j.response.ListResponse;
import com.github.wtekiela.opensub4j.response.MovieInfo;
import discord4j.core.event.domain.message.MessageCreateEvent;
import discord4j.core.object.reaction.ReactionEmoji;
import org.apache.xmlrpc.XmlRpcException;
import reactor.core.publisher.Mono;
import xyz.vallat.louis.subtitles.OpenSubtitles;
public class Search implements Command {
private static final ReactionEmoji WAITING = ReactionEmoji.unicode("");
@Override
public Mono<Void> execute(MessageCreateEvent event) {
String[] args = event.getMessage().getContent().split(" ");
if (args.length != 1) return event.getMessage().getChannel().flatMap(channel -> channel.createMessage("Misuse")).then();
return event.getMessage().getChannel()
.flatMap(channel -> {
if (OpenSubtitles.isLoggedIn()) {
return event.getMessage().addReaction(WAITING)
.then(event.getMessage().getChannel().flatMap(messageChannel -> messageChannel.createMessage(args[1])))
.then(event.getMessage().getChannel().flatMap(messageChannel -> {
try {
ListResponse<MovieInfo> response = OpenSubtitles.searchImdb(args[1]);
StringBuilder b = new StringBuilder();
for (MovieInfo m : response.getData())
b.append(m.getId()).append(" > ").append(m.getTitle()).append("\n");
return messageChannel.createMessage(String.valueOf(b));
} catch (XmlRpcException e) {
return channel.createMessage("Error");
}
}))
.then(event.getMessage().removeSelfReaction(WAITING))
.then();
} else return channel.createMessage("I cannot search for subtitles right now. Sorry.");
})
.then();
}
}

View File

@ -0,0 +1,59 @@
package xyz.vallat.louis.subtitles;
import com.github.wtekiela.opensub4j.api.OpenSubtitlesClient;
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 org.apache.xmlrpc.XmlRpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
public final class OpenSubtitles {
private static final Logger logger = LoggerFactory.getLogger(OpenSubtitles.class.getCanonicalName());
private static String username;
private static String password;
private static String lang;
private static String userAgent;
private static OpenSubtitlesClient client;
private OpenSubtitles() {
}
public static void login(String username, String password, String lang, String userAgent) {
OpenSubtitles.username = username;
OpenSubtitles.password = password;
OpenSubtitles.lang = lang;
OpenSubtitles.userAgent = userAgent;
login();
}
public static void login() {
try {
URL serverUrl = new URL("https", "api.opensubtitles.org", 443, "/xml-rpc");
client = new OpenSubtitlesClientImpl(serverUrl);
ResponseStatus status = client.login(username, password, lang, userAgent).getStatus();
if (!client.isLoggedIn()) {
logger.error("Cannot login on OpenSubtitles.org.");
logger.error("Message: [{}] - {}", status.getCode(), status.getMessage());
} else logger.info("Logged in on OpenSubtitles.org.");
} catch (MalformedURLException | XmlRpcException e) {
logger.error(e.getMessage());
System.exit(3);
}
}
public static ListResponse<MovieInfo> searchImdb (String name) throws XmlRpcException {
return client.searchMoviesOnImdb(name);
}
public static boolean isLoggedIn() {
return client != null && client.isLoggedIn();
}
}