[AB-197] splitting utility maven module into separate maven modules

aligning some package names
removing some unnecessary computed values from liquibase
This commit is contained in:
Sheldan
2021-03-12 17:29:49 +01:00
parent e2da800d84
commit 2ed456c164
835 changed files with 12790 additions and 3310 deletions

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.utility.commands;
package dev.sheldan.abstracto.utility.command;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
@@ -8,11 +8,11 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.serverinfo.ServerInfoModel;
import dev.sheldan.abstracto.utility.config.UtilityFeatureDefinition;
import dev.sheldan.abstracto.utility.model.ServerInfoModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -43,7 +43,7 @@ public class ServerInfo extends AbstractConditionableCommand {
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("serverInfo")
.module(UtilityModuleInterface.UTILITY)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.async(true)
.supportsEmbedException(true)
@@ -54,7 +54,7 @@ public class ServerInfo extends AbstractConditionableCommand {
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.UTILITY;
public FeatureDefinition getFeature() {
return UtilityFeatureDefinition.UTILITY;
}
}

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.utility.commands;
package dev.sheldan.abstracto.utility.command;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
@@ -8,11 +8,11 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.ShowAvatarModel;
import dev.sheldan.abstracto.utility.config.UtilityFeatureDefinition;
import dev.sheldan.abstracto.utility.model.ShowAvatarModel;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
@@ -49,7 +49,7 @@ public class ShowAvatar extends AbstractConditionableCommand {
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("showAvatar")
.module(UtilityModuleInterface.UTILITY)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.async(true)
.supportsEmbedException(true)
@@ -60,7 +60,7 @@ public class ShowAvatar extends AbstractConditionableCommand {
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.UTILITY;
public FeatureDefinition getFeature() {
return UtilityFeatureDefinition.UTILITY;
}
}

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.utility.commands;
package dev.sheldan.abstracto.utility.command;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
@@ -8,11 +8,11 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.ShowEmoteLog;
import dev.sheldan.abstracto.utility.config.UtilityFeatureDefinition;
import dev.sheldan.abstracto.utility.model.ShowEmoteLog;
import net.dv8tion.jda.api.entities.Emote;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -46,7 +46,7 @@ public class ShowEmote extends AbstractConditionableCommand {
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("showEmote")
.module(UtilityModuleInterface.UTILITY)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.async(true)
.supportsEmbedException(true)
@@ -57,7 +57,7 @@ public class ShowEmote extends AbstractConditionableCommand {
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.UTILITY;
public FeatureDefinition getFeature() {
return UtilityFeatureDefinition.UTILITY;
}
}

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.utility.commands;
package dev.sheldan.abstracto.utility.command;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
@@ -8,12 +8,12 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.UserInfoModel;
import dev.sheldan.abstracto.utility.config.UtilityFeatureDefinition;
import dev.sheldan.abstracto.utility.model.UserInfoModel;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
@@ -68,7 +68,7 @@ public class UserInfo extends AbstractConditionableCommand {
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("userInfo")
.module(UtilityModuleInterface.UTILITY)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.async(true)
.supportsEmbedException(true)
@@ -79,7 +79,7 @@ public class UserInfo extends AbstractConditionableCommand {
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.UTILITY;
public FeatureDefinition getFeature() {
return UtilityFeatureDefinition.UTILITY;
}
}

View File

@@ -1,73 +0,0 @@
package dev.sheldan.abstracto.utility.commands;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.MemberStarStatsModel;
import dev.sheldan.abstracto.utility.service.StarboardService;
import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class StarStats extends AbstractConditionableCommand {
public static final String STARSTATS_RESPONSE_TEMPLATE = "starStats_response";
public static final String STARSTATS_SINGLE_MEMBER_RESPONSE_TEMPLATE = "starStats_single_member_response";
@Autowired
private StarboardService starboardService;
@Autowired
private ChannelService channelService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
if(parameters.isEmpty()) {
return starboardService.retrieveStarStats(commandContext.getGuild().getIdLong())
.thenCompose(starStatsModel ->
FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(STARSTATS_RESPONSE_TEMPLATE, starStatsModel, commandContext.getChannel()))
).thenApply(o -> CommandResult.fromIgnored());
} else {
Member targetMember = (Member) parameters.get(0);
MemberStarStatsModel memberStarStatsModel = starboardService.retrieveStarStatsForMember(targetMember);
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(STARSTATS_SINGLE_MEMBER_RESPONSE_TEMPLATE, memberStarStatsModel, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
}
@Override
public CommandConfiguration getConfiguration() {
Parameter memberParameter = Parameter.builder().templated(true).name("member").type(Member.class).optional(true).build();
List<Parameter> parameters = Collections.singletonList(memberParameter);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("starStats")
.module(UtilityModuleInterface.UTILITY)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(false)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.STARBOARD;
}
}

View File

@@ -1,65 +0,0 @@
package dev.sheldan.abstracto.utility.commands.entertainment;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.ChooseResponseModel;
import dev.sheldan.abstracto.utility.service.EntertainmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class Choose extends AbstractConditionableCommand {
public static final String CHOOSE_RESPONSE_TEMPLATE_KEY = "choose_response";
@Autowired
private EntertainmentService entertainmentService;
@Autowired
private ChannelService channelService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<String> choices = (List) commandContext.getParameters().getParameters().get(0);
String choice = entertainmentService.takeChoice(choices, commandContext.getAuthor());
ChooseResponseModel responseModel = (ChooseResponseModel) ContextConverter.slimFromCommandContext(commandContext, ChooseResponseModel.class);
responseModel.setChosenValue(choice);
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(CHOOSE_RESPONSE_TEMPLATE_KEY, responseModel, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
parameters.add(Parameter.builder().name("text").type(String.class).templated(true).remainder(true).isListParam(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("choose")
.async(true)
.module(UtilityModuleInterface.UTILITY)
.templated(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.UTILITY;
}
}

View File

@@ -1,69 +0,0 @@
package dev.sheldan.abstracto.utility.commands.entertainment;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.utility.config.EntertainmentModuleInterface;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.EightBallResponseModel;
import dev.sheldan.abstracto.utility.service.EntertainmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class EightBall extends AbstractConditionableCommand {
public static final String EIGHT_BALL_RESPONSE_TEMPLATE_KEY = "eight_ball_response";
@Autowired
private EntertainmentService entertainmentService;
@Autowired
private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
String text = (String) commandContext.getParameters().getParameters().get(0);
String chosenKey = entertainmentService.getEightBallValue(text);
EightBallResponseModel responseModel = (EightBallResponseModel) ContextConverter.slimFromCommandContext(commandContext, EightBallResponseModel.class);
responseModel.setChosenKey(chosenKey);
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(EIGHT_BALL_RESPONSE_TEMPLATE_KEY, responseModel, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
parameters.add(Parameter.builder().name("text").type(String.class).templated(true).remainder(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("8Ball")
.async(true)
.module(EntertainmentModuleInterface.ENTERTAINMENT)
.templated(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.ENTERTAINMENT;
}
}

View File

@@ -1,71 +0,0 @@
package dev.sheldan.abstracto.utility.commands.entertainment;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.EntertainmentModuleInterface;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.LoveCalcResponseModel;
import dev.sheldan.abstracto.utility.service.EntertainmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class LoveCalc extends AbstractConditionableCommand {
public static final String LOVE_CALC_RESPONSE_TEMPLATE_KEY = "loveCalc_response";
@Autowired
private ChannelService channelService;
@Autowired
private EntertainmentService entertainmentService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String firstPart = (String) parameters.get(0);
String secondPart = (String) parameters.get(1);
Integer rolled = entertainmentService.getLoveCalcValue(firstPart, secondPart);
LoveCalcResponseModel model = (LoveCalcResponseModel) ContextConverter.slimFromCommandContext(commandContext, LoveCalcResponseModel.class);
model.setRolled(rolled);
model.setFirstPart(firstPart);
model.setSecondPart(secondPart);
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(LOVE_CALC_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
parameters.add(Parameter.builder().name("firstSubject").type(String.class).templated(true).optional(true).build());
parameters.add(Parameter.builder().name("secondSubject").type(String.class).templated(true).optional(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("loveCalc")
.async(true)
.module(EntertainmentModuleInterface.ENTERTAINMENT)
.templated(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.ENTERTAINMENT;
}
}

View File

@@ -1,84 +0,0 @@
package dev.sheldan.abstracto.utility.commands.entertainment;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.ConfigService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.EntertainmentModuleInterface;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.RollResponseModel;
import dev.sheldan.abstracto.utility.service.EntertainmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static dev.sheldan.abstracto.utility.config.features.EntertainmentFeature.ROLL_DEFAULT_HIGH_KEY;
@Component
public class Roll extends AbstractConditionableCommand {
public static final String ROLL_RESPONSE_TEMPLATE_KEY = "roll_response";
@Autowired
private ChannelService channelService;
@Autowired
private EntertainmentService entertainmentService;
@Autowired
private ConfigService configService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Integer high = configService.getLongValue(ROLL_DEFAULT_HIGH_KEY, commandContext.getGuild().getIdLong()).intValue();
Integer low = 1;
if(parameters.size() > 1) {
low = (Integer) parameters.get(1);
}
if(!parameters.isEmpty()) {
high = (Integer) parameters.get(0);
}
Integer rolled = entertainmentService.calculateRollResult(low, high);
RollResponseModel model = (RollResponseModel) ContextConverter.slimFromCommandContext(commandContext, RollResponseModel.class);
model.setRolled(rolled);
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(ROLL_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
parameters.add(Parameter.builder().name("high").type(Integer.class).templated(true).validators(Arrays.asList(MinIntegerValueValidator.min(2L))).optional(true).build());
parameters.add(Parameter.builder().name("low").type(Integer.class).templated(true).validators(Arrays.asList(MinIntegerValueValidator.min(0L))).optional(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("roll")
.async(true)
.module(EntertainmentModuleInterface.ENTERTAINMENT)
.templated(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.ENTERTAINMENT;
}
}

View File

@@ -1,63 +0,0 @@
package dev.sheldan.abstracto.utility.commands.entertainment;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.EntertainmentModuleInterface;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.RouletteResponseModel;
import dev.sheldan.abstracto.utility.service.EntertainmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class Roulette extends AbstractConditionableCommand {
public static final String ROULETTE_RESPONSE_TEMPLATE_KEY = "roulette_response";
@Autowired
private ChannelService channelService;
@Autowired
private EntertainmentService entertainmentService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
boolean rouletteResult = entertainmentService.executeRoulette(commandContext.getAuthor());
RouletteResponseModel responseModel = (RouletteResponseModel) ContextConverter.slimFromCommandContext(commandContext, RouletteResponseModel.class);
responseModel.setResult(rouletteResult);
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(ROULETTE_RESPONSE_TEMPLATE_KEY, responseModel, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("roulette")
.async(true)
.module(EntertainmentModuleInterface.ENTERTAINMENT)
.templated(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.ENTERTAINMENT;
}
}

View File

@@ -1,83 +0,0 @@
package dev.sheldan.abstracto.utility.commands.remind;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.database.Reminder;
import dev.sheldan.abstracto.utility.models.template.commands.reminder.ReminderModel;
import dev.sheldan.abstracto.utility.service.ReminderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
public class Remind extends AbstractConditionableCommand {
public static final String REMINDER_EMBED_KEY = "remind_response";
@Autowired
private ReminderService remindService;
@Autowired
private ChannelService channelService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Duration remindTime = (Duration) parameters.get(0);
String text = (String) parameters.get(1);
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
ReminderModel remindModel = (ReminderModel) ContextConverter.fromCommandContext(commandContext, ReminderModel.class);
remindModel.setRemindText(text);
Reminder createdReminder = remindService.createReminderInForUser(aUserInAServer, text, remindTime, commandContext.getMessage());
remindModel.setReminder(createdReminder);
log.info("Notifying user {} about reminder being scheduled.", commandContext.getAuthor().getId());
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(REMINDER_EMBED_KEY, remindModel, commandContext.getChannel()))
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
parameters.add(Parameter.builder().name("duration").type(Duration.class).templated(true).build());
parameters.add(Parameter.builder().name("remindText").type(String.class).templated(true).remainder(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
return CommandConfiguration.builder()
.name("remind")
.async(true)
.module(UtilityModuleInterface.UTILITY)
.templated(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.REMIND;
}
}

View File

@@ -1,69 +0,0 @@
package dev.sheldan.abstracto.utility.commands.remind;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.database.Reminder;
import dev.sheldan.abstracto.utility.models.template.commands.reminder.RemindersModel;
import dev.sheldan.abstracto.utility.service.management.ReminderManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
public class Reminders extends AbstractConditionableCommand {
public static final String REMINDERS_RESPONSE_TEMPLATE = "reminders_response";
@Autowired
private ReminderManagementService reminderManagementService;
@Autowired
private ChannelService channelService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
List<Reminder> activeReminders = reminderManagementService.getActiveRemindersForUser(aUserInAServer);
RemindersModel model = (RemindersModel) ContextConverter.fromCommandContext(commandContext, RemindersModel.class);
model.setReminders(activeReminders);
log.info("Showing {} reminders for user {} in server {}.", activeReminders.size(), commandContext.getAuthor().getId(), commandContext.getGuild().getId());
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(REMINDERS_RESPONSE_TEMPLATE, model, commandContext.getChannel()))
.thenApply(aVoid -> CommandResult.fromIgnored());
}
@Override
public CommandConfiguration getConfiguration() {
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("reminders")
.async(true)
.module(UtilityModuleInterface.UTILITY)
.templated(true)
.supportsEmbedException(true)
.causesReaction(true)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.REMIND;
}
}

View File

@@ -1,62 +0,0 @@
package dev.sheldan.abstracto.utility.commands.remind;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.service.ReminderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Slf4j
@Component
public class UnRemind extends AbstractConditionableCommand {
@Autowired
private ReminderService reminderService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Override
public CommandResult execute(CommandContext commandContext) {
Long reminderId = (Long) commandContext.getParameters().getParameters().get(0);
reminderService.unRemind(reminderId, userInServerManagementService.loadOrCreateUser(commandContext.getAuthor()));
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
List<ParameterValidator> reminderIdValidator = Arrays.asList(MinIntegerValueValidator.min(1L));
parameters.add(Parameter.builder().name("reminderId").validators(reminderIdValidator).templated(true).type(Long.class).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("unRemind")
.module(UtilityModuleInterface.UTILITY)
.templated(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.REMIND;
}
}

View File

@@ -1,67 +0,0 @@
package dev.sheldan.abstracto.utility.commands.repost;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.utility.config.RepostDetectionModuleInterface;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.service.RepostCheckChannelService;
import dev.sheldan.abstracto.utility.service.RepostServiceBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Component
public class DisableRepostCheck extends AbstractConditionableCommand {
@Autowired
private RepostCheckChannelService repostCheckChannelService;
@Autowired
private ChannelGroupManagementService channelGroupManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Override
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
AChannelGroup fakeChannelGroup = (AChannelGroup) parameters.get(0);
AServer actualServer = serverManagementService.loadServer(commandContext.getGuild().getIdLong());
AChannelGroup actualChannelGroup = channelGroupManagementService.findByNameAndServerAndType(fakeChannelGroup.getGroupName(), actualServer, RepostServiceBean.REPOST_CHECK_CHANNEL_GROUP_TYPE);
repostCheckChannelService.setRepostCheckDisabledForChannelGroup(actualChannelGroup);
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
Parameter channelToSet = Parameter.builder().name("channelGroup").type(AChannelGroup.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(channelToSet);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("disableRepostCheck")
.module(RepostDetectionModuleInterface.REPOST_DETECTION)
.templated(true)
.async(false)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.REPOST_DETECTION;
}
}

View File

@@ -1,67 +0,0 @@
package dev.sheldan.abstracto.utility.commands.repost;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.utility.config.RepostDetectionModuleInterface;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.service.RepostCheckChannelService;
import dev.sheldan.abstracto.utility.service.RepostServiceBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Component
public class EnableRepostCheck extends AbstractConditionableCommand {
@Autowired
private RepostCheckChannelService repostCheckChannelService;
@Autowired
private ChannelGroupManagementService channelGroupManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Override
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
AChannelGroup fakeChannelGroup = (AChannelGroup) parameters.get(0);
AServer actualServer = serverManagementService.loadServer(commandContext.getGuild().getIdLong());
AChannelGroup actualChannelGroup = channelGroupManagementService.findByNameAndServerAndType(fakeChannelGroup.getGroupName(), actualServer, RepostServiceBean.REPOST_CHECK_CHANNEL_GROUP_TYPE);
repostCheckChannelService.setRepostCheckEnabledForChannelGroup(actualChannelGroup);
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
Parameter channelToSet = Parameter.builder().name("channelGroup").type(AChannelGroup.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(channelToSet);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("enableRepostCheck")
.module(RepostDetectionModuleInterface.REPOST_DETECTION)
.templated(true)
.async(false)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.REPOST_DETECTION;
}
}

View File

@@ -1,64 +0,0 @@
package dev.sheldan.abstracto.utility.commands.repost;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.config.RepostDetectionModuleInterface;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.service.PostedImageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Component
public class PurgeImagePosts extends AbstractConditionableCommand {
@Autowired
private PostedImageService postedImageService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Override
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
if(!parameters.isEmpty()) {
AUserInAServer fakeUser = (AUserInAServer) parameters.get(0);
AUserInAServer actualUser = userInServerManagementService.loadOrCreateUser(fakeUser.getUserInServerId());
postedImageService.purgePostedImages(actualUser);
} else {
postedImageService.purgePostedImages(commandContext.getGuild());
}
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
Parameter channelToSet = Parameter.builder().name("member").type(AUserInAServer.class).templated(true).optional(true).build();
List<Parameter> parameters = Arrays.asList(channelToSet);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("purgeImagePosts")
.module(RepostDetectionModuleInterface.REPOST_DETECTION)
.templated(true)
.async(false)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.REPOST_DETECTION;
}
}

View File

@@ -1,64 +0,0 @@
package dev.sheldan.abstracto.utility.commands.repost;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.config.RepostDetectionModuleInterface;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.service.RepostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Component
public class PurgeReposts extends AbstractConditionableCommand {
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private RepostService repostService;
@Override
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
if(!parameters.isEmpty()) {
AUserInAServer fakeUser = (AUserInAServer) parameters.get(0);
AUserInAServer actualUser = userInServerManagementService.loadOrCreateUser(fakeUser.getUserInServerId());
repostService.purgeReposts(actualUser);
} else {
repostService.purgeReposts(commandContext.getGuild());
}
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
Parameter channelToSet = Parameter.builder().name("member").type(AUserInAServer.class).templated(true).optional(true).build();
List<Parameter> parameters = Arrays.asList(channelToSet);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("purgeReposts")
.module(RepostDetectionModuleInterface.REPOST_DETECTION)
.templated(true)
.async(false)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.REPOST_DETECTION;
}
}

View File

@@ -1,102 +0,0 @@
package dev.sheldan.abstracto.utility.commands.repost;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.FeatureMode;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.utility.config.RepostDetectionModuleInterface;
import dev.sheldan.abstracto.utility.config.features.RepostDetectionFeatureMode;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.converter.RepostLeaderBoardConverter;
import dev.sheldan.abstracto.utility.models.RepostLeaderboardEntryModel;
import dev.sheldan.abstracto.utility.models.RepostLeaderboardModel;
import dev.sheldan.abstracto.utility.models.database.result.RepostLeaderboardResult;
import dev.sheldan.abstracto.utility.service.RepostService;
import dev.sheldan.abstracto.utility.service.management.RepostManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class RepostLeaderboard extends AbstractConditionableCommand {
public static final String REPOST_LEADERBOARD_RESPONSE_TEMPLATE_KEY = "repostLeaderboard_response";
@Autowired
private RepostService repostService;
@Autowired
private RepostManagementService repostManagementService;
@Autowired
private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Autowired
private RepostLeaderBoardConverter converter;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Integer page = !parameters.isEmpty() ? (Integer) parameters.get(0) : 1;
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
List<RepostLeaderboardResult> topRepostingUsersOfServer = repostManagementService.findTopRepostingUsersOfServer(commandContext.getGuild().getIdLong(), page, 5);
RepostLeaderboardResult resultOfUser = repostManagementService.getRepostRankOfUser(aUserInAServer);
CompletableFuture<List<RepostLeaderboardEntryModel>> leaderBoardFuture = converter.fromLeaderBoardResults(topRepostingUsersOfServer);
CompletableFuture<RepostLeaderboardEntryModel> userFuture = converter.convertSingleUser(resultOfUser);
return CompletableFuture.allOf(leaderBoardFuture, userFuture).thenCompose(unused -> {
List<RepostLeaderboardEntryModel> entries = leaderBoardFuture.join();
RepostLeaderboardModel model = RepostLeaderboardModel
.builder()
.guild(commandContext.getGuild())
.entries(entries)
.userExecuting(userFuture.join())
.member(commandContext.getAuthor())
.build();
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(REPOST_LEADERBOARD_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel()));
}).thenApply(o -> CommandResult.fromIgnored());
}
@Override
public CommandConfiguration getConfiguration() {
Parameter channelToSet = Parameter.builder().name("page").type(Integer.class).templated(true).optional(true).build();
List<Parameter> parameters = Arrays.asList(channelToSet);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("repostLeaderboard")
.module(RepostDetectionModuleInterface.REPOST_DETECTION)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.REPOST_DETECTION;
}
@Override
public List<FeatureMode> getFeatureModeLimitations() {
return Arrays.asList(RepostDetectionFeatureMode.LEADERBOARD);
}
}

View File

@@ -1,62 +0,0 @@
package dev.sheldan.abstracto.utility.commands.repost;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.RepostDetectionModuleInterface;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.converter.RepostCheckChannelModelConverter;
import dev.sheldan.abstracto.utility.models.database.RepostCheckChannelGroup;
import dev.sheldan.abstracto.utility.models.template.commands.RepostCheckChannelsModel;
import dev.sheldan.abstracto.utility.service.RepostCheckChannelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class ShowRepostCheckChannels extends AbstractConditionableCommand {
public static final String SHOW_REPOST_CHECK_CHANNELS_RESPONSE_TEMPLATE_KEY = "showRepostCheckChannels_response";
@Autowired
private RepostCheckChannelModelConverter converter;
@Autowired
private RepostCheckChannelService checkChannelService;
@Autowired
private ChannelService channelService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<RepostCheckChannelGroup> channelGroups = checkChannelService.getChannelGroupsWithEnabledCheck(commandContext.getGuild().getIdLong());
RepostCheckChannelsModel model = converter.fromRepostCheckChannelGroups(channelGroups, commandContext.getGuild());
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(SHOW_REPOST_CHECK_CHANNELS_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CommandConfiguration getConfiguration() {
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("showRepostCheckChannels")
.module(RepostDetectionModuleInterface.REPOST_DETECTION)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(false)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.REPOST_DETECTION;
}
}

View File

@@ -1,68 +0,0 @@
package dev.sheldan.abstracto.utility.commands.suggest;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.SuggestionLog;
import dev.sheldan.abstracto.utility.service.SuggestionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
public class Accept extends AbstractConditionableCommand {
@Autowired
private SuggestionService suggestionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Long suggestionId = (Long) parameters.get(0);
String text = parameters.size() == 2 ? (String) parameters.get(1) : "";
log.trace("Using default reason for accept: {}.", parameters.size() != 2);
SuggestionLog suggestionModel = (SuggestionLog) ContextConverter.fromCommandContext(commandContext, SuggestionLog.class);
return suggestionService.acceptSuggestion(suggestionId, text, suggestionModel)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
List<ParameterValidator> suggestionIdValidator = Arrays.asList(MinIntegerValueValidator.min(1L));
parameters.add(Parameter.builder().name("suggestionId").validators(suggestionIdValidator).type(Long.class).templated(true).build());
parameters.add(Parameter.builder().name("text").type(String.class).optional(true).remainder(true).templated(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
return CommandConfiguration.builder()
.name("accept")
.module(UtilityModuleInterface.UTILITY)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.SUGGEST;
}
}

View File

@@ -1,68 +0,0 @@
package dev.sheldan.abstracto.utility.commands.suggest;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.SuggestionLog;
import dev.sheldan.abstracto.utility.service.SuggestionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
public class Reject extends AbstractConditionableCommand {
@Autowired
private SuggestionService suggestionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Long suggestionId = (Long) parameters.get(0);
String text = parameters.size() == 2 ? (String) parameters.get(1) : "";
log.trace("Using default reason for accept: {}.", parameters.size() != 2);
SuggestionLog suggestionModel = (SuggestionLog) ContextConverter.fromCommandContext(commandContext, SuggestionLog.class);
return suggestionService.rejectSuggestion(suggestionId, text, suggestionModel)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
List<ParameterValidator> suggestionIdValidator = Arrays.asList(MinIntegerValueValidator.min(1L));
parameters.add(Parameter.builder().name("suggestionId").validators(suggestionIdValidator).type(Long.class).templated(true).build());
parameters.add(Parameter.builder().name("text").type(String.class).optional(true).remainder(true).templated(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
return CommandConfiguration.builder()
.name("reject")
.module(UtilityModuleInterface.UTILITY)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.SUGGEST;
}
}

View File

@@ -1,59 +0,0 @@
package dev.sheldan.abstracto.utility.commands.suggest;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.SuggestionLog;
import dev.sheldan.abstracto.utility.service.SuggestionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class Suggest extends AbstractConditionableCommand {
@Autowired
private SuggestionService suggestionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String text = (String) parameters.get(0);
SuggestionLog suggestLogModel = (SuggestionLog) ContextConverter.fromCommandContext(commandContext, SuggestionLog.class);
suggestLogModel.setSuggester(commandContext.getAuthor());
return suggestionService.createSuggestionMessage(commandContext.getAuthor(), text, suggestLogModel)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
parameters.add(Parameter.builder().name("text").type(String.class).templated(true).remainder(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("suggest")
.module(UtilityModuleInterface.UTILITY)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.SUGGEST;
}
}

View File

@@ -1,17 +0,0 @@
package dev.sheldan.abstracto.utility.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@Configuration
public class UtilitySpringConfig {
@Bean(name = "reminderScheduler")
public ScheduledExecutorService getUnMuteExecutor() {
return Executors.newScheduledThreadPool(1);
}
}

View File

@@ -1,42 +0,0 @@
package dev.sheldan.abstracto.utility.converter;
import dev.sheldan.abstracto.core.models.FullChannel;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.utility.models.database.RepostCheckChannelGroup;
import dev.sheldan.abstracto.utility.models.template.commands.RepostCheckChannelGroupDisplayModel;
import dev.sheldan.abstracto.utility.models.template.commands.RepostCheckChannelsModel;
import net.dv8tion.jda.api.entities.Guild;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Component
public class RepostCheckChannelModelConverter {
@Autowired
private ChannelService channelService;
public RepostCheckChannelsModel fromRepostCheckChannelGroups(List<RepostCheckChannelGroup> channelGroups, Guild guild) {
List<RepostCheckChannelGroupDisplayModel> repostCheckChannelGroups = new ArrayList<>();
channelGroups.forEach(repostCheckChannelGroup -> {
List<FullChannel> fullChannels = repostCheckChannelGroup.getChannelGroup().getChannels().stream().map(channel ->
FullChannel
.builder()
.channel(channel)
.serverChannel(channelService.getTextChannelFromServerNullable(guild, channel.getId()))
.build()
).collect(Collectors.toList());
repostCheckChannelGroups.add(
RepostCheckChannelGroupDisplayModel
.builder()
.channelGroup(repostCheckChannelGroup)
.channels(fullChannels)
.build());
});
return RepostCheckChannelsModel.builder().repostCheckChannelGroups(repostCheckChannelGroups).build();
}
}

View File

@@ -1,62 +0,0 @@
package dev.sheldan.abstracto.utility.converter;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.models.RepostLeaderboardEntryModel;
import dev.sheldan.abstracto.utility.models.database.result.RepostLeaderboardResult;
import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@Component
public class RepostLeaderBoardConverter {
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private MemberService memberService;
@Autowired
private RepostLeaderBoardConverter self;
public CompletableFuture<List<RepostLeaderboardEntryModel>> fromLeaderBoardResults(List<RepostLeaderboardResult> results) {
if(results.isEmpty()) {
return CompletableFuture.completedFuture(new ArrayList<>());
}
List<CompletableFuture<RepostLeaderboardEntryModel>> modelFutures =
results.stream().map(this::convertSingleUser).collect(Collectors.toList());
return FutureUtils.toSingleFutureGeneric(modelFutures).thenApply(unused ->
modelFutures.stream().map(CompletableFuture::join).collect(Collectors.toList())
);
}
public CompletableFuture<RepostLeaderboardEntryModel> convertSingleUser(RepostLeaderboardResult result) {
AUserInAServer user = userInServerManagementService.loadOrCreateUser(result.getUserInServerId());
Integer count = result.getRepostCount();
Long userInServerId = result.getUserInServerId();
Integer rank = result.getRank();
return memberService.getMemberInServerAsync(user).thenApply(member ->
self.loadUserFromDatabase(member, count, userInServerId, rank)
);
}
@Transactional
public RepostLeaderboardEntryModel loadUserFromDatabase(Member member, Integer count, Long userInServerId, Integer rank) {
return RepostLeaderboardEntryModel
.builder()
.member(member)
.user(userInServerManagementService.loadOrCreateUser(userInServerId))
.count(count)
.rank(rank)
.build();
}
}

View File

@@ -1,41 +0,0 @@
package dev.sheldan.abstracto.utility.jobs;
import dev.sheldan.abstracto.utility.service.ReminderService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
@Slf4j
@DisallowConcurrentExecution
@Component
@PersistJobDataAfterExecution
public class ReminderJob extends QuartzJobBean {
private Long reminderId;
@Autowired
private ReminderService reminderService;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
log.info("Executing reminder job for reminder {}", reminderId);
reminderService.executeReminder(reminderId);
} catch (Exception e) {
log.error("Reminder job failed to execute.", e);
}
}
public Long getReminderId() {
return reminderId;
}
public void setReminderId(Long reminderId) {
this.reminderId = reminderId;
}
}

View File

@@ -1,125 +0,0 @@
package dev.sheldan.abstracto.utility.listener.embed;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.execution.result.ExecutionResult;
import dev.sheldan.abstracto.core.execution.result.MessageReceivedListenerResult;
import dev.sheldan.abstracto.core.listener.sync.jda.MessageReceivedListener;
import dev.sheldan.abstracto.core.metrics.service.CounterMetric;
import dev.sheldan.abstracto.core.metrics.service.MetricService;
import dev.sheldan.abstracto.core.metrics.service.MetricTag;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.service.MessageCache;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.MessageEmbedLink;
import dev.sheldan.abstracto.utility.service.MessageEmbedService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.Event;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
@Component
@Slf4j
public class MessageEmbedListener implements MessageReceivedListener {
@Autowired
private MessageCache messageCache;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private MessageEmbedService messageEmbedService;
@Autowired
private MessageEmbedListener self;
@Autowired
private MetricService metricService;
@Autowired
private MessageService messageService;
public static final String MESSAGE_EMBEDDED = "message.embedded";
public static final String MESSAGE_EMBED_ACTION = "action";
private static final CounterMetric MESSAGE_EMBED_CREATED = CounterMetric
.builder()
.name(MESSAGE_EMBEDDED)
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "created")))
.build();
@Override
public MessageReceivedListenerResult execute(Message message) {
String messageRaw = message.getContentRaw();
List<MessageEmbedLink> links = messageEmbedService.getLinksInMessage(messageRaw);
if(!links.isEmpty()) {
log.trace("We found {} links to embed in message {} in channel {} in guild {}.", links.size(), message.getId(), message.getChannel().getId(), message.getGuild().getId());
Long userEmbeddingUserInServerId = userInServerManagementService.loadOrCreateUser(message.getMember()).getUserInServerId();
for (MessageEmbedLink messageEmbedLink : links) {
if(!messageEmbedLink.getServerId().equals(message.getGuild().getIdLong())) {
log.info("Link for message {} was from a foreign server {}. Do not embed.", messageEmbedLink.getMessageId(), messageEmbedLink.getServerId());
continue;
}
messageRaw = messageRaw.replace(messageEmbedLink.getWholeUrl(), "");
Consumer<CachedMessage> cachedMessageConsumer = cachedMessage -> self.embedSingleLink(message, userEmbeddingUserInServerId, cachedMessage);
messageCache.getMessageFromCache(messageEmbedLink.getServerId(), messageEmbedLink.getChannelId(), messageEmbedLink.getMessageId())
.thenAccept(cachedMessageConsumer)
.exceptionally(throwable -> {
log.error("Error when embedding link for message {}", message.getId(), throwable);
return null;
});
}
}
if(StringUtils.isBlank(messageRaw) && !links.isEmpty()) {
messageService.deleteMessage(message);
return MessageReceivedListenerResult.DELETED;
}
if(!links.isEmpty()) {
return MessageReceivedListenerResult.PROCESSED;
}
return MessageReceivedListenerResult.IGNORED;
}
@Transactional
public void embedSingleLink(Message message, Long cause, CachedMessage cachedMessage) {
log.info("Embedding link to message {} in channel {} in server {} to channel {} and server {}.",
cachedMessage.getMessageId(), cachedMessage.getChannelId(), cachedMessage.getServerId(), message.getChannel().getId(), message.getGuild().getId());
messageEmbedService.embedLink(cachedMessage, message.getTextChannel(), cause , message).thenAccept(unused ->
metricService.incrementCounter(MESSAGE_EMBED_CREATED)
).exceptionally(throwable -> {
log.error("Failed to embed link towards message {} in channel {} in sever {} linked from message {} in channel {} in server {}.", cachedMessage.getMessageId(), cachedMessage.getChannelId(), cachedMessage.getServerId(),
message.getId(), message.getChannel().getId(), message.getGuild().getId(), throwable);
return null;
});
}
@Override
public boolean shouldConsume(Event event, ExecutionResult result) {
return result.equals(MessageReceivedListenerResult.DELETED);
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.LINK_EMBEDS;
}
@Override
public Integer getPriority() {
return ListenerPriority.MEDIUM;
}
@PostConstruct
public void postConstruct() {
metricService.registerCounter(MESSAGE_EMBED_CREATED, "Message embeds created");
}
}

View File

@@ -1,106 +0,0 @@
package dev.sheldan.abstracto.utility.listener.embed;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncReactionAddedListener;
import dev.sheldan.abstracto.core.metrics.service.CounterMetric;
import dev.sheldan.abstracto.core.metrics.service.MetricService;
import dev.sheldan.abstracto.core.metrics.service.MetricTag;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.database.EmbeddedMessage;
import dev.sheldan.abstracto.utility.service.management.MessageEmbedPostManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.Optional;
import static dev.sheldan.abstracto.utility.listener.embed.MessageEmbedListener.MESSAGE_EMBEDDED;
import static dev.sheldan.abstracto.utility.listener.embed.MessageEmbedListener.MESSAGE_EMBED_ACTION;
@Component
@Slf4j
public class MessageEmbedRemovalReactionListener implements AsyncReactionAddedListener {
public static final String REMOVAL_EMOTE = "removeEmbed";
@Autowired
private BotService botService;
@Autowired
private MessageEmbedPostManagementService messageEmbedPostManagementService;
@Autowired
private MessageService messageService;
@Autowired
private EmoteService emoteService;
@Autowired
private MetricService metricService;
private static final CounterMetric MESSAGE_EMBED_REMOVED_CREATOR = CounterMetric
.builder()
.name(MESSAGE_EMBEDDED)
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "removed.creator")))
.build();
private static final CounterMetric MESSAGE_EMBED_REMOVED_SOURCE = CounterMetric
.builder()
.name(MESSAGE_EMBEDDED)
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "removed.source")))
.build();
@Override
public void executeReactionAdded(CachedMessage message, CachedReactions cachedReaction, ServerUser serverUser) {
Long guildId = message.getServerId();
AEmote aEmote = emoteService.getEmoteOrDefaultEmote(REMOVAL_EMOTE, guildId);
if(emoteService.compareCachedEmoteWithAEmote(cachedReaction.getEmote(), aEmote)) {
Optional<EmbeddedMessage> embeddedMessageOptional = messageEmbedPostManagementService.findEmbeddedPostByMessageId(message.getMessageId());
if(embeddedMessageOptional.isPresent()) {
EmbeddedMessage embeddedMessage = embeddedMessageOptional.get();
boolean embeddedUserRemoves = embeddedMessage.getEmbeddedUser().getUserReference().getId().equals(serverUser.getUserId());
boolean embeddingUserRemoves = embeddedMessage.getEmbeddingUser().getUserReference().getId().equals(serverUser.getUserId());
if(embeddedUserRemoves || embeddingUserRemoves) {
log.info("Removing embed in message {} in channel {} in server {} because of a user reaction.", message.getMessageId(), message.getChannelId(), message.getServerId());
messageService.deleteMessageInChannelInServer(message.getServerId(), message.getChannelId(), message.getMessageId()).thenAccept(aVoid -> {
Optional<EmbeddedMessage> innerOptional = messageEmbedPostManagementService.findEmbeddedPostByMessageId(message.getMessageId());
innerOptional.ifPresent(value -> messageEmbedPostManagementService.deleteEmbeddedMessage(value));
if(embeddedUserRemoves) {
metricService.incrementCounter(MESSAGE_EMBED_REMOVED_SOURCE);
} else {
metricService.incrementCounter(MESSAGE_EMBED_REMOVED_CREATOR);
}
});
} else {
log.trace("Somebody besides the original author and the user embedding added the removal reaction to the message {} in channel {} in server {}.",
message.getMessageId(), message.getChannelId(), message.getServerId());
}
} else {
log.trace("Removal emote was placed on a message which was not recognized as an embedded message.");
}
}
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.LINK_EMBEDS;
}
@PostConstruct
public void postConstruct() {
metricService.registerCounter(MESSAGE_EMBED_REMOVED_CREATOR, "Message embeds which are created by the embedding user.");
metricService.registerCounter(MESSAGE_EMBED_REMOVED_SOURCE, "Message embeds which are created by the embedded user.");
}
}

View File

@@ -1,22 +0,0 @@
package dev.sheldan.abstracto.utility.listener.repost;
import dev.sheldan.abstracto.core.listener.sync.entity.ChannelGroupCreatedListener;
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.utility.service.RepostServiceBean;
import dev.sheldan.abstracto.utility.service.management.RepostCheckChannelGroupManagement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class RepostCheckChannelGroupCreatedListener implements ChannelGroupCreatedListener {
@Autowired
private RepostCheckChannelGroupManagement checkChannelGroupManagement;
@Override
public void channelGroupCreated(AChannelGroup channelGroup) {
if(channelGroup.getChannelGroupType().getGroupTypeKey().equals(RepostServiceBean.REPOST_CHECK_CHANNEL_GROUP_TYPE)) {
checkChannelGroupManagement.createRepostCheckChannelGroup(channelGroup);
}
}
}

View File

@@ -1,22 +0,0 @@
package dev.sheldan.abstracto.utility.listener.repost;
import dev.sheldan.abstracto.core.listener.sync.entity.ChannelGroupDeletedListener;
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.utility.service.RepostServiceBean;
import dev.sheldan.abstracto.utility.service.management.RepostCheckChannelGroupManagement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class RepostCheckChannelGroupDeletedListener implements ChannelGroupDeletedListener {
@Autowired
private RepostCheckChannelGroupManagement checkChannelGroupManagement;
@Override
public void channelGroupDeleted(AChannelGroup channelGroup) {
if(channelGroup.getChannelGroupType().getGroupTypeKey().equals(RepostServiceBean.REPOST_CHECK_CHANNEL_GROUP_TYPE)) {
checkChannelGroupManagement.deleteRepostCheckChannelGroup(channelGroup);
}
}
}

View File

@@ -1,64 +0,0 @@
package dev.sheldan.abstracto.utility.listener.repost;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageEmbeddedListener;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.listener.GuildMessageEmbedEventModel;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.service.RepostCheckChannelService;
import dev.sheldan.abstracto.utility.service.RepostService;
import dev.sheldan.abstracto.utility.service.management.PostedImageManagement;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.EmbedType;
import net.dv8tion.jda.api.entities.MessageEmbed;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
@Component
@Slf4j
public class RepostEmbedListener implements AsyncMessageEmbeddedListener {
@Autowired
private RepostCheckChannelService repostCheckChannelService;
@Autowired
private RepostService repostService;
@Autowired
private PostedImageManagement repostManagement;
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private ChannelService channelService;
@Override
public void execute(GuildMessageEmbedEventModel eventModel) {
AChannel channel = channelManagementService.loadChannel(eventModel.getChannelId());
if(repostCheckChannelService.duplicateCheckEnabledForChannel(channel)) {
if(repostManagement.messageEmbedsHaveBeenCovered(eventModel.getMessageId())) {
log.info("The embeds of the message {} in channel {} in server {} have already been covered by repost check -- ignoring.",
eventModel.getMessageId(), eventModel.getChannelId(), eventModel.getServerId());
return;
}
channelService.retrieveMessageInChannel(eventModel.getServerId(), eventModel.getChannelId(), eventModel.getMessageId()).thenAccept(message -> {
List<MessageEmbed> imageEmbeds = eventModel.getEmbeds().stream().filter(messageEmbed -> messageEmbed.getType().equals(EmbedType.IMAGE)).collect(Collectors.toList());
if(!imageEmbeds.isEmpty()) {
repostService.processMessageEmbedsRepostCheck(imageEmbeds, message);
}
});
}
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.REPOST_DETECTION;
}
}

View File

@@ -1,49 +0,0 @@
package dev.sheldan.abstracto.utility.listener.repost;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageReceivedListener;
import dev.sheldan.abstracto.core.models.cache.CachedEmbed;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.service.RepostCheckChannelService;
import dev.sheldan.abstracto.utility.service.RepostService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.EmbedType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
@Component
@Slf4j
public class RepostMessageReceivedListener implements AsyncMessageReceivedListener {
@Autowired
private RepostCheckChannelService repostCheckChannelService;
@Autowired
private RepostService repostService;
@Autowired
private ChannelManagementService channelManagementService;
@Override
public void execute(CachedMessage message) {
AChannel channel = channelManagementService.loadChannel(message.getChannelId());
if(repostCheckChannelService.duplicateCheckEnabledForChannel(channel)) {
repostService.processMessageAttachmentRepostCheck(message);
List<CachedEmbed> imageEmbeds = message.getEmbeds().stream().filter(messageEmbed -> messageEmbed.getType().equals(EmbedType.IMAGE)).collect(Collectors.toList());
repostService.processMessageEmbedsRepostCheck(imageEmbeds, message);
}
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.REPOST_DETECTION;
}
}

View File

@@ -1,213 +0,0 @@
package dev.sheldan.abstracto.utility.listener.starboard;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncReactionAddedListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncReactionClearedListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncReactionRemovedListener;
import dev.sheldan.abstracto.core.metrics.service.CounterMetric;
import dev.sheldan.abstracto.core.metrics.service.MetricService;
import dev.sheldan.abstracto.core.metrics.service.MetricTag;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.management.ConfigManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
import dev.sheldan.abstracto.utility.service.StarboardService;
import dev.sheldan.abstracto.utility.service.management.StarboardPostManagementService;
import dev.sheldan.abstracto.utility.service.management.StarboardPostReactorManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@Component
@Slf4j
public class StarboardListener implements AsyncReactionAddedListener, AsyncReactionRemovedListener, AsyncReactionClearedListener {
public static final String STAR_EMOTE = "star";
public static final String FIRST_LEVEL_THRESHOLD_KEY = "starLvl1";
@Autowired
private BotService botService;
@Autowired
private ConfigManagementService configManagementService;
@Autowired
private StarboardService starboardService;
@Autowired
private StarboardPostManagementService starboardPostManagementService;
@Autowired
private StarboardPostReactorManagementService starboardPostReactorManagementService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private EmoteService emoteService;
@Autowired
private MetricService metricService;
public static final String STARBOARD_STARS = "starboard.stars";
public static final String STARBOARD_POSTS = "starboard.posts";
public static final String STAR_ACTION = "action";
private static final CounterMetric STARBOARD_STARS_ADDED = CounterMetric
.builder()
.name(STARBOARD_STARS)
.tagList(Arrays.asList(MetricTag.getTag(STAR_ACTION, "added")))
.build();
private static final CounterMetric STARBOARD_STARS_REMOVED = CounterMetric
.builder()
.name(STARBOARD_STARS)
.tagList(Arrays.asList(MetricTag.getTag(STAR_ACTION, "removed")))
.build();
private static final CounterMetric STARBOARD_STARS_THRESHOLD_REACHED = CounterMetric
.builder()
.name(STARBOARD_POSTS)
.tagList(Arrays.asList(MetricTag.getTag(STAR_ACTION, "threshold.reached")))
.build();
private static final CounterMetric STARBOARD_STARS_THRESHOLD_FELL = CounterMetric
.builder()
.name(STARBOARD_POSTS)
.tagList(Arrays.asList(MetricTag.getTag(STAR_ACTION, "threshold.below")))
.build();
@Override
@Transactional
public void executeReactionAdded(CachedMessage message, CachedReactions cachedReaction, ServerUser serverUser) {
if(serverUser.getUserId().equals(message.getAuthor().getAuthorId())) {
return;
}
Long guildId = message.getServerId();
AEmote aEmote = emoteService.getEmoteOrDefaultEmote(STAR_EMOTE, guildId);
if(emoteService.compareCachedEmoteWithAEmote(cachedReaction.getEmote(), aEmote)) {
metricService.incrementCounter(STARBOARD_STARS_ADDED);
log.info("User {} in server {} reacted with star to put a message {} from channel {} on starboard.", serverUser.getUserId(), message.getServerId(), message.getMessageId(), message.getChannelId());
Optional<CachedReactions> reactionOptional = emoteService.getReactionFromMessageByEmote(message, aEmote);
handleStarboardPostChange(message, reactionOptional.orElse(null), serverUser, true);
}
}
private void handleStarboardPostChange(CachedMessage message, CachedReactions reaction, ServerUser serverUser, boolean adding) {
Optional<StarboardPost> starboardPostOptional = starboardPostManagementService.findByMessageId(message.getMessageId());
if(reaction != null) {
AUserInAServer author = userInServerManagementService.loadOrCreateUser(message.getServerId(), message.getAuthor().getAuthorId());
List<AUserInAServer> userExceptAuthor = getUsersExcept(reaction.getUsers(), author);
Long starMinimum = getFromConfig(FIRST_LEVEL_THRESHOLD_KEY, message.getServerId());
AUserInAServer userAddingReaction = userInServerManagementService.loadOrCreateUser(serverUser);
if (userExceptAuthor.size() >= starMinimum) {
log.info("Post reached starboard minimum. Message {} in channel {} in server {} will be starred/updated.",
message.getMessageId(), message.getChannelId(), message.getServerId());
if(starboardPostOptional.isPresent()) {
updateStarboardPost(message, userAddingReaction, adding, starboardPostOptional.get(), userExceptAuthor);
} else {
metricService.incrementCounter(STARBOARD_STARS_THRESHOLD_REACHED);
log.info("Creating starboard post for message {} in channel {} in server {}", message.getMessageId(), message.getChannelId(), message.getServerId());
starboardService.createStarboardPost(message, userExceptAuthor, userAddingReaction, author);
}
} else {
if(starboardPostOptional.isPresent()) {
metricService.incrementCounter(STARBOARD_STARS_THRESHOLD_FELL);
log.info("Removing starboard post for message {} in channel {} in server {}. It fell under the threshold {}", message.getMessageId(), message.getChannelId(), message.getServerId(), starMinimum);
starboardPostOptional.ifPresent(this::completelyRemoveStarboardPost);
}
}
} else {
if(starboardPostOptional.isPresent()) {
log.info("Removing starboard post for message {} in channel {} in server {}", message.getMessageId(), message.getChannelId(), message.getServerId());
starboardPostOptional.ifPresent(this::completelyRemoveStarboardPost);
}
}
}
private void updateStarboardPost(CachedMessage message, AUserInAServer userReacting, boolean adding, StarboardPost starboardPost, List<AUserInAServer> userExceptAuthor) {
starboardPost.setIgnored(false);
// TODO handle futures correctly
starboardService.updateStarboardPost(starboardPost, message, userExceptAuthor);
if(adding) {
log.trace("Adding reactor {} from message {}", userReacting.getUserReference().getId(), message.getMessageId());
starboardPostReactorManagementService.addReactor(starboardPost, userReacting);
} else {
log.trace("Removing reactor {} from message {}", userReacting.getUserReference().getId(), message.getMessageId());
starboardPostReactorManagementService.removeReactor(starboardPost, userReacting);
}
}
private void completelyRemoveStarboardPost(StarboardPost starboardPost) {
starboardService.deleteStarboardMessagePost(starboardPost);
starboardPostManagementService.removePost(starboardPost);
}
@Override
@Transactional
public void executeReactionRemoved(CachedMessage message, CachedReactions removedReaction, ServerUser userRemoving) {
if(message.getAuthor().getAuthorId().equals(userRemoving.getUserId())) {
return;
}
Long guildId = message.getServerId();
AEmote aEmote = emoteService.getEmoteOrDefaultEmote(STAR_EMOTE, guildId);
if(emoteService.compareCachedEmoteWithAEmote(removedReaction.getEmote(), aEmote)) {
metricService.incrementCounter(STARBOARD_STARS_REMOVED);
log.info("User {} in server {} removed star reaction from message {} on starboard.",
userRemoving.getUserId(), message.getServerId(), message.getMessageId());
Optional<CachedReactions> reactionOptional = emoteService.getReactionFromMessageByEmote(message, aEmote);
handleStarboardPostChange(message, reactionOptional.orElse(null), userRemoving, false);
}
}
private Long getFromConfig(String key, Long guildId) {
return configManagementService.loadConfig(guildId, key).getLongValue();
}
private List<AUserInAServer> getUsersExcept(List<ServerUser> users, AUserInAServer author) {
return users.stream().filter(user -> !(user.getServerId().equals(author.getServerReference().getId()) && user.getUserId().equals(author.getUserReference().getId()))).map(serverUser -> {
Optional<AUserInAServer> aUserInAServer = userInServerManagementService.loadUserOptional(serverUser.getServerId(), serverUser.getUserId());
return aUserInAServer.orElse(null);
}).filter(Objects::nonNull).collect(Collectors.toList());
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.STARBOARD;
}
@Override
public void executeReactionCleared(CachedMessage message) {
Optional<StarboardPost> starboardPostOptional = starboardPostManagementService.findByMessageId(message.getMessageId());
starboardPostOptional.ifPresent(starboardPost -> {
log.info("Reactions on message {} in channel {} in server {} were cleared. Completely deleting the starboard post {}.",
message.getMessageId(), message.getChannelId(), message.getServerId(), starboardPost.getId());
starboardPostReactorManagementService.removeReactors(starboardPost);
completelyRemoveStarboardPost(starboardPost);
});
}
@PostConstruct
public void postConstruct() {
metricService.registerCounter(STARBOARD_STARS_ADDED, "Star reaction added");
metricService.registerCounter(STARBOARD_STARS_REMOVED, "Star reaction removed");
metricService.registerCounter(STARBOARD_STARS_THRESHOLD_REACHED, "Starboard posts reaching threshold");
metricService.registerCounter(STARBOARD_STARS_THRESHOLD_FELL, "Starboard posts falling below threshold");
}
}

View File

@@ -1,38 +0,0 @@
package dev.sheldan.abstracto.utility.listener.starboard;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageDeletedListener;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
import dev.sheldan.abstracto.utility.service.management.StarboardPostManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
@Slf4j
public class StarboardPostDeletedListener implements AsyncMessageDeletedListener {
@Autowired
private StarboardPostManagementService starboardPostManagementService;
@Override
public void execute(CachedMessage messageBefore) {
Optional<StarboardPost> byStarboardPostId = starboardPostManagementService.findByStarboardPostId(messageBefore.getMessageId());
if(byStarboardPostId.isPresent()) {
StarboardPost post = byStarboardPostId.get();
log.info("Removing starboard post: message {}, channel {}, server {}, because the message was deleted",
post.getPostMessageId(), post.getSourceChannel().getId(), messageBefore.getServerId());
starboardPostManagementService.setStarboardPostIgnored(messageBefore.getMessageId(), true);
}
}
@Override
public FeatureEnum getFeature() {
return UtilityFeature.STARBOARD;
}
}

View File

@@ -1,10 +0,0 @@
package dev.sheldan.abstracto.utility.repository;
import dev.sheldan.abstracto.utility.models.database.EmbeddedMessage;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EmbeddedMessageRepository extends JpaRepository<EmbeddedMessage, Long> {
EmbeddedMessage findByEmbeddingMessageId(Long messageId);
}

View File

@@ -1,22 +0,0 @@
package dev.sheldan.abstracto.utility.repository;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.utility.models.database.PostedImage;
import dev.sheldan.abstracto.utility.models.database.embed.PostIdentifier;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface PostedImageRepository extends JpaRepository<PostedImage, PostIdentifier> {
boolean existsByImageHashAndServerId(String hash, Long serverId);
Optional<PostedImage> findByImageHashAndServerId(String hash, Long serverId);
boolean existsByPostId_MessageId(Long messageId);
boolean existsByPostId_MessageIdAndPostId_PositionGreaterThan(Long messageId, Integer position);
List<PostedImage> findByPostId_MessageId(Long messageId);
void deleteByServer(AServer server);
void deleteByPoster(AUserInAServer aUserInAServer);
}

View File

@@ -1,23 +0,0 @@
package dev.sheldan.abstracto.utility.repository;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.utility.models.database.Reminder;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface ReminderRepository extends JpaRepository<Reminder, Long> {
List<Reminder> getByRemindedUserAndRemindedFalse(AUserInAServer aUserInAServer);
Reminder getByIdAndRemindedUserAndRemindedFalse(Long reminderId, AUserInAServer aUserInAServer);
@NotNull
@Override
Optional<Reminder> findById(@NonNull Long aLong);
}

View File

@@ -1,9 +0,0 @@
package dev.sheldan.abstracto.utility.repository;
import dev.sheldan.abstracto.utility.models.database.RepostCheckChannelGroup;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface RepostCheckChannelRepository extends JpaRepository<RepostCheckChannelGroup, Long> {
}

View File

@@ -1,55 +0,0 @@
package dev.sheldan.abstracto.utility.repository;
import dev.sheldan.abstracto.utility.models.database.Repost;
import dev.sheldan.abstracto.utility.models.database.embed.RepostIdentifier;
import dev.sheldan.abstracto.utility.models.database.result.RepostLeaderboardResult;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface RepostRepository extends JpaRepository<Repost, RepostIdentifier> {
@Query(value = "WITH repost_rank AS " +
"( " +
"SELECT user_in_server_id as user_in_server_id, SUM(count) as repost_count, ROW_NUMBER() OVER ( ORDER BY SUM(count) DESC ) \n" +
"FROM repost \n" +
"WHERE server_id = :server_id " +
"GROUP BY user_in_server_id \n" +
"ORDER BY SUM(count) DESC \n" +
" )" +
"SELECT rank.user_in_server_id as userInServerId, rank.repost_count as repostCount, rank.row_number as rank " +
"FROM repost_rank rank ",
countQuery = "SELECT COUNT(1) FROM repost WHERE server_id = :server_id GROUP BY user_in_server_id",
nativeQuery = true)
List<RepostLeaderboardResult> findTopRepostingUsers(@Param("server_id") Long serverId, Pageable pageable);
@Query(value = "WITH repost_rank AS " +
"( " +
"SELECT user_in_server_id as user_in_server_id, SUM(count) as repost_count, ROW_NUMBER() OVER ( ORDER BY SUM(count) DESC ) \n" +
"FROM repost \n" +
"WHERE server_id = :server_id " +
"GROUP BY user_in_server_id \n" +
"ORDER BY SUM(count) DESC \n" +
" )" +
"SELECT rank.user_in_server_id as userInServerId, rank.repost_count as repostCount, rank.row_number as rank " +
"FROM repost_rank rank " +
"WHERE rank.user_in_server_id = :user_in_server_id " +
"UNION ALL " +
"SELECT :user_in_server_id as userInServerId, 0 as repostCount, 0 as rank " +
"WHERE NOT EXISTS " +
"(SELECT 1 " +
"FROM repost_rank rank WHERE rank.user_in_server_id = :user_in_server_id" +
")",
nativeQuery = true)
RepostLeaderboardResult getRepostRankOfUserInServer(@Param("user_in_server_id") Long useInServerId, @Param("server_id") Long serverId);
void deleteByServerId(Long serverId);
void deleteByRepostId_UserInServerIdAndServerId(Long userInServerId, Long serverId);
}

View File

@@ -1,7 +0,0 @@
package dev.sheldan.abstracto.utility.repository;
public interface StarStatsGuildUserResult {
// this is the User in Server Id
Long getUserId();
Integer getStarCount();
}

View File

@@ -1,43 +0,0 @@
package dev.sheldan.abstracto.utility.repository;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
import dev.sheldan.abstracto.utility.models.database.StarboardPostReaction;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
public interface StarboardPostReactionRepository extends JpaRepository<StarboardPostReaction, Long> {
void deleteByReactorAndStarboardPost(AUserInAServer user, StarboardPost post);
void deleteByStarboardPost(StarboardPost post);
@Query(value = "SELECT r.reactor_user_in_server_id as userId, COUNT(*) AS starCount \n" +
"FROM starboard_post_reaction r \n" +
"INNER JOIN starboard_post p ON p.id = r.post_id\n" +
"WHERE p.server_id = :serverId\n" +
" AND p.ignored = false\n" +
"GROUP BY r.reactor_user_in_server_id \n" +
"ORDER BY starCount DESC \n" +
"LIMIT :count", nativeQuery = true)
List<StarStatsGuildUserResult> findTopStarGiverInServer(Long serverId, Integer count);
@Query(value = "SELECT COUNT(*) \n" +
"FROM starboard_post_reaction r \n" +
"INNER JOIN starboard_post p ON p.id = r.post_id\n" +
"WHERE p.server_id = :serverId\n"
, nativeQuery = true)
Integer getReactionCountByServer(Long serverId);
@Query(value = "SELECT p.author_user_in_server_id as userId, COUNT(*) AS starCount \n" +
"FROM starboard_post_reaction r \n" +
"INNER JOIN starboard_post p ON p.id = r.post_id\n" +
"WHERE p.server_id = :serverId\n" +
" AND p.ignored = false\n" +
"GROUP BY p.author_user_in_server_id \n" +
"ORDER BY starCount DESC \n" +
"LIMIT :count", nativeQuery = true)
List<StarStatsGuildUserResult> retrieveTopStarReceiverInServer(Long serverId, Integer count);
}

View File

@@ -1,52 +0,0 @@
package dev.sheldan.abstracto.utility.repository;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface StarboardPostRepository extends JpaRepository<StarboardPost, Long> {
StarboardPost findByPostMessageId(Long messageId);
StarboardPost findByStarboardMessageId(Long messageId);
boolean existsByStarboardMessageId(Long messageId);
List<StarboardPost> findByServer_Id(Long serverId);
@Query(value = "SELECT p.id, COUNT(*) AS starCount \n" +
" FROM starboard_post p \n" +
" INNER JOIN starboard_post_reaction r ON p.id = r.post_id\n" +
" INNER JOIN user_in_server usi ON usi.user_in_server_id = p.author_user_in_server_id\n" +
" WHERE p.server_id = :serverId\n" +
" AND p.ignored = false\n" +
" AND usi.user_id = :userId\n" +
" GROUP BY p.id \n" +
" ORDER BY starCount DESC \n" +
" LIMIT :count", nativeQuery = true)
List<Long> getTopStarboardPostsForUser(Long serverId, Long userId, Integer count);
@Query(value = "SELECT COUNT(*) AS starCount\n" +
"FROM starboard_post_reaction r \n" +
" INNER JOIN starboard_post p ON p.id = r.post_id \n" +
" INNER JOIN user_in_server usi ON usi.user_in_server_id = r.reactor_user_in_server_id \n" +
" WHERE usi.user_id = :userId \n" +
" AND p.ignored = false\n" +
" AND r.server_id = :serverId", nativeQuery = true)
Long getGivenStarsOfUserInServer(Long serverId, Long userId);
@Query(value = "SELECT COUNT(*) AS starCount\n" +
" FROM starboard_post_reaction r \n" +
" INNER JOIN starboard_post p ON p.id = r.post_id \n" +
" INNER JOIN user_in_server usi ON usi.user_in_server_id = p.author_user_in_server_id \n" +
" WHERE p.author_user_in_server_id = usi.user_in_server_id \n" +
" AND usi.user_id = :userId \n" +
" AND p.ignored = false\n" +
" AND r.server_id = :serverId", nativeQuery = true)
Long getReceivedStarsOfUserInServer(Long serverId, Long userId);
}

View File

@@ -1,17 +0,0 @@
package dev.sheldan.abstracto.utility.repository;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.utility.models.database.Suggestion;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface SuggestionRepository extends JpaRepository<Suggestion, ServerSpecificId> {
@NotNull
@Override
Optional<Suggestion> findById(@NonNull ServerSpecificId aLong);
}

View File

@@ -1,56 +0,0 @@
package dev.sheldan.abstracto.utility.repository.converter;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsUser;
import dev.sheldan.abstracto.utility.repository.StarStatsGuildUserResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class StarStatsUserConverter {
@Autowired
private MemberService memberService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private UserManagementService userManagementService;
@Autowired
private StarStatsUserConverter self;
public List<CompletableFuture<StarStatsUser>> convertToStarStatsUser(List<StarStatsGuildUserResult> users, Long serverId) {
List<CompletableFuture<StarStatsUser>> result = new ArrayList<>();
users.forEach(starStatsUserResult ->
result.add(createStarStatsUser(serverId, starStatsUserResult))
);
return result;
}
private CompletableFuture<StarStatsUser> createStarStatsUser(Long serverId, StarStatsGuildUserResult starStatsGuildUserResult) {
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(starStatsGuildUserResult.getUserId());
return memberService.getMemberInServerAsync(serverId, aUserInAServer.getUserReference().getId())
.thenApply(member -> self.loadStarStatsUser(starStatsGuildUserResult, member))
.exceptionally(throwable -> self.loadStarStatsUser(starStatsGuildUserResult, null));
}
@Transactional
public StarStatsUser loadStarStatsUser(StarStatsGuildUserResult starStatsGuildUserResult, net.dv8tion.jda.api.entities.Member member) {
return StarStatsUser
.builder()
.starCount(starStatsGuildUserResult.getStarCount())
.member(member)
.user(userInServerManagementService.loadOrCreateUser(starStatsGuildUserResult.getUserId()))
.build();
}
}

View File

@@ -1,58 +0,0 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.service.ConfigService;
import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.List;
import static dev.sheldan.abstracto.utility.config.features.EntertainmentFeature.ROULETTE_BULLETS_CONFIG_KEY;
@Component
public class EntertainmentServiceBean implements EntertainmentService {
public static final List<String> EIGHT_BALL_ANSWER_KEYS = Arrays.asList(
"IS_CERTAIN", "IS_DECIDEDLY", "WITHOUT_DOUBT", "DEFINITELY_SO", "MAY_RELY", // certain
"SEE_IT", "MOST_LIKELY", "OUTLOOK", "YES", "POINT_YES", // certain
"HAZY", "ASK_AGAIN", "NOT_TELL", "CANNOT_PREDICT", "CONCENTRATE", // uncertain
"DONT_COUNT", "REPLY_NO", "SOURCES_NO", "OUTLOOK_NOT_GOOD", "DOUBTFUL" // negative
);
@Autowired
private SecureRandom secureRandom;
@Autowired
private ConfigService configService;
@Override
public String getEightBallValue(String text) {
return EIGHT_BALL_ANSWER_KEYS.get(secureRandom.nextInt(EIGHT_BALL_ANSWER_KEYS.size()));
}
@Override
public Integer getLoveCalcValue(String firstPart, String secondPart) {
return secureRandom.nextInt(100);
}
@Override
public Integer calculateRollResult(Integer low, Integer high) {
int actualLow = Math.min(low, high);
int actualHigh = Math.max(low, high);
return actualLow + secureRandom.nextInt(actualHigh - actualLow);
}
@Override
public boolean executeRoulette(Member memberExecuting) {
Long possibilities = configService.getLongValue(ROULETTE_BULLETS_CONFIG_KEY, memberExecuting.getGuild().getIdLong());
// 1/possibilities of chance, we don't have a state, each time its reset
return secureRandom.nextInt(possibilities.intValue()) == 0;
}
@Override
public String takeChoice(List<String> choices, Member memberExecuting) {
return choices.get(secureRandom.nextInt(choices.size()));
}
}

View File

@@ -1,161 +0,0 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.template.listener.MessageEmbeddedModel;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.utility.models.MessageEmbedLink;
import dev.sheldan.abstracto.utility.service.management.MessageEmbedPostManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Component
@Slf4j
public class MessageEmbedServiceBean implements MessageEmbedService {
private Pattern messageRegex = Pattern.compile("(?<whole>https://discord(?:app)?.com/channels/(?<server>\\d+)/(?<channel>\\d+)/(?<message>\\d+)(?:.*?))+");
public static final String MESSAGE_EMBED_TEMPLATE = "message_embed";
public static final String REMOVAL_EMOTE = "removeEmbed";
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private MemberService memberService;
@Autowired
private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Autowired
private MessageEmbedServiceBean self;
@Autowired
private MessageCache messageCache;
@Autowired
private MessageEmbedPostManagementService messageEmbedPostManagementService;
@Autowired
private ReactionService reactionService;
@Override
public List<MessageEmbedLink> getLinksInMessage(String message) {
List<MessageEmbedLink> links = new ArrayList<>();
Matcher matcher = messageRegex.matcher(message);
while(matcher.find()) {
String serverId = matcher.group("server");
String channelId = matcher.group("channel");
String messageId = matcher.group("message");
String wholeLink = matcher.group("whole");
Long serverIdLong = Long.parseLong(serverId);
Long channelIdLong = Long.parseLong(channelId);
Long messageIdLong = Long.parseLong(messageId);
MessageEmbedLink messageEmbedLink = MessageEmbedLink
.builder()
.serverId(serverIdLong)
.channelId(channelIdLong)
.messageId(messageIdLong)
.wholeUrl(wholeLink)
.build();
links.add(messageEmbedLink);
}
return links;
}
@Override
public void embedLinks(List<MessageEmbedLink> linksToEmbed, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage) {
linksToEmbed.forEach(messageEmbedLink ->
messageCache.getMessageFromCache(messageEmbedLink.getServerId(), messageEmbedLink.getChannelId(), messageEmbedLink.getMessageId())
.thenAccept(cachedMessage -> self.embedLink(cachedMessage, target, userEmbeddingUserInServerId, embeddingMessage)
).exceptionally(throwable -> {
log.error("Message embedding from cache failed for message {}.", messageEmbedLink.getMessageId(), throwable);
return null;
})
);
}
@Override
@Transactional
public CompletableFuture<Void> embedLink(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage) {
Optional<AUserInAServer> causeOpt = userInServerManagementService.loadUserOptional(userEmbeddingUserInServerId);
if(causeOpt.isPresent()) {
return buildTemplateParameter(embeddingMessage, cachedMessage).thenCompose(messageEmbeddedModel ->
self.sendEmbeddingMessage(cachedMessage, target, userEmbeddingUserInServerId, messageEmbeddedModel)
);
} else {
log.warn("User {} which was not found in database wanted to embed link in message {}.", userEmbeddingUserInServerId, embeddingMessage.getJumpUrl());
return CompletableFuture.completedFuture(null);
}
}
@Transactional
public CompletableFuture<Void> sendEmbeddingMessage(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, MessageEmbeddedModel messageEmbeddedModel) {
MessageToSend embed = templateService.renderEmbedTemplate(MESSAGE_EMBED_TEMPLATE, messageEmbeddedModel);
AUserInAServer cause = userInServerManagementService.loadOrCreateUser(userEmbeddingUserInServerId);
List<CompletableFuture<Message>> completableFutures = channelService.sendMessageToSendToChannel(embed, target);
log.trace("Embedding message {} from channel {} from server {}, because of user {}", cachedMessage.getMessageId(),
cachedMessage.getChannelId(), cachedMessage.getServerId(), cause.getUserReference().getId());
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenCompose(aVoid -> {
Message createdMessage = completableFutures.get(0).join();
return reactionService.addReactionToMessageAsync(REMOVAL_EMOTE, cachedMessage.getServerId(), createdMessage).thenAccept(aVoid1 ->
self.loadUserAndPersistMessage(cachedMessage, userEmbeddingUserInServerId, createdMessage)
);
});
}
@Transactional
public void loadUserAndPersistMessage(CachedMessage cachedMessage, Long userInServerId, Message createdMessage) {
AUserInAServer innerCause = userInServerManagementService.loadOrCreateUser(userInServerId);
messageEmbedPostManagementService.createMessageEmbed(cachedMessage, createdMessage, innerCause);
}
private CompletableFuture<MessageEmbeddedModel> buildTemplateParameter(Message message, CachedMessage embeddedMessage) {
return memberService.getMemberInServerAsync(embeddedMessage.getServerId(), embeddedMessage.getAuthor().getAuthorId()).thenApply(member ->
self.loadMessageEmbedModel(message, embeddedMessage, member)
);
}
@Transactional
public MessageEmbeddedModel loadMessageEmbedModel(Message message, CachedMessage embeddedMessage, Member member) {
Optional<TextChannel> textChannelFromServer = channelService.getTextChannelFromServerOptional(embeddedMessage.getServerId(), embeddedMessage.getChannelId());
TextChannel sourceChannel = textChannelFromServer.orElse(null);
return MessageEmbeddedModel
.builder()
.member(message.getMember())
.author(member)
.sourceChannel(sourceChannel)
.embeddingUser(message.getMember())
.messageChannel(message.getChannel())
.guild(message.getGuild())
.embeddedMessage(embeddedMessage)
.build();
}
}

View File

@@ -1,30 +0,0 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.utility.service.management.PostedImageManagement;
import net.dv8tion.jda.api.entities.Guild;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class PostedImageServiceBean implements PostedImageService {
@Autowired
private PostedImageManagement postedImageManagement;
@Autowired
private ServerManagementService serverManagementService;
@Override
public void purgePostedImages(AUserInAServer aUserInAServer) {
postedImageManagement.removePostedImagesOf(aUserInAServer);
}
@Override
public void purgePostedImages(Guild guild) {
AServer server = serverManagementService.loadServer(guild.getIdLong());
postedImageManagement.removedPostedImagesIn(server);
}
}

View File

@@ -1,162 +0,0 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.GuildService;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.scheduling.model.JobParameters;
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.utility.exception.ReminderNotFoundException;
import dev.sheldan.abstracto.utility.models.database.Reminder;
import dev.sheldan.abstracto.utility.models.template.commands.reminder.ExecutedReminderModel;
import dev.sheldan.abstracto.utility.service.management.ReminderManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
public class RemindServiceBean implements ReminderService {
public static final String REMINDER_TEMPLATE_TEXT = "remind_reminder";
@Autowired
private ReminderManagementService reminderManagementService;
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private TemplateService templateService;
@Autowired
private SchedulerService schedulerService;
@Autowired
private MemberService memberService;
@Autowired
private GuildService guildService;
@Autowired
private RemindServiceBean self;
@Autowired
private ChannelService channelService;
@Autowired
@Qualifier("reminderScheduler")
private ScheduledExecutorService instantReminderScheduler;
@Override
public Reminder createReminderInForUser(AUserInAServer user, String remindText, Duration remindIn, Message message) {
AChannel channel = channelManagementService.loadChannel(message.getChannel().getIdLong());
AServerAChannelAUser aServerAChannelAUser = AServerAChannelAUser
.builder()
.user(user.getUserReference())
.aUserInAServer(user)
.guild(user.getServerReference())
.channel(channel)
.build();
Instant remindAt = Instant.now().plusNanos(remindIn.toNanos());
Reminder reminder = reminderManagementService.createReminder(aServerAChannelAUser, remindText, remindAt, message.getIdLong());
log.info("Creating reminder for user {} in guild {} due at {}.",
user.getUserReference().getId(), user.getServerReference().getId(), remindAt);
if(remindIn.getSeconds() < 60) {
log.info("Directly scheduling unremind for reminder {}, because it was below the threshold.", reminder.getId());
instantReminderScheduler.schedule(() -> {
try {
self.executeReminder(reminder.getId());
} catch (Exception exception) {
log.error("Failed to remind immediately.", exception);
}
}, remindIn.toNanos(), TimeUnit.NANOSECONDS);
} else {
HashMap<Object, Object> parameters = new HashMap<>();
parameters.put("reminderId", reminder.getId());
JobParameters jobParameters = JobParameters.builder().parameters(parameters).build();
String triggerKey = schedulerService.executeJobWithParametersOnce("reminderJob", "utility", jobParameters, Date.from(reminder.getTargetDate()));
log.info("Starting scheduled job with trigger {} to execute reminder. {}", triggerKey, reminder.getId());
reminder.setJobTriggerKey(triggerKey);
reminderManagementService.saveReminder(reminder);
}
return reminder;
}
@Override
@Transactional
public void executeReminder(Long reminderId) {
Reminder reminderToRemindFor = reminderManagementService.loadReminder(reminderId);
if(reminderToRemindFor.isReminded()) {
return;
}
AServer server = reminderToRemindFor.getServer();
AChannel channel = reminderToRemindFor.getChannel();
log.info("Executing reminder {} in channel {} in server {} for user {}.",
reminderId, channel.getId(), server.getId(), reminderToRemindFor.getRemindedUser().getUserReference().getId());
Optional<Guild> guildToAnswerIn = guildService.getGuildByIdOptional(server.getId());
if(guildToAnswerIn.isPresent()) {
Optional<TextChannel> channelToAnswerIn = channelService.getTextChannelFromServerOptional(server.getId(), channel.getId());
// only send the message if the channel still exists, if not, only set the reminder to reminded.
if(channelToAnswerIn.isPresent()) {
memberService.getMemberInServerAsync(server.getId(), reminderToRemindFor.getRemindedUser().getUserReference().getId()).thenAccept(member ->
self.sendReminderText(reminderId, channelToAnswerIn.get(), member)
);
} else {
log.warn("Channel {} in server {} to remind user did not exist anymore. Ignoring reminder {}", channel.getId(), server.getId(), reminderId);
}
} else {
log.warn("Guild {} to remind user in did not exist anymore. Ignoring reminder {}.", server.getId(), reminderId);
}
reminderManagementService.setReminded(reminderToRemindFor);
}
@Transactional
public CompletableFuture<Void> sendReminderText(Long reminderId, TextChannel channelToAnswerIn, Member member) {
Reminder reminder = reminderManagementService.loadReminder(reminderId);
log.trace("Sending remind message for reminder {} to user user {} in server {}.", reminderId, member.getIdLong(), member.getGuild().getIdLong());
ExecutedReminderModel build = ExecutedReminderModel
.builder()
.reminder(reminder)
.member(member)
.duration(Duration.between(reminder.getReminderDate(), reminder.getTargetDate()))
.build();
MessageToSend messageToSend = templateService.renderEmbedTemplate(REMINDER_TEMPLATE_TEXT, build);
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, channelToAnswerIn));
}
@Override
public void unRemind(Long reminderId, AUserInAServer aUserInAServer) {
log.info("Trying to end reminder {} for user {} in server {}.", reminderId, aUserInAServer.getUserReference().getId(), aUserInAServer.getServerReference().getId());
Reminder reminder = reminderManagementService.getReminderByAndByUserNotReminded(aUserInAServer, reminderId).orElseThrow(() -> new ReminderNotFoundException(reminderId));
reminder.setReminded(true);
if(reminder.getJobTriggerKey() != null) {
log.trace("Stopping scheduled trigger {} for reminder {}.", reminder.getJobTriggerKey(), reminderId);
schedulerService.stopTrigger(reminder.getJobTriggerKey());
}
}
}

View File

@@ -1,104 +0,0 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.ChannelGroupService;
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.utility.models.database.RepostCheckChannelGroup;
import dev.sheldan.abstracto.utility.service.management.RepostCheckChannelGroupManagement;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static dev.sheldan.abstracto.utility.service.RepostServiceBean.REPOST_CHECK_CHANNEL_GROUP_TYPE;
@Component
public class RepostCheckChannelServiceBean implements RepostCheckChannelService {
@Autowired
private RepostCheckChannelGroupManagement repostCheckChannelManagement;
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private ChannelGroupService channelGroupService;
@Autowired
private ChannelGroupManagementService channelGroupManagementService;
@Override
public void setRepostCheckEnabledForChannelGroup(AChannelGroup channelGroup) {
RepostCheckChannelGroup group = repostCheckChannelManagement.loadRepostChannelGroupByChannelGroup(channelGroup);
setRepostCheckEnabledForChannelGroup(group);
}
@Override
public void setRepostCheckEnabledForChannelGroup(RepostCheckChannelGroup channelGroup) {
channelGroup.setCheckEnabled(true);
}
@Override
public void setRepostCheckDisabledForChannelGroup(AChannelGroup channelGroup) {
RepostCheckChannelGroup group = repostCheckChannelManagement.loadRepostChannelGroupByChannelGroup(channelGroup);
setRepostCheckDisabledForChannelGroup(group);
}
@Override
public void setRepostCheckDisabledForChannelGroup(RepostCheckChannelGroup channelGroup) {
channelGroup.setCheckEnabled(false);
}
@Override
public boolean duplicateCheckEnabledForChannel(TextChannel textChannel) {
AChannel channel = channelManagementService.loadChannel(textChannel.getIdLong());
return duplicateCheckEnabledForChannel(channel);
}
@Override
public boolean duplicateCheckEnabledForChannel(AChannel channel) {
List<AChannelGroup> channelGroups = channelGroupService.getChannelGroupsOfChannelWithType(channel, REPOST_CHECK_CHANNEL_GROUP_TYPE);
if(!channelGroups.isEmpty()) {
List<RepostCheckChannelGroup> repostChannelGroups = channelGroups.stream().map(aChannelGroup ->
repostCheckChannelManagement.loadRepostChannelGroupById(aChannelGroup.getId())
).collect(Collectors.toList());
return repostChannelGroups.stream().anyMatch(RepostCheckChannelGroup::getCheckEnabled);
}
return false;
}
@Override
public List<RepostCheckChannelGroup> getRepostCheckChannelGroupsForServer(AServer server) {
return getRepostCheckChannelGroupsForServer(server.getId());
}
@Override
public List<RepostCheckChannelGroup> getRepostCheckChannelGroupsForServer(Long serverId) {
List<AChannelGroup> channelGroups = channelGroupManagementService.findAllInServerWithType(serverId, REPOST_CHECK_CHANNEL_GROUP_TYPE);
if(!channelGroups.isEmpty()) {
return channelGroups.stream().map(aChannelGroup ->
repostCheckChannelManagement.loadRepostChannelGroupById(aChannelGroup.getId())
).collect(Collectors.toList());
}
return new ArrayList<>();
}
@Override
public List<RepostCheckChannelGroup> getChannelGroupsWithEnabledCheck(AServer server) {
return getChannelGroupsWithEnabledCheck(server.getId());
}
@Override
public List<RepostCheckChannelGroup> getChannelGroupsWithEnabledCheck(Long serverId) {
return getRepostCheckChannelGroupsForServer(serverId)
.stream()
.filter(RepostCheckChannelGroup::getCheckEnabled)
.collect(Collectors.toList());
}
}

View File

@@ -1,307 +0,0 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
import dev.sheldan.abstracto.core.models.ServerChannelMessageUser;
import dev.sheldan.abstracto.core.models.cache.CachedAttachment;
import dev.sheldan.abstracto.core.models.cache.CachedEmbed;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.FileService;
import dev.sheldan.abstracto.utility.config.features.RepostDetectionFeatureMode;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.converter.RepostLeaderBoardConverter;
import dev.sheldan.abstracto.utility.models.RepostLeaderboardEntryModel;
import dev.sheldan.abstracto.utility.models.database.PostedImage;
import dev.sheldan.abstracto.utility.models.database.Repost;
import dev.sheldan.abstracto.utility.models.database.result.RepostLeaderboardResult;
import dev.sheldan.abstracto.utility.service.management.PostedImageManagement;
import dev.sheldan.abstracto.utility.service.management.RepostManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
public class RepostServiceBean implements RepostService {
public static final Integer LEADER_BOARD_PAGE_SIZE = 5;
@Autowired
private HttpService httpService;
@Autowired
private HashService hashService;
@Autowired
private FileService fileService;
@Autowired
private PostedImageManagement postedImageManagement;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private ReactionService reactionService;
@Autowired
private FeatureModeService featureModeService;
@Autowired
private RepostManagementService repostManagementService;
@Autowired
private RepostLeaderBoardConverter leaderBoardConverter;
@Autowired
private RepostServiceBean self;
public static final List<String> NUMBER_EMOJI = Arrays.asList("\u0031\u20e3", "\u0032\u20e3", "\u0033\u20e3",
"\u0034\u20e3", "\u0035\u20e3", "\u0036\u20e3",
"\u0037\u20e3", "\u0038\u20e3", "\u0039\u20e3");
public static final String REPOST_CHECK_CHANNEL_GROUP_TYPE = "repostDetection";
// any embedded post will create an repost instance with a position higher than this
public static final Integer EMBEDDED_LINK_POSITION_START_INDEX = 1000;
public static final String REPOST_MARKER_EMOTE_KEY = "repostMarker";
@Override
public boolean isRepost(CachedMessage message, CachedEmbed messageEmbed, Integer index) {
return getRepostFor(message, messageEmbed, index).isPresent();
}
@Override
public Optional<PostedImage> getRepostFor(CachedMessage message, CachedEmbed messageEmbed, Integer embedIndex) {
if(messageEmbed.getCachedThumbnail() == null && messageEmbed.getCachedImageInfo() == null) {
return Optional.empty();
}
String urlToUse = null;
if(messageEmbed.getCachedThumbnail() != null) {
urlToUse = messageEmbed.getCachedThumbnail().getProxyUrl();
} else if (messageEmbed.getCachedImageInfo() != null) {
urlToUse = messageEmbed.getCachedImageInfo().getProxyUrl();
}
ServerChannelMessageUser serverChannelMessageUser = ServerChannelMessageUser
.builder()
.serverId(message.getServerId())
.channelId(message.getChannelId())
.userId(message.getAuthor().getAuthorId())
.messageId(message.getMessageId())
.build();
return checkForDuplicates(serverChannelMessageUser, EMBEDDED_LINK_POSITION_START_INDEX + embedIndex, urlToUse);
}
@Override
public Optional<PostedImage> getRepostFor(Message message, MessageEmbed messageEmbed, Integer embedIndex) {
if(messageEmbed.getThumbnail() == null && messageEmbed.getImage() == null) {
return Optional.empty();
}
String urlToUse = null;
if(messageEmbed.getThumbnail() != null) {
urlToUse = messageEmbed.getThumbnail().getProxyUrl();
} else if (messageEmbed.getImage() != null) {
urlToUse = messageEmbed.getImage().getProxyUrl();
}
ServerChannelMessageUser serverChannelMessageUser = ServerChannelMessageUser
.builder()
.serverId(message.getGuild().getIdLong())
.channelId(message.getChannel().getIdLong())
.userId(message.getAuthor().getIdLong())
.messageId(message.getIdLong())
.build();
return checkForDuplicates(serverChannelMessageUser, EMBEDDED_LINK_POSITION_START_INDEX + embedIndex, urlToUse);
}
private Optional<PostedImage> checkForDuplicates(ServerChannelMessageUser serverChannelMessageUser, Integer index, String fileUrl) {
String fileHash = calculateHashForPost(fileUrl, serverChannelMessageUser.getServerId());
AServer aServer = serverManagementService.loadServer(serverChannelMessageUser.getServerId());
Optional<PostedImage> potentialRepost = postedImageManagement.getPostWithHash(fileHash, aServer);
if(potentialRepost.isPresent()) {
PostedImage existingRepost = potentialRepost.get();
return !existingRepost.getPostId().getMessageId().equals(serverChannelMessageUser.getMessageId()) ? Optional.of(existingRepost) : Optional.empty();
} else {
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(serverChannelMessageUser.getServerId(), serverChannelMessageUser.getUserId());
AServerAChannelAUser cause = AServerAChannelAUser
.builder()
.aUserInAServer(aUserInAServer)
.channel(channelManagementService.loadChannel(serverChannelMessageUser.getChannelId()))
.guild(aServer)
.user(aUserInAServer.getUserReference())
.build();
postedImageManagement.createPost(cause, serverChannelMessageUser.getMessageId(), fileHash, index);
return Optional.empty();
}
}
@Override
public boolean isRepost(CachedMessage message, CachedAttachment attachment, Integer index) {
return getRepostFor(message, attachment, index).isPresent();
}
@Override
public Optional<PostedImage> getRepostFor(CachedMessage message, CachedAttachment attachment, Integer index) {
ServerChannelMessageUser serverChannelMessageUser = ServerChannelMessageUser
.builder()
.serverId(message.getServerId())
.channelId(message.getChannelId())
.userId(message.getAuthor().getAuthorId())
.messageId(message.getMessageId())
.build();
return checkForDuplicates(serverChannelMessageUser, index, attachment.getProxyUrl());
}
@Override
public String calculateHashForPost(String url, Long serverId) {
File downloadedFile = null;
try {
if(featureModeService.featureModeActive(UtilityFeature.REPOST_DETECTION, serverId, RepostDetectionFeatureMode.DOWNLOAD)) {
downloadedFile = httpService.downloadFileToTempFile(url);
return hashService.sha256HashFileContent(downloadedFile);
} else {
return hashService.sha256HashString(url);
}
} catch (IOException e) {
log.error("Failed to download attachment for repost check.", e);
} finally {
if(downloadedFile != null) {
try {
fileService.safeDelete(downloadedFile);
} catch (IOException e) {
log.error("Failed to delete downloaded repost check file.", e);
}
}
}
return null;
}
@Override
public void processMessageAttachmentRepostCheck(CachedMessage message) {
boolean canThereBeMultipleReposts = message.getAttachments().size() > 1;
for (int imageIndex = 0; imageIndex < message.getAttachments().size(); imageIndex++) {
executeRepostCheckForAttachment(message, message.getAttachments().get(imageIndex), imageIndex, canThereBeMultipleReposts);
}
}
private void executeRepostCheckForAttachment(CachedMessage message, CachedAttachment attachment, Integer index, boolean moreRepostsPossible) {
Optional<PostedImage> originalPostOptional = getRepostFor(message, attachment, index);
ServerChannelMessageUser serverChannelMessageUser = ServerChannelMessageUser
.builder()
.serverId(message.getServerId())
.channelId(message.getChannelId())
.userId(message.getAuthor().getAuthorId())
.messageId(message.getMessageId())
.build();
originalPostOptional.ifPresent(postedImage -> markMessageAndPersist(serverChannelMessageUser, index, moreRepostsPossible, postedImage));
}
private void markMessageAndPersist(ServerChannelMessageUser messageUser, Integer index, boolean moreRepostsPossible, PostedImage originalPost) {
log.info("Detected repost in message embed {} of message {} in channel {} in server {}.", index, messageUser.getMessageId(), messageUser.getChannelId(), messageUser.getServerId());
CompletableFuture<Void> markerFuture = reactionService.addReactionToMessageAsync(REPOST_MARKER_EMOTE_KEY, messageUser.getServerId(), messageUser.getChannelId(), messageUser.getMessageId());
CompletableFuture<Void> counterFuture;
if (moreRepostsPossible) {
counterFuture = reactionService.addDefaultReactionToMessageAsync(NUMBER_EMOJI.get(index), messageUser.getServerId(), messageUser.getChannelId(), messageUser.getMessageId());
} else {
counterFuture = CompletableFuture.completedFuture(null);
}
Long messageId = originalPost.getPostId().getMessageId();
Integer position = originalPost.getPostId().getPosition();
Long serverId = messageUser.getServerId();
Long userId = messageUser.getUserId();
CompletableFuture.allOf(markerFuture, counterFuture).thenAccept(unused ->
self.persistRepost(messageId, position, serverId, userId)
);
}
@Transactional
public void persistRepost(Long messageId, Integer position, Long serverId, Long userId) {
PostedImage postedImage = postedImageManagement.getPostFromMessageAndPosition(messageId, position);
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(serverId, userId);
Optional<Repost> existingPost = repostManagementService.findRepostOptional(postedImage, userInAServer);
if(existingPost.isPresent()) {
Repost previousRepost = existingPost.get();
existingPost.get().setCount(previousRepost.getCount() + 1);
} else {
repostManagementService.createRepost(postedImage, userInAServer);
}
}
@Override
public void processMessageEmbedsRepostCheck(List<CachedEmbed> embeds, CachedMessage message) {
boolean canThereBeMultipleReposts = embeds.size() > 1 || !message.getAttachments().isEmpty();
for (int imageIndex = 0; imageIndex < embeds.size(); imageIndex++) {
executeRepostCheckForMessageEmbed(message, embeds.get(imageIndex), imageIndex + message.getAttachments().size(), canThereBeMultipleReposts);
}
}
@Override
public void processMessageEmbedsRepostCheck(List<MessageEmbed> embeds, Message message) {
boolean canThereBeMultipleReposts = embeds.size() > 1 || !message.getAttachments().isEmpty();
for (int imageIndex = 0; imageIndex < embeds.size(); imageIndex++) {
executeRepostCheckForMessageEmbed(message, embeds.get(imageIndex), imageIndex + message.getAttachments().size(), canThereBeMultipleReposts);
}
}
@Override
public CompletableFuture<List<RepostLeaderboardEntryModel>> retrieveRepostLeaderboard(Guild guild, Integer page) {
AServer server = serverManagementService.loadServer(guild.getIdLong());
List<RepostLeaderboardResult> topRepostingUsersOfServer = repostManagementService.findTopRepostingUsersOfServer(server, page, LEADER_BOARD_PAGE_SIZE);
return leaderBoardConverter.fromLeaderBoardResults(topRepostingUsersOfServer);
}
@Override
public void purgeReposts(AUserInAServer userInAServer) {
repostManagementService.deleteRepostsFromUser(userInAServer);
}
@Override
public void purgeReposts(Guild guild) {
AServer server = serverManagementService.loadServer(guild.getIdLong());
repostManagementService.deleteRepostsFromServer(server);
}
private void executeRepostCheckForMessageEmbed(CachedMessage message, CachedEmbed messageEmbed, Integer index, boolean moreRepostsPossible) {
Optional<PostedImage> originalPostOptional = getRepostFor(message, messageEmbed, index);
ServerChannelMessageUser serverChannelMessageUser = ServerChannelMessageUser
.builder()
.serverId(message.getServerId())
.channelId(message.getChannelId())
.userId(message.getAuthor().getAuthorId())
.messageId(message.getMessageId())
.build();
originalPostOptional.ifPresent(postedImage -> markMessageAndPersist(serverChannelMessageUser, index, moreRepostsPossible, postedImage));
}
private void executeRepostCheckForMessageEmbed(Message message, MessageEmbed messageEmbed, Integer index, boolean moreRepostsPossible) {
Optional<PostedImage> originalPostOptional = getRepostFor(message, messageEmbed, index);
ServerChannelMessageUser serverChannelMessageUser = ServerChannelMessageUser
.builder()
.serverId(message.getGuild().getIdLong())
.channelId(message.getChannel().getIdLong())
.userId(message.getAuthor().getIdLong())
.messageId(message.getIdLong())
.build();
originalPostOptional.ifPresent(postedImage -> markMessageAndPersist(serverChannelMessageUser, index, moreRepostsPossible, postedImage));
}
}

View File

@@ -1,264 +0,0 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.exception.UserInServerNotFoundException;
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.database.PostTarget;
import dev.sheldan.abstracto.core.models.property.SystemConfigProperty;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.DefaultConfigManagementService;
import dev.sheldan.abstracto.core.service.management.PostTargetManagement;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.utility.config.features.StarboardFeature;
import dev.sheldan.abstracto.utility.config.posttargets.StarboardPostTarget;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.*;
import dev.sheldan.abstracto.utility.service.management.StarboardPostManagementService;
import dev.sheldan.abstracto.utility.service.management.StarboardPostReactorManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
@Component
@Slf4j
public class StarboardServiceBean implements StarboardService {
public static final String STARBOARD_POST_TEMPLATE = "starboard_post";
@Autowired
private MemberService memberService;
@Autowired
private GuildService guildService;
@Autowired
private ChannelService channelService;
@Autowired
private PostTargetService postTargetService;
@Autowired
private TemplateService templateService;
@Autowired
private ConfigService configService;
@Autowired
private StarboardPostManagementService starboardPostManagementService;
@Autowired
private StarboardPostReactorManagementService starboardPostReactorManagementService;
@Autowired
private PostTargetManagement postTargetManagement;
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private EmoteService emoteService;
@Autowired
private DefaultConfigManagementService defaultConfigManagementService;
@Autowired
private MessageService messageService;
@Autowired
private StarboardServiceBean self;
@Override
public CompletableFuture<Void> createStarboardPost(CachedMessage message, List<AUserInAServer> userExceptAuthor, AUserInAServer userReacting, AUserInAServer starredUser) {
Long starredUserId = starredUser.getUserInServerId();
List<Long> userExceptAuthorIds = userExceptAuthor.stream().map(AUserInAServer::getUserInServerId).collect(Collectors.toList());
return buildStarboardPostModel(message, userExceptAuthor.size()).thenCompose(starboardPostModel ->
self.sendStarboardPostAndStore(message, starredUserId, userExceptAuthorIds, starboardPostModel)
);
}
@Transactional
public CompletionStage<Void> sendStarboardPostAndStore(CachedMessage message, Long starredUserId, List<Long> userExceptAuthorIds, StarboardPostModel starboardPostModel) {
MessageToSend messageToSend = templateService.renderEmbedTemplate(STARBOARD_POST_TEMPLATE, starboardPostModel);
PostTarget starboard = postTargetManagement.getPostTarget(StarboardPostTarget.STARBOARD.getKey(), message.getServerId());
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(messageToSend, StarboardPostTarget.STARBOARD, message.getServerId());
Long starboardChannelId = starboard.getChannelReference().getId();
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenAccept(aVoid ->
self.persistPost(message, userExceptAuthorIds, completableFutures, starboardChannelId, starredUserId)
);
}
@Transactional
public void persistPost(CachedMessage message, List<Long> userExceptAuthorIds, List<CompletableFuture<Message>> completableFutures, Long starboardChannelId, Long starredUserId) {
AUserInAServer innerStarredUser = userInServerManagementService.loadUserOptional(starredUserId).orElseThrow(() -> new UserInServerNotFoundException(starredUserId));
AChannel starboardChannel = channelManagementService.loadChannel(starboardChannelId);
Message message1 = completableFutures.get(0).join();
AServerAChannelMessage aServerAChannelMessage = AServerAChannelMessage
.builder()
.messageId(message1.getIdLong())
.channel(starboardChannel)
.server(starboardChannel.getServer())
.build();
StarboardPost starboardPost = starboardPostManagementService.createStarboardPost(message, innerStarredUser, aServerAChannelMessage);
log.info("Persisting starboard post in channel {} with message {} with {} reactors.", message1.getId(),starboardChannelId, userExceptAuthorIds.size());
if(userExceptAuthorIds.isEmpty()) {
log.warn("There are no user ids except the author for the reactions in post {} in guild {} for message {} in channel {}.", starboardPost.getId(), message.getChannelId(), message.getMessageId(), message.getChannelId());
}
userExceptAuthorIds.forEach(aLong -> {
AUserInAServer user = userInServerManagementService.loadUserOptional(aLong).orElseThrow(() -> new UserInServerNotFoundException(aLong));
starboardPostReactorManagementService.addReactor(starboardPost, user);
});
}
private CompletableFuture<StarboardPostModel> buildStarboardPostModel(CachedMessage message, Integer starCount) {
return memberService.getMemberInServerAsync(message.getServerId(), message.getAuthor().getAuthorId()).thenApply(member -> {
Optional<TextChannel> channel = channelService.getTextChannelFromServerOptional(message.getServerId(), message.getChannelId());
Optional<Guild> guild = guildService.getGuildByIdOptional(message.getServerId());
// TODO use model objects instead of building entity models
AChannel aChannel = AChannel.builder().id(message.getChannelId()).build();
AUser user = AUser.builder().id(message.getAuthor().getAuthorId()).build();
String starLevelEmote = getAppropriateEmote(message.getServerId(), starCount);
return StarboardPostModel
.builder()
.message(message)
.author(member)
.channel(channel.orElse(null))
.aChannel(aChannel)
.starCount(starCount)
.guild(guild.orElse(null))
.user(user)
.starLevelEmote(starLevelEmote)
.build();
});
}
@Override
public CompletableFuture<Void> updateStarboardPost(StarboardPost post, CachedMessage message, List<AUserInAServer> userExceptAuthor) {
int starCount = userExceptAuthor.size();
log.info("Updating starboard post {} in server {} with reactors {}.", post.getId(), post.getSourceChannel().getServer().getId(), starCount);
return buildStarboardPostModel(message, starCount).thenCompose(starboardPostModel -> {
MessageToSend messageToSend = templateService.renderEmbedTemplate(STARBOARD_POST_TEMPLATE, starboardPostModel);
List<CompletableFuture<Message>> futures = postTargetService.editOrCreatedInPostTarget(post.getStarboardMessageId(), messageToSend, StarboardPostTarget.STARBOARD, message.getServerId());
Long starboardPostId = post.getId();
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenAccept(aVoid -> {
Optional<StarboardPost> innerPost = starboardPostManagementService.findByStarboardPostId(starboardPostId);
innerPost.ifPresent(starboardPost -> starboardPostManagementService.setStarboardPostMessageId(starboardPost, futures.get(0).join().getIdLong()));
});
});
}
@Override
public void deleteStarboardMessagePost(StarboardPost message) {
AChannel starboardChannel = message.getStarboardChannel();
log.info("Deleting starboard post {} in server {}", message.getId(), message.getSourceChannel().getServer().getId());
messageService.deleteMessageInChannelInServer(starboardChannel.getServer().getId(), starboardChannel.getId(), message.getStarboardMessageId());
}
@Override
public CompletableFuture<GuildStarStatsModel> retrieveStarStats(Long serverId) {
int count = 3;
List<CompletableFuture<StarStatsUser>> topStarGiverFutures = starboardPostReactorManagementService.retrieveTopStarGiver(serverId, count);
List<CompletableFuture<StarStatsUser>> topStarReceiverFutures = starboardPostReactorManagementService.retrieveTopStarReceiver(serverId, count);
List<CompletableFuture> allFutures = new ArrayList<>();
allFutures.addAll(topStarGiverFutures);
allFutures.addAll(topStarReceiverFutures);
return FutureUtils.toSingleFuture(allFutures).thenApply(aVoid -> {
List<StarboardPost> starboardPosts = starboardPostManagementService.retrieveTopPosts(serverId, count);
List<StarStatsPost> starStatsPosts = starboardPosts.stream().map(this::fromStarboardPost).collect(Collectors.toList());
Integer postCount = starboardPostManagementService.getPostCount(serverId);
Integer reactionCount = starboardPostReactorManagementService.getStarCount(serverId);
List<String> emotes = new ArrayList<>();
for (int i = 1; i < count + 1; i++) {
emotes.add(getStarboardRankingEmote(serverId, i));
}
List<StarStatsUser> topStarGivers = topStarGiverFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
List<StarStatsUser> topStarReceiver = topStarReceiverFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
return GuildStarStatsModel
.builder()
.badgeEmotes(emotes)
.starGiver(topStarGivers)
.starReceiver(topStarReceiver)
.topPosts(starStatsPosts)
.starredMessages(postCount)
.totalStars(reactionCount)
.build();
});
}
@Override
public MemberStarStatsModel retrieveStarStatsForMember(Member member) {
int count = 3;
Long receivedStars = starboardPostManagementService.retrieveReceivedStarsOfUserInServer(member.getGuild().getIdLong(), member.getIdLong());
Long givenStars = starboardPostManagementService.retrieveGivenStarsOfUserInServer(member.getGuild().getIdLong(), member.getIdLong());
List<StarboardPost> topPosts = starboardPostManagementService.retrieveTopPostsForUserInServer(member.getGuild().getIdLong(), member.getIdLong(), count);
List<StarStatsPost> starStatsPosts = topPosts.stream().map(this::fromStarboardPost).collect(Collectors.toList());
List<String> emotes = new ArrayList<>();
for (int i = 1; i < count + 1; i++) {
emotes.add(getStarboardRankingEmote(member.getGuild().getIdLong(), i));
}
return MemberStarStatsModel
.builder()
.member(member)
.topPosts(starStatsPosts)
.badgeEmotes(emotes)
.receivedStars(receivedStars)
.givenStars(givenStars)
.build();
}
public StarStatsPost fromStarboardPost(StarboardPost starboardPost) {
AChannel channel = starboardPost.getStarboardChannel();
return StarStatsPost
.builder()
.serverId(starboardPost.getServer().getId())
.channelId(channel.getId())
.messageId(starboardPost.getPostMessageId())
.starCount(starboardPost.getReactions().size())
.build();
}
private String getStarboardRankingEmote(Long serverId, Integer position) {
return emoteService.getUsableEmoteOrDefault(serverId, buildBadgeName(position));
}
private String buildBadgeName(Integer position) {
return StarboardFeature.STAR_BADGE_EMOTE_PREFIX + position;
}
private String getAppropriateEmote(Long serverId, Integer starCount) {
int maxLevels = defaultConfigManagementService.getDefaultConfig(StarboardFeature.STAR_LEVELS_CONFIG_KEY).getLongValue().intValue();
for(int i = maxLevels; i > 0; i--) {
String key = StarboardFeature.STAR_LVL_CONFIG_PREFIX + i;
SystemConfigProperty defaultStars = defaultConfigManagementService.getDefaultConfig(key);
Long starMinimum = configService.getLongValue(key, serverId, defaultStars.getLongValue());
if(starCount >= starMinimum) {
return emoteService.getUsableEmoteOrDefault(serverId, StarboardFeature.STAR_EMOTE_PREFIX + i);
}
}
return emoteService.getUsableEmoteOrDefault(serverId, StarboardFeature.STAR_EMOTE_PREFIX);
}
}

View File

@@ -1,163 +0,0 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.core.utils.MessageUtils;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.utility.config.posttargets.SuggestionPostTarget;
import dev.sheldan.abstracto.utility.exception.SuggestionNotFoundException;
import dev.sheldan.abstracto.utility.exception.SuggestionUpdateException;
import dev.sheldan.abstracto.utility.models.SuggestionState;
import dev.sheldan.abstracto.utility.models.database.Suggestion;
import dev.sheldan.abstracto.utility.models.template.commands.SuggestionLog;
import dev.sheldan.abstracto.utility.service.management.SuggestionManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
public class SuggestionServiceBean implements SuggestionService {
public static final String SUGGESTION_LOG_TEMPLATE = "suggest_log";
public static final String SUGGESTION_YES_EMOTE = "suggestionYes";
public static final String SUGGESTION_NO_EMOTE = "suggestionNo";
public static final String SUGGESTION_COUNTER_KEY = "suggestion";
@Autowired
private SuggestionManagementService suggestionManagementService;
@Autowired
private PostTargetService postTargetService;
@Autowired
private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Autowired
private MemberService memberService;
@Autowired
private ReactionService reactionService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private SuggestionServiceBean self;
@Autowired
private CounterService counterService;
@Autowired
private ServerManagementService serverManagementService;
@Override
public CompletableFuture<Void> createSuggestionMessage(Member member, String text, SuggestionLog suggestionLog) {
AServer server = serverManagementService.loadServer(member.getGuild());
AUserInAServer suggester = userInServerManagementService.loadOrCreateUser(member);
Long newSuggestionId = counterService.getNextCounterValue(server, SUGGESTION_COUNTER_KEY);
suggestionLog.setSuggestionId(newSuggestionId);
suggestionLog.setState(SuggestionState.NEW);
suggestionLog.setSuggesterUser(suggester);
suggestionLog.setText(text);
MessageToSend messageToSend = templateService.renderEmbedTemplate(SUGGESTION_LOG_TEMPLATE, suggestionLog);
long guildId = member.getGuild().getIdLong();
log.info("Creating suggestion with id {} in server {} from member {}.", newSuggestionId, member.getGuild().getId(), member.getId());
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(messageToSend, SuggestionPostTarget.SUGGESTION, guildId);
return FutureUtils.toSingleFutureGeneric(completableFutures).thenCompose(aVoid -> {
Message message = completableFutures.get(0).join();
log.trace("Posted message, adding reaction for suggestion {} to message {}.", newSuggestionId, message.getId());
CompletableFuture<Void> firstReaction = reactionService.addReactionToMessageAsync(SUGGESTION_YES_EMOTE, guildId, message);
CompletableFuture<Void> secondReaction = reactionService.addReactionToMessageAsync(SUGGESTION_NO_EMOTE, guildId, message);
return CompletableFuture.allOf(firstReaction, secondReaction).thenAccept(aVoid1 -> {
log.trace("Reaction added to message {} for suggestion {}.", message.getId(), newSuggestionId);
self.persistSuggestionInDatabase(member, text, message, newSuggestionId);
});
});
}
@Transactional
public void persistSuggestionInDatabase(Member member, String text, Message message, Long suggestionId) {
log.info("Persisting suggestion {} for server {} in database.", suggestionId, member.getGuild().getId());
suggestionManagementService.createSuggestion(member, text, message, suggestionId);
}
@Override
public CompletableFuture<Void> acceptSuggestion(Long suggestionId, String text, SuggestionLog suggestionLog) {
Suggestion suggestion = suggestionManagementService.getSuggestion(suggestionId, suggestionLog.getGuild().getIdLong()).orElseThrow(() -> new SuggestionNotFoundException(suggestionId));
suggestionManagementService.setSuggestionState(suggestion, SuggestionState.ACCEPTED);
log.info("Accepting suggestion {} in server {}.", suggestionId, suggestion.getServer().getId());
return updateSuggestion(text, suggestionLog, suggestion);
}
private CompletableFuture<Void> updateSuggestion(String text, SuggestionLog suggestionLog, Suggestion suggestion) {
suggestionLog.setSuggesterUser(suggestion.getSuggester());
Long channelId = suggestion.getChannel().getId();
Long originalMessageId = suggestion.getMessageId();
Long serverId = suggestion.getServer().getId();
log.info("Updated posted suggestion {} in server {}.", suggestion.getSuggestionId().getId(), suggestion.getServer().getId());
suggestionLog.setOriginalChannelId(channelId);
suggestionLog.setOriginalMessageId(originalMessageId);
suggestionLog.setOriginalMessageUrl(MessageUtils.buildMessageUrl(serverId, channelId, originalMessageId));
AUserInAServer suggester = suggestion.getSuggester();
TextChannel textChannelById = channelService.getTextChannelFromServer(serverId, channelId);
CompletableFuture<Member> memberById = memberService.getMemberInServerAsync(serverId, suggester.getUserReference().getId());
suggestionLog.setState(suggestion.getState());
suggestionLog.setSuggestionId(suggestion.getSuggestionId().getId());
CompletableFuture<Void> finalFuture = new CompletableFuture<>();
memberById.whenComplete((member, throwable) -> {
if(throwable == null) {
suggestionLog.setSuggester(member);
}
channelService.retrieveMessageInChannel(textChannelById, originalMessageId).thenCompose(message ->
self.updateSuggestionMessageText(text, suggestionLog, message)
).thenAccept(aVoid -> finalFuture.complete(null));
});
return finalFuture;
}
@Transactional
public CompletableFuture<Void> updateSuggestionMessageText(String text, SuggestionLog suggestionLog, Message message) {
Optional<MessageEmbed> embedOptional = message.getEmbeds().stream().filter(embed -> embed.getDescription() != null).findFirst();
if(embedOptional.isPresent()) {
log.info("Updating the text of the suggestion {} in server {}.", suggestionLog.getSuggestionId(), message.getGuild().getId());
MessageEmbed suggestionEmbed = embedOptional.get();
suggestionLog.setReason(text);
suggestionLog.setText(suggestionEmbed.getDescription());
MessageToSend messageToSend = templateService.renderEmbedTemplate(SUGGESTION_LOG_TEMPLATE, suggestionLog);
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(messageToSend, SuggestionPostTarget.SUGGESTION, suggestionLog.getGuild().getIdLong());
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0]));
} else {
log.warn("The message to update the suggestion for, did not contain an embed to update. Suggestions require an embed with a description as a container. MessageURL: {}", message.getJumpUrl());
throw new SuggestionUpdateException();
}
}
@Override
public CompletableFuture<Void> rejectSuggestion(Long suggestionId, String text, SuggestionLog suggestionLog) {
Suggestion suggestion = suggestionManagementService.getSuggestion(suggestionId, suggestionLog.getGuild().getIdLong()).orElseThrow(() -> new SuggestionNotFoundException(suggestionId));
suggestionManagementService.setSuggestionState(suggestion, SuggestionState.REJECTED);
log.info("Rejecting suggestion {} in server {}.", suggestionId, suggestion.getServer().getId());
return updateSuggestion(text, suggestionLog, suggestion);
}
}

View File

@@ -1,79 +0,0 @@
package dev.sheldan.abstracto.utility.service.management;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.exception.CrossServerEmbedException;
import dev.sheldan.abstracto.utility.models.database.EmbeddedMessage;
import dev.sheldan.abstracto.utility.repository.EmbeddedMessageRepository;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
@Component
@Slf4j
public class MessageEmbedPostManagementServiceBean implements MessageEmbedPostManagementService {
@Autowired
private EmbeddedMessageRepository embeddedMessageRepository;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private ChannelManagementService channelManagementService;
@Override
@Transactional
public void createMessageEmbed(CachedMessage embeddedMessage, Message messageContainingEmbed, AUserInAServer embeddingUser) {
AServer embeddedServer = serverManagementService.loadOrCreate(embeddedMessage.getServerId());
AServer embeddingServer = serverManagementService.loadOrCreate(messageContainingEmbed.getGuild().getIdLong());
if(!embeddedServer.getId().equals(embeddingServer.getId())) {
throw new CrossServerEmbedException(String.format("Message %s is not from server %s", embeddedMessage.getMessageUrl(), embeddingServer.getId()));
}
AChannel embeddingChannel = channelManagementService.loadChannel(messageContainingEmbed.getChannel().getIdLong());
AChannel embeddedChannel = channelManagementService.loadChannel(embeddedMessage.getChannelId());
AUserInAServer embeddedAuthor = userInServerManagementService.loadOrCreateUser(embeddedMessage.getServerId(), embeddedMessage.getAuthor().getAuthorId());
EmbeddedMessage messageEmbedPost = EmbeddedMessage
.builder()
.embeddedMessageId(embeddedMessage.getMessageId())
.embeddedChannel(embeddedChannel)
.embeddedServer(embeddedServer)
.embeddingServer(embeddingServer)
.embeddingChannel(embeddingChannel)
.embeddingMessageId(messageContainingEmbed.getIdLong())
.embeddedUser(embeddedAuthor)
.embeddingUser(embeddingUser)
.build();
log.info("Saving embedded post: message {} by user {} in channel {} in server {} embedded message {} by user {} in channel {} in server {}.",
messageContainingEmbed.getIdLong(), messageContainingEmbed.getAuthor().getIdLong(), embeddingChannel.getId(), messageContainingEmbed.getChannel().getIdLong(),
embeddedMessage.getMessageId(), embeddedMessage.getAuthor().getAuthorId(), embeddedMessage.getChannelId(), embeddedMessage.getServerId());
embeddedMessageRepository.save(messageEmbedPost);
}
@Override
public Optional<EmbeddedMessage> findEmbeddedPostByMessageId(Long messageId) {
return Optional.ofNullable(embeddedMessageRepository.findByEmbeddingMessageId(messageId));
}
@Override
@Transactional
public void deleteEmbeddedMessage(EmbeddedMessage embeddedMessage) {
log.info("Deleting embedded message {}.", embeddedMessage.getEmbeddingMessageId());
embeddedMessageRepository.delete(embeddedMessage);
}
}

View File

@@ -1,85 +0,0 @@
package dev.sheldan.abstracto.utility.service.management;
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.utility.exception.PostedImageNotFoundException;
import dev.sheldan.abstracto.utility.models.database.PostedImage;
import dev.sheldan.abstracto.utility.models.database.embed.PostIdentifier;
import dev.sheldan.abstracto.utility.repository.PostedImageRepository;
import dev.sheldan.abstracto.utility.service.RepostServiceBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
@Component
public class PostedImageManagementBean implements PostedImageManagement {
@Autowired
private PostedImageRepository postedImageRepository;
@Autowired
private RepostCheckChannelGroupManagement checkChannelBean;
@Override
public PostedImage createPost(AServerAChannelAUser creation, Long messageId, String hash, Integer index) {
PostedImage post = PostedImage
.builder()
.imageHash(hash)
.postId(new PostIdentifier(messageId, index))
.poster(creation.getAUserInAServer())
.server(creation.getGuild())
.postedChannel(creation.getChannel())
.build();
postedImageRepository.save(post);
return post;
}
@Override
public boolean postWitHashExists(String hash, AServer server) {
return postedImageRepository.existsByImageHashAndServerId(hash, server.getId());
}
@Override
public Optional<PostedImage> getPostWithHash(String hash, AServer server) {
return postedImageRepository.findByImageHashAndServerId(hash, server.getId());
}
@Override
public boolean messageHasBeenCovered(Long messageId) {
return postedImageRepository.existsByPostId_MessageId(messageId);
}
@Override
public boolean messageEmbedsHaveBeenCovered(Long messageId) {
return postedImageRepository.existsByPostId_MessageIdAndPostId_PositionGreaterThan(messageId, RepostServiceBean.EMBEDDED_LINK_POSITION_START_INDEX - 1);
}
@Override
public List<PostedImage> getAllFromMessage(Long messageId) {
return postedImageRepository.findByPostId_MessageId(messageId);
}
@Override
public Optional<PostedImage> getPostFromMessageAndPositionOptional(Long messageId, Integer position) {
return postedImageRepository.findById(new PostIdentifier(messageId, position));
}
@Override
public PostedImage getPostFromMessageAndPosition(Long messageId, Integer position) {
return getPostFromMessageAndPositionOptional(messageId, position).orElseThrow(() -> new PostedImageNotFoundException(messageId, position));
}
@Override
public void removePostedImagesOf(AUserInAServer poster) {
postedImageRepository.deleteByPoster(poster);
}
@Override
public void removedPostedImagesIn(AServer aServer) {
postedImageRepository.deleteByServer(aServer);
}
}

View File

@@ -1,75 +0,0 @@
package dev.sheldan.abstracto.utility.service.management;
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.utility.exception.ReminderNotFoundException;
import dev.sheldan.abstracto.utility.models.database.Reminder;
import dev.sheldan.abstracto.utility.repository.ReminderRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
@Component
@Slf4j
public class ReminderManagementServiceBean implements ReminderManagementService {
@Autowired
private ReminderRepository reminderRepository;
@Override
public Reminder createReminder(AServerAChannelAUser userToBeReminded, String text, Instant timeToBeRemindedAt, Long messageId) {
Reminder reminder = Reminder.builder()
.channel(userToBeReminded.getChannel())
.server(userToBeReminded.getGuild())
.remindedUser(userToBeReminded.getAUserInAServer())
.reminded(false)
.text(text)
.reminderDate(Instant.now())
.targetDate(timeToBeRemindedAt)
.messageId(messageId)
.build();
log.info("Creating reminder for user {} in server {} in message {} to be reminded at {}.",
userToBeReminded.getAUserInAServer().getUserReference().getId(), userToBeReminded.getGuild().getId(), messageId, timeToBeRemindedAt);
reminderRepository.save(reminder);
return reminder;
}
@Override
public Optional<Reminder> loadReminderOptional(Long reminderId) {
return reminderRepository.findById(reminderId);
}
@Override
public Reminder loadReminder(Long reminderId) {
return loadReminderOptional(reminderId).orElseThrow(() -> new ReminderNotFoundException(reminderId));
}
@Override
public void setReminded(Reminder reminder) {
reminder.setReminded(true);
log.info("Setting reminder {} to reminded.", reminder.getId());
reminderRepository.save(reminder);
}
@Override
public Reminder saveReminder(Reminder reminder) {
return reminderRepository.save(reminder);
}
@Override
public List<Reminder> getActiveRemindersForUser(AUserInAServer aUserInAServer) {
return reminderRepository.getByRemindedUserAndRemindedFalse(aUserInAServer);
}
@Override
public Optional<Reminder> getReminderByAndByUserNotReminded(AUserInAServer aUserInAServer, Long reminderId) {
return Optional.ofNullable(reminderRepository.getByIdAndRemindedUserAndRemindedFalse(reminderId, aUserInAServer));
}
}

View File

@@ -1,61 +0,0 @@
package dev.sheldan.abstracto.utility.service.management;
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.utility.exception.RepostCheckChannelGroupNotFoundException;
import dev.sheldan.abstracto.utility.models.database.RepostCheckChannelGroup;
import dev.sheldan.abstracto.utility.repository.RepostCheckChannelRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
public class RepostCheckChannelGroupManagementBean implements RepostCheckChannelGroupManagement {
@Autowired
private RepostCheckChannelRepository repository;
@Override
public RepostCheckChannelGroup loadRepostChannelGroupById(Long channelGroupId) {
return loadRepostChanelGroupByIdOptional(channelGroupId).orElseThrow(() -> new RepostCheckChannelGroupNotFoundException(channelGroupId));
}
@Override
public Optional<RepostCheckChannelGroup> loadRepostChanelGroupByIdOptional(Long channelGroupId) {
return repository.findById(channelGroupId);
}
@Override
public boolean repostCheckChannelGroupExists(Long channelGroupId) {
return loadRepostChanelGroupByIdOptional(channelGroupId).isPresent();
}
@Override
public Optional<RepostCheckChannelGroup> loadRepostChannelGroupByChannelGroupOptional(AChannelGroup channelGroup) {
return loadRepostChanelGroupByIdOptional(channelGroup.getId());
}
@Override
public RepostCheckChannelGroup loadRepostChannelGroupByChannelGroup(AChannelGroup channelGroup) {
return loadRepostChannelGroupById(channelGroup.getId());
}
@Override
public RepostCheckChannelGroup createRepostCheckChannelGroup(AChannelGroup channelGroup) {
RepostCheckChannelGroup repostCheckChannelGroup = RepostCheckChannelGroup
.builder()
.checkEnabled(true)
.channelGroup(channelGroup)
.id(channelGroup.getId())
.build();
repository.save(repostCheckChannelGroup);
return repostCheckChannelGroup;
}
@Override
public void deleteRepostCheckChannelGroup(AChannelGroup channelGroup) {
RepostCheckChannelGroup repostCheckChannelGroup = loadRepostChannelGroupByChannelGroup(channelGroup);
repository.delete(repostCheckChannelGroup);
}
}

View File

@@ -1,85 +0,0 @@
package dev.sheldan.abstracto.utility.service.management;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.utility.exception.RepostNotFoundException;
import dev.sheldan.abstracto.utility.models.database.PostedImage;
import dev.sheldan.abstracto.utility.models.database.Repost;
import dev.sheldan.abstracto.utility.models.database.embed.RepostIdentifier;
import dev.sheldan.abstracto.utility.models.database.result.RepostLeaderboardResult;
import dev.sheldan.abstracto.utility.repository.RepostRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
@Component
public class RepostManagementServiceBean implements RepostManagementService {
@Autowired
private RepostRepository repostRepository;
@Override
public Repost createRepost(PostedImage postedImage, AUserInAServer poster) {
Repost repost = Repost
.builder()
.originalPost(postedImage)
.poster(poster)
.repostId(buildRepostIdentifier(postedImage, poster))
.server(postedImage.getServer())
.count(1)
.build();
repostRepository.save(repost);
return repost;
}
@Override
public Repost setRepostCount(PostedImage postedImage, AUserInAServer poster, Integer newCount) {
Repost repost = findRepost(postedImage, poster);
repost.setCount(newCount);
return repost;
}
@Override
public Repost findRepost(PostedImage postedImage, AUserInAServer poster) {
return findRepostOptional(postedImage, poster)
.orElseThrow(() -> new RepostNotFoundException(postedImage.getPostId().getMessageId(), postedImage.getPostId().getPosition(), poster.getUserInServerId()));
}
@Override
public Optional<Repost> findRepostOptional(PostedImage postedImage, AUserInAServer poster) {
return repostRepository.findById(buildRepostIdentifier(postedImage, poster));
}
@Override
public List<RepostLeaderboardResult> findTopRepostingUsersOfServer(AServer server, Integer page, Integer pageSize) {
return findTopRepostingUsersOfServer(server.getId(), page, pageSize);
}
@Override
public List<RepostLeaderboardResult> findTopRepostingUsersOfServer(Long serverId, Integer page, Integer pageSize) {
return repostRepository.findTopRepostingUsers(serverId, PageRequest.of(page - 1, pageSize));
}
@Override
public RepostLeaderboardResult getRepostRankOfUser(AUserInAServer aUserInAServer) {
return repostRepository.getRepostRankOfUserInServer(aUserInAServer.getUserInServerId(), aUserInAServer.getServerReference().getId());
}
@Override
public void deleteRepostsFromUser(AUserInAServer aUserInAServer) {
repostRepository.deleteByRepostId_UserInServerIdAndServerId(aUserInAServer.getUserInServerId(), aUserInAServer.getServerReference().getId());
}
@Override
public void deleteRepostsFromServer(AServer server) {
repostRepository.deleteByServerId(server.getId());
}
private RepostIdentifier buildRepostIdentifier(PostedImage postedImage, AUserInAServer poster) {
return new RepostIdentifier(postedImage.getPostId().getMessageId(), postedImage.getPostId().getPosition(), poster.getUserInServerId());
}
}

View File

@@ -1,125 +0,0 @@
package dev.sheldan.abstracto.utility.service.management;
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
import dev.sheldan.abstracto.utility.repository.StarboardPostRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
@Component
@Slf4j
public class StarboardPostManagementServiceBean implements StarboardPostManagementService {
@Autowired
private StarboardPostRepository repository;
@Autowired
private ChannelManagementService channelManagementService;
@Override
public StarboardPost createStarboardPost(CachedMessage starredMessage, AUserInAServer starredUser, AServerAChannelMessage starboardPost) {
AChannel build = channelManagementService.loadChannel(starredMessage.getChannelId());
StarboardPost post = StarboardPost
.builder()
.author(starredUser)
.postMessageId(starredMessage.getMessageId())
.sourceChannel(build)
.ignored(false)
.server(starboardPost.getServer())
.starboardMessageId(starboardPost.getMessageId())
.starboardChannel(starboardPost.getChannel())
.starredDate(Instant.now())
.build();
log.info("Persisting starboard post for message {} in channel {} in server {} on starboard at message {} in channel {} and server {} of user {}.",
starredMessage.getMessageId(), starredMessage.getChannelId(), starredMessage.getServerId(),
starboardPost.getMessageId(), starboardPost.getChannel().getId(), starboardPost.getServer().getId(),
starredUser.getUserReference().getId());
repository.save(post);
return post;
}
@Override
public StarboardPost createStarboardPost(StarboardPost post) {
return repository.save(post);
}
@Override
public void setStarboardPostMessageId(StarboardPost post, Long messageId) {
post.setStarboardMessageId(messageId);
repository.save(post);
}
@Override
public List<StarboardPost> retrieveTopPosts(Long serverId, Integer count) {
List<StarboardPost> posts = retrieveAllPosts(serverId);
posts.sort(Comparator.comparingInt(o -> o.getReactions().size()));
Collections.reverse(posts);
return posts.subList(0, Math.min(count, posts.size()));
}
@Override
public List<StarboardPost> retrieveTopPostsForUserInServer(Long serverId, Long userId, Integer count) {
List<Long> topPostIds = repository.getTopStarboardPostsForUser(serverId, userId, count);
return repository.findAllById(topPostIds);
}
@Override
public Long retrieveGivenStarsOfUserInServer(Long serverId, Long userId) {
return repository.getGivenStarsOfUserInServer(serverId, userId);
}
@Override
public Long retrieveReceivedStarsOfUserInServer(Long serverId, Long userId) {
return repository.getReceivedStarsOfUserInServer(serverId, userId);
}
@Override
public List<StarboardPost> retrieveAllPosts(Long serverId) {
return repository.findByServer_Id(serverId);
}
@Override
public Integer getPostCount(Long serverId) {
return retrieveAllPosts(serverId).size();
}
@Override
public Optional<StarboardPost> findByMessageId(Long messageId) {
return Optional.ofNullable(repository.findByPostMessageId(messageId));
}
@Override
public Optional<StarboardPost> findByStarboardPostId(Long postId) {
return Optional.ofNullable(repository.findByStarboardMessageId(postId));
}
@Override
public void setStarboardPostIgnored(Long messageId, Boolean newValue) {
StarboardPost post = repository.findByStarboardMessageId(messageId);
post.setIgnored(newValue);
repository.save(post);
}
@Override
public boolean isStarboardPost(Long messageId) {
return repository.existsByStarboardMessageId(messageId);
}
@Override
public void removePost(StarboardPost starboardPost) {
starboardPost.getReactions().clear();
repository.delete(starboardPost);
}
}

View File

@@ -1,69 +0,0 @@
package dev.sheldan.abstracto.utility.service.management;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
import dev.sheldan.abstracto.utility.models.database.StarboardPostReaction;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsUser;
import dev.sheldan.abstracto.utility.repository.StarStatsGuildUserResult;
import dev.sheldan.abstracto.utility.repository.StarboardPostReactionRepository;
import dev.sheldan.abstracto.utility.repository.converter.StarStatsUserConverter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
public class StarboardPostReactorManagementServiceBean implements StarboardPostReactorManagementService {
@Autowired
private StarboardPostReactionRepository repository;
@Autowired
private StarStatsUserConverter converter;
@Override
public StarboardPostReaction addReactor(StarboardPost post, AUserInAServer user) {
StarboardPostReaction reactor = StarboardPostReaction
.builder()
.starboardPost(post)
.reactor(user)
.server(user.getServerReference())
.build();
log.info("Persisting the reactor {} for starboard post {} in server {}.", user.getUserReference().getId(), post.getId(), user.getServerReference().getId());
repository.save(reactor);
return reactor;
}
@Override
public void removeReactor(StarboardPost post, AUserInAServer user) {
log.info("Removing reactor {} from post {} in server {}.", user.getUserReference().getId(), post.getId(), user.getServerReference().getId());
repository.deleteByReactorAndStarboardPost(user, post);
}
@Override
public void removeReactors(StarboardPost post) {
log.info("Removing all {} reactors from starboard post {}", post.getReactions().size(), post.getId());
repository.deleteByStarboardPost(post);
}
@Override
public Integer getStarCount(Long serverId) {
return repository.getReactionCountByServer(serverId);
}
@Override
public List<CompletableFuture<StarStatsUser>> retrieveTopStarGiver(Long serverId, Integer count) {
List<StarStatsGuildUserResult> starGivers = repository.findTopStarGiverInServer(serverId, count);
return converter.convertToStarStatsUser(starGivers, serverId);
}
@Override
public List<CompletableFuture<StarStatsUser>> retrieveTopStarReceiver(Long serverId, Integer count) {
List<StarStatsGuildUserResult> starReceivers = repository.retrieveTopStarReceiverInServer(serverId, count);
return converter.convertToStarStatsUser(starReceivers, serverId);
}
}

View File

@@ -1,75 +0,0 @@
package dev.sheldan.abstracto.utility.service.management;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.models.SuggestionState;
import dev.sheldan.abstracto.utility.models.database.Suggestion;
import dev.sheldan.abstracto.utility.repository.SuggestionRepository;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.Optional;
@Component
@Slf4j
public class SuggestionManagementServiceBean implements SuggestionManagementService {
@Autowired
private SuggestionRepository suggestionRepository;
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Override
public Suggestion createSuggestion(Member suggester, String text, Message message, Long suggestionId) {
AUserInAServer user = userInServerManagementService.loadOrCreateUser(suggester);
return this.createSuggestion(user, text, message, suggestionId);
}
@Override
public Suggestion createSuggestion(AUserInAServer suggester, String text, Message message, Long suggestionId) {
long channelId = message.getChannel().getIdLong();
AChannel channel = channelManagementService.loadChannel(channelId);
Suggestion suggestion = Suggestion
.builder()
.state(SuggestionState.NEW)
.suggester(suggester)
.suggestionId(new ServerSpecificId(suggester.getServerReference().getId(), suggestionId))
.server(suggester.getServerReference())
.suggestionDate(Instant.now())
.channel(channel)
.messageId(message.getIdLong())
.build();
log.info("Persisting suggestion {} at message {} in channel {} on server {} from user {}.",
suggestionId, message.getId(), channelId, message.getGuild().getId(), suggester.getUserReference().getId());
suggestionRepository.save(suggestion);
return suggestion;
}
@Override
public Optional<Suggestion> getSuggestion(Long suggestionId, Long serverId) {
return suggestionRepository.findById(new ServerSpecificId(serverId, suggestionId));
}
@Override
public void setSuggestionState(Suggestion suggestion, SuggestionState newState) {
suggestion.setState(newState);
log.info("Setting suggestion {} in server {} to state {}.", suggestion.getSuggestionId().getId(), suggestion.getSuggestionId().getServerId(), newState);
suggestionRepository.save(suggestion);
}
}

View File

@@ -1,14 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="repost_channel_group_type-insertion">
<insert tableName="channel_group_type">
<column name="group_type_key" value="repostDetection"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -7,159 +7,28 @@
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<property name="utilityModule" value="(SELECT id FROM module WHERE name = 'utility')"/>
<property name="repostDetectionModule" value="(SELECT id FROM module WHERE name = 'repostDetection')"/>
<property name="entertainmentModule" value="(SELECT id FROM module WHERE name = 'entertainment')"/>
<property name="remindFeature" value="(SELECT id FROM feature WHERE key = 'remind')"/>
<property name="starboardFeature" value="(SELECT id FROM feature WHERE key = 'starboard')"/>
<property name="suggestionFeature" value="(SELECT id FROM feature WHERE key = 'suggestion')"/>
<property name="utilityFeature" value="(SELECT id FROM feature WHERE key = 'utility')"/>
<property name="repostDetectionFeature" value="(SELECT id FROM feature WHERE key = 'repostDetection')"/>
<property name="entertainmentFeature" value="(SELECT id FROM feature WHERE key = 'entertainment')"/>
<property name="today" value="(SELECT NOW())"/>
<changeSet author="Sheldan" id="utility_remind-commands">
<insert tableName="command">
<column name="name" value="remind"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${remindFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="reminders"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${remindFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="unRemind"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${remindFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
</changeSet>
<changeSet author="Sheldan" id="utility_starboard-commands">
<insert tableName="command">
<column name="name" value="starStats"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${remindFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
</changeSet>
<changeSet author="Sheldan" id="utility_suggestion-commands">
<insert tableName="command">
<column name="name" value="accept"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${remindFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="reject"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${remindFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="suggest"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${remindFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
</changeSet>
<changeSet author="Sheldan" id="utility_utility-commands">
<insert tableName="command">
<column name="name" value="serverInfo"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${remindFeature}"/>
<column name="created" valueComputed="${today}"/>
<column name="feature_id" valueComputed="${utilityFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="showEmote"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${remindFeature}"/>
<column name="created" valueComputed="${today}"/>
<column name="feature_id" valueComputed="${utilityFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="userInfo"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${remindFeature}"/>
<column name="created" valueComputed="${today}"/>
<column name="feature_id" valueComputed="${utilityFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="showAvatar"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${remindFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
</changeSet>
<changeSet author="Sheldan" id="utility_repostDetection-commands">
<insert tableName="command">
<column name="name" value="disableRepostCheck"/>
<column name="module_id" valueComputed="${repostDetectionModule}"/>
<column name="feature_id" valueComputed="${repostDetectionFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="enableRepostCheck"/>
<column name="module_id" valueComputed="${repostDetectionModule}"/>
<column name="feature_id" valueComputed="${repostDetectionFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="purgeImagePosts"/>
<column name="module_id" valueComputed="${repostDetectionModule}"/>
<column name="feature_id" valueComputed="${repostDetectionFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="purgeReposts"/>
<column name="module_id" valueComputed="${repostDetectionModule}"/>
<column name="feature_id" valueComputed="${repostDetectionFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="repostLeaderboard"/>
<column name="module_id" valueComputed="${repostDetectionModule}"/>
<column name="feature_id" valueComputed="${repostDetectionFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="showRepostCheckChannels"/>
<column name="module_id" valueComputed="${repostDetectionModule}"/>
<column name="feature_id" valueComputed="${remindFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
</changeSet>
<changeSet author="Sheldan" id="utility_entertainment-commands">
<insert tableName="command">
<column name="name" value="8Ball"/>
<column name="module_id" valueComputed="${entertainmentModule}"/>
<column name="feature_id" valueComputed="${entertainmentFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="loveCalc"/>
<column name="module_id" valueComputed="${entertainmentModule}"/>
<column name="feature_id" valueComputed="${entertainmentFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="roll"/>
<column name="module_id" valueComputed="${entertainmentModule}"/>
<column name="feature_id" valueComputed="${entertainmentFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="roulette"/>
<column name="module_id" valueComputed="${entertainmentModule}"/>
<column name="feature_id" valueComputed="${entertainmentFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="choose"/>
<column name="module_id" valueComputed="${entertainmentModule}"/>
<column name="feature_id" valueComputed="${entertainmentFeature}"/>
<column name="created" valueComputed="${today}"/>
<column name="feature_id" valueComputed="${utilityFeature}"/>
</insert>
</changeSet>

View File

@@ -6,10 +6,6 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<include file="default_emote.xml" relativeToChangelogFile="true"/>
<include file="feature.xml" relativeToChangelogFile="true"/>
<include file="module.xml" relativeToChangelogFile="true"/>
<include file="command.xml" relativeToChangelogFile="true"/>
<include file="reminder_job.xml" relativeToChangelogFile="true"/>
<include file="channel_group_types.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -1,72 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<property name="today" value="(SELECT NOW())"/>
<changeSet author="Sheldan" id="utility_default_emote-insert">
<insert tableName="default_emote">
<column name="emote_key" value="suggestionYes"/>
<column name="name" value="⬆"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="default_emote">
<column name="emote_key" value="suggestionNo"/>
<column name="name" value="⬇️"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="default_emote">
<column name="emote_key" value="star"/>
<column name="name" value="⭐"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="default_emote">
<column name="emote_key" value="star1"/>
<column name="name" value="⭐"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="default_emote">
<column name="emote_key" value="star2"/>
<column name="name" value="🌟"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="default_emote">
<column name="emote_key" value="star3"/>
<column name="name" value="💫"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="default_emote">
<column name="emote_key" value="star4"/>
<column name="name" value="🌠"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="default_emote">
<column name="emote_key" value="starboardBadge1"/>
<column name="name" value="🥇"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="default_emote">
<column name="emote_key" value="starboardBadge2"/>
<column name="name" value="🥈"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="default_emote">
<column name="emote_key" value="starboardBadge3"/>
<column name="name" value="🥉"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="default_emote">
<column name="emote_key" value="removeEmbed"/>
<column name="name" value="🗑"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="default_emote">
<column name="emote_key" value="repostMarker"/>
<column name="name" value="♻️"/>
<column name="created" valueComputed="${today}"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -6,35 +6,9 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<property name="today" value="(SELECT NOW())"/>
<changeSet author="Sheldan" id="utility_feature-insertion">
<insert tableName="feature">
<column name="key" value="starboard"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="feature">
<column name="key" value="remind"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="feature">
<column name="key" value="suggestion"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="feature">
<column name="key" value="utility"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="feature">
<column name="key" value="linkEmbeds"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="feature">
<column name="key" value="repostDetection"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="feature">
<column name="key" value="entertainment"/>
<column name="created" valueComputed="${today}"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -1,22 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<property name="today" value="(SELECT NOW())"/>
<changeSet author="Sheldan" id="utility-module-insertion">
<insert tableName="module">
<column name="name" value="repostDetection"/>
<column name="created" valueComputed="${today}"/>
</insert>
</changeSet>
<changeSet author="Sheldan" id="entertainment-module-insertion">
<insert tableName="module">
<column name="name" value="entertainment"/>
<column name="created" valueComputed="${today}"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -1,18 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="reminder-job-insert">
<insert tableName="scheduler_job">
<column name="name" value="reminderJob"/>
<column name="group_name" value="utility"/>
<column name="clazz" value="dev.sheldan.abstracto.utility.jobs.ReminderJob"/>
<column name="active" value="true"/>
<column name="recovery" value="false"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -1,56 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="embedded_message-table">
<createTable tableName="embedded_message">
<column name="embedding_message_id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="embedded_message_pkey"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="embedded_message_id" type="BIGINT">
<constraints nullable="true"/>
</column>
<column name="embedded_channel_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="embedded_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="embedded_user_in_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="embedding_channel_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="embedding_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="embedding_user_in_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
</createTable>
<addForeignKeyConstraint baseColumnNames="embedding_channel_id" baseTableName="embedded_message" constraintName="fk_embed_channel_channel" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel" validate="true"/>
<addForeignKeyConstraint baseColumnNames="embedded_channel_id" baseTableName="embedded_message" constraintName="fk_embed_embedded_channel_id_channel" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel" validate="true"/>
<addForeignKeyConstraint baseColumnNames="embedding_user_in_server_id" baseTableName="embedded_message" constraintName="fk_embedded_user_in_server_id_user" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="embedded_user_in_server_id" baseTableName="embedded_message" constraintName="fk_embedding_user_in_server_id_user" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="embedding_server_id" baseTableName="embedded_message" constraintName="fk_embedding_server_id_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="embedded_server_id" baseTableName="embedded_message" constraintName="fk_embed_embedded_server_id_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS embedded_message_update_trigger ON embedded_message;
CREATE TRIGGER embedded_message_update_trigger BEFORE UPDATE ON embedded_message FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS embedded_message_insert_trigger ON embedded_message;
CREATE TRIGGER embedded_message_insert_trigger BEFORE INSERT ON embedded_message FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -1,58 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="posted_image-table">
<createTable tableName="posted_image">
<column name="message_id" type="BIGINT" >
<constraints nullable="true"/>
</column>
<column name="position" type="INTEGER" >
<constraints nullable="true"/>
</column>
<column name="author_user_in_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="posted_channel_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="image_hash" type="VARCHAR(512)">
<constraints nullable="false"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
</createTable>
<createIndex indexName="idx_posted_image_hash_server" tableName="posted_image">
<column name="image_hash"/>
<column name="server_id"/>
</createIndex>
<addPrimaryKey columnNames="message_id, position" tableName="posted_image" constraintName="pk_posted_image" validate="true"/>
<addForeignKeyConstraint baseColumnNames="author_user_in_server_id" baseTableName="posted_image" constraintName="fk_posted_image_user"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="posted_channel_id" baseTableName="posted_image" constraintName="fk_posted_image_channel"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id"
referencedTableName="channel" validate="true"/>
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="posted_image" constraintName="fk_posted_image_server"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id"
referencedTableName="server" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS posted_image_update_trigger ON posted_image;
CREATE TRIGGER posted_image_update_trigger BEFORE UPDATE ON posted_image FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS posted_image_insert_trigger ON posted_image;
CREATE TRIGGER posted_image_insert_trigger BEFORE INSERT ON posted_image FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -1,57 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="reminder-table">
<createTable tableName="reminder">
<column autoIncrement="true" name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="reminder_pkey"/>
</column>
<column name="job_trigger_key" type="VARCHAR(255)"/>
<column name="message_id" type="BIGINT">
<constraints nullable="true"/>
</column>
<column name="reminded" type="BOOLEAN">
<constraints nullable="false"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="target_date" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="text" type="VARCHAR(255)">
<constraints nullable="true"/>
</column>
<column name="channel_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="user_in_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
</createTable>
<createIndex indexName="idx_reminder_user_reminded" tableName="reminder">
<column name="user_in_server_id"/>
<column name="reminded"/>
</createIndex>
<addForeignKeyConstraint baseColumnNames="channel_id" baseTableName="reminder" constraintName="fk_reminder_channel" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel" validate="true"/>
<addForeignKeyConstraint baseColumnNames="user_in_server_id" baseTableName="reminder" constraintName="fk_reminder_user" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="reminder" constraintName="fk_reminder_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS reminder_update_trigger ON reminder;
CREATE TRIGGER reminder_update_trigger BEFORE UPDATE ON reminder FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS reminder_insert_trigger ON reminder;
CREATE TRIGGER reminder_insert_trigger BEFORE INSERT ON reminder FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -1,51 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="repost-table">
<createTable tableName="repost">
<column name="message_id" type="BIGINT" >
<constraints nullable="true"/>
</column>
<column name="position" type="INTEGER" >
<constraints nullable="true"/>
</column>
<column name="user_in_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="count" type="INTEGER">
<constraints nullable="false"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
</createTable>
<addPrimaryKey columnNames="message_id, position, user_in_server_id" tableName="repost" constraintName="pk_repost" validate="true"/>
<addForeignKeyConstraint baseColumnNames="user_in_server_id" baseTableName="repost" constraintName="fk_repost_server"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
referencedColumnNames="id" referencedTableName="server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="message_id, position" baseTableName="repost" constraintName="fk_repost_posted_image"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="message_id, position"
referencedTableName="posted_image" validate="true"/>
<addForeignKeyConstraint baseColumnNames="user_in_server_id" baseTableName="repost" constraintName="fk_repost_user_in_server"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id"
referencedTableName="user_in_server" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS repost_update_trigger ON repost;
CREATE TRIGGER repost_update_trigger BEFORE UPDATE ON repost FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS repost_insert_trigger ON repost;
CREATE TRIGGER repost_insert_trigger BEFORE INSERT ON repost FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -1,35 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="repost_check_channel_group-table">
<createTable tableName="repost_check_channel_group">
<column name="id" type="BIGINT">
<constraints nullable="true"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="enabled" type="BOOLEAN">
<constraints nullable="true"/>
</column>
</createTable>
<addForeignKeyConstraint baseColumnNames="id" baseTableName="repost_check_channel_group" constraintName="fk_repost_check_channel_group_group"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel_group" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS repost_check_channel_group_update_trigger ON repost_check_channel_group;
CREATE TRIGGER repost_check_channel_group_update_trigger BEFORE UPDATE ON repost_check_channel_group FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS repost_check_channel_group_insert_trigger ON repost_check_channel_group;
CREATE TRIGGER repost_check_channel_group_insert_trigger BEFORE INSERT ON repost_check_channel_group FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -1,69 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="starboard-table">
<createTable tableName="starboard_post">
<column autoIncrement="true" name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="starboard_post_pkey"/>
</column>
<column name="ignored" type="BOOLEAN">
<constraints nullable="true"/>
</column>
<column name="post_message_id" type="BIGINT">
<constraints nullable="true"/>
</column>
<column name="starboard_message_id" type="BIGINT">
<constraints nullable="true"/>
</column>
<column name="starred_date" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="author_user_in_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="source_channel_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="channel_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
</createTable>
<createIndex indexName="idx_starboard_post_message" tableName="starboard_post">
<column name="post_message_id"/>
</createIndex>
<createIndex indexName="idx_starboard_starboard_message" tableName="starboard_post">
<column name="starboard_message_id"/>
</createIndex>
<createIndex indexName="idx_starboard_server" tableName="starboard_post">
<column name="server_id"/>
</createIndex>
<addForeignKeyConstraint baseColumnNames="author_user_in_server_id" baseTableName="starboard_post" constraintName="fk_starboard_post_author_user_in_server_id" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="channel_id" baseTableName="starboard_post" constraintName="fk_starboard_post_channel" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel" validate="true"/>
<addForeignKeyConstraint baseColumnNames="source_channel_id" baseTableName="starboard_post" constraintName="fk_starboard_post_source_channel" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel" validate="true"/>
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="starboard_post" constraintName="fk_starboard_post_server"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id"
referencedTableName="server" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS starboard_post_update_trigger ON starboard_post;
CREATE TRIGGER starboard_post_update_trigger BEFORE UPDATE ON starboard_post FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS starboard_insert_trigger ON starboard_post;
CREATE TRIGGER starboard_post_insert_trigger BEFORE INSERT ON starboard_post FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -1,42 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="starboard_post_reaction-table">
<createTable tableName="starboard_post_reaction">
<column autoIncrement="true" name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="starboard_post_reaction_pkey"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="reactor_user_in_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="post_id" type="BIGINT">
<constraints nullable="true"/>
</column>
<column name="server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
</createTable>
<addForeignKeyConstraint baseColumnNames="reactor_user_in_server_id" baseTableName="starboard_post_reaction" constraintName="fk_starboard_post_reaction_reactor" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="post_id" baseTableName="starboard_post_reaction" constraintName="fk_starboard_post_reaction_post" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="starboard_post" validate="true"/>
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="starboard_post_reaction" constraintName="fk_starboard_post_reaction_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS starboard_post_reaction_update_trigger ON starboard_post_reaction;
CREATE TRIGGER starboard_post_reaction_update_trigger BEFORE UPDATE ON starboard_post_reaction FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS starboard_post_reaction_insert_trigger ON starboard_post_reaction;
CREATE TRIGGER starboard_post_reaction_insert_trigger BEFORE INSERT ON starboard_post_reaction FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -1,53 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="suggestion-table">
<createTable tableName="suggestion">
<column name="id" type="BIGINT">
<constraints nullable="true"/>
</column>
<column name="message_id" type="BIGINT">
<constraints nullable="true"/>
</column>
<column name="state" type="VARCHAR(255)">
<constraints nullable="true"/>
</column>
<column name="suggestion_date" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="channel_id" type="BIGINT">
<constraints nullable="true"/>
</column>
<column name="server_id" type="BIGINT">
<constraints nullable="true"/>
</column>
<column name="suggester_user_in_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
</createTable>
<addPrimaryKey columnNames="server_id, id" tableName="suggestion" constraintName="pk_suggestion" validate="true"/>
<addForeignKeyConstraint baseColumnNames="channel_id" baseTableName="suggestion" constraintName="fk_suggestion_channel" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel" validate="true"/>
<addForeignKeyConstraint baseColumnNames="suggester_user_in_server_id" baseTableName="suggestion" constraintName="fk_suggestion_suggester" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="suggestion" constraintName="fk_suggestion_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS suggestion_update_trigger ON suggestion;
CREATE TRIGGER suggestion_update_trigger BEFORE UPDATE ON suggestion FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS suggestion_insert_trigger ON suggestion;
CREATE TRIGGER suggestion_insert_trigger BEFORE INSERT ON suggestion FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
<sql>
ALTER TABLE suggestion ADD CONSTRAINT check_suggestion_state CHECK (state IN ('NEW','ACCEPTED', 'REJECTED'));
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -6,12 +6,4 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<include file="embedded_message.xml" relativeToChangelogFile="true"/>
<include file="reminder.xml" relativeToChangelogFile="true"/>
<include file="starboard_post.xml" relativeToChangelogFile="true"/>
<include file="starboard_post_reaction.xml" relativeToChangelogFile="true"/>
<include file="suggestion.xml" relativeToChangelogFile="true"/>
<include file="repost_check_channel_group.xml" relativeToChangelogFile="true"/>
<include file="posted_image.xml" relativeToChangelogFile="true"/>
<include file="repost.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -1,11 +1,11 @@
package dev.sheldan.abstracto.utility.commands;
package dev.sheldan.abstracto.utility.command;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.serverinfo.ServerInfoModel;
import dev.sheldan.abstracto.utility.model.ServerInfoModel;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;

View File

@@ -1,11 +1,11 @@
package dev.sheldan.abstracto.utility.commands;
package dev.sheldan.abstracto.utility.command;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.ShowAvatarModel;
import dev.sheldan.abstracto.utility.model.ShowAvatarModel;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,11 +1,11 @@
package dev.sheldan.abstracto.utility.commands;
package dev.sheldan.abstracto.utility.command;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.ShowEmoteLog;
import dev.sheldan.abstracto.utility.model.ShowEmoteLog;
import net.dv8tion.jda.api.entities.Emote;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,4 +1,4 @@
package dev.sheldan.abstracto.utility.commands;
package dev.sheldan.abstracto.utility.command;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
@@ -6,7 +6,7 @@ import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.UserInfoModel;
import dev.sheldan.abstracto.utility.model.UserInfoModel;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Assert;

View File

@@ -1,63 +0,0 @@
package dev.sheldan.abstracto.utility.commands;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.GuildStarStatsModel;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.MemberStarStatsModel;
import dev.sheldan.abstracto.utility.service.StarboardService;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class StarStatsTest {
@InjectMocks
private StarStats testUnit;
@Mock
private StarboardService starboardService;
@Mock
private ChannelService channelService;
@Test
public void executeCommand() {
CommandContext noParameters = CommandTestUtilities.getNoParameters();
GuildStarStatsModel guildStarStatsModel = Mockito.mock(GuildStarStatsModel.class);
when(starboardService.retrieveStarStats(noParameters.getGuild().getIdLong())).thenReturn(CompletableFuture.completedFuture(guildStarStatsModel));
CompletableFuture<CommandResult> result = testUnit.executeAsync(noParameters);
verify(channelService, times(1)).sendEmbedTemplateInTextChannelList(StarStats.STARSTATS_RESPONSE_TEMPLATE, guildStarStatsModel, noParameters.getChannel());
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test
public void executeCommandForMember() {
Member member = Mockito.mock(Member.class);
CommandContext memberParameter = CommandTestUtilities.getWithParameters(Arrays.asList(member));
MemberStarStatsModel model = Mockito.mock(MemberStarStatsModel.class);
when(starboardService.retrieveStarStatsForMember(member)).thenReturn(model);
CompletableFuture<CommandResult> result = testUnit.executeAsync(memberParameter);
verify(channelService, times(1)).sendEmbedTemplateInTextChannelList(StarStats.STARSTATS_SINGLE_MEMBER_RESPONSE_TEMPLATE, model, memberParameter.getChannel());
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,57 +0,0 @@
package dev.sheldan.abstracto.utility.commands.entertainment;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.ChooseResponseModel;
import dev.sheldan.abstracto.utility.service.EntertainmentService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static dev.sheldan.abstracto.utility.commands.entertainment.Choose.CHOOSE_RESPONSE_TEMPLATE_KEY;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class ChooseTest {
@InjectMocks
private Choose testUnit;
@Mock
private EntertainmentService entertainmentService;
@Mock
private ChannelService channelService;
@Captor
private ArgumentCaptor<ChooseResponseModel> responseModelArgumentCaptor;
@Test
public void executeChooseCommand() {
List<String> choices = Arrays.asList("choice1", "choice2");
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(choices));
when(entertainmentService.takeChoice(choices, parameters.getAuthor())).thenReturn(choices.get(0));
when(channelService.sendEmbedTemplateInTextChannelList(eq(CHOOSE_RESPONSE_TEMPLATE_KEY), responseModelArgumentCaptor.capture(), eq(parameters.getChannel()))).thenReturn(CommandTestUtilities.messageFutureList());
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
Assert.assertEquals(choices.get(0), responseModelArgumentCaptor.getValue().getChosenValue());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,58 +0,0 @@
package dev.sheldan.abstracto.utility.commands.entertainment;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.EightBallResponseModel;
import dev.sheldan.abstracto.utility.service.EntertainmentService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static dev.sheldan.abstracto.utility.commands.entertainment.EightBall.EIGHT_BALL_RESPONSE_TEMPLATE_KEY;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class EightBallTest {
@InjectMocks
private EightBall testUnit;
@Mock
private EntertainmentService entertainmentService;
@Mock
private ChannelService channelService;
@Captor
private ArgumentCaptor<EightBallResponseModel> responseModelArgumentCaptor;
@Test
public void execute8BallCommand() {
String inputText = "text";
String chosenKey = "key";
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(inputText));
when(entertainmentService.getEightBallValue(inputText)).thenReturn(chosenKey);
when(channelService.sendEmbedTemplateInTextChannelList(eq(EIGHT_BALL_RESPONSE_TEMPLATE_KEY), responseModelArgumentCaptor.capture(), eq(parameters.getChannel()))).thenReturn(CommandTestUtilities.messageFutureList());
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
Assert.assertEquals(chosenKey, responseModelArgumentCaptor.getValue().getChosenKey());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,61 +0,0 @@
package dev.sheldan.abstracto.utility.commands.entertainment;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.LoveCalcResponseModel;
import dev.sheldan.abstracto.utility.service.EntertainmentService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static dev.sheldan.abstracto.utility.commands.entertainment.LoveCalc.LOVE_CALC_RESPONSE_TEMPLATE_KEY;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class LoveCalcTest {
@InjectMocks
private LoveCalc testUnit;
@Mock
private EntertainmentService entertainmentService;
@Mock
private ChannelService channelService;
@Captor
private ArgumentCaptor<LoveCalcResponseModel> responseModelArgumentCaptor;
@Test
public void execute8BallCommand() {
String inputText = "text";
String inputText2 = "text2";
Integer loveResult = 2;
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(inputText, inputText2));
when(entertainmentService.getLoveCalcValue(inputText, inputText2)).thenReturn(loveResult);
when(channelService.sendEmbedTemplateInTextChannelList(eq(LOVE_CALC_RESPONSE_TEMPLATE_KEY), responseModelArgumentCaptor.capture(), eq(parameters.getChannel()))).thenReturn(CommandTestUtilities.messageFutureList());
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
Assert.assertEquals(loveResult, responseModelArgumentCaptor.getValue().getRolled());
Assert.assertEquals(inputText, responseModelArgumentCaptor.getValue().getFirstPart());
Assert.assertEquals(inputText2, responseModelArgumentCaptor.getValue().getSecondPart());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,88 +0,0 @@
package dev.sheldan.abstracto.utility.commands.entertainment;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.ConfigService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.RollResponseModel;
import dev.sheldan.abstracto.utility.service.EntertainmentService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static dev.sheldan.abstracto.utility.commands.entertainment.Roll.ROLL_RESPONSE_TEMPLATE_KEY;
import static dev.sheldan.abstracto.utility.config.features.EntertainmentFeature.ROLL_DEFAULT_HIGH_KEY;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class RollTest {
@InjectMocks
private Roll testUnit;
@Mock
private EntertainmentService entertainmentService;
@Mock
private ChannelService channelService;
@Mock
private ConfigService configService;
@Captor
private ArgumentCaptor<RollResponseModel> responseModelArgumentCaptor;
@Test
public void executeWithNoParameter() {
CommandContext noParameters = CommandTestUtilities.getNoParameters();
Integer result = 4;
Long serverId = 3L;
Integer max = 10;
when(noParameters.getGuild().getIdLong()).thenReturn(serverId);
when(configService.getLongValue(ROLL_DEFAULT_HIGH_KEY, serverId)).thenReturn(max.longValue());
when(entertainmentService.calculateRollResult(1, max)).thenReturn(result);
when(channelService.sendEmbedTemplateInTextChannelList(eq(ROLL_RESPONSE_TEMPLATE_KEY), responseModelArgumentCaptor.capture(), eq(noParameters.getChannel()))).thenReturn(CommandTestUtilities.messageFutureList());
CompletableFuture<CommandResult> futureResult = testUnit.executeAsync(noParameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(futureResult);
Assert.assertEquals(4, responseModelArgumentCaptor.getValue().getRolled().intValue());
}
@Test
public void executeWithHighParameter() {
CommandContext noParameters = CommandTestUtilities.getWithParameters(Arrays.asList(20));
Integer result = 4;
when(entertainmentService.calculateRollResult(1, 20)).thenReturn(result);
when(channelService.sendEmbedTemplateInTextChannelList(eq(ROLL_RESPONSE_TEMPLATE_KEY), responseModelArgumentCaptor.capture(), eq(noParameters.getChannel()))).thenReturn(CommandTestUtilities.messageFutureList());
CompletableFuture<CommandResult> futureResult = testUnit.executeAsync(noParameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(futureResult);
Assert.assertEquals(4, responseModelArgumentCaptor.getValue().getRolled().intValue());
}
@Test
public void executeWithBothParameters() {
CommandContext noParameters = CommandTestUtilities.getWithParameters(Arrays.asList(20, 10));
Integer result = 4;
when(entertainmentService.calculateRollResult(10, 20)).thenReturn(result);
when(channelService.sendEmbedTemplateInTextChannelList(eq(ROLL_RESPONSE_TEMPLATE_KEY), responseModelArgumentCaptor.capture(), eq(noParameters.getChannel()))).thenReturn(CommandTestUtilities.messageFutureList());
CompletableFuture<CommandResult> futureResult = testUnit.executeAsync(noParameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(futureResult);
Assert.assertEquals(4, responseModelArgumentCaptor.getValue().getRolled().intValue());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,56 +0,0 @@
package dev.sheldan.abstracto.utility.commands.entertainment;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.RouletteResponseModel;
import dev.sheldan.abstracto.utility.service.EntertainmentService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.concurrent.CompletableFuture;
import static dev.sheldan.abstracto.utility.commands.entertainment.Roulette.ROULETTE_RESPONSE_TEMPLATE_KEY;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class RouletteTest {
@InjectMocks
private Roulette testUnit;
@Mock
private EntertainmentService entertainmentService;
@Mock
private ChannelService channelService;
@Captor
private ArgumentCaptor<RouletteResponseModel> responseModelArgumentCaptor;
@Test
public void executeWithNoParameter() {
CommandContext noParameters = CommandTestUtilities.getNoParameters();
Boolean result = false;
when(entertainmentService.executeRoulette(noParameters.getAuthor())).thenReturn(result);
when(channelService.sendEmbedTemplateInTextChannelList(eq(ROULETTE_RESPONSE_TEMPLATE_KEY), responseModelArgumentCaptor.capture(), eq(noParameters.getChannel()))).thenReturn(CommandTestUtilities.messageFutureList());
CompletableFuture<CommandResult> futureResult = testUnit.executeAsync(noParameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(futureResult);
Assert.assertEquals(result, responseModelArgumentCaptor.getValue().getResult());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,63 +0,0 @@
package dev.sheldan.abstracto.utility.commands.remind;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.reminder.ReminderModel;
import dev.sheldan.abstracto.utility.service.ReminderService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.time.Duration;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class RemindTest {
@InjectMocks
private Remind testUnit;
@Mock
private ReminderService remindService;
@Mock
private ChannelService channelService;
@Mock
private UserInServerManagementService userInServerManagementService;
@Captor
private ArgumentCaptor<ReminderModel> captor;
@Test
public void executeCommand() {
String reminderText = "text";
Duration duration = Duration.ofMinutes(10);
CommandContext withParameters = CommandTestUtilities.getWithParameters(Arrays.asList(duration, reminderText));
AUserInAServer user = Mockito.mock(AUserInAServer.class);
when(userInServerManagementService.loadOrCreateUser(withParameters.getAuthor())).thenReturn(user);
CompletableFuture<CommandResult> result = testUnit.executeAsync(withParameters);
verify(remindService, times(1)).createReminderInForUser(user, reminderText, duration, withParameters.getMessage());
verify(channelService, times(1)).sendEmbedTemplateInTextChannelList(eq(Remind.REMINDER_EMBED_KEY), captor.capture(), eq(withParameters.getChannel()));
ReminderModel reminderModel = captor.getValue();
Assert.assertEquals(reminderText, reminderModel.getRemindText());
Assert.assertEquals(withParameters.getMessage(), reminderModel.getMessage());
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,65 +0,0 @@
package dev.sheldan.abstracto.utility.commands.remind;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.database.Reminder;
import dev.sheldan.abstracto.utility.models.template.commands.reminder.RemindersModel;
import dev.sheldan.abstracto.utility.service.management.ReminderManagementService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class RemindersTest {
@InjectMocks
private Reminders testUnit;
@Mock
private ReminderManagementService reminderManagementService;
@Mock
private ChannelService channelService;
@Mock
private UserInServerManagementService userInServerManagementService;
@Captor
private ArgumentCaptor<RemindersModel> modelCaptor;
@Test
public void testExecuteCommand() {
CommandContext context = CommandTestUtilities.getNoParameters();
Reminder reminder = Mockito.mock(Reminder.class);
Reminder secondReminder = Mockito.mock(Reminder.class);
List<Reminder> reminders = Arrays.asList(reminder, secondReminder);
AUserInAServer user = Mockito.mock(AUserInAServer.class);
when(userInServerManagementService.loadOrCreateUser(context.getAuthor())).thenReturn(user);
when(reminderManagementService.getActiveRemindersForUser(user)).thenReturn(reminders);
CompletableFuture<CommandResult> result = testUnit.executeAsync(context);
verify(channelService, times(1)).sendEmbedTemplateInTextChannelList(eq(Reminders.REMINDERS_RESPONSE_TEMPLATE), modelCaptor.capture(), eq(context.getChannel()));
RemindersModel usedModel = modelCaptor.getValue();
Assert.assertEquals(reminder, usedModel.getReminders().get(0));
Assert.assertEquals(secondReminder, usedModel.getReminders().get(1));
Assert.assertEquals(reminders.size(), usedModel.getReminders().size());
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,48 +0,0 @@
package dev.sheldan.abstracto.utility.commands.remind;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.service.ReminderService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class UnRemindTest {
@InjectMocks
private UnRemind testUnit;
@Mock
private ReminderService reminderService;
@Mock
private UserInServerManagementService userInServerManagementService;
@Test
public void testExecuteCommand() {
Long reminderId = 6L;
CommandContext withParameters = CommandTestUtilities.getWithParameters(Arrays.asList(reminderId));
AUserInAServer user = Mockito.mock(AUserInAServer.class);
when(userInServerManagementService.loadOrCreateUser(withParameters.getAuthor())).thenReturn(user);
CommandResult result = testUnit.execute(withParameters);
verify(reminderService, times(1)).unRemind(reminderId, user);
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,61 +0,0 @@
package dev.sheldan.abstracto.utility.commands.repost;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.service.RepostCheckChannelService;
import dev.sheldan.abstracto.utility.service.RepostServiceBean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class DisableRepostCheckTest {
@InjectMocks
private DisableRepostCheck testUnit;
@Mock
private ServerManagementService serverManagementService;
@Mock
private ChannelGroupManagementService channelGroupManagementService;
@Mock
private RepostCheckChannelService repostCheckChannelService;
@Test
public void executeCommandWithChannelGroupParameter() {
AChannelGroup channelGroup = Mockito.mock(AChannelGroup.class);
AChannelGroup actualChannelGroup = Mockito.mock(AChannelGroup.class);
Long serverId = 2L;
AServer server = Mockito.mock(AServer.class);
String channelGroupName = "test";
when(channelGroup.getGroupName()).thenReturn(channelGroupName);
when(serverManagementService.loadServer(serverId)).thenReturn(server);
when(channelGroupManagementService.findByNameAndServerAndType(channelGroupName, server, RepostServiceBean.REPOST_CHECK_CHANNEL_GROUP_TYPE)).thenReturn(actualChannelGroup);
CommandContext channelGroupParameters = CommandTestUtilities.getWithParameters(Arrays.asList(channelGroup));
when(channelGroupParameters.getGuild().getIdLong()).thenReturn(serverId);
CommandResult result = testUnit.execute(channelGroupParameters);
CommandTestUtilities.checkSuccessfulCompletion(result);
verify(repostCheckChannelService, times(1)).setRepostCheckDisabledForChannelGroup(actualChannelGroup);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,61 +0,0 @@
package dev.sheldan.abstracto.utility.commands.repost;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.service.RepostCheckChannelService;
import dev.sheldan.abstracto.utility.service.RepostServiceBean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class EnableRepostCheckTest {
@InjectMocks
private EnableRepostCheck testUnit;
@Mock
private ServerManagementService serverManagementService;
@Mock
private ChannelGroupManagementService channelGroupManagementService;
@Mock
private RepostCheckChannelService repostCheckChannelService;
@Test
public void executeCommandWithChannelGroupParameter() {
AChannelGroup channelGroup = Mockito.mock(AChannelGroup.class);
AChannelGroup actualChannelGroup = Mockito.mock(AChannelGroup.class);
Long serverId = 2L;
AServer server = Mockito.mock(AServer.class);
String channelGroupName = "test";
when(channelGroup.getGroupName()).thenReturn(channelGroupName);
when(serverManagementService.loadServer(serverId)).thenReturn(server);
when(channelGroupManagementService.findByNameAndServerAndType(channelGroupName, server, RepostServiceBean.REPOST_CHECK_CHANNEL_GROUP_TYPE)).thenReturn(actualChannelGroup);
CommandContext channelGroupParameters = CommandTestUtilities.getWithParameters(Arrays.asList(channelGroup));
when(channelGroupParameters.getGuild().getIdLong()).thenReturn(serverId);
CommandResult result = testUnit.execute(channelGroupParameters);
CommandTestUtilities.checkSuccessfulCompletion(result);
verify(repostCheckChannelService, times(1)).setRepostCheckEnabledForChannelGroup(actualChannelGroup);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,58 +0,0 @@
package dev.sheldan.abstracto.utility.commands.repost;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.service.PostedImageService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class PurgeImagePostsTest {
@InjectMocks
private PurgeImagePosts testUnit;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private PostedImageService postedImageService;
@Test
public void testPurgeImagePostsFromMember(){
AUserInAServer fakeUser = Mockito.mock(AUserInAServer.class);
AUserInAServer actualUser = Mockito.mock(AUserInAServer.class);
Long userInServerId = 1L;
when(fakeUser.getUserInServerId()).thenReturn(userInServerId);
CommandContext purgeImagePostsParameters = CommandTestUtilities.getWithParameters(Arrays.asList(fakeUser));
when(userInServerManagementService.loadOrCreateUser(userInServerId)).thenReturn(actualUser);
CommandResult result = testUnit.execute(purgeImagePostsParameters);
CommandTestUtilities.checkSuccessfulCompletion(result);
verify(postedImageService, times(1)).purgePostedImages(actualUser);
}
@Test
public void testPurgeImagePostsFromServer(){
CommandContext noParameters = CommandTestUtilities.getNoParameters();
CommandResult result = testUnit.execute(noParameters);
CommandTestUtilities.checkSuccessfulCompletion(result);
verify(postedImageService, times(1)).purgePostedImages(noParameters.getGuild());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,58 +0,0 @@
package dev.sheldan.abstracto.utility.commands.repost;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.service.RepostService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class PurgeRepostsTest {
@InjectMocks
private PurgeReposts testUnit;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private RepostService repostService;
@Test
public void testPurgeImagePostsFromMember(){
AUserInAServer fakeUser = Mockito.mock(AUserInAServer.class);
AUserInAServer actualUser = Mockito.mock(AUserInAServer.class);
Long userInServerId = 1L;
when(fakeUser.getUserInServerId()).thenReturn(userInServerId);
CommandContext purgeImagePostsParameters = CommandTestUtilities.getWithParameters(Arrays.asList(fakeUser));
when(userInServerManagementService.loadOrCreateUser(userInServerId)).thenReturn(actualUser);
CommandResult result = testUnit.execute(purgeImagePostsParameters);
CommandTestUtilities.checkSuccessfulCompletion(result);
verify(repostService, times(1)).purgeReposts(actualUser);
}
@Test
public void testPurgeImagePostsFromServer(){
CommandContext noParameters = CommandTestUtilities.getNoParameters();
CommandResult result = testUnit.execute(noParameters);
CommandTestUtilities.checkSuccessfulCompletion(result);
verify(repostService, times(1)).purgeReposts(noParameters.getGuild());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,109 +0,0 @@
package dev.sheldan.abstracto.utility.commands.repost;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.utility.converter.RepostLeaderBoardConverter;
import dev.sheldan.abstracto.utility.models.RepostLeaderboardEntryModel;
import dev.sheldan.abstracto.utility.models.RepostLeaderboardModel;
import dev.sheldan.abstracto.utility.models.database.result.RepostLeaderboardResult;
import dev.sheldan.abstracto.utility.service.management.RepostManagementService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static dev.sheldan.abstracto.utility.commands.repost.RepostLeaderboard.REPOST_LEADERBOARD_RESPONSE_TEMPLATE_KEY;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class RepostLeaderboardTest {
@InjectMocks
private RepostLeaderboard testUnit;
@Mock
private RepostManagementService repostManagementService;
@Mock
private TemplateService templateService;
@Mock
private ChannelService channelService;
@Mock
private RepostLeaderBoardConverter converter;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private AUserInAServer aUserInAServer;
@Mock
private RepostLeaderboardResult result;
@Mock
private RepostLeaderboardResult userResult;
@Mock
private RepostLeaderboardEntryModel convertedResult;
@Mock
private RepostLeaderboardEntryModel convertedUserResult;
private static final Long SERVER_ID = 1L;
@Captor
private ArgumentCaptor<RepostLeaderboardModel> modelCaptor;
@Test
public void testExecuteWithoutParameter() {
executeRepostLeaderboardTest(1, CommandTestUtilities.getNoParameters());
}
@Test
public void testExecuteWithPageParameter() {
Integer page = 2;
CommandContext noParameters = CommandTestUtilities.getWithParameters(Arrays.asList(page));
executeRepostLeaderboardTest(page, noParameters);
}
public void executeRepostLeaderboardTest(Integer page, CommandContext noParameters) {
when(noParameters.getGuild().getIdLong()).thenReturn(SERVER_ID);
when(userInServerManagementService.loadOrCreateUser(noParameters.getAuthor())).thenReturn(aUserInAServer);
when(repostManagementService.getRepostRankOfUser(aUserInAServer)).thenReturn(userResult);
List<RepostLeaderboardResult> resultList = Arrays.asList(result);
when(repostManagementService.findTopRepostingUsersOfServer(SERVER_ID, page, 5)).thenReturn(resultList);
List<RepostLeaderboardEntryModel> convertedList = Arrays.asList(convertedResult);
when(converter.fromLeaderBoardResults(resultList)).thenReturn(CompletableFuture.completedFuture(convertedList));
when(converter.convertSingleUser(userResult)).thenReturn(CompletableFuture.completedFuture(convertedUserResult));
CompletableFuture<CommandResult> resultFuture = testUnit.executeAsync(noParameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(resultFuture);
verify(channelService, times(1)).sendEmbedTemplateInTextChannelList(eq(REPOST_LEADERBOARD_RESPONSE_TEMPLATE_KEY), modelCaptor.capture(), eq(noParameters.getChannel()));
RepostLeaderboardModel model = modelCaptor.getValue();
Assert.assertEquals(noParameters.getGuild(), model.getGuild());
Assert.assertEquals(convertedList, model.getEntries());
Assert.assertEquals(convertedUserResult, model.getUserExecuting());
Assert.assertEquals(noParameters.getAuthor(), model.getMember());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,62 +0,0 @@
package dev.sheldan.abstracto.utility.commands.repost;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.converter.RepostCheckChannelModelConverter;
import dev.sheldan.abstracto.utility.models.database.RepostCheckChannelGroup;
import dev.sheldan.abstracto.utility.models.template.commands.RepostCheckChannelsModel;
import dev.sheldan.abstracto.utility.service.RepostCheckChannelService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static dev.sheldan.abstracto.utility.commands.repost.ShowRepostCheckChannels.SHOW_REPOST_CHECK_CHANNELS_RESPONSE_TEMPLATE_KEY;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class ShowRepostCheckChannelsTest {
@InjectMocks
private ShowRepostCheckChannels testUnit;
@Mock
private RepostCheckChannelModelConverter converter;
@Mock
private RepostCheckChannelService checkChannelService;
@Mock
private ChannelService channelService;
@Test
public void testExecuteCommand() {
Long serverId = 1L;
CommandContext noParameters = CommandTestUtilities.getNoParameters();
when(noParameters.getGuild().getIdLong()).thenReturn(serverId);
RepostCheckChannelGroup group = Mockito.mock(RepostCheckChannelGroup.class);
List<RepostCheckChannelGroup> groupList = Arrays.asList(group);
when(checkChannelService.getChannelGroupsWithEnabledCheck(serverId)).thenReturn(groupList);
RepostCheckChannelsModel model = Mockito.mock(RepostCheckChannelsModel.class);
when(converter.fromRepostCheckChannelGroups(groupList, noParameters.getGuild())).thenReturn(model);
CompletableFuture<CommandResult> futureResult = testUnit.executeAsync(noParameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(futureResult);
verify(channelService, times(1)).sendEmbedTemplateInTextChannelList(SHOW_REPOST_CHECK_CHANNELS_RESPONSE_TEMPLATE_KEY, model, noParameters.getChannel());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,47 +0,0 @@
package dev.sheldan.abstracto.utility.commands.suggest;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.SuggestionLog;
import dev.sheldan.abstracto.utility.service.SuggestionService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class AcceptTest {
@InjectMocks
private Accept testUnit;
@Mock
private SuggestionService suggestionService;
@Test
public void testExecuteCommand() throws ExecutionException, InterruptedException {
String text = "text";
Long suggestionId = 5L;
CommandContext context = CommandTestUtilities.getWithParameters(Arrays.asList(suggestionId, text));
when(suggestionService.acceptSuggestion(eq(suggestionId), eq(text), any(SuggestionLog.class))).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(context);
verify(suggestionService, times(1)).acceptSuggestion(eq(suggestionId), eq(text), any(SuggestionLog.class));
CommandTestUtilities.checkSuccessfulCompletion(result.get());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,47 +0,0 @@
package dev.sheldan.abstracto.utility.commands.suggest;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.SuggestionLog;
import dev.sheldan.abstracto.utility.service.SuggestionService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class RejectTest {
@InjectMocks
private Reject testUnit;
@Mock
private SuggestionService suggestionService;
@Test
public void testExecuteCommand() throws ExecutionException, InterruptedException {
String text = "text";
Long suggestionId = 5L;
CommandContext context = CommandTestUtilities.getWithParameters(Arrays.asList(suggestionId, text));
when(suggestionService.rejectSuggestion(eq(suggestionId), eq(text), any(SuggestionLog.class))).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(context);
verify(suggestionService, times(1)).rejectSuggestion(eq(suggestionId), eq(text), any(SuggestionLog.class));
CommandTestUtilities.checkSuccessfulCompletion(result.get());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,45 +0,0 @@
package dev.sheldan.abstracto.utility.commands.suggest;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.utility.models.template.commands.SuggestionLog;
import dev.sheldan.abstracto.utility.service.SuggestionService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class SuggestTest {
@InjectMocks
private Suggest testUnit;
@Mock
private SuggestionService suggestionService;
@Test
public void testExecuteCommand() throws ExecutionException, InterruptedException {
String text = "text";
CommandContext context = CommandTestUtilities.getWithParameters(Arrays.asList(text));
when(suggestionService.createSuggestionMessage(eq(context.getAuthor()), eq(text), any(SuggestionLog.class))).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(context);
verify(suggestionService, times(1)).createSuggestionMessage(eq(context.getAuthor()), eq(text), any(SuggestionLog.class));
CommandTestUtilities.checkSuccessfulCompletion(result.get());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,83 +0,0 @@
package dev.sheldan.abstracto.utility.converter;
import dev.sheldan.abstracto.core.models.FullChannel;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.utility.models.database.RepostCheckChannelGroup;
import dev.sheldan.abstracto.utility.models.template.commands.RepostCheckChannelGroupDisplayModel;
import dev.sheldan.abstracto.utility.models.template.commands.RepostCheckChannelsModel;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.TextChannel;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.ArrayList;
import java.util.Arrays;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class RepostCheckChannelModelConverterTest {
@InjectMocks
private RepostCheckChannelModelConverter testUnit;
@Mock
private ChannelService channelService;
@Mock
private Guild guild;
@Test
public void testConvertEmptyList() {
RepostCheckChannelsModel model = testUnit.fromRepostCheckChannelGroups(new ArrayList<>(), guild);
Assert.assertEquals(0, model.getRepostCheckChannelGroups().size());
}
@Test
public void testConvertChannelGroupNoChannels() {
RepostCheckChannelGroup element = Mockito.mock(RepostCheckChannelGroup.class);
AChannelGroup group = Mockito.mock(AChannelGroup.class);
when(element.getChannelGroup()).thenReturn(group);
when(group.getChannels()).thenReturn(new ArrayList<>());
RepostCheckChannelsModel model = testUnit.fromRepostCheckChannelGroups(Arrays.asList(element), guild);
Assert.assertEquals(1, model.getRepostCheckChannelGroups().size());
RepostCheckChannelGroupDisplayModel displayModel = model.getRepostCheckChannelGroups().get(0);
Assert.assertEquals(element, displayModel.getChannelGroup());
Assert.assertEquals(0, displayModel.getChannels().size());
}
@Test
public void testConvertChannelGroupWithChannelsOneDeleted() {
RepostCheckChannelGroup element = Mockito.mock(RepostCheckChannelGroup.class);
AChannelGroup group = Mockito.mock(AChannelGroup.class);
when(element.getChannelGroup()).thenReturn(group);
Long channelId1 = 1L;
AChannel channel1 = Mockito.mock(AChannel.class);
when(channel1.getId()).thenReturn(channelId1);
TextChannel textChannel = Mockito.mock(TextChannel.class);
when(channelService.getTextChannelFromServerNullable(guild, channelId1)).thenReturn(textChannel);
Long channelId2 = 2L;
AChannel channel2 = Mockito.mock(AChannel.class);
when(channel2.getId()).thenReturn(channelId2);
when(channelService.getTextChannelFromServerNullable(guild, channelId2)).thenReturn(null);
when(group.getChannels()).thenReturn(Arrays.asList(channel1, channel2));
RepostCheckChannelsModel model = testUnit.fromRepostCheckChannelGroups(Arrays.asList(element), guild);
Assert.assertEquals(1, model.getRepostCheckChannelGroups().size());
RepostCheckChannelGroupDisplayModel displayModel = model.getRepostCheckChannelGroups().get(0);
Assert.assertEquals(element, displayModel.getChannelGroup());
Assert.assertEquals(2, displayModel.getChannels().size());
FullChannel firstFullChannel = displayModel.getChannels().get(0);
Assert.assertEquals(channel1, firstFullChannel.getChannel());
Assert.assertEquals(textChannel, firstFullChannel.getServerChannel());
FullChannel secondFullChannel = displayModel.getChannels().get(1);
Assert.assertEquals(channel2, secondFullChannel.getChannel());
Assert.assertNull(secondFullChannel.getServerChannel());
}
}

View File

@@ -1,110 +0,0 @@
package dev.sheldan.abstracto.utility.converter;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.models.RepostLeaderboardEntryModel;
import dev.sheldan.abstracto.utility.models.database.result.RepostLeaderboardResult;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class RepostLeaderBoardConverterTest {
@InjectMocks
private RepostLeaderBoardConverter testUnit;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private MemberService memberService;
@Mock
private RepostLeaderBoardConverter self;
@Mock
private AUserInAServer aUserInAServer;
@Mock
private Member member;
private static final Long USER_IN_SERVER_ID = 1L;
private static final Integer REPOST_COUNT = 1;
private static final Integer RANK = 2;
@Test
public void testConvertEmptyList() {
CompletableFuture<List<RepostLeaderboardEntryModel>> future = testUnit.fromLeaderBoardResults(new ArrayList<>());
Assert.assertTrue(future.isDone());
Assert.assertEquals(0, future.join().size());
}
@Test
public void testConvertOneResult() {
RepostLeaderboardResult result = setupFirstResult();
CompletableFuture<List<RepostLeaderboardEntryModel>> future = testUnit.fromLeaderBoardResults(Arrays.asList(result));
Assert.assertTrue(future.isDone());
Assert.assertEquals(1, future.join().size());
verifyFirstResultConversion();
}
@Test
public void testConvertTwoResults() {
RepostLeaderboardResult result = setupFirstResult();
RepostLeaderboardResult result2 = Mockito.mock(RepostLeaderboardResult.class);
Long secondUserInServerId = USER_IN_SERVER_ID + 1;
when(result2.getUserInServerId()).thenReturn(secondUserInServerId);
Integer secondRepostCount = REPOST_COUNT + 1;
when(result2.getRepostCount()).thenReturn(secondRepostCount);
Integer secondRank = RANK + 1;
when(result2.getRank()).thenReturn(secondRank);
AUserInAServer secondAUserInAServer = Mockito.mock(AUserInAServer.class);
when(userInServerManagementService.loadOrCreateUser(secondUserInServerId)).thenReturn(secondAUserInAServer);
Member secondMember = Mockito.mock(Member.class);
when(memberService.getMemberInServerAsync(secondAUserInAServer)).thenReturn(CompletableFuture.completedFuture(secondMember));
CompletableFuture<List<RepostLeaderboardEntryModel>> future = testUnit.fromLeaderBoardResults(Arrays.asList(result, result2));
Assert.assertTrue(future.isDone());
Assert.assertEquals(2, future.join().size());
verifyFirstResultConversion();
verify(self, times(1)).loadUserFromDatabase(secondMember, secondRepostCount, secondUserInServerId, secondRank);
}
private void verifyFirstResultConversion() {
verify(self, times(1)).loadUserFromDatabase(member, REPOST_COUNT, USER_IN_SERVER_ID, RANK);
}
private RepostLeaderboardResult setupFirstResult() {
RepostLeaderboardResult result = Mockito.mock(RepostLeaderboardResult.class);
when(result.getUserInServerId()).thenReturn(USER_IN_SERVER_ID);
when(result.getRepostCount()).thenReturn(REPOST_COUNT);
when(result.getRank()).thenReturn(RANK);
when(userInServerManagementService.loadOrCreateUser(USER_IN_SERVER_ID)).thenReturn(aUserInAServer);
when(memberService.getMemberInServerAsync(aUserInAServer)).thenReturn(CompletableFuture.completedFuture(member));
return result;
}
@Test
public void testLoadUserFromDatabase() {
when(userInServerManagementService.loadOrCreateUser(USER_IN_SERVER_ID)).thenReturn(aUserInAServer);
RepostLeaderboardEntryModel loadedModel = testUnit.loadUserFromDatabase(member, REPOST_COUNT, USER_IN_SERVER_ID, RANK);
Assert.assertEquals(REPOST_COUNT, loadedModel.getCount());
Assert.assertEquals(RANK, loadedModel.getRank());
Assert.assertEquals(member, loadedModel.getMember());
Assert.assertEquals(aUserInAServer, loadedModel.getUser());
}
}

Some files were not shown because too many files have changed in this diff Show More