diff options
| author | Pinapelz <yukais@pinapelz.com> | 2025-12-26 21:48:57 -0800 |
|---|---|---|
| committer | Pinapelz <yukais@pinapelz.com> | 2025-12-26 21:48:57 -0800 |
| commit | a0414925cdf6d57acc8d2f0f0646e495707bd632 (patch) | |
| tree | 9d08efd4d6d0b300b8fda433ddbc1c5025f3b58a | |
initial commit
| -rw-r--r-- | .gitignore | 41 | ||||
| -rw-r--r-- | pom.xml | 70 | ||||
| -rw-r--r-- | schema.sql | 43 | ||||
| -rw-r--r-- | src/main/java/com/pinapelz/Database.java | 60 | ||||
| -rw-r--r-- | src/main/java/com/pinapelz/FileSystem.java | 23 | ||||
| -rw-r--r-- | src/main/java/com/pinapelz/Main.java | 35 | ||||
| -rw-r--r-- | src/main/java/com/pinapelz/MessageListener.java | 39 |
7 files changed, 311 insertions, 0 deletions
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 @@ -0,0 +1,70 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.example</groupId> + <artifactId>NewDiscordAsStorage</artifactId> + <version>1.0-SNAPSHOT</version> + <packaging>jar</packaging> + + <name>NewDiscordAsStorage</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>net.dv8tion</groupId> + <artifactId>JDA</artifactId> + <version>6.2.0</version> + <!-- Optionally disable audio natives to reduce jar size by excluding `opus-java` and `tink` --> + <exclusions> + <!-- required for encoding audio into opus, not needed if audio is already provided in opus encoding + <exclusion> + <groupId>club.minnced</groupId> + <artifactId>opus-java</artifactId> + </exclusion> --> + <!-- required for encrypting and decrypting audio + <exclusion> + <groupId>com.google.crypto.tink</groupId> + <artifactId>tink</artifactId> + </exclusion> --> + </exclusions> + </dependency> + <dependency> + <groupId>io.github.cdimascio</groupId> + <artifactId>dotenv-java</artifactId> + <version>3.0.0</version> + </dependency> + <dependency> + <groupId>org.postgresql</groupId> + <artifactId>postgresql</artifactId> + <version>42.7.7</version> + </dependency> + <dependency> + <groupId>com.sparkjava</groupId> + <artifactId>spark-core</artifactId> + <version>2.9.4</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>3.8.1</version> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>15</source> + <target>15</target> + </configuration> + </plugin> + </plugins> + </build> +</project> 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(...) + } + } + +} |
