added template support to echo

replaced HashMaps for templates with concrete models, so the interface is easier known
added rendering method for objects directly
added default parameters available for commands
split up service beans for server/channel into management and service bean
added server reference in AChannel
refactored join/leave listener
This commit is contained in:
Sheldan
2020-03-17 19:41:25 +01:00
parent 0521a1ab44
commit 167bbb0f8b
41 changed files with 399 additions and 205 deletions

View File

@@ -2,11 +2,11 @@ package dev.sheldan.abstracto.command.channels;
import dev.sheldan.abstracto.command.Command; import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.execution.Configuration; import dev.sheldan.abstracto.command.execution.Configuration;
import dev.sheldan.abstracto.command.execution.Context; import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.Parameter; import dev.sheldan.abstracto.command.execution.Parameter;
import dev.sheldan.abstracto.command.execution.Result; import dev.sheldan.abstracto.command.execution.Result;
import dev.sheldan.abstracto.core.service.ChannelService; import dev.sheldan.abstracto.core.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.PostTargetService; import dev.sheldan.abstracto.core.management.PostTargetManagement;
import net.dv8tion.jda.api.entities.GuildChannel; import net.dv8tion.jda.api.entities.GuildChannel;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -19,17 +19,17 @@ import java.util.List;
public class SetPostTargetCommand implements Command { public class SetPostTargetCommand implements Command {
@Autowired @Autowired
private PostTargetService postTargetService; private PostTargetManagement postTargetManagement;
@Autowired @Autowired
private ChannelService channelService; private ChannelManagementService channelManagementService;
@Override @Override
@Transactional @Transactional
public Result execute(Context context) { public Result execute(CommandContext commandContext) {
GuildChannel channel = (GuildChannel) context.getParameters().getParameters().get(1); GuildChannel channel = (GuildChannel) commandContext.getParameters().getParameters().get(1);
String targetName = (String) context.getParameters().getParameters().get(0); String targetName = (String) commandContext.getParameters().getParameters().get(0);
postTargetService.createOrUpdate(targetName, channel.getIdLong(), channel.getGuild().getIdLong()); postTargetManagement.createOrUpdate(targetName, channel.getIdLong(), channel.getGuild().getIdLong());
return Result.fromSuccess(); return Result.fromSuccess();
} }

View File

@@ -26,22 +26,4 @@
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<configuration>
<proc>only</proc>
<annotationProcessors>
<annotationProcessor>dev.sheldan.abstracto.command.annotations.CommandSpecProcessor</annotationProcessor>
</annotationProcessors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project> </project>

View File

@@ -11,8 +11,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@Service @Service
@@ -23,10 +21,10 @@ public class Help implements Command {
private ModuleRegistry registry; private ModuleRegistry registry;
@Override @Override
public Result execute(Context context) { public Result execute(CommandContext commandContext) {
CommandHierarchy commandStructure = registry.getDetailedModules(); CommandHierarchy commandStructure = registry.getDetailedModules();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if(context.getParameters().getParameters().isEmpty()){ if(commandContext.getParameters().getParameters().isEmpty()){
sb.append("Help | Module overview \n"); sb.append("Help | Module overview \n");
sb.append("```"); sb.append("```");
commandStructure.getRootModules().forEach(packedModule -> { commandStructure.getRootModules().forEach(packedModule -> {
@@ -35,7 +33,7 @@ public class Help implements Command {
}); });
sb.append("```"); sb.append("```");
} else { } else {
String parameterValue = context.getParameters().getParameters().get(0).toString(); String parameterValue = commandContext.getParameters().getParameters().get(0).toString();
PackedModule module = commandStructure.getModuleWithName(parameterValue); PackedModule module = commandStructure.getModuleWithName(parameterValue);
if(module != null){ if(module != null){
sb.append("Help | Module overview \n"); sb.append("Help | Module overview \n");
@@ -53,7 +51,7 @@ public class Help implements Command {
} }
} }
context.getChannel().sendMessage(sb.toString()).queue(); commandContext.getChannel().sendMessage(sb.toString()).queue();
return Result.fromSuccess(); return Result.fromSuccess();
} }

View File

@@ -3,10 +3,14 @@ package dev.sheldan.abstracto.command.utility;
import dev.sheldan.abstracto.command.Command; import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.HelpInfo; import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.command.execution.Configuration; import dev.sheldan.abstracto.command.execution.Configuration;
import dev.sheldan.abstracto.command.execution.Context; import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.Parameter; import dev.sheldan.abstracto.command.execution.Parameter;
import dev.sheldan.abstracto.command.execution.Result; import dev.sheldan.abstracto.command.execution.Result;
import dev.sheldan.abstracto.command.utility.model.EchoModel;
import dev.sheldan.abstracto.templating.TemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -14,13 +18,20 @@ import java.util.List;
@Service @Service
public class Echo implements Command { public class Echo implements Command {
private static final String TEMPLATE_NAME = "echo";
@Autowired
private TemplateService templateService;
@Override @Override
public Result execute(Context context) { @Transactional
public Result execute(CommandContext commandContext) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
context.getParameters().getParameters().forEach(o -> { commandContext.getParameters().getParameters().forEach(o -> {
sb.append(o.toString()); sb.append(o.toString());
}); });
context.getChannel().sendMessage(sb.toString()).queue(); EchoModel model = EchoModel.parentBuilder().parent(commandContext.getCommandTemplateContext()).text(sb.toString()).build();
commandContext.getChannel().sendMessage(templateService.renderTemplate(TEMPLATE_NAME, model)).queue();
return Result.fromSuccess(); return Result.fromSuccess();
} }

View File

@@ -2,15 +2,14 @@ package dev.sheldan.abstracto.command.utility;
import dev.sheldan.abstracto.command.Command; import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.execution.Configuration; import dev.sheldan.abstracto.command.execution.Configuration;
import dev.sheldan.abstracto.command.execution.Context; import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.Result; import dev.sheldan.abstracto.command.execution.Result;
import dev.sheldan.abstracto.command.utility.model.PingModel;
import dev.sheldan.abstracto.templating.TemplateService; import dev.sheldan.abstracto.templating.TemplateService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
@Service @Service
public class Ping implements Command { public class Ping implements Command {
@@ -21,12 +20,11 @@ public class Ping implements Command {
@Override @Override
@Transactional @Transactional
public Result execute(Context context) { public Result execute(CommandContext commandContext) {
long ping = context.getJda().getGatewayPing(); long ping = commandContext.getJda().getGatewayPing();
HashMap<String, Object> parameters = new HashMap<>(); PingModel model = PingModel.parentBuilder().parent(commandContext.getCommandTemplateContext()).latency(ping).build();
parameters.put("latency", ping); String text = templateService.renderTemplate(PING_TEMPLATE, model);
String text = templateService.renderTemplate(PING_TEMPLATE, parameters); commandContext.getChannel().sendMessage(text).queue();
context.getChannel().sendMessage(text).queue();
return Result.fromSuccess(); return Result.fromSuccess();
} }

View File

@@ -0,0 +1,17 @@
package dev.sheldan.abstracto.command.utility.model;
import dev.sheldan.abstracto.command.execution.CommandTemplateContext;
import lombok.Builder;
import lombok.Getter;
@Getter
public class EchoModel extends CommandTemplateContext {
private String text;
@Builder(builderMethodName = "parentBuilder")
private EchoModel(CommandTemplateContext parent, String text) {
super(parent);
this.text = text;
}
}

View File

@@ -0,0 +1,16 @@
package dev.sheldan.abstracto.command.utility.model;
import dev.sheldan.abstracto.command.execution.CommandTemplateContext;
import lombok.Builder;
import lombok.Getter;
@Getter
public class PingModel extends CommandTemplateContext {
private Long latency;
@Builder(builderMethodName = "parentBuilder")
private PingModel(CommandTemplateContext parent, Long latency) {
super(parent);
this.latency = latency;
}
}

View File

@@ -35,6 +35,12 @@
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>dev.sheldan.abstracto.core</groupId>
<artifactId>core-interface</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies> </dependencies>

View File

@@ -1,11 +1,11 @@
package dev.sheldan.abstracto.command; package dev.sheldan.abstracto.command;
import dev.sheldan.abstracto.command.execution.Configuration; import dev.sheldan.abstracto.command.execution.Configuration;
import dev.sheldan.abstracto.command.execution.Context; import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.Result; import dev.sheldan.abstracto.command.execution.Result;
public interface Command<T> { public interface Command<T> {
Result execute(Context context); Result execute(CommandContext commandContext);
Configuration getConfiguration(); Configuration getConfiguration();
} }

View File

@@ -1,8 +1,8 @@
package dev.sheldan.abstracto.command; package dev.sheldan.abstracto.command;
import dev.sheldan.abstracto.command.execution.Context; import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.Result; import dev.sheldan.abstracto.command.execution.Result;
public interface PostCommandExecution { public interface PostCommandExecution {
void execute(Context context, Result result, Command command); void execute(CommandContext commandContext, Result result, Command command);
} }

View File

@@ -10,11 +10,12 @@ import net.dv8tion.jda.api.entities.User;
@Builder @Builder
@Getter @Getter
public class Context { public class CommandContext {
private TextChannel channel; private TextChannel channel;
private Guild guild; private Guild guild;
private User author; private User author;
private Message message; private Message message;
private CommandTemplateContext commandTemplateContext;
private Parameters parameters; private Parameters parameters;
private JDA jda; private JDA jda;
} }

View File

@@ -0,0 +1,18 @@
package dev.sheldan.abstracto.command.execution;
import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AServer;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
@Getter @Builder @AllArgsConstructor
public class CommandTemplateContext {
private AChannel channel;
private AServer server;
public CommandTemplateContext(CommandTemplateContext commandTemplateContext) {
this.channel = commandTemplateContext.channel;
this.server = commandTemplateContext.server;
}
}

View File

@@ -6,6 +6,7 @@ import dev.sheldan.abstracto.command.execution.Configuration;
import dev.sheldan.abstracto.command.execution.Parameter; import dev.sheldan.abstracto.command.execution.Parameter;
import dev.sheldan.abstracto.command.meta.CommandRegistry; import dev.sheldan.abstracto.command.meta.CommandRegistry;
import dev.sheldan.abstracto.command.meta.UnParsedCommandParameter; import dev.sheldan.abstracto.command.meta.UnParsedCommandParameter;
import dev.sheldan.abstracto.commands.management.exception.CommandNotFoundException;
import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.Message;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;

View File

@@ -2,12 +2,12 @@ package dev.sheldan.abstracto.commands.management;
import dev.sheldan.abstracto.command.Command; import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.PostCommandExecution; import dev.sheldan.abstracto.command.PostCommandExecution;
import dev.sheldan.abstracto.command.execution.Context; import dev.sheldan.abstracto.command.execution.*;
import dev.sheldan.abstracto.command.execution.Parameter;
import dev.sheldan.abstracto.command.execution.Parameters;
import dev.sheldan.abstracto.command.execution.Result;
import dev.sheldan.abstracto.command.meta.UnParsedCommandParameter; import dev.sheldan.abstracto.command.meta.UnParsedCommandParameter;
import net.dv8tion.jda.api.entities.Guild; import dev.sheldan.abstracto.core.management.ChannelManagementService;
import dev.sheldan.abstracto.core.management.ServerManagementService;
import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AServer;
import net.dv8tion.jda.api.entities.GuildChannel; import net.dv8tion.jda.api.entities.GuildChannel;
import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
@@ -29,6 +29,12 @@ public class CommandReceivedHandler extends ListenerAdapter {
@Autowired @Autowired
private PostCommandExecution execution; private PostCommandExecution execution;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private ChannelManagementService channelManagementService;
@Override @Override
public void onMessageReceived(@Nonnull MessageReceivedEvent event) { public void onMessageReceived(@Nonnull MessageReceivedEvent event) {
if(!manager.isCommand(event.getMessage())) { if(!manager.isCommand(event.getMessage())) {
@@ -40,16 +46,23 @@ public class CommandReceivedHandler extends ListenerAdapter {
String withoutPrefix = parameters.get(0).substring(1); String withoutPrefix = parameters.get(0).substring(1);
Command foundCommand = manager.findCommandByParameters(withoutPrefix, unparsedParameter); Command foundCommand = manager.findCommandByParameters(withoutPrefix, unparsedParameter);
Parameters parsedParameters = getParsedParameters(unparsedParameter, foundCommand, event.getMessage()); Parameters parsedParameters = getParsedParameters(unparsedParameter, foundCommand, event.getMessage());
Context context = Context.builder() CommandContext commandContext = CommandContext.builder()
.author(event.getAuthor()) .author(event.getAuthor())
.guild(event.getGuild()) .guild(event.getGuild())
.channel(event.getTextChannel()) .channel(event.getTextChannel())
.message(event.getMessage()) .message(event.getMessage())
.parameters(parsedParameters) .parameters(parsedParameters)
.jda(event.getJDA()) .jda(event.getJDA())
.commandTemplateContext(buildTemplateParameter(event))
.build(); .build();
Result result = foundCommand.execute(context); Result result = foundCommand.execute(commandContext);
execution.execute(context, result, foundCommand); execution.execute(commandContext, result, foundCommand);
}
private CommandTemplateContext buildTemplateParameter(MessageReceivedEvent event) {
AChannel channel = channelManagementService.loadChannel(event.getChannel().getIdLong());
AServer server = serverManagementService.loadServer(event.getGuild().getIdLong());
return CommandTemplateContext.builder().channel(channel).server(server).build();
} }
public Parameters getParsedParameters(UnParsedCommandParameter unParsedCommandParameter, Command command, Message message){ public Parameters getParsedParameters(UnParsedCommandParameter unParsedCommandParameter, Command command, Message message){

View File

@@ -2,16 +2,16 @@ package dev.sheldan.abstracto.commands.management;
import dev.sheldan.abstracto.command.Command; import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.PostCommandExecution; import dev.sheldan.abstracto.command.PostCommandExecution;
import dev.sheldan.abstracto.command.execution.Context; import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.Result; import dev.sheldan.abstracto.command.execution.Result;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service
public class ReactionPostExecution implements PostCommandExecution { public class ReactionPostExecution implements PostCommandExecution {
@Override @Override
public void execute(Context context, Result result, Command command) { public void execute(CommandContext commandContext, Result result, Command command) {
if(command.getConfiguration().isCausesReaction()){ if(command.getConfiguration().isCausesReaction()){
context.getMessage().addReaction("").queue(); commandContext.getMessage().addReaction("").queue();
} }
} }
} }

View File

@@ -1,4 +1,4 @@
package dev.sheldan.abstracto.commands.management; package dev.sheldan.abstracto.commands.management.exception;
public class CommandNotFoundException extends RuntimeException { public class CommandNotFoundException extends RuntimeException {
} }

View File

@@ -1,4 +1,4 @@
package dev.sheldan.abstracto.commands.management; package dev.sheldan.abstracto.core.exception;
public class PostTargetException extends RuntimeException { public class PostTargetException extends RuntimeException {
public PostTargetException(String message) { public PostTargetException(String message) {

View File

@@ -0,0 +1,25 @@
package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AChannelType;
import dev.sheldan.abstracto.core.management.ChannelManagementService;
import dev.sheldan.abstracto.repository.ChannelRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ChannelManagementServiceBean implements ChannelManagementService {
@Autowired
private ChannelRepository repository;
@Override
public AChannel loadChannel(Long id) {
return repository.getOne(id);
}
@Override
public AChannel createChannel(Long id, AChannelType type) {
return repository.save(AChannel.builder().id(id).type(type).build());
}
}

View File

@@ -1,28 +1,29 @@
package dev.sheldan.abstracto.core.service; package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.commands.management.PostTargetException; import dev.sheldan.abstracto.core.exception.PostTargetException;
import dev.sheldan.abstracto.core.models.AChannel; import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AServer; import dev.sheldan.abstracto.core.models.AServer;
import dev.sheldan.abstracto.core.models.PostTarget; import dev.sheldan.abstracto.core.models.PostTarget;
import dev.sheldan.abstracto.core.management.ChannelManagementService;
import dev.sheldan.abstracto.core.management.PostTargetManagement;
import dev.sheldan.abstracto.core.management.ServerManagementService;
import dev.sheldan.abstracto.repository.PostTargetRepository; import dev.sheldan.abstracto.repository.PostTargetRepository;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
@Service @Service
@Slf4j @Slf4j
public class PostTargetServiceServiceBean implements PostTargetService { public class PostTargetManagementBean implements PostTargetManagement {
@Autowired @Autowired
private PostTargetRepository postTargetRepository; private PostTargetRepository postTargetRepository;
@Autowired @Autowired
private ChannelService channelService; private ChannelManagementService channelManagementService;
@Autowired @Autowired
private ServerService serverService; private ServerManagementService serverManagementService;
@Override @Override
public void createPostTarget(String name, AChannel targetChannel, AServer server) { public void createPostTarget(String name, AChannel targetChannel, AServer server) {
@@ -45,14 +46,14 @@ public class PostTargetServiceServiceBean implements PostTargetService {
@Override @Override
public void createOrUpdate(String name, Long channelId, AServer server) { public void createOrUpdate(String name, Long channelId, AServer server) {
AChannel dbChannel = channelService.loadChannel(channelId); AChannel dbChannel = channelManagementService.loadChannel(channelId);
createOrUpdate(name, dbChannel, server); createOrUpdate(name, dbChannel, server);
} }
@Override @Override
public void createOrUpdate(String name, Long channelId, Long serverId) { public void createOrUpdate(String name, Long channelId, Long serverId) {
AChannel dbChannel = channelService.loadChannel(channelId); AChannel dbChannel = channelManagementService.loadChannel(channelId);
AServer dbServer = serverService.loadServer(serverId); AServer dbServer = serverManagementService.loadServer(serverId);
createOrUpdate(name, dbChannel, dbServer); createOrUpdate(name, dbChannel, dbServer);
} }
@@ -62,6 +63,12 @@ public class PostTargetServiceServiceBean implements PostTargetService {
return postTargetRepository.findPostTargetByName(name); return postTargetRepository.findPostTargetByName(name);
} }
@Override
public PostTarget getPostTarget(String name, Long serverId) {
AServer server = serverManagementService.loadServer(serverId);
return getPostTarget(name, server);
}
@Override @Override
public void updatePostTarget(PostTarget target, AChannel newTargetChannel, AServer server) { public void updatePostTarget(PostTarget target, AChannel newTargetChannel, AServer server) {
postTargetRepository.getOne(target.getId()).setChannelReference(newTargetChannel); postTargetRepository.getOne(target.getId()).setChannelReference(newTargetChannel);

View File

@@ -1,12 +1,13 @@
package dev.sheldan.abstracto.core.service; package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.models.ARole; import dev.sheldan.abstracto.core.models.ARole;
import dev.sheldan.abstracto.core.management.RoleManagementService;
import dev.sheldan.abstracto.repository.RoleRepository; import dev.sheldan.abstracto.repository.RoleRepository;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service
public class RoleServiceBean implements RoleService { public class RoleManagementServiceBean implements RoleManagementService {
@Autowired @Autowired
private RoleRepository repository; private RoleRepository repository;

View File

@@ -0,0 +1,64 @@
package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AServer;
import dev.sheldan.abstracto.core.models.PostTarget;
import dev.sheldan.abstracto.core.management.ChannelManagementService;
import dev.sheldan.abstracto.core.management.PostTargetManagement;
import dev.sheldan.abstracto.core.management.ServerManagementService;
import dev.sheldan.abstracto.repository.ServerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ServerManagementServiceBean implements ServerManagementService {
@Autowired
private ServerRepository repository;
@Autowired
private PostTargetManagement postTargetManagement;
@Autowired
private ChannelManagementService channelManagementService;
@Override
public AServer createServer(Long id) {
return repository.save(AServer.builder().id(id).build());
}
@Override
public AServer loadServer(Long id) {
return repository.getOne(id);
}
@Override
public void addChannelToServer(AServer server, AChannel channel) {
server.getChannels().add(channel);
}
@Override
public AChannel getPostTarget(Long serverId, String name) {
AServer server = this.loadServer(serverId);
return getPostTarget(server, name);
}
@Override
public AChannel getPostTarget(Long serverId, PostTarget target) {
AServer server = this.loadServer(serverId);
return getPostTarget(server, target);
}
@Override
public AChannel getPostTarget(AServer server, PostTarget target) {
return target.getChannelReference();
}
@Override
public AChannel getPostTarget(AServer server, String name) {
PostTarget target = postTargetManagement.getPostTarget(name, server);
return getPostTarget(server, target);
}
}

View File

@@ -1,24 +1,31 @@
package dev.sheldan.abstracto.core.service; package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.models.AChannel; import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AChannelType; import lombok.extern.slf4j.Slf4j;
import dev.sheldan.abstracto.repository.ChannelRepository; import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Component;
@Service @Slf4j
@Component
public class ChannelServiceBean implements ChannelService { public class ChannelServiceBean implements ChannelService {
@Autowired @Autowired
private ChannelRepository repository; private BotService botService;
@Override @Override
public AChannel loadChannel(Long id) { public void sendTextInAChannel(String text, AChannel channel) {
return repository.getOne(id); Guild guild = botService.getInstance().getGuildById(channel.getServer().getId());
} if (guild != null) {
TextChannel textChannel = guild.getTextChannelById(channel.getId());
@Override if(textChannel != null) {
public AChannel createChannel(Long id, AChannelType type) { textChannel.sendMessage(text).queue();
return repository.save(AChannel.builder().id(id).type(type).build()); } else {
log.warn("Channel {} to post towards was not found in server {}", channel.getId(), channel.getServer().getId());
}
} else {
log.warn("Guild {} was not found when trying to post a message", channel.getServer().getId());
}
} }
} }

View File

@@ -0,0 +1,37 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.management.ServerManagementService;
import dev.sheldan.abstracto.core.models.PostTarget;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class PostTargetServiceBean implements PostTargetService {
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private BotService botService;
@Override
public void sendTextInPostTarget(String text, PostTarget target) {
Guild guild = botService.getInstance().getGuildById(target.getServerReference().getId());
if(guild != null) {
TextChannel textChannelById = guild.getTextChannelById(target.getChannelReference().getId());
if(textChannelById != null) {
textChannelById.sendMessage(text).queue();
} else {
log.warn("Incorrect post target configuration: {} points to {} on server {}", target.getName(),
target.getChannelReference().getId(), target.getServerReference().getId());
}
} else {
log.warn("Incorrect post target configuration: Guild id {} was not found.", target.getServerReference().getId());
}
}
}

View File

@@ -1,36 +0,0 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AServer;
import dev.sheldan.abstracto.repository.ServerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
@Service
public class ServerServiceBean implements ServerService {
@Autowired
private ServerRepository repository;
@Override
@Transactional
public AServer createServer(Long id) {
return repository.save(AServer.builder().id(id).build());
}
@Override
@Transactional
public AServer loadServer(Long id) {
return repository.getOne(id);
}
@Override
@Transactional
public void addChannelToServer(AServer server, AChannel channel) {
server.getChannels().add(channel);
}
}

View File

@@ -1,6 +1,9 @@
package dev.sheldan.abstracto.core.service; package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.SnowflakeUtils; import dev.sheldan.abstracto.SnowflakeUtils;
import dev.sheldan.abstracto.core.management.ChannelManagementService;
import dev.sheldan.abstracto.core.management.RoleManagementService;
import dev.sheldan.abstracto.core.management.ServerManagementService;
import dev.sheldan.abstracto.core.models.AChannel; import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AChannelType; import dev.sheldan.abstracto.core.models.AChannelType;
import dev.sheldan.abstracto.core.models.ARole; import dev.sheldan.abstracto.core.models.ARole;
@@ -31,13 +34,13 @@ public class StartupManager implements Startup {
private List<? extends ListenerAdapter> listeners; private List<? extends ListenerAdapter> listeners;
@Autowired @Autowired
private ServerService serverService; private ServerManagementService serverManagementService;
@Autowired @Autowired
private ChannelService channelService; private ChannelManagementService channelManagementService;
@Autowired @Autowired
private RoleService roleService; private RoleManagementService roleManagementService;
@Override @Override
@@ -59,7 +62,7 @@ public class StartupManager implements Startup {
List<Guild> onlineGuilds = instance.getGuilds(); List<Guild> onlineGuilds = instance.getGuilds();
Set<Long> availableServers = SnowflakeUtils.getSnowflakeIds(onlineGuilds); Set<Long> availableServers = SnowflakeUtils.getSnowflakeIds(onlineGuilds);
availableServers.forEach(aLong -> { availableServers.forEach(aLong -> {
AServer newAServer = serverService.createServer(aLong); AServer newAServer = serverManagementService.createServer(aLong);
Guild newGuild = instance.getGuildById(aLong); Guild newGuild = instance.getGuildById(aLong);
log.debug("Synchronizing server: {}", aLong); log.debug("Synchronizing server: {}", aLong);
if(newGuild != null){ if(newGuild != null){
@@ -77,7 +80,7 @@ public class StartupManager implements Startup {
Set<Long> availableRoles = SnowflakeUtils.getSnowflakeIds(existingRoles); Set<Long> availableRoles = SnowflakeUtils.getSnowflakeIds(existingRoles);
Set<Long> newRoles = SetUtils.disjunction(availableRoles, knownRolesId); Set<Long> newRoles = SetUtils.disjunction(availableRoles, knownRolesId);
newRoles.forEach(aLong -> { newRoles.forEach(aLong -> {
ARole newRole = roleService.createRole(aLong); ARole newRole = roleManagementService.createRole(aLong);
log.debug("Adding new role: {}", aLong); log.debug("Adding new role: {}", aLong);
existingAServer.getRoles().add(newRole); existingAServer.getRoles().add(newRole);
}); });
@@ -93,8 +96,8 @@ public class StartupManager implements Startup {
GuildChannel channel1 = available.stream().filter(channel -> channel.getIdLong() == aLong).findFirst().get(); GuildChannel channel1 = available.stream().filter(channel -> channel.getIdLong() == aLong).findFirst().get();
log.debug("Adding new channel: {}", aLong); log.debug("Adding new channel: {}", aLong);
AChannelType type = AChannel.getAChannelType(channel1.getType()); AChannelType type = AChannel.getAChannelType(channel1.getType());
AChannel newChannel = channelService.createChannel(channel1.getIdLong(), type); AChannel newChannel = channelManagementService.createChannel(channel1.getIdLong(), type);
serverService.addChannelToServer(existingServer, newChannel); serverManagementService.addChannelToServer(existingServer, newChannel);
}); });
} }
} }

View File

@@ -1,12 +1,11 @@
package dev.sheldan.abstracto.listener; package dev.sheldan.abstracto.listener;
import dev.sheldan.abstracto.core.models.AServer;
import dev.sheldan.abstracto.core.models.PostTarget; import dev.sheldan.abstracto.core.models.PostTarget;
import dev.sheldan.abstracto.core.management.PostTargetManagement;
import dev.sheldan.abstracto.core.service.PostTargetService; import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.service.ServerService; import dev.sheldan.abstracto.core.management.ServerManagementService;
import dev.sheldan.abstracto.templating.TemplateService; import dev.sheldan.abstracto.templating.TemplateService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent; import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
import net.dv8tion.jda.api.events.guild.member.GuildMemberLeaveEvent; import net.dv8tion.jda.api.events.guild.member.GuildMemberLeaveEvent;
@@ -23,30 +22,34 @@ import java.util.HashMap;
@Slf4j @Slf4j
public class JoinLeaveListener extends ListenerAdapter { public class JoinLeaveListener extends ListenerAdapter {
public static final String USER_JOIN_TEMPLATE = "user_join"; private static final String USER_JOIN_TEMPLATE = "user_join";
public static final String USER_LEAVE_TEMPLATE = "user_leave"; private static final String USER_LEAVE_TEMPLATE = "user_leave";
@Autowired @Autowired
private PostTargetService postTargetService; private PostTargetManagement postTargetManagement;
@Autowired @Autowired
private ServerService serverService; private ServerManagementService serverManagementService;
@Autowired @Autowired
private TemplateService templateService; private TemplateService templateService;
@Autowired
private PostTargetService postTargetService;
@Override @Override
@Transactional @Transactional
public void onGuildMemberJoin(@Nonnull GuildMemberJoinEvent event) { public void onGuildMemberJoin(@Nonnull GuildMemberJoinEvent event) {
AServer server = serverService.loadServer(event.getGuild().getIdLong()); String text = getRenderedEvent(event.getUser(), USER_JOIN_TEMPLATE);
PostTarget target = postTargetService.getPostTarget(PostTarget.JOIN_LOG, server); PostTarget postTarget = postTargetManagement.getPostTarget(PostTarget.JOIN_LOG, event.getGuild().getIdLong());
TextChannel textChannelById = event.getGuild().getTextChannelById(target.getChannelReference().getId()); postTargetService.sendTextInPostTarget(text, postTarget);
if(textChannelById != null){ }
HashMap<String, Object> parameters = getUserParameter(event.getUser());
String text = templateService.renderTemplate(USER_JOIN_TEMPLATE, parameters); @Override
textChannelById.sendMessage(text).queue(); @Transactional
} else { public void onGuildMemberLeave(@Nonnull GuildMemberLeaveEvent event) {
log.warn("{} post target is not defined for server {}", PostTarget.JOIN_LOG, server.getId()); String text = getRenderedEvent(event.getUser(), USER_LEAVE_TEMPLATE);
} PostTarget postTarget = postTargetManagement.getPostTarget(PostTarget.LEAVE_LOG, event.getGuild().getIdLong());
postTargetService.sendTextInPostTarget(text, postTarget);
} }
@NotNull @NotNull
@@ -57,18 +60,8 @@ public class JoinLeaveListener extends ListenerAdapter {
return parameters; return parameters;
} }
@Override private String getRenderedEvent(User user, String templateName) {
@Transactional HashMap<String, Object> parameters = getUserParameter(user);
public void onGuildMemberLeave(@Nonnull GuildMemberLeaveEvent event) { return templateService.renderTemplate(templateName, parameters);
AServer server = serverService.loadServer(event.getGuild().getIdLong());
PostTarget target = postTargetService.getPostTarget(PostTarget.LEAVE_LOG, server);
TextChannel textChannelById = event.getGuild().getTextChannelById(target.getChannelReference().getId());
if(textChannelById != null){
HashMap<String, Object> parameters = getUserParameter(event.getUser());
String text = templateService.renderTemplate(USER_LEAVE_TEMPLATE, parameters);
textChannelById.sendMessage(text).queue();
} else {
log.warn("{} post target is not defined for server {}", PostTarget.LEAVE_LOG, server.getId());
}
} }
} }

View File

@@ -0,0 +1,9 @@
package dev.sheldan.abstracto.core.management;
import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AChannelType;
public interface ChannelManagementService {
AChannel loadChannel(Long id);
AChannel createChannel(Long id, AChannelType type);
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.core.management;
import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AServer;
import dev.sheldan.abstracto.core.models.PostTarget;
public interface PostTargetManagement {
void createPostTarget(String name, AChannel targetChanel, AServer server);
void createOrUpdate(String name, AChannel targetChannel, AServer server);
void createOrUpdate(String name, Long channelId, AServer server);
void createOrUpdate(String name, Long channelId, Long serverId);
PostTarget getPostTarget(String name, AServer server);
PostTarget getPostTarget(String name, Long serverId);
void updatePostTarget(PostTarget target, AChannel newTargetChannel, AServer server);
}

View File

@@ -0,0 +1,7 @@
package dev.sheldan.abstracto.core.management;
import dev.sheldan.abstracto.core.models.ARole;
public interface RoleManagementService {
ARole createRole(Long id);
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.core.management;
import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AServer;
import dev.sheldan.abstracto.core.models.PostTarget;
public interface ServerManagementService {
AServer createServer(Long id);
AServer loadServer(Long id);
void addChannelToServer(AServer server, AChannel channel);
AChannel getPostTarget(Long serverId, String name);
AChannel getPostTarget(Long serverId, PostTarget target);
AChannel getPostTarget(AServer server, PostTarget target);
AChannel getPostTarget(AServer server, String name);
}

View File

@@ -1,9 +1,6 @@
package dev.sheldan.abstracto.core.models; package dev.sheldan.abstracto.core.models;
import lombok.AllArgsConstructor; import lombok.*;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import net.dv8tion.jda.api.entities.ChannelType; import net.dv8tion.jda.api.entities.ChannelType;
import javax.persistence.*; import javax.persistence.*;
@@ -24,6 +21,10 @@ public class AChannel implements SnowFlake {
@ManyToMany(mappedBy = "channels") @ManyToMany(mappedBy = "channels")
private Set<ChannelGroup> groups; private Set<ChannelGroup> groups;
@ManyToOne(fetch = FetchType.LAZY)
@Getter @Setter
private AServer server;
@Getter @Getter
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
private AChannelType type; private AChannelType type;

View File

@@ -25,7 +25,11 @@ public class AServer implements SnowFlake {
@Builder.Default @Builder.Default
private List<ARole> roles = new ArrayList<>(); private List<ARole> roles = new ArrayList<>();
@OneToMany(fetch = FetchType.LAZY) @OneToMany(
fetch = FetchType.LAZY,
mappedBy = "server",
cascade = CascadeType.ALL,
orphanRemoval = true)
@Getter @Getter
@Builder.Default @Builder.Default
private List<AChannel> channels = new ArrayList<>(); private List<AChannel> channels = new ArrayList<>();

View File

@@ -1,9 +1,7 @@
package dev.sheldan.abstracto.core.service; package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.models.AChannel; import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AChannelType;
public interface ChannelService { public interface ChannelService {
AChannel loadChannel(Long id); void sendTextInAChannel(String text, AChannel channel);
AChannel createChannel(Long id, AChannelType type);
} }

View File

@@ -1,14 +1,7 @@
package dev.sheldan.abstracto.core.service; package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AServer;
import dev.sheldan.abstracto.core.models.PostTarget; import dev.sheldan.abstracto.core.models.PostTarget;
public interface PostTargetService { public interface PostTargetService {
void createPostTarget(String name, AChannel targetChanel, AServer server); void sendTextInPostTarget(String text, PostTarget target);
void createOrUpdate(String name, AChannel targetChannel, AServer server);
void createOrUpdate(String name, Long channelId, AServer server);
void createOrUpdate(String name, Long channelId, Long serverId);
PostTarget getPostTarget(String name, AServer server);
void updatePostTarget(PostTarget target, AChannel newTargetChannel, AServer server);
} }

View File

@@ -1,7 +0,0 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.models.ARole;
public interface RoleService {
ARole createRole(Long id);
}

View File

@@ -1,10 +0,0 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.models.AChannel;
import dev.sheldan.abstracto.core.models.AServer;
public interface ServerService {
AServer createServer(Long id);
AServer loadServer(Long id);
void addChannelToServer(AServer server, AChannel channel);
}

View File

@@ -18,12 +18,7 @@ public class DatabaseTemplateLoader implements TemplateLoader {
@Override @Override
public Object findTemplateSource(String s) throws IOException { public Object findTemplateSource(String s) throws IOException {
TemplateDto templateDtoByKey = templateService.getTemplateByKey(s); return templateService.getTemplateByKey(s);
if(templateDtoByKey != null){
return templateDtoByKey;
} else {
return null;
}
} }
@Override @Override

View File

@@ -4,6 +4,7 @@ import dev.sheldan.abstracto.templating.TemplateDto;
import dev.sheldan.abstracto.templating.TemplateService; import dev.sheldan.abstracto.templating.TemplateService;
import freemarker.template.Configuration; import freemarker.template.Configuration;
import freemarker.template.TemplateException; import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -13,6 +14,7 @@ import java.io.IOException;
import java.time.Instant; import java.time.Instant;
import java.util.HashMap; import java.util.HashMap;
@Slf4j
@Component @Component
public class TemplateServiceBean implements TemplateService { public class TemplateServiceBean implements TemplateService {
@@ -37,10 +39,18 @@ public class TemplateServiceBean implements TemplateService {
public String renderTemplate(String key, HashMap<String, Object> parameters) { public String renderTemplate(String key, HashMap<String, Object> parameters) {
try { try {
return FreeMarkerTemplateUtils.processTemplateIntoString(configuration.getTemplate(key), parameters); return FreeMarkerTemplateUtils.processTemplateIntoString(configuration.getTemplate(key), parameters);
} catch (IOException e) { } catch (IOException | TemplateException e) {
e.printStackTrace(); log.warn("Failed to render template: {}", e.getMessage());
} catch (TemplateException e) { }
e.printStackTrace(); return "";
}
@Override
public String renderTemplate(String key, Object model) {
try {
return FreeMarkerTemplateUtils.processTemplateIntoString(configuration.getTemplate(key), model);
} catch (IOException | TemplateException e) {
log.warn("Failed to render template: {}", e.getMessage());
} }
return ""; return "";
} }

View File

@@ -1,4 +1,4 @@
package dev.sheldan.abstracto.templating.seeddata; package dev.sheldan.abstracto.templating.seeding;
import dev.sheldan.abstracto.templating.TemplateService; import dev.sheldan.abstracto.templating.TemplateService;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;

View File

@@ -6,5 +6,6 @@ public interface TemplateService {
TemplateDto getTemplateByKey(String key); TemplateDto getTemplateByKey(String key);
String renderTemplate(TemplateDto templateDto); String renderTemplate(TemplateDto templateDto);
String renderTemplate(String key, HashMap<String, Object> parameters); String renderTemplate(String key, HashMap<String, Object> parameters);
String renderTemplate(String key, Object model);
void createTemplate(String key, String content); void createTemplate(String key, String content);
} }