[AB-77] moving the templating module into the core module

adding a possibility to overlay specific templates for particular servers
adding commands to configure templates
adding file parameter support
This commit is contained in:
Sheldan
2021-02-19 16:27:27 +01:00
parent 909dc87d94
commit 43eca33113
361 changed files with 2158 additions and 2591 deletions

View File

@@ -9,7 +9,6 @@ import dev.sheldan.abstracto.core.command.service.management.CommandInServerMana
import dev.sheldan.abstracto.core.command.service.management.CommandManagementService;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.service.RoleService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
@@ -32,9 +31,6 @@ public class CommandDisallowedCondition implements CommandCondition {
@Autowired
private RoleService roleService;
@Autowired
private TemplateService templateService;
@Override
public ConditionResult shouldExecute(CommandContext context, Command command) {
ACommand aCommand = commandService.findCommandByName(command.getConfiguration().getName());

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.core.command.condition;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public interface ConditionDetail extends Templatable {
}

View File

@@ -6,7 +6,6 @@ import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.FeatureConfigService;
import dev.sheldan.abstracto.core.service.FeatureFlagService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -15,9 +14,6 @@ import org.springframework.stereotype.Component;
@Slf4j
public class FeatureEnabledCondition implements CommandCondition {
@Autowired
private TemplateService templateService;
@Autowired
private FeatureConfigService featureConfigService;

View File

@@ -9,7 +9,6 @@ import dev.sheldan.abstracto.core.command.service.management.CommandInServerMana
import dev.sheldan.abstracto.core.command.service.management.CommandManagementService;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.service.RoleService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
@@ -30,9 +29,6 @@ public class ImmuneUserCondition implements CommandCondition {
@Autowired
private RoleService roleService;
@Autowired
private TemplateService templateService;
@Override
public ConditionResult shouldExecute(CommandContext context, Command command) {
ACommand aCommand = commandService.findCommandByName(command.getConfiguration().getName());

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.command.config;
import dev.sheldan.abstracto.core.command.config.validator.ValidatorParam;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import java.util.List;

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class AbstractoTemplatedException extends AbstractoRunTimeException implements Templatable {

View File

@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.command.models.exception.ChannelAlreadyInChann
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class ChannelAlreadyInChannelGroupException extends AbstractoRunTimeException implements Templatable {

View File

@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.command.models.exception.ChannelGroupExistsExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class ChannelGroupExistsException extends AbstractoRunTimeException implements Templatable {

View File

@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.command.models.exception.ChannelGroupNotFoundExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import java.util.List;

View File

@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.command.models.exception.ChannelNotInChannelGr
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class ChannelNotInChannelGroupException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class CommandNotFoundException extends AbstractoRunTimeException implements Templatable {
public CommandNotFoundException() {

View File

@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.command.models.exception.CommandParameterKeyValueWrongTypeExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import java.util.List;

View File

@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.validator.ValidatorParam;
import dev.sheldan.abstracto.core.command.models.exception.CommandParameterValidationExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import lombok.Getter;
import lombok.Setter;

View File

@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.FeatureMode;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.models.exception.IncorrectFeatureModeModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import java.util.List;

View File

@@ -3,7 +3,7 @@ package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.models.exception.IncorrectParameterExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class IncorrectParameterException extends AbstractoRunTimeException implements Templatable {

View File

@@ -3,7 +3,7 @@ package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.models.exception.InsufficientParametersExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class InsufficientParametersException extends AbstractoRunTimeException implements Templatable {

View File

@@ -0,0 +1,21 @@
package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.templating.Templatable;
public class NoAttachmentFoundException extends AbstractoRunTimeException implements Templatable {
public NoAttachmentFoundException() {
super("No attachment was found in the message.");
}
@Override
public String getTemplateName() {
return "attachment_not_found_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -0,0 +1,5 @@
package dev.sheldan.abstracto.core.command.execution;
public enum ParameterPieceType {
STRING, ATTACHMENT
}

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.core.command.execution;
import lombok.Getter;
import net.dv8tion.jda.api.entities.Message;
import java.util.ArrayList;
import java.util.List;
@@ -12,7 +13,7 @@ public class UnParsedCommandParameter {
private static Pattern SPLIT_REGEX = Pattern.compile("\"([^\"]*)\"|(\\S+)");
public UnParsedCommandParameter(String parameters) {
public UnParsedCommandParameter(String parameters, Message message) {
this.parameters = new ArrayList<>();
Matcher m = SPLIT_REGEX.matcher(parameters);
boolean skippedCommand = false;
@@ -24,15 +25,17 @@ public class UnParsedCommandParameter {
if (m.group(1) != null) {
String group = m.group(1);
if(!group.equals("")) {
this.parameters.add(group);
this.parameters.add(UnparsedCommandParameterPiece.builder().value(group).build());
}
} else {
String group = m.group(2);
if(!group.equals("")) {
this.parameters.add(group);
this.parameters.add(UnparsedCommandParameterPiece.builder().value(group).build());
}
}
}
message.getAttachments().forEach(attachment ->
this.parameters.add(UnparsedCommandParameterPiece.builder().value(attachment).type(ParameterPieceType.ATTACHMENT).build()));
}
private List<String> parameters;
private List<UnparsedCommandParameterPiece> parameters;
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.abstracto.core.command.execution;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class UnparsedCommandParameterPiece {
private Object value;
@Builder.Default
private ParameterPieceType type = ParameterPieceType.STRING;
}

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.core.command.handler;
import dev.sheldan.abstracto.core.command.execution.UnparsedCommandParameterPiece;
import net.dv8tion.jda.api.entities.Message;
import java.util.concurrent.CompletableFuture;
@@ -8,7 +9,7 @@ import java.util.concurrent.CompletableFuture;
public interface CommandParameterHandler {
boolean handles(Class clazz);
default boolean async() { return false; }
default Object handle(String input, CommandParameterIterators iterators, Class clazz, Message context) { return new Object();}
default CompletableFuture<Object> handleAsync(String input, CommandParameterIterators iterators, Class clazz, Message context) { return CompletableFuture.completedFuture(null); }
default Object handle(UnparsedCommandParameterPiece input, CommandParameterIterators iterators, Class clazz, Message context) { return new Object();}
default CompletableFuture<Object> handleAsync(UnparsedCommandParameterPiece input, CommandParameterIterators iterators, Class clazz, Message context) { return CompletableFuture.completedFuture(null); }
Integer getPriority();
}

View File

@@ -0,0 +1,6 @@
package dev.sheldan.abstracto.core.command.handler.provided;
import dev.sheldan.abstracto.core.command.handler.CommandParameterHandler;
public interface FileParameterHandler extends CommandParameterHandler {
}

View File

@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.core.command.models.exception;
import dev.sheldan.abstracto.core.models.FullUser;
import dev.sheldan.abstracto.core.models.FullUserInServer;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

View File

@@ -26,6 +26,6 @@ public interface CommandService {
void disAllowCommandForRole(ACommand aCommand, ARole role);
void disAllowFeatureForRole(FeatureEnum featureEnum, ARole role);
ConditionResult isCommandExecutable(Command command, CommandContext commandContext);
UnParsedCommandParameter getUnParsedCommandParameter(String messageContent);
UnParsedCommandParameter getUnParsedCommandParameter(String messageContent, Message message);
CompletableFuture<Parameters> getParametersForCommand(String commandName, Message messageContainingContent);
}

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.CategoryNotFoundExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class CategoryNotFoundException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.ChannelGroupTypeNotFoundExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import java.util.List;

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.ChannelNotFoundExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class ChannelNotFoundException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.ChannelNotFoundExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class ChannelNotInGuildException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.ConfigurationKeyNotFoundExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class ConfigurationKeyNotFoundException extends AbstractoRunTimeException implements Templatable {

View File

@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.models.exception.EmoteConfiguredButNotUsableExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class ConfiguredEmoteNotUsableException extends AbstractoRunTimeException implements Templatable {

View File

@@ -0,0 +1,29 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.CustomTemplateNotFoundExceptionModel;
import dev.sheldan.abstracto.core.templating.Templatable;
import net.dv8tion.jda.api.entities.Guild;
public class CustomTemplateNotFoundException extends AbstractoRunTimeException implements Templatable {
private final CustomTemplateNotFoundExceptionModel model;
public CustomTemplateNotFoundException(String templateKey, Guild guild) {
super("Custom template not found.");
this.model = CustomTemplateNotFoundExceptionModel
.builder()
.templateKey(templateKey)
.guild(guild)
.build();
}
@Override
public String getTemplateName() {
return "custom_template_not_found_exception";
}
@Override
public Object getTemplateModel() {
return this.model;
}
}

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.DurationFormatExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import java.util.List;

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.EmoteNotDefinedExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class EmoteNotDefinedException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.EmoteNotFoundExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import java.util.List;

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.EmoteNotFoundInDbExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class EmoteNotFoundInDbException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.EmoteNotInServerExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class EmoteNotInServerException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.EmoteNotUsableExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import net.dv8tion.jda.api.entities.Emote;
public class EmoteNotUsableException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.FeatureModeNotFoundExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import java.util.List;

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.FeatureNotFoundExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import java.util.List;

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.GuildNotFoundExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class GuildNotFoundException extends AbstractoRunTimeException implements Templatable {
private final GuildNotFoundExceptionModel model;

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class MemberNotFoundException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.PostTargetNotFoundExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class PostTargetNotFoundException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.PostTargetNotValidExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import java.util.List;

View File

@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.exception.RoleDeletedExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class RoleDeletedException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.RoleNotFoundInDBExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class RoleNotFoundInDBException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.RoleNotFoundInGuildExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class RoleNotFoundInGuildException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.ServerChannelConflictExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class ServerChannelConflictException extends AbstractoRunTimeException implements Templatable {

View File

@@ -0,0 +1,24 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.TemplateNotFoundExceptionModel;
import dev.sheldan.abstracto.core.templating.Templatable;
public class TemplateNotFoundException extends AbstractoRunTimeException implements Templatable {
private final TemplateNotFoundExceptionModel model;
public TemplateNotFoundException(String templateKey) {
super("Template not found.");
this.model = TemplateNotFoundExceptionModel.builder().templateKey(templateKey).build();
}
@Override
public String getTemplateName() {
return "template_not_found_exception";
}
@Override
public Object getTemplateModel() {
return this.model;
}
}

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class UnknownMentionTypeException extends AbstractoRunTimeException implements Templatable {
@Override

View File

@@ -0,0 +1,28 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.UploadFileTooLargeExceptionModel;
import dev.sheldan.abstracto.core.templating.Templatable;
public class UploadFileTooLargeException extends AbstractoRunTimeException implements Templatable {
private UploadFileTooLargeExceptionModel model;
public UploadFileTooLargeException(Long fileSize, Long fileSizeLimit) {
super("File too large for uploading it into the server.");
this.model = UploadFileTooLargeExceptionModel
.builder()
.fileSize(fileSize)
.fileSizeLimit(fileSizeLimit)
.build();
}
@Override
public String getTemplateName() {
return "upload_file_too_large_exception";
}
@Override
public Object getTemplateModel() {
return model;
}
}

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.core.models.exception.UserInServerNotFoundExceptionModel;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class UserInServerNotFoundException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.interactive;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Message;

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.core.interactive;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public interface DelayedActionConfig extends Templatable {
}

View File

@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.core.interactive;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import java.util.function.Consumer;

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.interactive;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -20,7 +20,7 @@ public class InteractiveUtils {
@Transactional
public void sendTimeoutMessage(Long serverId, Long channelId) {
String s = templateService.renderSimpleTemplate("feature_setup_configuration_timeout");
String s = templateService.renderSimpleTemplate("feature_setup_configuration_timeout", serverId);
Optional<TextChannel> channelOptional = channelService.getTextChannelFromServerOptional(serverId, channelId);
channelOptional.ifPresent(channel -> channelService.sendTextToChannelNotAsync(s, channel));
}

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.interactive;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public class SetupStepException extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.models;
import dev.sheldan.abstracto.core.config.FeatureConfig;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.core.models;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.templating.Templatable;
public interface ValidationErrorModel extends Templatable {
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.abstracto.core.models.exception;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Guild;
@Getter
@Setter
@Builder
public class CustomTemplateNotFoundExceptionModel {
private String templateKey;
private Guild guild;
}

View File

@@ -0,0 +1,12 @@
package dev.sheldan.abstracto.core.models.exception;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class TemplateNotFoundExceptionModel {
private String templateKey;
}

View File

@@ -0,0 +1,13 @@
package dev.sheldan.abstracto.core.models.exception;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class UploadFileTooLargeExceptionModel {
private Long fileSize;
private Long fileSizeLimit;
}

View File

@@ -0,0 +1,18 @@
package dev.sheldan.abstracto.core.models.template.commands;
import dev.sheldan.abstracto.core.models.context.SlimUserInitiatedServerContext;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import java.time.Instant;
@Getter
@Setter
@SuperBuilder
public class GetCustomTemplateModel extends SlimUserInitiatedServerContext {
private String templateKey;
private String templateContent;
private Instant lastModified;
private Instant created;
}

View File

@@ -0,0 +1,18 @@
package dev.sheldan.abstracto.core.models.template.commands;
import dev.sheldan.abstracto.core.models.context.SlimUserInitiatedServerContext;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import java.time.Instant;
@Getter
@Setter
@SuperBuilder
public class GetTemplateModel extends SlimUserInitiatedServerContext {
private String templateKey;
private String templateContent;
private Instant lastModified;
private Instant created;
}

View File

@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.api.requests.restaction.MessageAction;
@@ -46,8 +46,10 @@ public interface ChannelService {
CompletableFuture<Message> removeFieldFromMessage(MessageChannel channel, Long messageId, Integer index, Integer embedIndex);
CompletableFuture<Void> deleteTextChannel(AChannel channel);
CompletableFuture<Void> deleteTextChannel(Long serverId, Long channelId);
List<CompletableFuture<Message>> sendEmbedTemplateInChannel(String templateKey, Object model, MessageChannel channel);
CompletableFuture<Message> sendTextTemplateInChannel(String templateKey, Object model, MessageChannel channel);
List<CompletableFuture<Message>> sendEmbedTemplateInTextChannelList(String templateKey, Object model, TextChannel channel);
List<CompletableFuture<Message>> sendEmbedTemplateInMessageChannelList(String templateKey, Object model, MessageChannel channel);
CompletableFuture<Message> sendTextTemplateInTextChannel(String templateKey, Object model, TextChannel channel);
CompletableFuture<Message> sendTextTemplateInMessageChannel(String templateKey, Object model, MessageChannel channel);
RestAction<Void> deleteMessagesInChannel(TextChannel textChannel, List<Message> messages);
CompletableFuture<TextChannel> createTextChannel(String name, AServer server, Long categoryId);
@@ -61,4 +63,5 @@ public interface ChannelService {
Optional<TextChannel> getTextChannelFromServerOptional(Long serverId, Long textChannelId);
TextChannel getTextChannelFromServer(Long serverId, Long textChannelId);
CompletableFuture<Void> setSlowModeInChannel(TextChannel textChannel, Integer seconds);
List<CompletableFuture<Message>> sendFileToChannel(String fileContent, String fileNameTemplate, String messageTemplate, Object model, TextChannel channel);
}

View File

@@ -3,7 +3,7 @@ package dev.sheldan.abstracto.core.service;
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.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.entities.MessageEmbed;

View File

@@ -1,8 +1,9 @@
package dev.sheldan.abstracto.core.service;
import com.jagrosh.jdautilities.commons.waiter.EventWaiter;
import com.jagrosh.jdautilities.menu.Paginator;
public interface PaginatorService {
Paginator createPaginatorFromTemplate(String templateKey, Object model, EventWaiter waiter);
Paginator createPaginatorFromTemplate(String templateKey, Object model, EventWaiter waiter, Long serverId);
}

View File

@@ -3,7 +3,7 @@ package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.config.PostTargetEnum;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.PostTarget;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;

View File

@@ -0,0 +1,19 @@
package dev.sheldan.abstracto.core.templating;
/**
* An interface to be used on objects, which should be able to be processable by the template engine.
* This contains a template key and the model which is used when rendering this template.
*/
public interface Templatable {
/**
* The template key to be used to render this object.
* @return The template key as string
*/
String getTemplateName();
/**
* The model to be used to render this template.
* @return The model containing the attributes to be used for rendering.
*/
Object getTemplateModel();
}

View File

@@ -0,0 +1,7 @@
package dev.sheldan.abstracto.core.templating.exception;
public class TemplatingException extends RuntimeException {
public TemplatingException(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,11 @@
package dev.sheldan.abstracto.core.templating.model;
import java.time.Instant;
public interface EffectiveTemplate {
String getKey();
String getContent();
Instant getLastModified();
}

View File

@@ -0,0 +1,36 @@
package dev.sheldan.abstracto.core.templating.model;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.MessageEmbed;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* A full message which is ready to be send. This message can contain an arbitrary amount of embeds and a string message.
*/
@Getter
@Setter
@Builder
public class MessageToSend {
/**
* The collections of embeds to be send. The first embed is in the same message as the string message.
*/
@Builder.Default
private List<MessageEmbed> embeds = new ArrayList<>();
/**
* The string content to be used in the first message.
*/
private String message;
/**
* The file handle to send attached to the message.
*/
private File fileToSend;
public boolean hasFileToSend() {
return fileToSend != null;
}
}

View File

@@ -0,0 +1,22 @@
package dev.sheldan.abstracto.core.templating.model.database;
import lombok.*;
import javax.persistence.*;
@Builder
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "auto_load_macro")
@Getter
@EqualsAndHashCode
public class AutoLoadMacro {
@Id
private String key;
@OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@PrimaryKeyJoinColumn
private Template template;
}

View File

@@ -0,0 +1,58 @@
package dev.sheldan.abstracto.core.templating.model.database;
import dev.sheldan.abstracto.core.models.database.AServer;
import lombok.*;
import javax.persistence.*;
import java.io.Serializable;
import java.time.Instant;
/**
* Represents the template stored in the database.
*/
@Builder
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "custom_template")
@Getter
@Setter
@EqualsAndHashCode
public class CustomTemplate implements Serializable {
/**
* The globally unique key of the template
*/
@Id
@Column(name = "key")
private String key;
/**
* The content of the template
*/
@Column(length = 4000, name = "content")
private String content;
@Column(name = "section")
private String section;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "server_id", nullable = false)
private AServer server;
@Column(name = "last_modified")
private Instant lastModified;
/**
* The time this template was created in the database
*/
@Column(name = "created")
private Instant created;
/**
* The time this template was updated in the database, only works when using the bot, does not work with triggers.
*/
@Column(name = "updated")
private Instant updated;
}

View File

@@ -0,0 +1,52 @@
package dev.sheldan.abstracto.core.templating.model.database;
import lombok.*;
import javax.persistence.*;
import java.io.Serializable;
import java.time.Instant;
/**
* Represents the template stored in the database.
*/
@Builder
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "template")
@EqualsAndHashCode
@Getter
public class Template implements Serializable {
/**
* The globally unique key of the template
*/
@Id
@Column(name = "key")
private String key;
/**
* The content of the template
*/
@Column(length = 4000, name = "content")
private String content;
@Column(name = "section")
private String section;
@Column(name = "last_modified")
private Instant lastModified;
/**
* The time this template was created in the database
*/
@Column(name = "created")
private Instant created;
/**
* The time this template was updated in the database, only works when using the bot, does not work with triggers.
*/
@Column(name = "updated")
private Instant updated;
}

View File

@@ -0,0 +1,67 @@
package dev.sheldan.abstracto.core.templating.service;
import dev.sheldan.abstracto.core.templating.Templatable;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import java.util.HashMap;
/**
* Provides methods to render templates with the appropriate model.
*/
public interface TemplateService {
/**
* The template containing a embed definition which should be rendered. The key must refer to an existing template and the supplied model will be used when rendering.
* This creates a {@link MessageToSend} object containing the rendered template and might result in multiple embeds.
* @param key The key of the embed template to be used for rendering.
* @param model The model providing the properties to be used for rendering
* @return A fully rendered message containing the content of the template and might contain multiple embeds.
*/
MessageToSend renderEmbedTemplate(String key, Object model);
MessageToSend renderEmbedTemplate(String key, Object model, Long serverId);
/**
* Renders the given template directly into a {@link MessageToSend} but the template only represents a text message.
* @param key The key of the string template to be rendered.
* @param model The model used to render the template
* @return A {@link MessageToSend} instance only containing the string property.
*/
MessageToSend renderTemplateToMessageToSend(String key, Object model);
MessageToSend renderTemplateToMessageToSend(String key, Object model, Long serverId);
/**
* Renders the template identified by the key with the given {@link HashMap} used as model and returns the value as a string
* @param key The key of the template to be rendered.
* @param parameters The {@link HashMap} to be used as the parameters for the template
* @return The template rendered as string.
*/
String renderTemplateWithMap(String key, HashMap<String, Object> parameters);
String renderTemplateWithMap(String key, HashMap<String, Object> parameters, Long serverId);
/**
* Renders the template identified by the key with the given model and returns the value as a string
* @param key The key of the template to be rendered
* @param model The object containing the model to be used in the template
* @return The template rendered as string.
*/
String renderTemplate(String key, Object model);
String renderTemplate(String key, Object model, Long serverId);
/**
* Renders the template without considering any model to be used. If a property is used in the given template, this will throw an exception.
* This is just a quick way to render templates, which do not *need* a model.
* @param key The key of the template to be rendered
* @return The template rendered as string
*/
String renderSimpleTemplate(String key);
String renderSimpleTemplate(String key, Long serverId);
/**
* Renders the given {@link Templatable} object, which means it retrieves the template key and renders the given template key with the given model.
* @param templatable The {@link Templatable} object to be rendered
* @return The template rendered as string
*/
String renderTemplatable(Templatable templatable);
String renderTemplatable(Templatable templatable, Long serverId);
void clearCache();
}

View File

@@ -0,0 +1,10 @@
package dev.sheldan.abstracto.core.templating.service.management;
import dev.sheldan.abstracto.core.templating.model.database.AutoLoadMacro;
import java.util.List;
public interface AutoLoadMacroManagementService {
List<AutoLoadMacro> loadAllMacros();
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.abstracto.core.templating.service.management;
import dev.sheldan.abstracto.core.templating.model.database.CustomTemplate;
import java.util.Optional;
public interface CustomTemplateManagementService {
CustomTemplate createOrUpdateCustomTemplate(String templateKey, String templateContent, Long serverId);
CustomTemplate createCustomTemplate(String templateKey, String templateContent, Long serverId);
Optional<CustomTemplate> getCustomTemplate(String templateKey, Long serverId);
boolean doesCustomTemplateExist(String templateKey, Long serverId);
void deleteCustomTemplateByKey(String templateKey, Long serverId);
void deleteCustomTemplate(CustomTemplate customTemplate);
}

View File

@@ -0,0 +1,20 @@
package dev.sheldan.abstracto.core.templating.service.management;
import dev.sheldan.abstracto.core.templating.model.EffectiveTemplate;
import dev.sheldan.abstracto.core.templating.model.database.Template;
import java.util.Optional;
/**
* Provides methods to access the stored templates.
*/
public interface EffectiveTemplateManagementService {
/**
* Retrieves the template identified by the key.
* @param key They template key to search for
* @return An {@link Optional} containing the {@link Template} if it exists, and null otherwise
*/
Optional<EffectiveTemplate> getTemplateByKeyAndServer(String key, Long server);
Optional<EffectiveTemplate> getTemplateByKey(String key);
}

View File

@@ -0,0 +1,32 @@
package dev.sheldan.abstracto.core.templating.service.management;
import dev.sheldan.abstracto.core.templating.model.database.Template;
import java.util.Optional;
/**
* Provides methods to access the stored templates.
*/
public interface TemplateManagementService {
/**
* Retrieves the template identified by the key.
* @param key They template key to search for
* @return An {@link Optional} containing the {@link Template} if it exists, and null otherwise
*/
Optional<Template> getTemplateByKey(String key);
/**
* Checks whether or not the template exists in the database.
* @param key They key of the template to search for
* @return true, if the template exists and false otherwise
*/
boolean templateExists(String key);
/**
* Creates a template identified by the key and with the provided content.
* @param key They key of the template to create.
* @param content The content the template should have
* @return The created template in the database.
*/
Template createTemplate(String key, String content);
}

View File

@@ -1,31 +0,0 @@
package dev.sheldan.abstracto.core.utils;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.templating.service.TemplateService;
import net.dv8tion.jda.api.entities.MessageChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
public class ExceptionUtils {
@Autowired
private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Transactional
public void handleExceptionIfTemplatable(Throwable throwable, MessageChannel channel) {
if(throwable != null) {
if(throwable.getCause() instanceof Templatable) {
String exceptionText = templateService.renderTemplatable((Templatable) throwable.getCause());
channelService.sendTextToChannel(exceptionText, channel);
} else {
channelService.sendTextToChannel(throwable.getCause().getMessage(), channel);
}
}
}
}

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.core.utils;
import com.google.common.io.Files;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Component;
import java.io.File;
@@ -8,7 +9,7 @@ import java.io.FileWriter;
import java.io.IOException;
@Component
public class FileUtils {
public class FileService {
public void writeContentToFile(File file, String content) throws IOException {
try(FileWriter fw = new FileWriter(file)) {
fw.write(content);
@@ -17,7 +18,7 @@ public class FileUtils {
}
public void writeBytesToFile(File file, byte[] content) throws IOException {
Files.write(content, file);
FileUtils.writeByteArrayToFile(file, content);
}
public File createTempFile(String fileName) {