Merge pull request #33 from Salmonllama/dev

Springify and Dockerize
This commit is contained in:
Aleksei Gryczewski 2020-09-06 18:35:39 -04:00 committed by GitHub
commit db65acd744
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 313 additions and 137 deletions

17
Dockerfile Normal file
View File

@ -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"]

7
Makefile Normal file
View File

@ -0,0 +1,7 @@
USERNAME=salmonllama
IMAGE=fsbot
TAG := $(shell git describe --tags)
docker:
echo ${TAG}
docker build -t ${USERNAME}/${IMAGE}:${TAG} .

View File

@ -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'
}

Binary file not shown.

View File

@ -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

53
gradlew vendored
View File

@ -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" "$@"

43
gradlew.bat vendored
View File

@ -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

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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"));
}
}

View File

@ -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"));
}
}

View File

@ -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<Role> 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"));
}
}

View File

@ -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";

View File

@ -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());

View File

@ -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<Void> insert(ColorRole cr) {
public static CompletableFuture<Void> insert(ColorRole cr) {
return CompletableFuture.runAsync(() -> {
try {
insertExec(cr);
@ -21,7 +23,7 @@ public class ColorRoleController {
});
}
public CompletableFuture<Boolean> exists(String color) {
public static CompletableFuture<Boolean> exists(String color) {
return CompletableFuture.supplyAsync(() -> {
try {
return existsExec(color);
@ -31,7 +33,7 @@ public class ColorRoleController {
});
}
public CompletableFuture<Boolean> exists(long roleId) {
public static CompletableFuture<Boolean> exists(long roleId) {
return CompletableFuture.supplyAsync(() -> {
try {
return existsExec(roleId);
@ -41,7 +43,7 @@ public class ColorRoleController {
});
}
public CompletableFuture<Optional<ColorRole>> get(String color) {
public static CompletableFuture<Optional<ColorRole>> get(String color) {
return CompletableFuture.supplyAsync(() -> {
try {
return getExec(color);
@ -51,7 +53,7 @@ public class ColorRoleController {
});
}
public CompletableFuture<Optional<ColorRole>> get(long roleId) {
public static CompletableFuture<Optional<ColorRole>> get(long roleId) {
return CompletableFuture.supplyAsync(() -> {
try {
return getExec(roleId);
@ -61,17 +63,17 @@ public class ColorRoleController {
});
}
public CompletableFuture<Integer> count(long serverId) {
public static CompletableFuture<Optional<Collection<ColorRole>>> getAll() {
return CompletableFuture.supplyAsync(() -> {
try {
return countExec(serverId);
return getAllExec();
} catch (SQLException e) {
throw new CompletionException(e);
}
});
}
public CompletableFuture<Void> delete(long roleId) {
public static CompletableFuture<Void> delete(long roleId) {
return CompletableFuture.runAsync(() -> {
try {
deleteExec(roleId);
@ -81,7 +83,7 @@ public class ColorRoleController {
});
}
public CompletableFuture<Void> delete(String color) {
public static CompletableFuture<Void> 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<ColorRole> getExec(String color) throws SQLException {
private static Optional<ColorRole> 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<ColorRole> getExec(Long roleId) throws SQLException {
private static Optional<ColorRole> 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<Collection<ColorRole>> getAllExec() throws SQLException {
ResultSet rs = FSDB.get().select("SELECT * FROM color_roles");
if (rs.next()) {
int count = rs.getInt("count");
Collection<ColorRole> 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"))

View File

@ -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;

View File

@ -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());
});
}
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")
);
});
});
});
}
}

View File

@ -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");
}, () -> {