adding notes
This commit is contained in:
@@ -8,6 +8,7 @@ import net.dv8tion.jda.api.interactions.InteractionContextType;
|
|||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
import net.dv8tion.jda.api.interactions.commands.build.Commands;
|
import net.dv8tion.jda.api.interactions.commands.build.Commands;
|
||||||
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -22,6 +23,7 @@ public class Main {
|
|||||||
private static final Properties properties = new Properties();
|
private static final Properties properties = new Properties();
|
||||||
private static String version = "Unknown version";
|
private static String version = "Unknown version";
|
||||||
private static Storage storage;
|
private static Storage storage;
|
||||||
|
private static Long adminId;
|
||||||
public static JDA jda;
|
public static JDA jda;
|
||||||
|
|
||||||
public static void main(String[] args) throws InterruptedException {
|
public static void main(String[] args) throws InterruptedException {
|
||||||
@@ -43,6 +45,8 @@ public class Main {
|
|||||||
|
|
||||||
logger.info("Starting " + version);
|
logger.info("Starting " + version);
|
||||||
|
|
||||||
|
adminId = Long.parseLong(properties.getProperty("ADMIN_USER_ID"));
|
||||||
|
|
||||||
jda = JDABuilder.createLight(properties.getProperty("DISCORD_TOKEN"), Collections.emptyList())
|
jda = JDABuilder.createLight(properties.getProperty("DISCORD_TOKEN"), Collections.emptyList())
|
||||||
.setCallbackPool(Executors.newVirtualThreadPerTaskExecutor())
|
.setCallbackPool(Executors.newVirtualThreadPerTaskExecutor())
|
||||||
.setActivity(Activity.customStatus("Notekeeping..."))
|
.setActivity(Activity.customStatus("Notekeeping..."))
|
||||||
@@ -58,8 +62,24 @@ public class Main {
|
|||||||
new OptionData(OptionType.BOOLEAN, "ephermeal", "Whether the note should be ephermal").setRequired(false)
|
new OptionData(OptionType.BOOLEAN, "ephermeal", "Whether the note should be ephermal").setRequired(false)
|
||||||
)
|
)
|
||||||
.setContexts(InteractionContextType.BOT_DM, InteractionContextType.GUILD, InteractionContextType.PRIVATE_CHANNEL)
|
.setContexts(InteractionContextType.BOT_DM, InteractionContextType.GUILD, InteractionContextType.PRIVATE_CHANNEL)
|
||||||
|
).queue();
|
||||||
|
|
||||||
|
jda.upsertCommand(Commands.slash("add-note", "Add a note")
|
||||||
|
.setIntegrationTypes(IntegrationType.GUILD_INSTALL, IntegrationType.USER_INSTALL)
|
||||||
|
.addOptions(
|
||||||
|
new OptionData(OptionType.STRING, "alias", "An alias for the note").setRequired(true),
|
||||||
|
new OptionData(OptionType.STRING, "title", "The title of the note").setRequired(true),
|
||||||
|
new OptionData(OptionType.STRING, "content", "The content of the note").setRequired(true),
|
||||||
|
new OptionData(OptionType.STRING, "image-url", "The image URL of the note").setRequired(false),
|
||||||
|
new OptionData(OptionType.STRING, "thumbnail-url", "The thumbnail URL of the note").setRequired(false),
|
||||||
|
new OptionData(OptionType.STRING, "color", "The color of the note").setRequired(false),
|
||||||
|
new OptionData(OptionType.STRING, "author", "The author of the note").setRequired(false),
|
||||||
|
new OptionData(OptionType.STRING, "author-url", "The author URL of the note").setRequired(false),
|
||||||
|
new OptionData(OptionType.STRING, "footer", "The footer of the note").setRequired(false),
|
||||||
|
new OptionData(OptionType.STRING, "footer-url", "The footer URL of the note").setRequired(false)
|
||||||
)
|
)
|
||||||
.queue();
|
.setContexts(InteractionContextType.BOT_DM)
|
||||||
|
).queue();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,10 +109,19 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static Long getAdminId() {
|
||||||
|
return adminId;
|
||||||
|
}
|
||||||
|
|
||||||
public static String getVersion() {
|
public static String getVersion() {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Storage getStorage() {
|
||||||
|
return storage;
|
||||||
|
}
|
||||||
|
|
||||||
private static void shutdown() {
|
private static void shutdown() {
|
||||||
jda.shutdown();
|
jda.shutdown();
|
||||||
storage.shutdown();
|
storage.shutdown();
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ public class SlashCommandListener extends ListenerAdapter {
|
|||||||
.queue();
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean ephemeral;
|
boolean ephemeral;
|
||||||
try {
|
try {
|
||||||
ephemeral = ephemeralOption != null && ephemeralOption.getAsBoolean();
|
ephemeral = ephemeralOption != null && ephemeralOption.getAsBoolean();
|
||||||
@@ -32,6 +31,29 @@ public class SlashCommandListener extends ListenerAdapter {
|
|||||||
String noteId = noteIdOption.getAsString();
|
String noteId = noteIdOption.getAsString();
|
||||||
getNote(event, noteId, ephemeral);
|
getNote(event, noteId, ephemeral);
|
||||||
}
|
}
|
||||||
|
case "add-note" -> {
|
||||||
|
Long adminId = Main.getAdminId();
|
||||||
|
if (adminId == null || !adminId.equals(event.getUser().getIdLong())) {
|
||||||
|
event.reply("You do not have permission to use this command.")
|
||||||
|
.setEphemeral(true)
|
||||||
|
.queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionMapping aliasOption = event.getOption("alias");
|
||||||
|
OptionMapping titleOption = event.getOption("title");
|
||||||
|
OptionMapping contentOption = event.getOption("content");
|
||||||
|
if (titleOption == null || contentOption == null || aliasOption == null) {
|
||||||
|
event.reply("Please provide a alias, title and content.")
|
||||||
|
.setEphemeral(true)
|
||||||
|
.queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String alias = aliasOption.getAsString();
|
||||||
|
String title = titleOption.getAsString();
|
||||||
|
String content = contentOption.getAsString();
|
||||||
|
addNote(event, alias, title, content);
|
||||||
|
}
|
||||||
|
|
||||||
default -> event.reply("Unknown command.")
|
default -> event.reply("Unknown command.")
|
||||||
.setEphemeral(true)
|
.setEphemeral(true)
|
||||||
@@ -39,17 +61,40 @@ public class SlashCommandListener extends ListenerAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getNote(SlashCommandInteractionEvent event, String noteId, boolean ephemeral) {
|
private void getNote(SlashCommandInteractionEvent event, String noteAlias, boolean ephemeral) {
|
||||||
Note note = Note.cache.getIfPresent(noteId);
|
Note note = Main.getStorage().getNote(noteAlias);
|
||||||
if (note == null) {
|
if (note == null) {
|
||||||
event.reply("Note with ID %s not found.".formatted(noteId))
|
event.reply("Note with ID %s not found.".formatted(noteAlias))
|
||||||
.setEphemeral(true)
|
.setEphemeral(true)
|
||||||
.queue();
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.replyEmbeds(note.toEmbed())
|
event.replyEmbeds(note.toEmbed())
|
||||||
.setEphemeral(ephemeral)
|
.setEphemeral(ephemeral)
|
||||||
.queue();
|
.queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addNote(SlashCommandInteractionEvent event, String noteAlias, String title, String description) {
|
||||||
|
Note note = Note.createNew(title, description);
|
||||||
|
Storage.Status status = Main.getStorage().addNote(note, noteAlias);
|
||||||
|
|
||||||
|
if (status == Storage.Status.ALIAS_EXISTS) {
|
||||||
|
event.reply("Alias already exists.")
|
||||||
|
.setEphemeral(true)
|
||||||
|
.queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (status == Storage.Status.ERROR) {
|
||||||
|
event.reply("An error occurred.")
|
||||||
|
.setEphemeral(true)
|
||||||
|
.queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.reply("Note added.")
|
||||||
|
.setEphemeral(true)
|
||||||
|
.queue();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,18 @@ package me.youhavetrouble.noted;
|
|||||||
|
|
||||||
import com.zaxxer.hikari.HikariConfig;
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import me.youhavetrouble.noted.note.Note;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
import java.awt.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
@@ -77,4 +84,105 @@ public class Storage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Status addNote(@NotNull Note note, @NotNull String alias) {
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
connection.setAutoCommit(false);
|
||||||
|
PreparedStatement statement = connection.prepareStatement("""
|
||||||
|
INSERT INTO notes (id, title, title_url, description, image_url, thumbnail_url, color, author, author_url, footer, footer_url)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
""");
|
||||||
|
|
||||||
|
statement.setString(1, note.id.toString());
|
||||||
|
statement.setString(2, note.title);
|
||||||
|
statement.setString(3, note.titleUrl);
|
||||||
|
statement.setString(4, note.content);
|
||||||
|
statement.setString(5, note.imageUrl);
|
||||||
|
statement.setString(6, note.thumbnailUrl);
|
||||||
|
statement.setInt(7, note.color != null ? note.color.getRGB() : 0);
|
||||||
|
statement.setString(8, note.author);
|
||||||
|
statement.setString(9, note.authorUrl);
|
||||||
|
statement.setString(10, note.footer);
|
||||||
|
statement.setString(11, note.footerUrl);
|
||||||
|
statement.executeUpdate();
|
||||||
|
|
||||||
|
statement = connection.prepareStatement("""
|
||||||
|
INSERT INTO aliases (alias, note_id)
|
||||||
|
VALUES (?, ?)
|
||||||
|
""");
|
||||||
|
statement.setString(1, alias);
|
||||||
|
statement.setString(2, note.id.toString());
|
||||||
|
statement.executeUpdate();
|
||||||
|
|
||||||
|
connection.commit();
|
||||||
|
return Status.SUCCESS;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
if (e.getErrorCode() == 19) {
|
||||||
|
return Status.ALIAS_EXISTS;
|
||||||
|
}
|
||||||
|
return Status.ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Status addAlias(@NotNull String alias, @NotNull UUID noteId) throws RuntimeException {
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
PreparedStatement statement = connection.prepareStatement("""
|
||||||
|
INSERT INTO aliases (alias, note_id)
|
||||||
|
VALUES (?, ?)
|
||||||
|
""");
|
||||||
|
statement.setString(1, alias);
|
||||||
|
statement.setString(2, noteId.toString());
|
||||||
|
statement.executeUpdate();
|
||||||
|
return Status.SUCCESS;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logger.warning("Failed to add alias");
|
||||||
|
return Status.ALIAS_EXISTS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Note getNote(@NotNull String alias) {
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
PreparedStatement statement = connection.prepareStatement("""
|
||||||
|
SELECT * FROM notes
|
||||||
|
WHERE id = (
|
||||||
|
SELECT note_id FROM aliases
|
||||||
|
WHERE alias = ?
|
||||||
|
)
|
||||||
|
""");
|
||||||
|
statement.setString(1, alias);
|
||||||
|
ResultSet resultSet = statement.executeQuery();
|
||||||
|
|
||||||
|
Color color = null;
|
||||||
|
try {
|
||||||
|
color = new Color(resultSet.getInt("color"));
|
||||||
|
} catch (SQLException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return new Note(
|
||||||
|
UUID.fromString(resultSet.getString("id")),
|
||||||
|
resultSet.getString("title"),
|
||||||
|
resultSet.getString("title_url"),
|
||||||
|
resultSet.getString("description"),
|
||||||
|
resultSet.getString("image_url"),
|
||||||
|
resultSet.getString("thumbnail_url"),
|
||||||
|
color,
|
||||||
|
resultSet.getString("author"),
|
||||||
|
resultSet.getString("author_url"),
|
||||||
|
resultSet.getString("footer"),
|
||||||
|
resultSet.getString("footer_url")
|
||||||
|
);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logger.warning("Failed to get note");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Status {
|
||||||
|
SUCCESS,
|
||||||
|
ALIAS_EXISTS,
|
||||||
|
ALIAS_NOT_FOUND,
|
||||||
|
ERROR
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,16 @@
|
|||||||
package me.youhavetrouble.noted.note;
|
package me.youhavetrouble.noted.note;
|
||||||
|
|
||||||
import com.github.benmanes.caffeine.cache.Cache;
|
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
|
||||||
import net.dv8tion.jda.api.EmbedBuilder;
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.time.Duration;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class Note {
|
public class Note {
|
||||||
|
|
||||||
public static final Cache<String, Note> cache = Caffeine.newBuilder()
|
public final UUID id;
|
||||||
.maximumSize(100)
|
|
||||||
.expireAfterWrite(Duration.ofMinutes(1))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
public final String title;
|
public final String title;
|
||||||
public final String titleUrl;
|
public final String titleUrl;
|
||||||
public final String content;
|
public final String content;
|
||||||
@@ -28,7 +22,8 @@ public class Note {
|
|||||||
public final String footer;
|
public final String footer;
|
||||||
public final String footerUrl;
|
public final String footerUrl;
|
||||||
|
|
||||||
private Note(
|
public Note(
|
||||||
|
@NotNull UUID id,
|
||||||
@NotNull String title,
|
@NotNull String title,
|
||||||
@Nullable String titleUrl,
|
@Nullable String titleUrl,
|
||||||
@NotNull String content,
|
@NotNull String content,
|
||||||
@@ -40,6 +35,7 @@ public class Note {
|
|||||||
@Nullable String footer,
|
@Nullable String footer,
|
||||||
@Nullable String footerUrl
|
@Nullable String footerUrl
|
||||||
) {
|
) {
|
||||||
|
this.id = id;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.titleUrl = titleUrl;
|
this.titleUrl = titleUrl;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
@@ -64,4 +60,24 @@ public class Note {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Note createNew(
|
||||||
|
@NotNull String title,
|
||||||
|
@NotNull String content
|
||||||
|
) {
|
||||||
|
UUID id = UUID.randomUUID();
|
||||||
|
return new Note(
|
||||||
|
id,
|
||||||
|
title,
|
||||||
|
null,
|
||||||
|
content,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
DISCORD_TOKEN=your_bot_token_here
|
DISCORD_TOKEN=your_bot_token_here
|
||||||
|
ADMIN_USER_ID=your_user_id_here
|
||||||
|
|||||||
Reference in New Issue
Block a user