diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..22e54e5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM gradle:6.6.1-jdk11 AS build + +ENV ENVIRONMENT=PROD + +COPY --chown=gradle:gradle . /home/gradle/src +WORKDIR /home/gradle/src +RUN gradle build --no-daemon + +FROM openjdk:11-jre-slim + +EXPOSE 8080 + +RUN mkdir /app + +COPY --from=build /home/gradle/src/build/libs/*.jar /app/fashionscape-bot.jar + +ENTRYPOINT ["java","-jar","-Xmx800m","/app/fashionscape-bot.jar"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a50a986 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ + USERNAME=salmonllama + IMAGE=fsbot + TAG := $(shell git describe --tags) + +docker: + echo ${TAG} + docker build -t ${USERNAME}/${IMAGE}:${TAG} . \ No newline at end of file diff --git a/build.gradle b/build.gradle index ac7d1e7..203ec66 100644 --- a/build.gradle +++ b/build.gradle @@ -5,9 +5,12 @@ */ plugins { + id 'org.springframework.boot' version '2.3.3.RELEASE' id 'application' } +apply plugin: 'io.spring.dependency-management' + group 'dev.salmonllama' version '2.0.1' @@ -27,6 +30,10 @@ dependencies { implementation 'com.vdurmont:emoji-java:4.0.0' implementation 'com.squareup.okhttp3:okhttp:4.4.0' + implementation 'org.springframework.boot:spring-boot-starter-actuator' + implementation 'org.springframework.boot:spring-boot-starter-web' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation group: 'junit', name: 'junit', version: '4.12' } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 1948b90..e708b1c 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d0edec2..12d38de 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,12 +1,5 @@ -# -# Developed by Alek Gryczewski on 10/18/18 1:39 PM -# Last modified 8/10/18 4:16 AM -# Copyright (c) 2018. All rights reserved. -# - -#Fri Aug 10 04:16:52 EDT 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip diff --git a/gradlew b/gradlew index cccdd3d..4f906e0 100755 --- a/gradlew +++ b/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -66,6 +82,7 @@ esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then @@ -109,10 +126,11 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath @@ -138,19 +156,19 @@ if $cygwin ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi @@ -159,14 +177,9 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index f955316..107acd3 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/src/main/java/dev/salmonllama/fsbot/Main.java b/src/main/java/dev/salmonllama/fsbot/Main.java index 544dceb..794cb29 100644 --- a/src/main/java/dev/salmonllama/fsbot/Main.java +++ b/src/main/java/dev/salmonllama/fsbot/Main.java @@ -12,15 +12,18 @@ import dev.salmonllama.fsbot.listeners.*; import org.javacord.api.DiscordApiBuilder; import dev.salmonllama.fsbot.utilities.Constants; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; // TODO: auto-switching status messages. // TODO: Add an official Logger --> logging to Discord, not console +@SpringBootApplication public class Main { - public static void main(String[] args) { String configLocation = Constants.BOT_FOLDER.concat(Constants.CONFIG_NAME); - BotConfig.initConfig(configLocation, false); // TODO: Use args to dictate newFiling. Also use args to dictate database setup. + BotConfig.initConfig(configLocation, false); + // TODO: Use args to dictate newFiling. Also use args to dictate database setup. FSDB.init(); @@ -40,5 +43,7 @@ public class Main { System.out.printf("Bot invite: %s%n", api.createBotInvite()); System.out.printf("Logged in as %s%n", api.getYourself().getDiscriminatedName()); }); + + SpringApplication.run(Main.class, args); } } diff --git a/src/main/java/dev/salmonllama/fsbot/commands/developer/TestCommand.java b/src/main/java/dev/salmonllama/fsbot/commands/developer/TestCommand.java index 3cac897..312cf1d 100644 --- a/src/main/java/dev/salmonllama/fsbot/commands/developer/TestCommand.java +++ b/src/main/java/dev/salmonllama/fsbot/commands/developer/TestCommand.java @@ -5,6 +5,7 @@ package dev.salmonllama.fsbot.commands.developer; +import dev.salmonllama.fsbot.Main; import dev.salmonllama.fsbot.database.controllers.OutfitController; import dev.salmonllama.fsbot.guthix.Command; import dev.salmonllama.fsbot.guthix.CommandContext; diff --git a/src/main/java/dev/salmonllama/fsbot/commands/general/ColorCommand.java b/src/main/java/dev/salmonllama/fsbot/commands/general/ColorCommand.java index 110ea1f..ca11050 100644 --- a/src/main/java/dev/salmonllama/fsbot/commands/general/ColorCommand.java +++ b/src/main/java/dev/salmonllama/fsbot/commands/general/ColorCommand.java @@ -5,10 +5,15 @@ package dev.salmonllama.fsbot.commands.general; +import dev.salmonllama.fsbot.config.BotConfig; +import dev.salmonllama.fsbot.database.controllers.ColorRoleController; import dev.salmonllama.fsbot.guthix.Command; import dev.salmonllama.fsbot.guthix.CommandContext; import dev.salmonllama.fsbot.guthix.CommandPermission; import dev.salmonllama.fsbot.guthix.PermissionType; +import org.apache.logging.log4j.util.Strings; +import org.javacord.api.entity.server.Server; +import org.javacord.api.entity.user.User; import java.util.ArrayList; import java.util.Arrays; @@ -24,6 +29,43 @@ public class ColorCommand extends Command { @Override public void onCommand(CommandContext ctx) { - ctx.reply("This command is a WIP and will be available soon"); + // The color given will be the args. + // Check if args[0] is reset. If so, remove all color roles. + // Check if the given string is a current color role. + // Remove any color roles that the user has. + // Give the user the color role they specified + ctx.getServer().ifPresentOrElse(server -> { + String[] args = ctx.getArgs(); + if (server.getIdAsString().equals(BotConfig.HOME_SERVER)) { + if (args[0].equals("reset")) { + // Remove all color roles + removeColorRoles(ctx.getUser(), server); + } + + String color = Strings.join(Arrays.asList(args), ' '); + ColorRoleController.get(color).thenAcceptAsync(possibleColorRole -> possibleColorRole.ifPresentOrElse(colorRole -> { + // Remove all color roles + removeColorRoles(ctx.getUser(), server); + // Give the user the one they specified + addColorRole(ctx.getUser(), server, colorRole.getRoleId()); + }, () -> ctx.reply("That color does not exist"))); + } + }, () -> ctx.reply("This command can only be used in the fashionscape server")); + } + + private static void removeColorRoles(User user, Server server) { + ColorRoleController.getAll().thenAcceptAsync( + possibleRoles -> possibleRoles.ifPresent( + colorRoles -> colorRoles.forEach( + colorRole -> server.getRoleById(colorRole.getRoleId()).ifPresent( + role -> user.removeRole(role, "Removed color role") + ) + ) + ) + ); + } + + private static void addColorRole(User user, Server server, long roleId) { + server.getRoleById(roleId).ifPresent(role -> user.addRole(role, "Added color role")); } } diff --git a/src/main/java/dev/salmonllama/fsbot/commands/general/ColorsCommand.java b/src/main/java/dev/salmonllama/fsbot/commands/general/ColorsCommand.java index 0f35521..6fa021e 100644 --- a/src/main/java/dev/salmonllama/fsbot/commands/general/ColorsCommand.java +++ b/src/main/java/dev/salmonllama/fsbot/commands/general/ColorsCommand.java @@ -5,10 +5,13 @@ package dev.salmonllama.fsbot.commands.general; +import dev.salmonllama.fsbot.config.BotConfig; +import dev.salmonllama.fsbot.database.controllers.ColorRoleController; import dev.salmonllama.fsbot.guthix.Command; import dev.salmonllama.fsbot.guthix.CommandContext; import dev.salmonllama.fsbot.guthix.CommandPermission; import dev.salmonllama.fsbot.guthix.PermissionType; +import org.javacord.api.entity.message.embed.EmbedBuilder; import java.util.ArrayList; import java.util.Arrays; @@ -24,6 +27,26 @@ public class ColorsCommand extends Command { @Override public void onCommand(CommandContext ctx) { - ctx.reply("This command is a WIP and will be available soon."); + // List available color roles + ctx.getServer().ifPresentOrElse(server -> { + if (server.getIdAsString().equals(BotConfig.HOME_SERVER)) { + ColorRoleController.getAll().thenAcceptAsync( + possibleColorRoles -> possibleColorRoles.ifPresentOrElse(colorRoles -> { + EmbedBuilder response = new EmbedBuilder() + .setTitle("Color roles") + .setFooter(String.format("Found %d roles", colorRoles.size())); + + colorRoles.forEach( + colorRole -> server.getRoleById(colorRole.getRoleId()).ifPresent( + role -> response.addField(colorRole.getColor(), role.getMentionTag(), true) + ) + ); + + ctx.reply(response); + }, () -> ctx.reply("No color roles have been found"))); + } else { + ctx.reply("This command can only be used in the fashionscape server"); + } + }, () -> ctx.reply("This command can only be used in the fashionscape server")); } } diff --git a/src/main/java/dev/salmonllama/fsbot/commands/staff/AddColorCommand.java b/src/main/java/dev/salmonllama/fsbot/commands/staff/AddColorCommand.java index 0e7536f..2863f78 100644 --- a/src/main/java/dev/salmonllama/fsbot/commands/staff/AddColorCommand.java +++ b/src/main/java/dev/salmonllama/fsbot/commands/staff/AddColorCommand.java @@ -6,14 +6,18 @@ package dev.salmonllama.fsbot.commands.staff; import dev.salmonllama.fsbot.config.BotConfig; +import dev.salmonllama.fsbot.database.controllers.ColorRoleController; +import dev.salmonllama.fsbot.database.models.ColorRole; import dev.salmonllama.fsbot.guthix.Command; import dev.salmonllama.fsbot.guthix.CommandContext; import dev.salmonllama.fsbot.guthix.CommandPermission; import dev.salmonllama.fsbot.guthix.PermissionType; +import org.javacord.api.entity.permission.Role; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.List; public class AddColorCommand extends Command { @Override public String name() { return "Add Color"; } @@ -25,6 +29,22 @@ public class AddColorCommand extends Command { @Override public void onCommand(CommandContext ctx) { - ctx.reply("This command is a WIP and will be available soon."); + // Command takes only a role mention. + ctx.getServer().ifPresentOrElse(server -> { + if (server.getIdAsString().equals(BotConfig.HOME_SERVER)) { + List roles = ctx.getMessage().getMentionedRoles(); + roles.forEach(role -> { + ColorRole colorRole = new ColorRole.ColorRoleBuilder(role.getId()) + .setColor(role.getName()) + .setServerId(server.getId()) + .build(); + + ColorRoleController.insert(colorRole); + ctx.reply("Added color role:" + colorRole.toString()); + }); + } else { + ctx.reply("This command can only be used in the fashionscape server"); + } + }, () -> ctx.reply("This command can only be used in the fashionscape server")); } } diff --git a/src/main/java/dev/salmonllama/fsbot/config/BotConfig.java b/src/main/java/dev/salmonllama/fsbot/config/BotConfig.java index 6911530..f202a66 100644 --- a/src/main/java/dev/salmonllama/fsbot/config/BotConfig.java +++ b/src/main/java/dev/salmonllama/fsbot/config/BotConfig.java @@ -58,7 +58,7 @@ public class BotConfig { public static String OUTFIT_LOG = "outfit log channel"; @ConfigurationOption - public static String BOT_LOG = "bot_log_channel"; + public static String ACTIVITY_LOG = "bot_log_channel"; @ConfigurationOption public static String HYDRIX_ROLE = "hydrix role id here"; diff --git a/src/main/java/dev/salmonllama/fsbot/database/FSDB.java b/src/main/java/dev/salmonllama/fsbot/database/FSDB.java index c353589..83f80bd 100644 --- a/src/main/java/dev/salmonllama/fsbot/database/FSDB.java +++ b/src/main/java/dev/salmonllama/fsbot/database/FSDB.java @@ -21,7 +21,7 @@ public class FSDB { return connections.get(key); } - System.out.println(String.format("Specified connection %s has not been set.", key)); + System.out.printf("Specified connection %s has not been set.%n", key); return null; } @@ -39,6 +39,7 @@ public class FSDB { private static void prepareTables() { try { get().query(Outfit.schema()); + get().query(ColorRole.schema()); get().query(GalleryChannel.schema()); get().query(ServerConfig.schema()); get().query(ServerBlacklist.schema()); diff --git a/src/main/java/dev/salmonllama/fsbot/database/controllers/ColorRoleController.java b/src/main/java/dev/salmonllama/fsbot/database/controllers/ColorRoleController.java index 896dd11..e249342 100644 --- a/src/main/java/dev/salmonllama/fsbot/database/controllers/ColorRoleController.java +++ b/src/main/java/dev/salmonllama/fsbot/database/controllers/ColorRoleController.java @@ -5,13 +5,15 @@ import dev.salmonllama.fsbot.database.models.ColorRole; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; public class ColorRoleController { // Need insert, get by color, exists by color, exists by role, get by server, count, and delete - public CompletableFuture insert(ColorRole cr) { + public static CompletableFuture insert(ColorRole cr) { return CompletableFuture.runAsync(() -> { try { insertExec(cr); @@ -21,7 +23,7 @@ public class ColorRoleController { }); } - public CompletableFuture exists(String color) { + public static CompletableFuture exists(String color) { return CompletableFuture.supplyAsync(() -> { try { return existsExec(color); @@ -31,7 +33,7 @@ public class ColorRoleController { }); } - public CompletableFuture exists(long roleId) { + public static CompletableFuture exists(long roleId) { return CompletableFuture.supplyAsync(() -> { try { return existsExec(roleId); @@ -41,7 +43,7 @@ public class ColorRoleController { }); } - public CompletableFuture> get(String color) { + public static CompletableFuture> get(String color) { return CompletableFuture.supplyAsync(() -> { try { return getExec(color); @@ -51,7 +53,7 @@ public class ColorRoleController { }); } - public CompletableFuture> get(long roleId) { + public static CompletableFuture> get(long roleId) { return CompletableFuture.supplyAsync(() -> { try { return getExec(roleId); @@ -61,17 +63,17 @@ public class ColorRoleController { }); } - public CompletableFuture count(long serverId) { + public static CompletableFuture>> getAll() { return CompletableFuture.supplyAsync(() -> { try { - return countExec(serverId); + return getAllExec(); } catch (SQLException e) { throw new CompletionException(e); } }); } - public CompletableFuture delete(long roleId) { + public static CompletableFuture delete(long roleId) { return CompletableFuture.runAsync(() -> { try { deleteExec(roleId); @@ -81,7 +83,7 @@ public class ColorRoleController { }); } - public CompletableFuture delete(String color) { + public static CompletableFuture delete(String color) { return CompletableFuture.runAsync(() -> { try { deleteExec(color); @@ -91,7 +93,7 @@ public class ColorRoleController { }); } - private void insertExec(ColorRole cr) throws SQLException { + private static void insertExec(ColorRole cr) throws SQLException { FSDB.get().insert("INSERT INTO color_roles (role_id, server_id, color) VALUES (?, ?, ?)", cr.getRoleId(), cr.getServerId(), @@ -99,7 +101,7 @@ public class ColorRoleController { ); } - private boolean existsExec(String color) throws SQLException { + private static boolean existsExec(String color) throws SQLException { ResultSet rs = FSDB.get().select("SELECT EXISTS(SELECT 1 FROM color_roles WHERE color = ?) AS hmm", color); boolean exists = rs.getBoolean("hmm"); @@ -107,7 +109,7 @@ public class ColorRoleController { return exists; } - private boolean existsExec(long roleId) throws SQLException { + private static boolean existsExec(long roleId) throws SQLException { ResultSet rs = FSDB.get().select("SELECT EXISTS(SELECT 1 FROM color_roles WHERE role_id = ?) AS hmm", roleId); boolean exists = rs.getBoolean("hmm"); @@ -115,7 +117,7 @@ public class ColorRoleController { return exists; } - private Optional getExec(String color) throws SQLException { + private static Optional getExec(String color) throws SQLException { ResultSet rs = FSDB.get().select("SELECT * FROM color_roles WHERE color = ?", color); if (rs.next()) { @@ -128,7 +130,7 @@ public class ColorRoleController { return Optional.empty(); } - private Optional getExec(Long roleId) throws SQLException { + private static Optional getExec(Long roleId) throws SQLException { ResultSet rs = FSDB.get().select("SELECT * FROM color_roles WHERE role_id = ?", roleId); if (rs.next()) { @@ -141,28 +143,31 @@ public class ColorRoleController { return Optional.empty(); } - private int countExec(long serverId) throws SQLException { - ResultSet rs = FSDB.get().select("SELECT COUNT(*) AS count FROM color_roles WHERE server_id = ?", serverId); + private static Optional> getAllExec() throws SQLException { + ResultSet rs = FSDB.get().select("SELECT * FROM color_roles"); - if (rs.next()) { - int count = rs.getInt("count"); + Collection roles = new ArrayList<>(); + while (rs.next()) { + roles.add(mapObject(rs)); FSDB.get().close(rs); - return count; } - FSDB.get().close(rs); - return 0; + if (roles.isEmpty()) { + return Optional.empty(); + } + + return Optional.of(roles); } - private void deleteExec(long roleId) throws SQLException { + private static void deleteExec(long roleId) throws SQLException { FSDB.get().query("DELETE FROM color_roles WHERE role_id = ?", roleId); } - private void deleteExec(String color) throws SQLException { + private static void deleteExec(String color) throws SQLException { FSDB.get().query("DELETE FROM color_roles WHERE color = ?", color); } - private ColorRole mapObject(ResultSet rs) throws SQLException { + private static ColorRole mapObject(ResultSet rs) throws SQLException { return new ColorRole.ColorRoleBuilder(rs.getLong("role_id")) .setServerId(rs.getLong("server_id")) .setColor(rs.getString("color")) diff --git a/src/main/java/dev/salmonllama/fsbot/database/models/ColorRole.java b/src/main/java/dev/salmonllama/fsbot/database/models/ColorRole.java index 39ff347..cd2810a 100644 --- a/src/main/java/dev/salmonllama/fsbot/database/models/ColorRole.java +++ b/src/main/java/dev/salmonllama/fsbot/database/models/ColorRole.java @@ -8,9 +8,9 @@ package dev.salmonllama.fsbot.database.models; import dev.salmonllama.fsbot.database.DatabaseModel; public class ColorRole extends DatabaseModel { - private long roleId; - private long serverId; - private String color; + private final long roleId; + private final long serverId; + private final String color; public ColorRole(ColorRoleBuilder builder) { roleId = builder.roleId; @@ -34,8 +34,13 @@ public class ColorRole extends DatabaseModel { return "CREATE TABLE IF NOT EXISTS color_roles (role_id INTEGER, server_id INTEGER, color TEXT)"; } + @Override + public String toString() { + return String.format("Color Role: {roleId: %d, serverId: %d, color: %s", roleId, serverId, color); + } + public static class ColorRoleBuilder { - private long roleId; + private final long roleId; private long serverId; private String color; diff --git a/src/main/java/dev/salmonllama/fsbot/listeners/ImageListener.java b/src/main/java/dev/salmonllama/fsbot/listeners/ImageListener.java index f384857..021d49d 100644 --- a/src/main/java/dev/salmonllama/fsbot/listeners/ImageListener.java +++ b/src/main/java/dev/salmonllama/fsbot/listeners/ImageListener.java @@ -11,22 +11,26 @@ import dev.salmonllama.fsbot.database.controllers.GalleryController; import dev.salmonllama.fsbot.database.controllers.OutfitController; import dev.salmonllama.fsbot.database.models.Outfit; import dev.salmonllama.fsbot.endpoints.imgur.ImgurAPIConnection; +import org.javacord.api.entity.channel.ServerTextChannel; import org.javacord.api.entity.message.MessageAttachment; import org.javacord.api.entity.message.embed.EmbedBuilder; import org.javacord.api.event.message.MessageCreateEvent; import org.javacord.api.listener.message.MessageCreateListener; import org.javacord.api.util.logging.ExceptionLogger; +import java.util.UUID; + public class ImageListener implements MessageCreateListener { @Override - public void onMessageCreate(MessageCreateEvent event) { // TODO: This needs immediate help + public void onMessageCreate(MessageCreateEvent event) { // Check for valid source -> DONE -> WORKING // Check for gallery channel presence -> DONE -> WORKING // Check for images (attached files and links from approved sources) -> DONE -> WORKING (approved links to be added later) // Upload the image(s) to imgur -> DONE -> WORKING // Store the image in the database -> DONE -> WORKING // Send confirmation && log event -> IN PROGRESS (waiting for logger upgrade) + // Check for production environment to avoid uploading dev images to Imgur -> DONE -> WORKING if (!event.getMessageAuthor().isRegularUser()) { // Ignore anything that is a webhook or a bot message @@ -40,61 +44,89 @@ public class ImageListener implements MessageCreateListener { if (exists) { // Check the message for images if (event.getMessageAttachments().stream().anyMatch(MessageAttachment::isImage)) { - // Upload the image(s) to Imgur, store in database, log the stored images. - ImgurAPIConnection imgur = new ImgurAPIConnection(); + event.getMessageAttachments().stream().filter(MessageAttachment::isImage).forEach(image -> { + // Check the ENVIRONMENT env-var. If PROD -> Upload to imgur and store. If not, just store + // Upload the image(s) to Imgur, store in database, log the stored images. - event.getMessageAttachments() - .stream() - .filter(MessageAttachment::isImage) - .forEach(image -> { - // Upload to Imgur - imgur.uploadImage(image.getUrl().toString()).thenAccept(upload -> { - // Store in the database - Outfit.OutfitBuilder outfitBuilder = new Outfit.OutfitBuilder() - .setId(upload.getId()) - .setMeta(event.getMessageContent()) - .setLink(upload.getLink()) - .setSubmitter(event.getMessageAuthor().getIdAsString()) - .setDeleteHash(upload.getDeleteHash()); - - GalleryController.getTag(channel.getIdAsString()).thenAccept(tag -> { - outfitBuilder.setTag(tag); - Outfit outfit = outfitBuilder.build(); - - OutfitController.insert(outfit).thenAcceptAsync((Void) -> { - // Log the outfit - event.getApi().getServerTextChannelById(BotConfig.OUTFIT_LOG).ifPresentOrElse(chnl -> { - EmbedBuilder response = new EmbedBuilder() - .setTitle("Outfit Added") - .setAuthor(event.getMessageAuthor()) - .setThumbnail(outfit.getLink()) - .setFooter(String.format("%s | %s", outfit.getTag(), outfit.getId())) - .setUrl(outfit.getLink()) - .addField("Uploaded:", outfit.getCreated().toString()); - - if (!outfit.getMeta().equals("")) { - response.addField("Meta:", outfit.getMeta()); - } - - chnl.sendMessage(response); - - // Add the reaction to the original message - GalleryController.getEmoji(channel.getIdAsString()).thenAcceptAsync(emoji -> { - event.getMessage().addReaction(EmojiParser.parseToUnicode(emoji)); - }).exceptionally(ExceptionLogger.get()); - }, () -> { - // Fallback error message to me - event.getApi().getUserById(BotConfig.BOT_OWNER).thenAcceptAsync(user -> { - user.sendMessage("Could not find OUTFIT LOG"); - }); - }); - }); - }); - }).exceptionally(ExceptionLogger.get()); - }); + if (System.getenv("ENVIRONMENT") != null) { + // Upload the image(s) to Imgur, store in database, log the stored images. + System.out.println("PROD environment, uploading"); + uploadAndStore(event, channel, image); + } else { + // Store the image(s) in database, log the stored images. + System.out.println("DEV environment, not uploading"); + store(event, channel, image); + } + }); } } }).exceptionally(ExceptionLogger.get()); }); } -} \ No newline at end of file + + private void uploadAndStore(MessageCreateEvent event, ServerTextChannel channel, MessageAttachment image) { + ImgurAPIConnection imgur = new ImgurAPIConnection(); + + // Upload to Imgur + imgur.uploadImage(image.getUrl().toString()).thenAccept(upload -> { + // Store in the database + Outfit.OutfitBuilder outfitBuilder = new Outfit.OutfitBuilder() + .setId(upload.getId()) + .setMeta(event.getMessageContent()) + .setLink(upload.getLink()) + .setSubmitter(event.getMessageAuthor().getIdAsString()) + .setDeleteHash(upload.getDeleteHash()); + + storeAndLog(event, channel, outfitBuilder); + }).exceptionally(ExceptionLogger.get()); + } + + private void store(MessageCreateEvent event, ServerTextChannel channel, MessageAttachment image) { + // Store in the database + Outfit.OutfitBuilder outfitBuilder = new Outfit.OutfitBuilder() + .setId(UUID.randomUUID().toString()) + .setMeta(event.getMessageContent()) + .setLink("DUMMY-LINK") + .setSubmitter(event.getMessageAuthor().getIdAsString()) + .setDeleteHash("DUMMY-DELETE-HASH"); + + storeAndLog(event, channel, outfitBuilder); + } + + private void storeAndLog(MessageCreateEvent event, ServerTextChannel channel, Outfit.OutfitBuilder outfitBuilder) { + GalleryController.getTag(channel.getIdAsString()).thenAccept(tag -> { + outfitBuilder.setTag(tag); + Outfit outfit = outfitBuilder.build(); + + OutfitController.insert(outfit).thenAcceptAsync((Void) -> { + // Log the outfit + event.getApi().getServerTextChannelById(BotConfig.OUTFIT_LOG).ifPresentOrElse(chnl -> { + EmbedBuilder response = new EmbedBuilder() + .setTitle("Outfit Added") + .setAuthor(event.getMessageAuthor()) + .setThumbnail(outfit.getLink()) + .setFooter(String.format("%s | %s", outfit.getTag(), outfit.getId())) + .setUrl(outfit.getLink()) + .addField("Uploaded:", outfit.getCreated().toString()); + + if (!outfit.getMeta().equals("")) { + response.addField("Meta:", outfit.getMeta()); + } + + chnl.sendMessage(response); + + // Add the reaction to the original message + GalleryController.getEmoji(channel.getIdAsString()).thenAcceptAsync( + emoji -> event.getMessage().addReaction(EmojiParser.parseToUnicode(emoji)) + ).exceptionally(ExceptionLogger.get()); + }, () -> { + // Fallback error message to me + event.getApi().getUserById(BotConfig.BOT_OWNER).thenAcceptAsync( + user -> user.sendMessage("Could not find OUTFIT LOG") + ); + }); + }); + }); + } +} + diff --git a/src/main/java/dev/salmonllama/fsbot/logging/Logger.java b/src/main/java/dev/salmonllama/fsbot/logging/Logger.java index 4d5c5ed..c48d982 100644 --- a/src/main/java/dev/salmonllama/fsbot/logging/Logger.java +++ b/src/main/java/dev/salmonllama/fsbot/logging/Logger.java @@ -18,7 +18,7 @@ public class Logger { private final String OUTFIT_LOG = BotConfig.OUTFIT_LOG; private final String REPORT_LOG = BotConfig.REPORT_LOG; private final String JOIN_LOG = BotConfig.JOIN_LOG; - private final String BOT_LOG = BotConfig.BOT_LOG; + private final String ACTIVITY_LOG = BotConfig.ACTIVITY_LOG; private final String SALMONLLAMA = BotConfig.BOT_OWNER; private EmbedBuilder reportEmbed; @@ -54,7 +54,7 @@ public class Logger { } public void logError(String errorMsg) { - api.getServerTextChannelById(BOT_LOG).ifPresentOrElse(channel -> { + api.getServerTextChannelById(ACTIVITY_LOG).ifPresentOrElse(channel -> { // Log the thing channel.sendMessage("error"); }, () -> {