Added a configuration system, including a default language
Signed-off-by: Louis Vallat <louis@louis-vallat.xyz>
This commit is contained in:
parent
3632e77b0b
commit
cea9eeb6b7
@ -1,4 +1,4 @@
|
||||
DROP TABLE IF EXISTS properties, films, languages, subtitle_lines, subtitles;
|
||||
DROP TABLE IF EXISTS properties, films, languages, subtitle_lines, subtitles, user_config;
|
||||
|
||||
/**
|
||||
Store some information on the application.
|
||||
@ -76,3 +76,18 @@ CREATE TABLE IF NOT EXISTS subtitle_lines
|
||||
FOREIGN KEY (subtitle_id)
|
||||
REFERENCES subtitles (id)
|
||||
);
|
||||
|
||||
/**
|
||||
User configurations
|
||||
*/
|
||||
CREATE TABLE IF NOT EXISTS user_config
|
||||
(
|
||||
id int GENERATED ALWAYS AS IDENTITY,
|
||||
user_id bigint NOT NULL,
|
||||
guild_id bigint DEFAULT NULL,
|
||||
default_language_id int DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE (user_id, guild_id),
|
||||
FOREIGN KEY (default_language_id)
|
||||
REFERENCES languages (id)
|
||||
);
|
@ -23,7 +23,7 @@ public class MoviesQuoteBot {
|
||||
public static final String PREFIX = "!";
|
||||
public static final String NAME = "Movies Quote Bot";
|
||||
public static final String DESCRIPTION = "I may know quotes from movies.";
|
||||
public static final String VERSION = "0.5";
|
||||
public static final String VERSION = "0.6";
|
||||
public static final String KILL_SWITCH_FILE = "system_locked";
|
||||
public static final String MAINTENANCE_MODE_FILE = "maintenance_mode_locked";
|
||||
private static final Logger logger = LoggerFactory.getLogger(MoviesQuoteBot.class.getCanonicalName());
|
||||
|
@ -58,14 +58,6 @@ public abstract class Command {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public int getMinArgs() {
|
||||
return minArgs;
|
||||
}
|
||||
|
||||
public int getMaxArgs() {
|
||||
return maxArgs;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
72
src/main/java/xyz/vallat/louis/commands/Config.java
Normal file
72
src/main/java/xyz/vallat/louis/commands/Config.java
Normal file
@ -0,0 +1,72 @@
|
||||
package xyz.vallat.louis.commands;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
||||
import discord4j.rest.util.Color;
|
||||
import org.apache.commons.cli.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Mono;
|
||||
import xyz.vallat.louis.database.LanguageManager;
|
||||
import xyz.vallat.louis.database.UserConfigManager;
|
||||
import xyz.vallat.louis.subtitles.dao.Lang;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public class Config extends Command {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(Config.class.getCanonicalName());
|
||||
private static final String NO_LANGUAGE = "None.";
|
||||
private static final String LANG_FIELD_NAME = "Language";
|
||||
|
||||
public Config(String name) {
|
||||
super(name, "Configure your own experience.", name + " [-g|--global] [-l/--lang 'default language'|-rl/--reset-lang]", 0, 0);
|
||||
OptionGroup langOrResetLang = new OptionGroup()
|
||||
.addOption(Option.builder("l").longOpt("lang").desc("Specify your default language").hasArg().build())
|
||||
.addOption(Option.builder("rl").longOpt("reset-lang").desc("Reset your default language").build());
|
||||
options.addOption(Option.builder("g").longOpt("global").desc("Specify that this configuration should be global.").build());
|
||||
options.addOptionGroup(langOrResetLang);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> execute(MessageCreateEvent event) {
|
||||
try {
|
||||
CommandLine cmd = new DefaultParser().parse(options,
|
||||
event.getMessage().getContent().substring(name.length()).split(" "));
|
||||
Lang language = cmd.hasOption("l") ? LanguageManager.getLangFromAny(cmd.getOptionValue("l")) : null;
|
||||
return event.getMessage().getChannel().flatMap(messageChannel -> messageChannel.createEmbed(embed -> {
|
||||
Snowflake user = event.getMessage().getAuthor().isPresent() ? event.getMessage().getAuthor().get().getId() : null;
|
||||
Snowflake guild = event.getMessage().getGuildId().isPresent() ? event.getMessage().getGuildId().get() : null;
|
||||
if (cmd.hasOption("g")) guild = null;
|
||||
embed.setTitle("Configuration").setColor(Color.RED);
|
||||
if (user == null) embed.setDescription("What? Are you a non-existent user? A bug in the matrix?");
|
||||
else {
|
||||
embed.setDescription("A configuration change has been noticed.");
|
||||
if (cmd.hasOption("l")) {
|
||||
if (language == null)
|
||||
embed.setColor(Color.ORANGE)
|
||||
.setDescription("The provided language is unknown. Try again with another one. Or don't try at all.");
|
||||
else {
|
||||
UserConfigManager.setDefaultLanguage(user, guild, language);
|
||||
embed.addField(LANG_FIELD_NAME, language.getEnglish(), true);
|
||||
}
|
||||
} else if (cmd.hasOption("rl")) {
|
||||
UserConfigManager.setDefaultLanguage(user, guild, null);
|
||||
Lang l = UserConfigManager.getDefaultLanguage(user, guild);
|
||||
embed.addField(LANG_FIELD_NAME, l == null ? NO_LANGUAGE : l.getEnglish(), false);
|
||||
} else {
|
||||
embed.setDescription("<@" + user.asString() + ">'s configuration.");
|
||||
Lang l = UserConfigManager.getDefaultLanguage(user, guild);
|
||||
embed.addField(LANG_FIELD_NAME, l == null ? NO_LANGUAGE : l.getEnglish(), false);
|
||||
}
|
||||
embed.setColor(Color.MEDIUM_SEA_GREEN);
|
||||
}
|
||||
embed.setTimestamp(Instant.now());
|
||||
})).then().onErrorResume(throwable -> fatalError(event, throwable));
|
||||
} catch (
|
||||
ParseException e) {
|
||||
logger.debug("Parsing error: {}", e.getMessage());
|
||||
return parsingError(event);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import com.github.wtekiela.opensub4j.response.ListResponse;
|
||||
import com.github.wtekiela.opensub4j.response.ResponseStatus;
|
||||
import com.github.wtekiela.opensub4j.response.SubtitleFile;
|
||||
import com.github.wtekiela.opensub4j.response.SubtitleInfo;
|
||||
import discord4j.common.util.Snowflake;
|
||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
||||
import discord4j.core.spec.EmbedCreateSpec;
|
||||
import discord4j.rest.util.Color;
|
||||
@ -15,6 +16,7 @@ import reactor.core.publisher.Mono;
|
||||
import xyz.vallat.louis.database.LanguageManager;
|
||||
import xyz.vallat.louis.database.SubtitleLineManager;
|
||||
import xyz.vallat.louis.database.SubtitleManager;
|
||||
import xyz.vallat.louis.database.UserConfigManager;
|
||||
import xyz.vallat.louis.omdb.OMDBClient;
|
||||
import xyz.vallat.louis.omdb.objects.Movie;
|
||||
import xyz.vallat.louis.subtitles.OpenSubtitles;
|
||||
@ -46,9 +48,16 @@ public class Download extends Command {
|
||||
public Mono<Void> execute(MessageCreateEvent event) {
|
||||
try {
|
||||
CommandLine cmd = new DefaultParser().parse(options, getArgArray(event));
|
||||
String langArg = cmd.hasOption("l") ? cmd.getOptionValue("l") : "english";
|
||||
Lang language = LanguageManager.getLangFromAny(langArg);
|
||||
if (language == null) return unknownLanguage(event, langArg);
|
||||
Snowflake user = event.getMessage().getAuthor().isPresent() ? event.getMessage().getAuthor().get().getId() : null;
|
||||
Snowflake guild = event.getMessage().getGuildId().isPresent() ? event.getMessage().getGuildId().get() : null;
|
||||
if (user == null) return Mono.empty();
|
||||
Lang l;
|
||||
if (!cmd.hasOption("l")) {
|
||||
l = UserConfigManager.getDefaultLanguage(user, guild);
|
||||
if (l == null) l = LanguageManager.getLangFromAny("english");
|
||||
} else l = LanguageManager.getLangFromAny(cmd.getOptionValue("l"));
|
||||
if (l == null) return unknownLanguage(event, cmd.getOptionValue("l"));
|
||||
Lang language = l;
|
||||
return event.getMessage().getChannel().flatMap(channel -> event.getMessage().addReaction(WAITING)
|
||||
.then(channel.createEmbed(embed -> {
|
||||
embed.setTitle("Importation").setColor(Color.RED);
|
||||
@ -59,7 +68,7 @@ public class Download extends Command {
|
||||
if (movie == null || movie.getId() < 0)
|
||||
embed.setDescription("We couldn't find any movie with these information. Sorry!");
|
||||
else if (SubtitleManager.getSubtitlesId(movie, language.getId()) > 0)
|
||||
embed.setDescription("This movie already has already this language imported.")
|
||||
embed.setDescription("This movie has already this language imported.")
|
||||
.setColor(Color.ORANGE);
|
||||
else
|
||||
computeImportation(event, language, embed, movie);
|
||||
@ -105,7 +114,7 @@ public class Download extends Command {
|
||||
subs.get(0).getContentAsString(subtitleInfo.getEncoding()));
|
||||
if (blocks.isEmpty())
|
||||
embed.setDescription("The file we downloaded was empty... \uD83E\uDD28 It should be a temporary error! " +
|
||||
"Try again please! And if you still have this issue, try contacting my administrator, please.");
|
||||
"Try again please! And if you still have this issue, try contacting my administrator.");
|
||||
else {
|
||||
SubtitleLineManager.importSubtitleLines(blocks, language, movie,
|
||||
event.getMember().isPresent() ? event.getMember().get().getId() : null,
|
||||
@ -114,6 +123,7 @@ public class Download extends Command {
|
||||
"Congratulations and thank you" +
|
||||
(event.getMember().isPresent() ? " <@!" + event.getMember().get().getId().asString() + "> " : " ")
|
||||
+ "for your contribution!");
|
||||
embed.setImage(movie.getPoster());
|
||||
embed.addField("You imported", blocks.size() + " lines into my database", true);
|
||||
embed.addField("From", movie.toString(), true);
|
||||
embed.addField("In", language.getEnglish(), true);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package xyz.vallat.louis.commands;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
||||
import discord4j.rest.util.Color;
|
||||
import org.apache.commons.cli.*;
|
||||
@ -10,6 +11,7 @@ import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Mono;
|
||||
import xyz.vallat.louis.database.LanguageManager;
|
||||
import xyz.vallat.louis.database.SubtitleLineManager;
|
||||
import xyz.vallat.louis.database.UserConfigManager;
|
||||
import xyz.vallat.louis.subtitles.dao.FilmQuote;
|
||||
import xyz.vallat.louis.subtitles.dao.Lang;
|
||||
|
||||
@ -38,27 +40,31 @@ public class Quote extends Command {
|
||||
try {
|
||||
CommandLine cmd = new DefaultParser().parse(options,
|
||||
event.getMessage().getContent().substring(name.length()).split(" "));
|
||||
Lang language = LanguageManager.getLangFromAny(cmd.hasOption("l") ? cmd.getOptionValue("l") : "english");
|
||||
Lang language;
|
||||
Snowflake user = event.getMessage().getAuthor().isPresent() ? event.getMessage().getAuthor().get().getId() : null;
|
||||
Snowflake guild = event.getMessage().getGuildId().isPresent() ? event.getMessage().getGuildId().get() : null;
|
||||
if (user == null) return Mono.empty();
|
||||
if (cmd.hasOption("l")) language = LanguageManager.getLangFromAny(cmd.getOptionValue("l"));
|
||||
else language = UserConfigManager.getDefaultLanguage(user, guild);
|
||||
if (language == null) language = LanguageManager.getLangFromAny("english");
|
||||
String imdb = cmd.hasOption("i") ? cmd.getOptionValue("i") : null;
|
||||
String title = cmd.hasOption("t") ? String.join(" ", cmd.getOptionValues("t")) : null;
|
||||
String search = cmd.hasOption("s") ? String.join(" ", cmd.getOptionValues("s")) : null;
|
||||
Lang finalLanguage = language;
|
||||
logger.error(finalLanguage.getFrench());
|
||||
return event.getMessage().getChannel().flatMap(messageChannel -> messageChannel.createEmbed(embed -> {
|
||||
embed.setTitle("Quote").setColor(Color.RED);
|
||||
if (language == null)
|
||||
embed.setDescription("This language is unknown. Try again with another one. Or don't try at all.");
|
||||
FilmQuote quote = SubtitleLineManager.getRandomLine(finalLanguage, imdb, title, search);
|
||||
if (quote == null)
|
||||
embed.setDescription("We don't have any quote in that language right now! Sorry!").setColor(Color.ORANGE);
|
||||
else {
|
||||
FilmQuote quote = SubtitleLineManager.getRandomLine(language, imdb, title, search);
|
||||
if (quote == null)
|
||||
embed.setDescription("We don't have any quote in that language right now! Sorry!").setColor(Color.ORANGE);
|
||||
else {
|
||||
embed.setDescription(Jsoup.clean(quote.getSubtitleBlock().getDialogue()
|
||||
.replaceAll("<i>|</i>", "*")
|
||||
.replaceAll("<b>|</b>", "**")
|
||||
.replaceAll("<u>|</u>", "__"),
|
||||
Whitelist.none()));
|
||||
embed.setFooter(quote.getMovie().toString(), quote.getMovie().getPoster());
|
||||
embed.setColor(Color.MEDIUM_SEA_GREEN);
|
||||
}
|
||||
embed.setDescription(Jsoup.clean(quote.getSubtitleBlock().getDialogue()
|
||||
.replaceAll("<i>|</i>", "*")
|
||||
.replaceAll("<b>|</b>", "**")
|
||||
.replaceAll("<u>|</u>", "__"),
|
||||
Whitelist.none()));
|
||||
embed.setFooter(quote.getMovie().toString(), quote.getMovie().getPoster());
|
||||
embed.setColor(Color.MEDIUM_SEA_GREEN);
|
||||
}
|
||||
embed.setTimestamp(Instant.now());
|
||||
})).then().onErrorResume(throwable -> fatalError(event, throwable));
|
||||
|
@ -16,6 +16,7 @@ import static xyz.vallat.louis.database.LanguageManager.initializeLanguages;
|
||||
import static xyz.vallat.louis.database.PropertyManager.initializeProperties;
|
||||
import static xyz.vallat.louis.database.SubtitleLineManager.initializeSubtitleLine;
|
||||
import static xyz.vallat.louis.database.SubtitleManager.initializeSubtitle;
|
||||
import static xyz.vallat.louis.database.UserConfigManager.initializeUserConfig;
|
||||
|
||||
public final class DBManager {
|
||||
|
||||
@ -57,6 +58,7 @@ public final class DBManager {
|
||||
initializeFilm(connection);
|
||||
initializeSubtitle(connection);
|
||||
initializeSubtitleLine(connection);
|
||||
initializeUserConfig(connection);
|
||||
importLanguageIfNeeded(connection);
|
||||
updateDatabaseIfNeeded();
|
||||
} catch (SQLException e) {
|
||||
|
@ -104,13 +104,38 @@ public final class LanguageManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static Lang getLangFromId(int id) {
|
||||
Lang lang = null;
|
||||
try (Connection connection = DBManager.getConnection()) {
|
||||
String query = "SELECT * FROM languages WHERE id = ?;";
|
||||
try (PreparedStatement stmt = connection.prepareStatement(query)) {
|
||||
stmt.setInt(1, id);
|
||||
stmt.execute();
|
||||
if (stmt.getResultSet().next()) {
|
||||
lang = new Lang(
|
||||
stmt.getResultSet().getInt("id"),
|
||||
stmt.getResultSet().getString("alpha3_b"),
|
||||
stmt.getResultSet().getString("alpha3_t"),
|
||||
stmt.getResultSet().getString("alpha2"),
|
||||
stmt.getResultSet().getString("english"),
|
||||
stmt.getResultSet().getString("french")
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
logger.error("Cannot connect to database: {}", e.getMessage());
|
||||
System.exit(ExitCodes.CANNOT_CONNECT_TO_DB.getValue());
|
||||
}
|
||||
return lang;
|
||||
}
|
||||
|
||||
public static Lang getLangFromAny(@NonNull String name) {
|
||||
Lang lang = null;
|
||||
name = name.toLowerCase();
|
||||
try (Connection connection = DBManager.getConnection()) {
|
||||
String query = "SELECT * FROM languages WHERE alpha3_b = ? " +
|
||||
"OR alpha3_t = ? OR alpha2 = ? OR english = ? OR french = ?;";
|
||||
try (PreparedStatement stmt = connection.prepareStatement(query)){
|
||||
try (PreparedStatement stmt = connection.prepareStatement(query)) {
|
||||
for (int i = 1; i < 6; i++) stmt.setString(i, name);
|
||||
stmt.execute();
|
||||
if (stmt.getResultSet().next()) {
|
||||
|
100
src/main/java/xyz/vallat/louis/database/UserConfigManager.java
Normal file
100
src/main/java/xyz/vallat/louis/database/UserConfigManager.java
Normal file
@ -0,0 +1,100 @@
|
||||
package xyz.vallat.louis.database;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import xyz.vallat.louis.codes.ExitCodes;
|
||||
import xyz.vallat.louis.subtitles.dao.Lang;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
public final class UserConfigManager {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(UserConfigManager.class.getCanonicalName());
|
||||
|
||||
private UserConfigManager() {
|
||||
}
|
||||
|
||||
public static Lang getDefaultLanguage(Snowflake user, Snowflake guild) {
|
||||
Lang lang = null;
|
||||
try (Connection connection = DBManager.getConnection()) {
|
||||
String query = "SELECT default_language_id FROM user_config " +
|
||||
"WHERE user_id = ? AND guild_id " + (guild == null ? "IS NULL" : "= ?") + ";";
|
||||
try (PreparedStatement stmt = connection.prepareStatement(query)) {
|
||||
stmt.setLong(1, user.asLong());
|
||||
if (guild != null) stmt.setLong(2, guild.asLong());
|
||||
stmt.executeQuery();
|
||||
if (!stmt.getResultSet().next()) return guild != null ? getDefaultLanguage(user, null) : null;
|
||||
int id = stmt.getResultSet().getInt("default_language_id");
|
||||
if (stmt.getResultSet().wasNull()) return null;
|
||||
return LanguageManager.getLangFromId(id);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
logger.error("Could not connect to the database right now. Reason: {}", e.getMessage());
|
||||
System.exit(ExitCodes.CANNOT_CONNECT_TO_DB.getValue());
|
||||
}
|
||||
return lang;
|
||||
}
|
||||
|
||||
public static void setDefaultLanguage(Snowflake user, Snowflake guild, Lang lang) {
|
||||
try (Connection connection = DBManager.getConnection()) {
|
||||
String query = "SELECT id FROM user_config WHERE user_id = ? AND guild_id " + (guild == null ? "IS NULL" : "= ?") + ";";
|
||||
try (PreparedStatement stmt = connection.prepareStatement(query)) {
|
||||
stmt.setLong(1, user.asLong());
|
||||
if (guild != null) stmt.setLong(2, guild.asLong());
|
||||
stmt.execute();
|
||||
if (stmt.getResultSet().next()) updateDefaultLanguage(user, guild, lang, connection);
|
||||
else insertDefaultLanguage(user, guild, lang, connection);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
logger.error("Could not connect to the database right now. Reason: {}", e.getMessage());
|
||||
System.exit(ExitCodes.CANNOT_CONNECT_TO_DB.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private static void insertDefaultLanguage(Snowflake user, Snowflake guild, Lang lang, Connection connection) throws SQLException {
|
||||
String insert = "INSERT INTO user_config(user_id, guild_id, default_language_id) VALUES(?, ?, ?);";
|
||||
try (PreparedStatement stmt = connection.prepareStatement(insert)) {
|
||||
stmt.setLong(1, user.asLong());
|
||||
if (guild == null) stmt.setObject(2, null);
|
||||
else stmt.setLong(2, guild.asLong());
|
||||
if (lang == null) stmt.setObject(3, null);
|
||||
else stmt.setInt(3, lang.getId());
|
||||
stmt.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateDefaultLanguage(Snowflake user, Snowflake guild, Lang lang, Connection connection) throws SQLException {
|
||||
String update = "UPDATE user_config SET default_language_id = ? WHERE user_id = ? AND guild_id "
|
||||
+ (guild == null ? "IS NULL" : "= ?") + ";";
|
||||
try (PreparedStatement stmt = connection.prepareStatement(update)) {
|
||||
if (lang == null) stmt.setObject(1, null);
|
||||
else stmt.setLong(1, lang.getId());
|
||||
stmt.setLong(2, user.asLong());
|
||||
if (guild != null) stmt.setLong(3, guild.asLong());
|
||||
stmt.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
static void initializeUserConfig(Connection connection) throws SQLException {
|
||||
logger.debug("Creating userConfigTable table.");
|
||||
try (Statement stmt = connection.createStatement()) {
|
||||
String query = """
|
||||
CREATE TABLE IF NOT EXISTS user_config
|
||||
(
|
||||
id int GENERATED ALWAYS AS IDENTITY,
|
||||
user_id bigint NOT NULL,
|
||||
guild_id bigint DEFAULT NULL,
|
||||
default_language_id int DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE (user_id, guild_id),
|
||||
FOREIGN KEY (default_language_id)
|
||||
REFERENCES languages (id)
|
||||
);""";
|
||||
stmt.executeUpdate(query);
|
||||
}
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ public final class DiscordManager {
|
||||
commands.add(new ListLang(PREFIX + "listLang"));
|
||||
commands.add(new Download(PREFIX + "download"));
|
||||
commands.add(new Quote(PREFIX + "quote"));
|
||||
commands.add(new Config(PREFIX + "config"));
|
||||
commands.add(new Ping(PREFIX + "ping"));
|
||||
commands.add(new Help(PREFIX + "help"));
|
||||
commands.add(new Version(PREFIX + "version"));
|
||||
|
Loading…
Reference in New Issue
Block a user