From a0414925cdf6d57acc8d2f0f0646e495707bd632 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Fri, 26 Dec 2025 21:48:57 -0800 Subject: initial commit --- .gitignore | 41 +++++++++++++++ pom.xml | 70 +++++++++++++++++++++++++ schema.sql | 43 +++++++++++++++ src/main/java/com/pinapelz/Database.java | 60 +++++++++++++++++++++ src/main/java/com/pinapelz/FileSystem.java | 23 ++++++++ src/main/java/com/pinapelz/Main.java | 35 +++++++++++++ src/main/java/com/pinapelz/MessageListener.java | 39 ++++++++++++++ 7 files changed, 311 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 schema.sql create mode 100644 src/main/java/com/pinapelz/Database.java create mode 100644 src/main/java/com/pinapelz/FileSystem.java create mode 100644 src/main/java/com/pinapelz/Main.java create mode 100644 src/main/java/com/pinapelz/MessageListener.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bd2f63d --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ +.kotlin + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store +/.env +.idea \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..6860f34 --- /dev/null +++ b/pom.xml @@ -0,0 +1,70 @@ + + 4.0.0 + + org.example + NewDiscordAsStorage + 1.0-SNAPSHOT + jar + + NewDiscordAsStorage + http://maven.apache.org + + + UTF-8 + + + + + net.dv8tion + JDA + 6.2.0 + + + + + + + + io.github.cdimascio + dotenv-java + 3.0.0 + + + org.postgresql + postgresql + 42.7.7 + + + com.sparkjava + spark-core + 2.9.4 + + + junit + junit + 3.8.1 + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 15 + 15 + + + + + diff --git a/schema.sql b/schema.sql new file mode 100644 index 0000000..aa5ee69 --- /dev/null +++ b/schema.sql @@ -0,0 +1,43 @@ +-- ========================= +-- Directories table +-- ========================= +CREATE TABLE IF NOT EXISTS directories ( + directory_id BIGSERIAL PRIMARY KEY, + path TEXT NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + CONSTRAINT directories_path_unique UNIQUE (path) +); + +-- ========================= +-- Files table +-- ========================= +CREATE TABLE IF NOT EXISTS files ( + file_id BIGSERIAL PRIMARY KEY, + disc_channel_id VARCHAR(255) NOT NULL, + disc_message_id VARCHAR(255) NOT NULL, + directory_id BIGINT NOT NULL + REFERENCES directories(directory_id) + ON DELETE RESTRICT, + file_name TEXT NOT NULL, + file_description TEXT, + size BIGINT, + mime_type TEXT, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + CONSTRAINT files_unique_name_per_directory + UNIQUE (directory_id, file_name) +); + +-- ========================= +-- Indexes +-- ========================= + +CREATE INDEX IF NOT EXISTS idx_directories_path +ON directories (path); + +CREATE INDEX IF NOT EXISTS idx_files_directory +ON files (directory_id); + + +INSERT INTO directories (path) +VALUES ('') +ON CONFLICT (path) DO NOTHING; \ No newline at end of file diff --git a/src/main/java/com/pinapelz/Database.java b/src/main/java/com/pinapelz/Database.java new file mode 100644 index 0000000..41d5257 --- /dev/null +++ b/src/main/java/com/pinapelz/Database.java @@ -0,0 +1,60 @@ +/* +Postgres will serve as the index for managing all the files. Iteration through all messages is too slow + */ +package com.pinapelz; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.sql.*; +import java.util.Properties; + +public class Database { + + private Connection conn; + + public Database(String host, String user, String password, String db){ + try { + conn = createDBConnection(host, user, password, db); + System.out.println("[Database] Running schema.sql as necessary"); + String schemaSQL = Files.readString(Path.of("schema.sql")); + Statement statement = conn.createStatement(); + statement.execute(schemaSQL); + } catch (IOException | SQLException e) { + throw new RuntimeException(e); + } + + } + + public static Connection createDBConnection(String host, String user, String password, String db) throws IOException, SQLException { + String url = "jdbc:postgresql://"+host+"/"+db+"?sslmode=require&channel_binding=require"; + Properties props = new Properties(); + props.setProperty("user", user); + props.setProperty("password", password); + return DriverManager.getConnection(url, props); + } + + public void recordFileMetadata(String channelId, String messageId, int rootDirId, String fileName, String description, int size, String mimeType) throws SQLException { + PreparedStatement ps = conn.prepareStatement(""" + INSERT INTO files ( + disc_channel_id, + disc_message_id, + directory_id, + file_name, + file_description, + size, + mime_type + ) + VALUES (?, ?, ?, ?, ?, ?, ?) +"""); + ps.setString(1, channelId); + ps.setString(2, messageId); + ps.setLong(3, rootDirId); + ps.setString(4, fileName); + ps.setString(5, description); + ps.setLong(6, size); + ps.setString(7, mimeType); + ps.executeUpdate(); + + } +} diff --git a/src/main/java/com/pinapelz/FileSystem.java b/src/main/java/com/pinapelz/FileSystem.java new file mode 100644 index 0000000..61b1bd6 --- /dev/null +++ b/src/main/java/com/pinapelz/FileSystem.java @@ -0,0 +1,23 @@ +package com.pinapelz; + +import net.dv8tion.jda.api.entities.Message; + +import java.sql.SQLException; + +public class FileSystem { + private Database database; + public FileSystem(String dbHost, String dbUser, String dbPass, String dbName){ + database = new Database(dbHost, dbUser, dbPass, dbName); + } + + public void createNewFile(String messageId, String channelId, String description, Message.Attachment attachment){ + int fileSize = attachment.getSize(); + String filename = attachment.getFileName(); + String mimeType = attachment.getContentType(); + try { + database.recordFileMetadata(channelId, messageId, 1, filename, description, fileSize, mimeType ); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/com/pinapelz/Main.java b/src/main/java/com/pinapelz/Main.java new file mode 100644 index 0000000..22ead2c --- /dev/null +++ b/src/main/java/com/pinapelz/Main.java @@ -0,0 +1,35 @@ +package com.pinapelz; + +import io.github.cdimascio.dotenv.Dotenv; +import net.dv8tion.jda.api.JDABuilder; +import net.dv8tion.jda.api.requests.GatewayIntent; +import static spark.Spark.*; + +public class Main +{ + private static final Dotenv dotenv = Dotenv.load(); + + public static String readSetting(String parameter) { + String value = System.getenv(parameter); + if (value != null) return value; + return dotenv.get(parameter); + } + + public static void startBot(){ + String dbHost = readSetting("PGHOST"); + String dbUser = readSetting("PGUSER"); + String dbPass = readSetting("PGPASSWORD"); + String dbName = readSetting("PGDATABASE"); + JDABuilder.createDefault(readSetting("BOT_TOKEN")) + .addEventListeners(new MessageListener(dbHost, dbUser, dbPass, dbName)) + .enableIntents(GatewayIntent.MESSAGE_CONTENT) + .build(); + } + + public static void main(String[] args) throws Exception{ + startBot(); + get("/hello", (req, res) -> "Hello World"); + } + + +} diff --git a/src/main/java/com/pinapelz/MessageListener.java b/src/main/java/com/pinapelz/MessageListener.java new file mode 100644 index 0000000..642d484 --- /dev/null +++ b/src/main/java/com/pinapelz/MessageListener.java @@ -0,0 +1,39 @@ +package com.pinapelz; + +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; + +public class MessageListener extends ListenerAdapter { + + private FileSystem fileSystem; + + public MessageListener(String dbHost, String dbUser, String dbPass, String dbName){ + fileSystem = new FileSystem(dbHost, dbUser, dbPass, dbName); + + } + + @Override + public void onMessageReceived(MessageReceivedEvent event) + { + if (event.getAuthor().isBot()) return; + Message message = event.getMessage(); + String content = message.getContentRaw(); + + System.out.println(message.getAttachments().get(0).getUrl()); + if(!message.getAttachments().isEmpty()){ + System.out.println("Attachment Received! Filing this away now..."); + for(Message.Attachment attachment : message.getAttachments()){ + fileSystem.createNewFile(message.getChannelId(), message.getChannelId(), content, attachment); + } + } + + if (content.equals("!ping")) + { + MessageChannel channel = event.getChannel(); + channel.sendMessage("Pong!").queue(); // Important to call .queue() on the RestAction returned by sendMessage(...) + } + } + +} -- cgit v1.2.3