mirror of
https://github.com/Sheldan/OnePlusBot.git
synced 2026-01-07 18:03:46 +00:00
Compare commits
26 Commits
oneplusbot
...
oneplusbot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c56f9fb90 | ||
|
|
f0ecd2643d | ||
|
|
f943247e7d | ||
|
|
377b4ef478 | ||
|
|
a43e000d88 | ||
|
|
ba7db6a542 | ||
|
|
733d0ebd78 | ||
|
|
7e3fbe5ec6 | ||
|
|
f304b20fe7 | ||
|
|
c9d1114731 | ||
|
|
d8f37117c4 | ||
|
|
c1437373ff | ||
|
|
1e2ab7fbfa | ||
|
|
b3b16d0e74 | ||
|
|
d3d79e8803 | ||
|
|
bf448e167a | ||
|
|
1a135a9bb8 | ||
|
|
fa5abaaed4 | ||
|
|
2d98cbba81 | ||
|
|
f7502c76de | ||
|
|
7c2b627fc9 | ||
|
|
0419c70e49 | ||
|
|
7777e4f1f0 | ||
|
|
02fd4af0f4 | ||
|
|
4778bca1ac | ||
|
|
c14dc1a0a5 |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -34,5 +34,5 @@ jobs:
|
||||
env:
|
||||
REGISTRY_PREFIX: docker.pkg.github.com/sheldan/oneplusbot/
|
||||
VERSION: ${{ env.version }}
|
||||
ABSTRACTO_VERSION: 1.2.11
|
||||
ABSTRACTO_VERSION: 1.2.17
|
||||
ABSTRACTO_REGISTRY_PREFIX: docker.pkg.github.com/sheldan/abstracto/
|
||||
@@ -6,6 +6,6 @@ and most of them will be in [abstracto](https://github.com/Sheldan/abstracto), b
|
||||
The migration of the existing data from the database is handled via one time migration, and can be found [here](https://github.com/Sheldan/OnePlusBot-migration).
|
||||
|
||||
Custom features which were ported
|
||||
- [ ] FAQ
|
||||
- [ ] Setup channel handling
|
||||
- [ ] Referral link handling
|
||||
- [x] FAQ
|
||||
- [x] Setup channel handling
|
||||
- [x] Referral link handling
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.oneplus.bot.application</groupId>
|
||||
<artifactId>application</artifactId>
|
||||
<version>1.3.11</version>
|
||||
<version>1.4.4</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>executable</artifactId>
|
||||
@@ -110,6 +110,26 @@
|
||||
<artifactId>invite-filter-impl</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>statistic-impl</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>profanity-filter-impl</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking-impl</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation-impl</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.oneplus.bot.application.custom</groupId>
|
||||
<artifactId>starboard-custom</artifactId>
|
||||
@@ -134,6 +154,12 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.oneplus.bot.application.modules</groupId>
|
||||
<artifactId>faq</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -29,7 +29,26 @@
|
||||
|
||||
</appender>
|
||||
|
||||
<appender name="requests-file" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${LOG_PATH}/requests_log.log</file>
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<Pattern>
|
||||
%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</Pattern>
|
||||
</encoder>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>
|
||||
${LOG_PATH}/archived/requests_log_%d{dd-MM-yyyy}.log
|
||||
</fileNamePattern>
|
||||
<maxHistory>10</maxHistory>
|
||||
<totalSizeCap>1GB</totalSizeCap>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<logger name="dev.sheldan.abstracto" level="INFO"/>
|
||||
<logger name="dev.sheldan.abstracto.core.logging" level="DEBUG">
|
||||
<appender-ref ref="requests-file"/>
|
||||
</logger>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="logFileAppender"/>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.oneplus.bot.application</groupId>
|
||||
<artifactId>application</artifactId>
|
||||
<version>1.3.11</version>
|
||||
<version>1.4.4</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.oneplus.bot.application.custom</groupId>
|
||||
<artifactId>oneplus-bot-customizations</artifactId>
|
||||
<version>1.3.11</version>
|
||||
<version>1.4.4</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
46
application/oneplus-bot-modules/faq/pom.xml
Normal file
46
application/oneplus-bot-modules/faq/pom.xml
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>oneplus-bot-modules</artifactId>
|
||||
<groupId>dev.sheldan.oneplus.bot.application.modules</groupId>
|
||||
<version>1.4.4</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>faq</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/liquibase.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,18 @@
|
||||
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
|
||||
<id>liquibase</id>
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<outputDirectory>.</outputDirectory>
|
||||
<directory>${project.basedir}/src/main/resources/migrations</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@@ -0,0 +1,75 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.command;
|
||||
|
||||
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.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.JSONValidationService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FileService;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQModuleDefinition;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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
|
||||
@Slf4j
|
||||
public class DeleteFAQ extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private FileService fileService;
|
||||
|
||||
@Autowired
|
||||
private FAQServiceBean faqServiceBean;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private JSONValidationService jsonValidationService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameter = commandContext.getParameters().getParameters();
|
||||
String faqCommandName = (String) parameter.get(0);
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
faqServiceBean.deleteFAQCommand(faqCommandName, server);
|
||||
return CompletableFuture.completedFuture(CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter fileAttachmentParameter = Parameter.builder().name("commandName").type(String.class).templated(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(fileAttachmentParameter);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("deleteFAQ")
|
||||
.module(FAQModuleDefinition.FAQ)
|
||||
.parameters(parameters)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.async(true)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return FAQFeatureDefinition.FAQ;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.command;
|
||||
|
||||
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.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQModuleDefinition;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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
|
||||
@Slf4j
|
||||
public class ExportFAQ extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private FAQServiceBean faqServiceBean;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
String configString;
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild().getIdLong());
|
||||
if(parameters.isEmpty()) {
|
||||
configString = faqServiceBean.exportFAQConfig(server);
|
||||
} else {
|
||||
String commandName = (String) parameters.get(0);
|
||||
configString = faqServiceBean.exportFAQConfig(commandName, server);
|
||||
}
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendFileToChannel(configString, "faqConfig.json", commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter commandNameParameter = Parameter.builder().name("commandName").type(String.class).optional(true).templated(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(commandNameParameter);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("exportFAQ")
|
||||
.module(FAQModuleDefinition.FAQ)
|
||||
.parameters(parameters)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.async(true)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return FAQFeatureDefinition.FAQ;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.command;
|
||||
|
||||
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.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQModuleDefinition;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.faq.FAQResponseModel;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.FAQResponseServiceBean;
|
||||
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.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class FAQ extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private FAQResponseServiceBean faqService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
private static final String FAQ_RESPONSE_TEMPLATE_KEY = "FAQ_response";
|
||||
private static final String FAQ_RESPONSE_NO_COMMAND_FOUND_TEMPLATE_KEY = "FAQ_response_no_command_found";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
String commandName;
|
||||
if(!parameters.isEmpty()) {
|
||||
commandName = (String) parameters.get(0);
|
||||
TextChannel channel;
|
||||
if (parameters.size() == 2) {
|
||||
channel = (TextChannel) parameters.get(1);
|
||||
} else {
|
||||
channel = commandContext.getChannel();
|
||||
}
|
||||
return faqService.loadFAQResponse(commandName, channel)
|
||||
.thenCompose(faqResponseModel -> {
|
||||
if (!faqResponseModel.getMessages().isEmpty()) {
|
||||
List<CompletableFuture<Void>> messageFutures = new ArrayList<>();
|
||||
faqResponseModel
|
||||
.getMessages()
|
||||
.forEach(faqResponseMessageModel ->
|
||||
messageFutures.add(FutureUtils.
|
||||
toSingleFutureGeneric(channelService.
|
||||
sendEmbedTemplateInTextChannelList(FAQ_RESPONSE_TEMPLATE_KEY,
|
||||
faqResponseMessageModel, commandContext.getChannel()))));
|
||||
return FutureUtils.toSingleFutureGeneric(messageFutures);
|
||||
} else {
|
||||
return FutureUtils
|
||||
.toSingleFutureGeneric(
|
||||
channelService.
|
||||
sendEmbedTemplateInTextChannelList(FAQ_RESPONSE_NO_COMMAND_FOUND_TEMPLATE_KEY,
|
||||
faqResponseModel, commandContext.getChannel()));
|
||||
}
|
||||
})
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
} else {
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
AChannel channel = channelManagementService.loadChannel(commandContext.getChannel());
|
||||
FAQResponseModel model = faqService.getNoCommandFoundModel(server, channel);
|
||||
return FutureUtils
|
||||
.toSingleFutureGeneric(
|
||||
channelService.
|
||||
sendEmbedTemplateInTextChannelList(FAQ_RESPONSE_NO_COMMAND_FOUND_TEMPLATE_KEY,
|
||||
model, commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter commandNameParameter = Parameter.builder().name("command").type(String.class).templated(true).optional(true).build();
|
||||
Parameter channelParameter = Parameter.builder().name("channel").type(TextChannel.class).optional(true).templated(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(commandNameParameter, channelParameter);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("FAQ")
|
||||
.module(FAQModuleDefinition.FAQ)
|
||||
.parameters(parameters)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.async(true)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return FAQFeatureDefinition.FAQ;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.command;
|
||||
|
||||
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.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureMode;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQModuleDefinition;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.faquses.FAQUsageModel;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.FAQUsageServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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
|
||||
@Slf4j
|
||||
public class FAQUsage extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private FAQUsageServiceBean faqUsageServiceBean;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
private static final String FAQ_USAGE_RESPONSE_TEMPLATE_KEY = "FAQUsage_response";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
FAQUsageModel model;
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
if(parameters.isEmpty()) {
|
||||
model = faqUsageServiceBean.getFAQUsageModel(server);
|
||||
} else {
|
||||
String commandName = (String) parameters.get(0);
|
||||
model = faqUsageServiceBean.getFAQUsageModel(server, commandName);
|
||||
}
|
||||
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(FAQ_USAGE_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter commandNameParameter = Parameter.builder().name("commandName").type(String.class).templated(true).optional(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(commandNameParameter);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("FAQUsage")
|
||||
.module(FAQModuleDefinition.FAQ)
|
||||
.parameters(parameters)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.async(true)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return FAQFeatureDefinition.FAQ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FeatureMode> getFeatureModeLimitations() {
|
||||
return Arrays.asList(FAQFeatureMode.FAQ_USES);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.command;
|
||||
|
||||
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.exception.AbstractoTemplatedException;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.models.JSONValidationResult;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.JSONValidationService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FileService;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQModuleDefinition;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.config.FaqCommandConfig;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.FAQValidationServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.everit.json.schema.ValidationException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ImportFAQ extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private FileService fileService;
|
||||
|
||||
@Autowired
|
||||
private FAQServiceBean faqServiceBean;
|
||||
|
||||
@Autowired
|
||||
private FAQValidationServiceBean faqValidationServiceBean;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private JSONValidationService jsonValidationService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameter = commandContext.getParameters().getParameters();
|
||||
File jsonConfigFile = (File) parameter.get(0);
|
||||
try {
|
||||
String jsonContent = FileUtils.readFileToString(jsonConfigFile, StandardCharsets.UTF_8);
|
||||
JSONValidationResult result = faqValidationServiceBean.validateJSONForCreation(jsonContent);
|
||||
if(result.getResult().equals(JSONValidationService.Result.SUCCESSFUL)) {
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
List<FaqCommandConfig> commands = faqServiceBean.loadFAQCommandsFromJson(jsonContent);
|
||||
faqServiceBean.createOrUpdateFAQCommands(commands, server);
|
||||
} else {
|
||||
|
||||
List<String> errors = jsonValidationService.getDetailedException(result.getExceptions())
|
||||
.stream()
|
||||
.map(ValidationException::getMessage)
|
||||
.collect(Collectors.toList());
|
||||
channelService.sendTextToChannel(String.join("\n", errors), commandContext.getChannel());
|
||||
}
|
||||
return CompletableFuture.completedFuture(CommandResult.fromSuccess());
|
||||
} catch (IOException e) {
|
||||
log.error("IO Exception when loading input file.", e);
|
||||
throw new AbstractoTemplatedException("Failed to load json config.", "failed_to_set_template_exception", e);
|
||||
} finally {
|
||||
try {
|
||||
fileService.safeDelete(jsonConfigFile);
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to delete downloaded json file.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter fileAttachmentParameter = Parameter.builder().name("file").type(File.class).templated(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(fileAttachmentParameter);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("importFAQ")
|
||||
.module(FAQModuleDefinition.FAQ)
|
||||
.parameters(parameters)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.async(true)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return FAQFeatureDefinition.FAQ;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.command;
|
||||
|
||||
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.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQModuleDefinition;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.list.ListFAQCommandsModel;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ListFAQCommands extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private FAQServiceBean faqServiceBean;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
private static final String LIST_FAQ_COMMANDS_RESPONSE_TEMPLATE_KEY = "listFAQCommands_response";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
ListFAQCommandsModel model = faqServiceBean.getCommandListingForServer(server);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(LIST_FAQ_COMMANDS_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("listFAQCommands")
|
||||
.module(FAQModuleDefinition.FAQ)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.async(true)
|
||||
.templated(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return FAQFeatureDefinition.FAQ;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import dev.sheldan.abstracto.core.interactive.AutoDelayedAction;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.setup.GlobalChannelGroupDelayedActionConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class FAQFeatureConfig implements FeatureConfig {
|
||||
|
||||
@Autowired
|
||||
private GlobalChannelGroupDelayedActionConfig globalChannelGroupDelayedActionConfig;
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return FAQFeatureDefinition.FAQ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AutoDelayedAction> getAutoSetupSteps() {
|
||||
return Arrays.asList(globalChannelGroupDelayedActionConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FeatureMode> getAvailableModes() {
|
||||
return Arrays.asList(FAQFeatureMode.FAQ_USES);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum FAQFeatureDefinition implements FeatureDefinition {
|
||||
FAQ("faq");
|
||||
|
||||
private String key;
|
||||
|
||||
FAQFeatureDefinition(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum FAQFeatureMode implements FeatureMode {
|
||||
FAQ_USES("faqUses");
|
||||
|
||||
private final String key;
|
||||
|
||||
FAQFeatureMode(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.config.ModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.command.config.ModuleInfo;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class FAQModuleDefinition implements ModuleDefinition {
|
||||
|
||||
public static final String FAQ = "faqModule";
|
||||
|
||||
@Override
|
||||
public ModuleInfo getInfo() {
|
||||
return ModuleInfo.builder().name(FAQ).templated(true).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParentModule() {
|
||||
return "default";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@Configuration
|
||||
@PropertySource("classpath:faq.properties")
|
||||
public class FAQProperties {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.config.setup;
|
||||
|
||||
import dev.sheldan.abstracto.core.interactive.DelayedActionConfig;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class GlobalChannelGroupDelayActionConfig implements DelayedActionConfig {
|
||||
|
||||
private Long serverId;
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "setup_global_channel_group_info";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.config.setup;
|
||||
|
||||
import dev.sheldan.abstracto.core.interactive.AutoDelayedAction;
|
||||
import dev.sheldan.abstracto.core.interactive.DelayedActionConfig;
|
||||
import dev.sheldan.abstracto.core.models.AServerChannelUserId;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class GlobalChannelGroupDelayedActionConfig implements AutoDelayedAction {
|
||||
@Override
|
||||
public DelayedActionConfig getDelayedActionConfig(AServerChannelUserId aServerChannelUserId) {
|
||||
return GlobalChannelGroupDelayActionConfig
|
||||
.builder()
|
||||
.serverId(aServerChannelUserId.getGuildId())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.config.setup;
|
||||
|
||||
import dev.sheldan.abstracto.core.interactive.DelayedAction;
|
||||
import dev.sheldan.abstracto.core.interactive.DelayedActionConfig;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.ChannelGroupType;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupTypeManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean.FAQ_CHANNEL_GROUP_KEY;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class GlobalChannelGroupSetupDelayedAction implements DelayedAction {
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupManagementService channelGroupManagementService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupTypeManagementService channelGroupTypeManagementService;
|
||||
|
||||
@Value("${abstracto.faq.globalChannelGroupName}")
|
||||
private String globalChannelGroupName;
|
||||
|
||||
@Override
|
||||
public void execute(DelayedActionConfig delayedActionConfig) {
|
||||
GlobalChannelGroupDelayActionConfig config = (GlobalChannelGroupDelayActionConfig) delayedActionConfig;
|
||||
AServer server = serverManagementService.loadServer(config.getServerId());
|
||||
if(!channelGroupManagementService.doesChannelGroupExist(globalChannelGroupName, server)) {
|
||||
ChannelGroupType faqChannelGroupType = channelGroupTypeManagementService.findChannelGroupTypeByKey(FAQ_CHANNEL_GROUP_KEY);
|
||||
channelGroupManagementService.createChannelGroup(globalChannelGroupName, server, faqChannelGroupType);
|
||||
} else {
|
||||
log.info("Global channel group named {} already exists for server {}.", globalChannelGroupName, config.getServerId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(DelayedActionConfig delayedActionConfig) {
|
||||
return delayedActionConfig instanceof GlobalChannelGroupDelayActionConfig;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.converter;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.config.*;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandResponse;
|
||||
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 FAQCommandConfigConverter {
|
||||
|
||||
@Autowired
|
||||
private Gson gson;
|
||||
|
||||
public String serializeCommands(List<FAQCommand> asList) {
|
||||
List<FaqCommandConfig> config = asList.stream().map(faqCommand -> {
|
||||
List<FaqCommandResponseConfig> commandResponseConfigs = convertGroupCommands(faqCommand.getGroupResponses());
|
||||
List<String> aliases;
|
||||
if(faqCommand.getAliases() != null) {
|
||||
aliases = faqCommand.getAliases().stream().map(faqCommandAlias -> faqCommandAlias.getId().getAlias()).collect(Collectors.toList());
|
||||
} else {
|
||||
aliases = new ArrayList<>();
|
||||
}
|
||||
return FaqCommandConfig
|
||||
.builder()
|
||||
.faqCommandName(faqCommand.getName())
|
||||
.global(faqCommand.getGlobal())
|
||||
.responses(commandResponseConfigs)
|
||||
.aliases(aliases)
|
||||
.build();
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
return gson.toJson(config);
|
||||
}
|
||||
|
||||
private List<FaqCommandResponseConfig> convertGroupCommands(List<FAQChannelGroupCommand> responses) {
|
||||
return responses.stream().map(faqChannelGroupCommand -> {
|
||||
List<FaqCommandResponseMessageConfig> responseConfigs = convertCommandResponses(faqChannelGroupCommand.getResponses());
|
||||
return FaqCommandResponseConfig
|
||||
.builder()
|
||||
.channelGroupName(faqChannelGroupCommand.getChannelGroup().getChannelGroup().getGroupName())
|
||||
.messages(responseConfigs)
|
||||
.build();
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<FaqCommandResponseMessageConfig> convertCommandResponses(List<FAQCommandResponse> responses) {
|
||||
return responses.stream().map(this::convertCommandResponse).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private FaqCommandResponseMessageConfig convertCommandResponse(FAQCommandResponse response) {
|
||||
FaqCommandResponseEmbedConfig embedConfig = null;
|
||||
if(response.getDescription() != null) {
|
||||
FaqCommandResponseEmbedColorConfig colorConfig = FaqCommandResponseEmbedColorConfig
|
||||
.builder()
|
||||
.red(response.getRed())
|
||||
.green(response.getGreen())
|
||||
.blue(response.getBlue())
|
||||
.build();
|
||||
FaqCommandResponseEmbedAuthorConfig authorConfig = FaqCommandResponseEmbedAuthorConfig
|
||||
.builder()
|
||||
.userId(response.getAuthorUserId())
|
||||
.useBot(null)
|
||||
.build();
|
||||
embedConfig = FaqCommandResponseEmbedConfig
|
||||
.builder()
|
||||
.description(response.getDescription())
|
||||
.imageUrl(response.getImageURL())
|
||||
.color(colorConfig)
|
||||
.author(authorConfig)
|
||||
.build();
|
||||
}
|
||||
return FaqCommandResponseMessageConfig
|
||||
.builder()
|
||||
.position(response.getId().getPosition())
|
||||
.additionalMessage(response.getAdditionalMessage())
|
||||
.embed(embedConfig)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.converter;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.list.ListFAQCommandsCommandChannelGroupModel;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.list.ListFAQCommandsModel;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.list.ListFAQCommandsCommandModel;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class ListFAQCommandsModelConverter {
|
||||
|
||||
public ListFAQCommandsModel fromFAQCommands(List<FAQCommand> faqCommandList) {
|
||||
List<ListFAQCommandsCommandModel> commands = faqCommandList
|
||||
.stream()
|
||||
.map(this::convertCommand)
|
||||
.collect(Collectors.toList());
|
||||
return ListFAQCommandsModel
|
||||
.builder()
|
||||
.commands(commands)
|
||||
.build();
|
||||
}
|
||||
|
||||
private ListFAQCommandsCommandModel convertCommand(FAQCommand faqCommand) {
|
||||
List<ListFAQCommandsCommandChannelGroupModel> channelGroups = faqCommand
|
||||
.getGroupResponses()
|
||||
.stream()
|
||||
.map(this::convertGroupCommand)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<String> aliases;
|
||||
if(faqCommand.getAliases() != null) {
|
||||
aliases = faqCommand.getAliases().stream().map(faqCommandAlias -> faqCommandAlias.getId().getAlias()).collect(Collectors.toList());
|
||||
} else {
|
||||
aliases = new ArrayList<>();
|
||||
}
|
||||
return ListFAQCommandsCommandModel
|
||||
.builder()
|
||||
.commandName(faqCommand.getName())
|
||||
.aliases(aliases)
|
||||
.channelGroups(channelGroups)
|
||||
.build();
|
||||
}
|
||||
|
||||
private ListFAQCommandsCommandChannelGroupModel convertGroupCommand(FAQChannelGroupCommand faqChannelGroupCommand) {
|
||||
AChannelGroup channelGroup = faqChannelGroupCommand.getChannelGroup().getChannelGroup();
|
||||
return ListFAQCommandsCommandChannelGroupModel
|
||||
.builder()
|
||||
.responseCount(faqChannelGroupCommand.getResponses().size())
|
||||
.channelGroupName(channelGroup.getGroupName())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.exception.DuplicatedCommandNameExceptionModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DuplicatedCommandNameOrAliasException extends AbstractoTemplatableException {
|
||||
|
||||
private final DuplicatedCommandNameExceptionModel model;
|
||||
|
||||
public DuplicatedCommandNameOrAliasException(List<String> commandKeys) {
|
||||
super("Duplicated command name or alias found.");
|
||||
this.model = DuplicatedCommandNameExceptionModel
|
||||
.builder()
|
||||
.duplicatedCommandKeys(commandKeys)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "duplicated_command_or_alias_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return this.model;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.exception.DuplicatedFAQCommandAliasExceptionModel;
|
||||
|
||||
public class DuplicatedFAQCommandAliasException extends AbstractoTemplatableException {
|
||||
private final DuplicatedFAQCommandAliasExceptionModel model;
|
||||
|
||||
public DuplicatedFAQCommandAliasException(String commandName, String alias, String usedCommand) {
|
||||
super("Alias for FAQ command is already used as an alias in another name.");
|
||||
this.model = DuplicatedFAQCommandAliasExceptionModel
|
||||
.builder()
|
||||
.alias(alias)
|
||||
.commandName(commandName)
|
||||
.originCommandName(usedCommand)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "duplicated_faq_command_alias_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return this.model;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.exception.FAQCommandAliasShadowingExceptionModel;
|
||||
|
||||
public class FAQCommandAliasShadowingException extends AbstractoTemplatableException {
|
||||
|
||||
private final FAQCommandAliasShadowingExceptionModel model;
|
||||
|
||||
public FAQCommandAliasShadowingException(String commandName, String alias) {
|
||||
super("Alias shadows another existing command.");
|
||||
this.model = FAQCommandAliasShadowingExceptionModel
|
||||
.builder()
|
||||
.alias(alias)
|
||||
.commandName(commandName)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "faq_command_alias_shadowing_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return this.model;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.exception.FAQCommandNotFoundExceptionModel;
|
||||
|
||||
public class FAQCommandNotFoundException extends AbstractoTemplatableException {
|
||||
private final FAQCommandNotFoundExceptionModel model;
|
||||
|
||||
public FAQCommandNotFoundException(String commandName) {
|
||||
super("FAQ command not found.");
|
||||
this.model = FAQCommandNotFoundExceptionModel
|
||||
.builder()
|
||||
.commandName(commandName)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "faq_command_not_found_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return this.model;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.exception.FAQCommandResponseDuplicatedPositionExceptionModel;
|
||||
|
||||
public class FAQCommandResponseDuplicatedPositionException extends AbstractoTemplatableException {
|
||||
private final FAQCommandResponseDuplicatedPositionExceptionModel model;
|
||||
|
||||
public FAQCommandResponseDuplicatedPositionException(String commandName, String channelGroupName) {
|
||||
super("Two messages within a FAQ command response have the same position.");
|
||||
this.model = FAQCommandResponseDuplicatedPositionExceptionModel
|
||||
.builder()
|
||||
.channelGroupName(channelGroupName)
|
||||
.commandName(commandName)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "faq_command_response_duplicated_position_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return this.model;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.exception.GlobalFAQCommandConfigMismatchExceptionModel;
|
||||
|
||||
public class GlobalFAQCommandConfigMismatchException extends AbstractoTemplatableException {
|
||||
private final GlobalFAQCommandConfigMismatchExceptionModel model;
|
||||
|
||||
public GlobalFAQCommandConfigMismatchException(String faqCommandName) {
|
||||
super("The configuration for a global FAQ command does not make sense. It must be a the global FAQ channel group and the command needs to have global enabled.");
|
||||
this.model = GlobalFAQCommandConfigMismatchExceptionModel
|
||||
.builder()
|
||||
.commandName(faqCommandName)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "global_faq_command_config_mismatch_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return this.model;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.exception.GlobalCommandResponseExceptionModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GlobalFAQCommandResponsesException extends AbstractoTemplatableException {
|
||||
private final GlobalCommandResponseExceptionModel model;
|
||||
|
||||
public GlobalFAQCommandResponsesException(List<String> commandNames) {
|
||||
super("A global command can only have one response.");
|
||||
this.model = GlobalCommandResponseExceptionModel
|
||||
.builder()
|
||||
.commandNames(commandNames)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "global_faq_command_responses_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return this.model;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
|
||||
public class NoFAQResponseFoundException extends AbstractoTemplatableException {
|
||||
|
||||
public NoFAQResponseFoundException() {
|
||||
super("No FAQ Command response found.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "no_faq_response_found_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.AsyncChannelGroupCreatedListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.listener.ChannelGroupCreatedListenerModel;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroup;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.management.FAQChannelGroupManagementServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class FAQAsyncChannelGroupCreatedListener implements AsyncChannelGroupCreatedListener {
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupManagementService channelGroupManagementService;
|
||||
|
||||
@Autowired
|
||||
private FAQChannelGroupManagementServiceBean faqChannelGroupManagementServiceBean;
|
||||
|
||||
@Value("${abstracto.faq.globalChannelGroupName}")
|
||||
private String globalChannelGroupName;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(ChannelGroupCreatedListenerModel model) {
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findChannelGroupById(model.getChannelGroupId());
|
||||
if(channelGroup.getChannelGroupType().getGroupTypeKey().equals(FAQServiceBean.FAQ_CHANNEL_GROUP_KEY)) {
|
||||
FAQChannelGroup createdChannelGroup = faqChannelGroupManagementServiceBean.createFAQChannelGroup(channelGroup);
|
||||
if(channelGroup.getGroupName().equals(globalChannelGroupName)) {
|
||||
Optional<FAQChannelGroup> globalGroup = faqChannelGroupManagementServiceBean.getGlobalChannelGroup(channelGroup.getServer());
|
||||
globalGroup.ifPresent(faqChannelGroup -> {
|
||||
log.info("Setting channel group {} to not be global for server {}.", faqChannelGroup.getId(), channelGroup.getServer().getId());
|
||||
faqChannelGroup.setGlobal(false);
|
||||
});
|
||||
log.info("Setting channel group {} to be global for server {}.", channelGroup.getId(), channelGroup.getServer().getId());
|
||||
createdChannelGroup.setGlobal(true);
|
||||
}
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.ChannelGroupDeletedListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.listener.ChannelGroupDeletedListenerModel;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.management.FAQChannelGroupManagementServiceBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class FAQChannelGroupDeletedListener implements ChannelGroupDeletedListener {
|
||||
|
||||
@Autowired
|
||||
private FAQChannelGroupManagementServiceBean faqChannelGroupManagementServiceBean;
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupManagementService channelGroupManagementService;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(ChannelGroupDeletedListenerModel model) {
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findChannelGroupById(model.getChannelGroupId());
|
||||
if(channelGroup.getChannelGroupType().getGroupTypeKey().equals(FAQServiceBean.FAQ_CHANNEL_GROUP_KEY)) {
|
||||
faqChannelGroupManagementServiceBean.deleteFAQChannelGroup(channelGroup);
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.config;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class FaqCommandConfig {
|
||||
private String faqCommandName;
|
||||
private Boolean global;
|
||||
private List<String> aliases;
|
||||
private List<FaqCommandResponseConfig> responses;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.config;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class FaqCommandResponseConfig {
|
||||
private String channelGroupName;
|
||||
private List<FaqCommandResponseMessageConfig> messages;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.config;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class FaqCommandResponseEmbedAuthorConfig {
|
||||
private Long userId;
|
||||
private Boolean useBot;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.config;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class FaqCommandResponseEmbedColorConfig {
|
||||
@Builder.Default
|
||||
private Integer red = 0;
|
||||
@Builder.Default
|
||||
private Integer green = 0;
|
||||
@Builder.Default
|
||||
private Integer blue = 0;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.config;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class FaqCommandResponseEmbedConfig {
|
||||
private String description;
|
||||
private String imageUrl;
|
||||
private FaqCommandResponseEmbedColorConfig color;
|
||||
private FaqCommandResponseEmbedAuthorConfig author;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.config;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class FaqCommandResponseMessageConfig {
|
||||
private Integer position;
|
||||
private String additionalMessage;
|
||||
private FaqCommandResponseEmbedConfig embed;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.faq;
|
||||
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandResponse;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class FAQResponseMessageModel {
|
||||
private User author;
|
||||
private String additionalMessage;
|
||||
private String description;
|
||||
private String imageURL;
|
||||
private Integer red;
|
||||
private Integer green;
|
||||
private Integer blue;
|
||||
|
||||
public static FAQResponseMessageModel fromFAQCommandResponse(FAQCommandResponse response, User user) {
|
||||
return FAQResponseMessageModel
|
||||
.builder()
|
||||
.author(user)
|
||||
.additionalMessage(response.getAdditionalMessage())
|
||||
.description(response.getDescription())
|
||||
.blue(response.getBlue())
|
||||
.green(response.getGreen())
|
||||
.red(response.getRed())
|
||||
.imageURL(response.getImageURL())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.faq;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class FAQResponseModel {
|
||||
@Builder.Default
|
||||
private List<FAQResponseMessageModel> messages = new ArrayList<>();
|
||||
@Builder.Default
|
||||
private List<String> availableCommands = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.faquses;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class FAQCommandResponseUsage {
|
||||
private String channelGroupName;
|
||||
private Integer uses;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.faquses;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class FAQCommandUsage {
|
||||
private String faqCommandName;
|
||||
private List<FAQCommandResponseUsage> faqChannelGroupUsages;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.faquses;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class FAQUsageModel {
|
||||
private List<FAQCommandUsage> uses;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.list;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class ListFAQCommandsCommandChannelGroupModel {
|
||||
private String channelGroupName;
|
||||
private Integer responseCount;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.list;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class ListFAQCommandsCommandModel {
|
||||
private String commandName;
|
||||
private List<String> aliases;
|
||||
private List<ListFAQCommandsCommandChannelGroupModel> channelGroups;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.command.list;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Setter
|
||||
@Builder
|
||||
@Getter
|
||||
public class ListFAQCommandsModel {
|
||||
private List<ListFAQCommandsCommandModel> commands;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.database;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.Instant;
|
||||
|
||||
@Builder
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "faq_channel_group")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
public class FAQChannelGroup {
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@PrimaryKeyJoinColumn
|
||||
private AChannelGroup channelGroup;
|
||||
|
||||
@Column(name = "global")
|
||||
private Boolean global;
|
||||
|
||||
@Column(name = "created", nullable = false, insertable = false, updatable = false)
|
||||
private Instant created;
|
||||
|
||||
@Column(name = "updated", insertable = false, updatable = false)
|
||||
private Instant updated;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.database;
|
||||
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.ChannelGroupCommandId;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Builder
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "faq_channel_group_command")
|
||||
@EqualsAndHashCode
|
||||
@Getter
|
||||
@Setter
|
||||
public class FAQChannelGroupCommand implements Serializable {
|
||||
|
||||
@EmbeddedId
|
||||
private ChannelGroupCommandId groupCommandId;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@MapsId("channelGroupId")
|
||||
@JoinColumn(name = "channel_group_id", referencedColumnName = "id", nullable = false)
|
||||
private FAQChannelGroup channelGroup;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@MapsId("commandId")
|
||||
@JoinColumn(name = "command_id", referencedColumnName = "id", nullable = false)
|
||||
private FAQCommand command;
|
||||
|
||||
@OneToMany(fetch = FetchType.LAZY, mappedBy = "groupCommand")
|
||||
@Builder.Default
|
||||
private List<FAQCommandResponse> responses = new ArrayList<>();
|
||||
|
||||
@Column(name = "created", nullable = false, insertable = false, updatable = false)
|
||||
private Instant created;
|
||||
|
||||
@Column(name = "uses")
|
||||
private Integer uses;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.database;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Builder
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "faq_command")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
public class FAQCommand implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "name", length = 20)
|
||||
private String name;
|
||||
|
||||
@Column(name = "global")
|
||||
private Boolean global;
|
||||
|
||||
@Getter
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "server_id", nullable = false)
|
||||
private AServer server;
|
||||
|
||||
@Column(name = "created", nullable = false, insertable = false, updatable = false)
|
||||
private Instant created;
|
||||
|
||||
@Column(name = "updated", insertable = false, updatable = false)
|
||||
private Instant updated;
|
||||
|
||||
@Getter
|
||||
@OneToMany(fetch = FetchType.LAZY, mappedBy = "command")
|
||||
@Builder.Default
|
||||
private List<FAQChannelGroupCommand> groupResponses = new ArrayList<>();
|
||||
|
||||
@OneToMany(fetch = FetchType.LAZY, mappedBy = "command")
|
||||
@Builder.Default
|
||||
private List<FAQCommandAlias> aliases = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.database;
|
||||
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.FAQCommandAliasId;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
|
||||
@Builder
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "faq_command_alias")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
public class FAQCommandAlias implements Serializable {
|
||||
|
||||
@EmbeddedId
|
||||
private FAQCommandAliasId id;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@MapsId("commandId")
|
||||
@JoinColumn(name = "command_id", referencedColumnName = "id", nullable = false)
|
||||
private FAQCommand command;
|
||||
|
||||
@Column(name = "created", nullable = false, insertable = false, updatable = false)
|
||||
private Instant created;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.database;
|
||||
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.CommandResponseId;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.Instant;
|
||||
|
||||
@Builder
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "faq_command_response")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
public class FAQCommandResponse {
|
||||
@EmbeddedId
|
||||
private CommandResponseId id;
|
||||
|
||||
@Column(name = "description", length = 2000)
|
||||
private String description;
|
||||
|
||||
@Column(name = "additional_message", length = 2000)
|
||||
private String additionalMessage;
|
||||
|
||||
@Column(name = "image_url", length = 2000)
|
||||
private String imageURL;
|
||||
|
||||
@Column(name = "red")
|
||||
private Integer red;
|
||||
|
||||
@Column(name = "green")
|
||||
private Integer green;
|
||||
|
||||
@Column(name = "blue")
|
||||
private Integer blue;
|
||||
|
||||
@Column(name = "author_user_id")
|
||||
private Long authorUserId;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumns(
|
||||
{
|
||||
@JoinColumn(updatable = false, insertable = false, name = "channel_group_id", referencedColumnName = "channel_group_id"),
|
||||
@JoinColumn(updatable = false, insertable = false, name = "command_id", referencedColumnName = "command_id")
|
||||
})
|
||||
private FAQChannelGroupCommand groupCommand;
|
||||
|
||||
@Column(name = "created", nullable = false, insertable = false, updatable = false)
|
||||
private Instant created;
|
||||
|
||||
@Column(name = "updated", insertable = false, updatable = false)
|
||||
private Instant updated;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.database.embed;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Embeddable
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
public class ChannelGroupCommandId implements Serializable {
|
||||
@Column(name = "channel_group_id")
|
||||
private Long channelGroupId;
|
||||
@Column(name = "command_id")
|
||||
private Long commandId;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.database.embed;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Embeddable
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CommandResponseId implements Serializable {
|
||||
@Column(name = "channel_group_id")
|
||||
private Long channelGroupId;
|
||||
@Column(name = "command_id")
|
||||
private Long commandId;
|
||||
@Column(name = "position")
|
||||
private Integer position;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.database.embed;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Embeddable
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class FAQCommandAliasId implements Serializable {
|
||||
@Column(name = "command_id")
|
||||
private Long faqCommandId;
|
||||
@Column(name = "alias", length = 20)
|
||||
private String alias;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.exception;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class DuplicatedCommandNameExceptionModel {
|
||||
private List<String> duplicatedCommandKeys;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.exception;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class DuplicatedFAQCommandAliasExceptionModel {
|
||||
private String commandName;
|
||||
private String alias;
|
||||
private String originCommandName;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.exception;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class FAQCommandAliasShadowingExceptionModel {
|
||||
private String commandName;
|
||||
private String alias;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.exception;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class FAQCommandNotFoundExceptionModel {
|
||||
private String commandName;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.exception;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class FAQCommandResponseDuplicatedPositionExceptionModel {
|
||||
private String commandName;
|
||||
private String channelGroupName;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.exception;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class GlobalCommandResponseExceptionModel {
|
||||
private List<String> commandNames;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.models.exception;
|
||||
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class GlobalFAQCommandConfigMismatchExceptionModel {
|
||||
private String commandName;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.repository;
|
||||
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroup;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.ChannelGroupCommandId;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface FAQChannelGroupCommandRepository extends JpaRepository<FAQChannelGroupCommand, ChannelGroupCommandId> {
|
||||
List<FAQChannelGroupCommand> findByChannelGroup(FAQChannelGroup faqChannelGroup);
|
||||
List<FAQChannelGroupCommand> findByChannelGroup_IdIn(List<Long> channelGroupIds);
|
||||
List<FAQChannelGroupCommand> findByChannelGroupIn(List<FAQChannelGroup> faqChannelGroup);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroup;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface FAQChannelGroupRepository extends JpaRepository<FAQChannelGroup, Long> {
|
||||
Optional<FAQChannelGroup> findByChannelGroup_ServerAndGlobalTrue(AServer server);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandAlias;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.FAQCommandAliasId;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface FAQCommandAliasRepository extends JpaRepository<FAQCommandAlias, FAQCommandAliasId> {
|
||||
Optional<FAQCommandAlias> findById_AliasAndCommand_Server(String alias, AServer server);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface FAQCommandRepository extends JpaRepository<FAQCommand, Long> {
|
||||
Optional<FAQCommand> findByNameEqualsIgnoreCaseAndServer(String name, AServer server);
|
||||
List<FAQCommand> findByNameInIgnoreCaseAndServer(List<String> names, AServer server);
|
||||
List<FAQCommand> findByServer(AServer server);
|
||||
List<FAQCommand> findByServerAndGlobalTrue(AServer server);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.repository;
|
||||
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandResponse;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.CommandResponseId;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface FAQCommandResponseRepository extends JpaRepository<FAQCommandResponse, CommandResponseId> {
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.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.FeatureModeService;
|
||||
import dev.sheldan.abstracto.core.service.UserService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureMode;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.exception.NoFAQResponseFoundException;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.faq.FAQResponseMessageModel;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.faq.FAQResponseModel;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandAlias;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandResponse;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.management.FAQChannelGroupCommandManagementServiceBean;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.management.FAQCommandAliasManagementService;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.management.FAQCommandManagementServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.ISnowflake;
|
||||
import net.dv8tion.jda.api.entities.SelfUser;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class FAQResponseServiceBean {
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Autowired
|
||||
private FAQCommandManagementServiceBean faqCommandManagementServiceBean;
|
||||
|
||||
@Autowired
|
||||
private FAQChannelGroupCommandManagementServiceBean faqChannelGroupCommandManagementServiceBean;
|
||||
|
||||
@Autowired
|
||||
private FAQCommandAliasManagementService faqCommandAliasManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
private FAQResponseServiceBean self;
|
||||
|
||||
public CompletableFuture<FAQResponseModel> loadFAQResponse(String commandName, TextChannel textChannel) {
|
||||
AServer server = serverManagementService.loadServer(textChannel.getGuild().getIdLong());
|
||||
Optional<FAQCommand> faqCommandOptional = faqCommandManagementServiceBean.findByNameAndServer(commandName, server);
|
||||
if(!faqCommandOptional.isPresent()) {
|
||||
log.debug("Did not find the command, trying via command alias.");
|
||||
Optional<FAQCommandAlias> faqCommandAlias = faqCommandAliasManagementService.findByNameAndServer(commandName, server);
|
||||
if(faqCommandAlias.isPresent()) {
|
||||
faqCommandOptional = Optional.of(faqCommandAlias.get().getCommand());
|
||||
}
|
||||
}
|
||||
AChannel channel = channelManagementService.loadChannel(textChannel.getIdLong());
|
||||
if (!faqCommandOptional.isPresent()) {
|
||||
log.debug("Did not find a faq response. Returning model with possible command names.");
|
||||
return CompletableFuture.completedFuture(getNoCommandFoundModel(server, channel));
|
||||
} else {
|
||||
FAQCommand command = faqCommandOptional.get();
|
||||
Optional<FAQChannelGroupCommand> groupCommand;
|
||||
if(command.getGlobal()) {
|
||||
groupCommand = command.getGroupResponses().stream().findAny();
|
||||
} else {
|
||||
Stream<FAQChannelGroupCommand> matchingChannels = command
|
||||
.getGroupResponses()
|
||||
.stream()
|
||||
.filter(faqChannelGroupCommand -> channelGroupService.isChannelInGroup(channel, faqChannelGroupCommand.getChannelGroup().getChannelGroup()));
|
||||
List<FAQChannelGroupCommand> allMatchingCommands = matchingChannels.collect(Collectors.toList());
|
||||
if(allMatchingCommands.size() > 1) {
|
||||
log.warn("There are multiple matching channel groups for command {} and channel {}.", command.getId(), channel.getId());
|
||||
}
|
||||
if(!allMatchingCommands.isEmpty()) {
|
||||
FAQChannelGroupCommand foundCommandChannelGroup = allMatchingCommands.get(0);
|
||||
log.info("Using response from channel group {} for command {} in server {}.", foundCommandChannelGroup.getChannelGroup().getId(), command.getId(), server.getId());
|
||||
groupCommand = Optional.of(foundCommandChannelGroup);
|
||||
} else {
|
||||
groupCommand = Optional.empty();
|
||||
}
|
||||
}
|
||||
if(groupCommand.isPresent()) {
|
||||
FAQChannelGroupCommand channelGroupCommand = groupCommand.get();
|
||||
if(featureModeService.featureModeActive(FAQFeatureDefinition.FAQ, server.getId(), FAQFeatureMode.FAQ_USES)){
|
||||
log.debug("Incrementing use counter for channel group {} for command {} in server {}.", channelGroupCommand.getChannelGroup().getId(), command.getId(), server.getId());
|
||||
channelGroupCommand.setUses(channelGroupCommand.getUses() + 1);
|
||||
}
|
||||
Set<Long> userIds = channelGroupCommand
|
||||
.getResponses()
|
||||
.stream()
|
||||
.map(FAQCommandResponse::getAuthorUserId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
Long commandId = channelGroupCommand.getGroupCommandId().getCommandId();
|
||||
Long channelGroupId = channelGroupCommand.getGroupCommandId().getChannelGroupId();
|
||||
CompletableFuture<FAQResponseModel> modelFuture = new CompletableFuture<>();
|
||||
if(userIds.isEmpty()) {
|
||||
log.info("No user could not be found for channel group {} for command {} in server {}. Continuing with the bot as user.", channelGroupCommand.getChannelGroup().getId(), command.getId(), server.getId());
|
||||
self.createModel(commandId, channelGroupId, null, modelFuture);
|
||||
} else {
|
||||
CompletableFutureList<User> userFutures = userService.retrieveUsers(new ArrayList<>(userIds));
|
||||
userFutures
|
||||
.getMainFuture()
|
||||
.whenComplete((unused, throwable) -> self.createModel(commandId, channelGroupId, userFutures, modelFuture));
|
||||
}
|
||||
return modelFuture;
|
||||
} else {
|
||||
throw new NoFAQResponseFoundException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FAQResponseModel getNoCommandFoundModel(AServer server, AChannel channel) {
|
||||
List<AChannelGroup> channelGroups = channelGroupService.getChannelGroupsOfChannelWithType(channel, FAQServiceBean.FAQ_CHANNEL_GROUP_KEY);
|
||||
List<FAQChannelGroupCommand> possibleCommands = faqChannelGroupCommandManagementServiceBean.getGroupCommandsForBasicChannelGroups(channelGroups);
|
||||
List<FAQCommand> globalCommands = faqCommandManagementServiceBean.findGlobalCommandsInServer(server);
|
||||
Set<String> commandNames = possibleCommands
|
||||
.stream()
|
||||
.map(faqChannelGroupCommand -> faqChannelGroupCommand.getCommand().getName())
|
||||
.collect(Collectors.toSet());
|
||||
commandNames.addAll(globalCommands.stream().map(FAQCommand::getName).collect(Collectors.toSet()));
|
||||
return FAQResponseModel
|
||||
.builder()
|
||||
.availableCommands(new ArrayList<>(commandNames))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void createModel(Long commandId, Long channelGroupId, CompletableFutureList<User> userFutures, CompletableFuture<FAQResponseModel> modelFuture) {
|
||||
try {
|
||||
FAQChannelGroupCommand loadedGroupCommand = faqChannelGroupCommandManagementServiceBean.findChannelGroupCommand(commandId, channelGroupId);
|
||||
FAQResponseModel mainModel = FAQResponseModel.builder().build();
|
||||
SelfUser selfUser = userService.getSelfUser();
|
||||
if(userFutures != null) {
|
||||
List<User> users = userFutures.getObjects();
|
||||
Map<Long, User> userMap = users.stream().collect(Collectors.toMap(ISnowflake::getIdLong, Function.identity()));
|
||||
loadedGroupCommand.getResponses().forEach(response -> {
|
||||
User user = userMap.getOrDefault(response.getAuthorUserId(), selfUser);
|
||||
mainModel.getMessages().add(FAQResponseMessageModel.fromFAQCommandResponse(response, user));
|
||||
});
|
||||
} else {
|
||||
loadedGroupCommand
|
||||
.getResponses()
|
||||
.forEach(response -> mainModel.getMessages().add(FAQResponseMessageModel.fromFAQCommandResponse(response, selfUser)));
|
||||
}
|
||||
modelFuture.complete(mainModel);
|
||||
} catch (Exception exception) {
|
||||
modelFuture.completeExceptionally(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,411 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.service;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.UserService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.converter.FAQCommandConfigConverter;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.converter.ListFAQCommandsModelConverter;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.exception.*;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.config.*;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.list.ListFAQCommandsModel;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroup;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandResponse;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.management.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class FAQServiceBean {
|
||||
|
||||
public static final String FAQ_CHANNEL_GROUP_KEY = "faq";
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupManagementService channelGroupManagementService;
|
||||
|
||||
@Autowired
|
||||
private Gson gson;
|
||||
|
||||
@Autowired
|
||||
private FAQCommandManagementServiceBean faqCommandManagementServiceBean;
|
||||
|
||||
@Autowired
|
||||
private FAQChannelGroupManagementServiceBean faqChannelGroupManagementServiceBean;
|
||||
|
||||
@Autowired
|
||||
private FAQCommandResponseManagementServiceBean faqCommandResponseManagementServiceBean;
|
||||
|
||||
@Autowired
|
||||
private FAQChannelGroupCommandManagementServiceBean faqChannelGroupCommandManagementServiceBean;
|
||||
|
||||
@Autowired
|
||||
private FAQCommandAliasManagementService faqCommandAliasManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private FAQCommandConfigConverter configConverter;
|
||||
|
||||
@Autowired
|
||||
private ListFAQCommandsModelConverter listFAQCommandsModelConverter;
|
||||
|
||||
public void createOrUpdateFAQCommands(List<FaqCommandConfig> commands, AServer server) {
|
||||
fillDefaults(commands);
|
||||
validateCommandConfig(commands, server);
|
||||
commands.forEach(faqCommandConfig -> handleFAQCommand(faqCommandConfig, server));
|
||||
}
|
||||
|
||||
private void validateCommandConfig(List<FaqCommandConfig> commands, AServer server) {
|
||||
List<FaqCommandConfig> incorrectGlobalConfigurations = commands
|
||||
.stream()
|
||||
.filter(faqCommandConfig -> faqCommandConfig.getGlobal() && faqCommandConfig.getResponses().size() > 1)
|
||||
.collect(Collectors.toList());
|
||||
if(!incorrectGlobalConfigurations.isEmpty()) {
|
||||
List<String> commandsWithIllegalConfiguration = incorrectGlobalConfigurations
|
||||
.stream()
|
||||
.map(FaqCommandConfig::getFaqCommandName)
|
||||
.collect(Collectors.toList());
|
||||
throw new GlobalFAQCommandResponsesException(commandsWithIllegalConfiguration);
|
||||
}
|
||||
|
||||
List<String> toBeConfiguredCommandNames = new ArrayList<>();
|
||||
commands.forEach(faqCommandConfig -> {
|
||||
toBeConfiguredCommandNames.add(faqCommandConfig.getFaqCommandName());
|
||||
if(faqCommandConfig.getAliases() != null) {
|
||||
toBeConfiguredCommandNames.addAll(faqCommandConfig.getAliases());
|
||||
}
|
||||
});
|
||||
|
||||
Set<String> uniqueToBeConfiguredCommandNames = new HashSet<>(toBeConfiguredCommandNames);
|
||||
if(toBeConfiguredCommandNames.size() != uniqueToBeConfiguredCommandNames.size()) {
|
||||
List<String> duplicatedKeys = getDuplicatedKeys(toBeConfiguredCommandNames);
|
||||
throw new DuplicatedCommandNameOrAliasException(duplicatedKeys);
|
||||
}
|
||||
List<FAQCommand> allCommands = faqCommandManagementServiceBean.findAllInServer(server);
|
||||
Map<String, FAQCommand> aliasMappings = getAliasMappings(allCommands);
|
||||
commands.forEach(faqCommandConfig -> {
|
||||
if(faqCommandConfig.getAliases() == null) return;
|
||||
// find a command in which the alias is used as alias
|
||||
faqCommandConfig.getAliases().forEach(aliasName -> {
|
||||
if(aliasMappings.containsKey(aliasName)) {
|
||||
FAQCommand faqCommand = aliasMappings.get(aliasName);
|
||||
// but the command should be a different one, else we would find ourselves
|
||||
if(!faqCommand.getName().equals(faqCommandConfig.getFaqCommandName())) {
|
||||
throw new DuplicatedFAQCommandAliasException(faqCommand.getName(), aliasName, faqCommandConfig.getFaqCommandName());
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
Map<String, FAQCommand> commandMappings = getCommandMappings(allCommands);
|
||||
commands.forEach(faqCommandConfig -> {
|
||||
if(faqCommandConfig.getAliases() == null) return;
|
||||
// check if the to be configured aliases clash with an existing command
|
||||
faqCommandConfig.getAliases().forEach(aliasName -> {
|
||||
if(commandMappings.containsKey(aliasName)) {
|
||||
throw new FAQCommandAliasShadowingException(faqCommandConfig.getFaqCommandName(), aliasName);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private List<String> getDuplicatedKeys(List<String> toBeConfiguredCommandNames) {
|
||||
Map<String, Long> collections = toBeConfiguredCommandNames.stream().collect(
|
||||
Collectors.groupingBy(
|
||||
Function.identity(),
|
||||
Collectors.counting()));
|
||||
List<String> duplicatedKeys = new ArrayList<>();
|
||||
collections.forEach((s, aLong) -> {
|
||||
if(aLong > 1) {
|
||||
duplicatedKeys.add(s);
|
||||
}
|
||||
});
|
||||
return duplicatedKeys;
|
||||
}
|
||||
|
||||
private void handleFAQCommand(FaqCommandConfig faqCommandConfig, AServer server) {
|
||||
Optional<FAQCommand> existingFAQCommandOptional = faqCommandManagementServiceBean.findByNameAndServer(faqCommandConfig.getFaqCommandName(), server);
|
||||
FAQCommand commandInstance;
|
||||
if(existingFAQCommandOptional.isPresent()) {
|
||||
commandInstance = existingFAQCommandOptional.get();
|
||||
log.debug("Updating command {} in server {}.", commandInstance.getId(), server.getId());
|
||||
updateFAQCommand(faqCommandConfig, commandInstance);
|
||||
} else {
|
||||
log.debug("Creating new command in server {}.", server.getId());
|
||||
commandInstance = createFAQCommand(faqCommandConfig, server);
|
||||
}
|
||||
Set<String> existingChannelGroupNames =
|
||||
commandInstance.getGroupResponses()
|
||||
.stream()
|
||||
.map(faqChannelGroupCommand -> faqChannelGroupCommand.getChannelGroup().getChannelGroup().getGroupName())
|
||||
.collect(Collectors.toSet());
|
||||
Set<String> configuredChannelGroupNames = new HashSet<>();
|
||||
faqCommandConfig
|
||||
.getResponses()
|
||||
.forEach(faqCommandResponseConfig -> {
|
||||
handleFAQChannelGroupCommand(faqCommandResponseConfig, commandInstance, server);
|
||||
configuredChannelGroupNames.add(faqCommandResponseConfig.getChannelGroupName());
|
||||
});
|
||||
// this deletes any channel group responses which were not reflected in the configuration
|
||||
existingChannelGroupNames.removeAll(configuredChannelGroupNames);
|
||||
existingChannelGroupNames.forEach(channelGroupName -> {
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findByNameAndServerAndType(channelGroupName, server, FAQ_CHANNEL_GROUP_KEY);
|
||||
FAQChannelGroup faqChannelGroup = faqChannelGroupManagementServiceBean.getFAQChannelGroupById(channelGroup.getId());
|
||||
faqChannelGroupCommandManagementServiceBean.deleteFAQChannelGroupCommand(commandInstance, faqChannelGroup);
|
||||
});
|
||||
}
|
||||
|
||||
private void handleFAQChannelGroupCommand(FaqCommandResponseConfig responseConfig, FAQCommand command, AServer server) {
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findByNameAndServerAndType(responseConfig.getChannelGroupName(), server, FAQ_CHANNEL_GROUP_KEY);
|
||||
FAQChannelGroup faqChannelGroup = faqChannelGroupManagementServiceBean.getFAQChannelGroupById(channelGroup.getId());
|
||||
Optional<FAQChannelGroupCommand> existingChannelGroupCommandOptional = command.getGroupResponses()
|
||||
.stream()
|
||||
.filter(faqChannelGroupCommand -> faqChannelGroupCommand.getChannelGroup().getChannelGroup()
|
||||
.equals(faqChannelGroup.getChannelGroup()))
|
||||
.findAny();
|
||||
if(command.getGlobal() && !faqChannelGroup.getGlobal()) {
|
||||
log.warn("Command {} is configured as global, but to be used channel group is not defined as the global channel group.", command.getId());
|
||||
throw new GlobalFAQCommandConfigMismatchException(command.getName());
|
||||
}
|
||||
if(faqChannelGroup.getGlobal() && !command.getGlobal()) {
|
||||
log.warn("Channel group to be used is configured as global, but command {} is not. This is an illegal combination.", command.getId());
|
||||
throw new GlobalFAQCommandConfigMismatchException(command.getName());
|
||||
}
|
||||
if(existingChannelGroupCommandOptional.isPresent()) {
|
||||
FAQChannelGroupCommand existing = existingChannelGroupCommandOptional.get();
|
||||
log.debug("Updating faq channel group command {} for channel group {} in server {}.", command.getId(), faqChannelGroup.getId(), server.getId());
|
||||
updateFAQChannelGroupCommand(existing, responseConfig);
|
||||
} else {
|
||||
log.debug("Creating new faq channel group command for command {} in channel group {} in server {}.", command.getId(), faqChannelGroup.getId(), server.getId());
|
||||
createFAQChannelGroupCommand(command, faqChannelGroup, responseConfig);
|
||||
}
|
||||
}
|
||||
|
||||
private void createFAQChannelGroupCommand(FAQCommand faqCommand, FAQChannelGroup faqChannelGroup, FaqCommandResponseConfig responseConfig) {
|
||||
FAQChannelGroupCommand channelGroupCommand = faqChannelGroupCommandManagementServiceBean.createFAQChannelGroupCommand(faqCommand, faqChannelGroup);
|
||||
log.debug("Creating {} messages.", responseConfig.getMessages().size());
|
||||
for (int i = 0; i < responseConfig.getMessages().size(); i++) {
|
||||
createFAQResponses(channelGroupCommand, responseConfig.getMessages().get(i), i);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFAQChannelGroupCommand(FAQChannelGroupCommand existing, FaqCommandResponseConfig responseConfig) {
|
||||
Set<Integer> positions = responseConfig
|
||||
.getMessages()
|
||||
.stream()
|
||||
.map(FaqCommandResponseMessageConfig::getPosition)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if(positions.size() != responseConfig.getMessages().size()) {
|
||||
throw new FAQCommandResponseDuplicatedPositionException(existing.getCommand().getName(), responseConfig.getChannelGroupName());
|
||||
}
|
||||
|
||||
List<FAQCommandResponse> existingResponses = existing
|
||||
.getResponses()
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(o -> o.getId().getPosition()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<FaqCommandResponseMessageConfig> configMessages = responseConfig
|
||||
.getMessages()
|
||||
.stream()
|
||||
.sorted(Comparator.comparingInt(FaqCommandResponseMessageConfig::getPosition))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// re-use the existing entries, and only update if necessary, so have the appropriate update timestamp
|
||||
int iterations = Math.min(configMessages.size(), existingResponses.size());
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
mergeConfig(existingResponses.get(i), configMessages.get(i));
|
||||
}
|
||||
|
||||
// remove all the rest, as they were not specified in the config
|
||||
for(int i = iterations; i < existingResponses.size(); i++) {
|
||||
faqCommandResponseManagementServiceBean.deleteCommandResponse(existingResponses.get(i));
|
||||
}
|
||||
|
||||
for(int i = iterations; i < configMessages.size(); i++) {
|
||||
createFAQResponses(existing, configMessages.get(i), i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createFAQResponses(FAQChannelGroupCommand existing, FaqCommandResponseMessageConfig config, int position) {
|
||||
faqCommandResponseManagementServiceBean.createResponse(config, position, existing);
|
||||
}
|
||||
|
||||
private void mergeConfig(FAQCommandResponse existingResponse, FaqCommandResponseMessageConfig config) {
|
||||
if(existingResponse.getAdditionalMessage() == null || !existingResponse.getAdditionalMessage().equals(config.getAdditionalMessage())) {
|
||||
existingResponse.setAdditionalMessage(config.getAdditionalMessage());
|
||||
}
|
||||
FaqCommandResponseEmbedConfig embed = config.getEmbed();
|
||||
if(embed != null) {
|
||||
if(existingResponse.getDescription() == null || !existingResponse.getDescription().equals(embed.getDescription())) {
|
||||
existingResponse.setDescription(embed.getDescription());
|
||||
}
|
||||
if(existingResponse.getImageURL() == null || !existingResponse.getImageURL().equals(embed.getImageUrl())) {
|
||||
existingResponse.setImageURL(embed.getImageUrl());
|
||||
}
|
||||
if(existingResponse.getAuthorUserId() == null || !existingResponse.getAuthorUserId().equals(embed.getAuthor().getUserId())) {
|
||||
existingResponse.setAuthorUserId(embed.getAuthor().getUserId());
|
||||
}
|
||||
mergeEmbedColor(existingResponse, embed);
|
||||
} else {
|
||||
existingResponse.setDescription(null);
|
||||
existingResponse.setImageURL(null);
|
||||
existingResponse.setAuthorUserId(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeEmbedColor(FAQCommandResponse existingResponse, FaqCommandResponseEmbedConfig embed) {
|
||||
FaqCommandResponseEmbedColorConfig embedColor = embed.getColor();
|
||||
if(existingResponse.getBlue() == null || !existingResponse.getBlue().equals(embedColor.getBlue())) {
|
||||
existingResponse.setBlue(embedColor.getBlue());
|
||||
}
|
||||
if(existingResponse.getGreen() == null || !existingResponse.getGreen().equals(embedColor.getGreen())){
|
||||
existingResponse.setGreen(embedColor.getGreen());
|
||||
}
|
||||
if(existingResponse.getRed() == null || !existingResponse.getRed().equals(embedColor.getRed())) {
|
||||
existingResponse.setRed(embedColor.getRed());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFAQCommand(FaqCommandConfig faqCommandConfig, FAQCommand command){
|
||||
if(!faqCommandConfig.getGlobal().equals(command.getGlobal())) {
|
||||
command.setGlobal(faqCommandConfig.getGlobal());
|
||||
}
|
||||
Set<String> existingAlias;
|
||||
if(command.getAliases() != null) {
|
||||
existingAlias = command
|
||||
.getAliases()
|
||||
.stream()
|
||||
.map(faqCommandAlias -> faqCommandAlias.getId().getAlias())
|
||||
.collect(Collectors.toSet());
|
||||
} else {
|
||||
existingAlias = new HashSet<>();
|
||||
}
|
||||
|
||||
Set<String> toBeConfigured;
|
||||
if(faqCommandConfig.getAliases() != null) {
|
||||
toBeConfigured = new HashSet<>(faqCommandConfig.getAliases());
|
||||
} else {
|
||||
toBeConfigured = new HashSet<>();
|
||||
}
|
||||
Set<String> aliasNeedingCreation = new HashSet<>(toBeConfigured);
|
||||
aliasNeedingCreation.removeAll(existingAlias);
|
||||
log.info("Creating {} aliases for command {}.", aliasNeedingCreation.size(), command.getId());
|
||||
createFAQCommandAlias(command, aliasNeedingCreation);
|
||||
Set<String> aliasToDelete = new HashSet<>(existingAlias);
|
||||
aliasToDelete.removeAll(toBeConfigured);
|
||||
log.info("Removing {} aliases for command {}.", aliasToDelete.size(), command.getId());
|
||||
deleteFAQCommandAlias(command, aliasToDelete);
|
||||
}
|
||||
|
||||
private void createFAQCommandAlias(FAQCommand command, Collection<String> aliasNames) {
|
||||
aliasNames.forEach(s -> faqCommandAliasManagementService.createFAQCommandAlias(command, s));
|
||||
}
|
||||
|
||||
private void deleteFAQCommandAlias(FAQCommand command, Collection<String> aliasName) {
|
||||
aliasName.forEach(s -> faqCommandAliasManagementService.deleteFAQCommandAlias(command, s));
|
||||
}
|
||||
|
||||
private FAQCommand createFAQCommand(FaqCommandConfig faqCommandConfig, AServer server) {
|
||||
FAQCommand faqCommand = faqCommandManagementServiceBean.createFAQCommand(faqCommandConfig, server);
|
||||
if(faqCommandConfig.getAliases() != null) {
|
||||
createFAQCommandAlias(faqCommand, faqCommandConfig.getAliases());
|
||||
}
|
||||
return faqCommand;
|
||||
}
|
||||
|
||||
private void fillDefaults(List<FaqCommandConfig> commands) {
|
||||
commands
|
||||
.forEach(faqCommandConfig -> {
|
||||
if(faqCommandConfig.getGlobal() == null) {
|
||||
faqCommandConfig.setGlobal(Boolean.FALSE);
|
||||
}
|
||||
faqCommandConfig
|
||||
.getResponses()
|
||||
.forEach(faqCommandResponse -> faqCommandResponse
|
||||
.getMessages().forEach(
|
||||
faqCommandResponseMessage -> {
|
||||
FaqCommandResponseEmbedConfig embed = faqCommandResponseMessage.getEmbed();
|
||||
if(embed == null) {
|
||||
return;
|
||||
}
|
||||
FaqCommandResponseEmbedColorConfig color = embed.getColor();
|
||||
if(color == null) {
|
||||
color = FaqCommandResponseEmbedColorConfig.builder().build();
|
||||
embed.setColor(color);
|
||||
}
|
||||
if(color.getBlue() == null || color.getBlue() == 0) {
|
||||
color.setBlue(0);
|
||||
}
|
||||
if(color.getRed() == null || color.getRed() == 0) {
|
||||
color.setRed(0);
|
||||
}
|
||||
if(color.getGreen() == null || color.getGreen() == 0) {
|
||||
color.setGreen(0);
|
||||
}
|
||||
if(embed.getAuthor().getUseBot() != null && embed.getAuthor().getUseBot()) {
|
||||
log.debug("Setting the BOT as the author.");
|
||||
embed.getAuthor().setUserId(userService.getSelfUser().getIdLong());
|
||||
}
|
||||
}
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
private Map<String, FAQCommand> getCommandMappings(List<FAQCommand> commands) {
|
||||
return commands
|
||||
.stream()
|
||||
.collect(Collectors.toMap(FAQCommand::getName, Function.identity()));
|
||||
}
|
||||
|
||||
private Map<String, FAQCommand> getAliasMappings(List<FAQCommand> commands) {
|
||||
Map<String, FAQCommand> commandMappings = commands
|
||||
.stream()
|
||||
.collect(Collectors.toMap(FAQCommand::getName, Function.identity()));
|
||||
commands
|
||||
.forEach(faqCommand -> faqCommand
|
||||
.getAliases()
|
||||
.forEach(faqCommandAlias ->
|
||||
commandMappings.put(faqCommandAlias.getId().getAlias(), faqCommand)));
|
||||
return commandMappings;
|
||||
}
|
||||
|
||||
public List<FaqCommandConfig> loadFAQCommandsFromJson(String json) {
|
||||
FaqCommandConfig[] faqCommandConfigs = gson.fromJson(json, FaqCommandConfig[].class);
|
||||
return Arrays.asList(faqCommandConfigs);
|
||||
}
|
||||
|
||||
public void deleteFAQCommand(String commandToDelete, AServer server) {
|
||||
FAQCommand toDelete = faqCommandManagementServiceBean.findByNameAndServer(commandToDelete, server)
|
||||
.orElseThrow(() -> new FAQCommandNotFoundException(commandToDelete));
|
||||
faqCommandManagementServiceBean.deleteFAQCommand(toDelete);
|
||||
}
|
||||
|
||||
public String exportFAQConfig(String commandToExport, AServer server) {
|
||||
FAQCommand toExport = faqCommandManagementServiceBean.findByNameAndServer(commandToExport, server)
|
||||
.orElseThrow(() -> new FAQCommandNotFoundException(commandToExport));
|
||||
return configConverter.serializeCommands(Arrays.asList(toExport));
|
||||
}
|
||||
|
||||
public String exportFAQConfig(AServer server) {
|
||||
List<FAQCommand> toExport = faqCommandManagementServiceBean.findAllInServer(server);
|
||||
log.info("Exporting {} FAQ commands for server {}.", toExport.size(), server.getId());
|
||||
return configConverter.serializeCommands(toExport);
|
||||
}
|
||||
|
||||
public ListFAQCommandsModel getCommandListingForServer(AServer server) {
|
||||
List<FAQCommand> faqCommands = faqCommandManagementServiceBean.findAllInServer(server);
|
||||
return listFAQCommandsModelConverter.fromFAQCommands(faqCommands);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.exception.FAQCommandNotFoundException;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.faquses.FAQCommandResponseUsage;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.faquses.FAQCommandUsage;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.faquses.FAQUsageModel;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.service.management.FAQCommandManagementServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class FAQUsageServiceBean {
|
||||
|
||||
@Autowired
|
||||
private FAQCommandManagementServiceBean faqCommandManagementServiceBean;
|
||||
|
||||
public FAQUsageModel getFAQUsageModel(AServer server, String faqCommandName) {
|
||||
FAQCommand faqCommand = faqCommandManagementServiceBean.findByNameAndServer(faqCommandName, server)
|
||||
.orElseThrow(() -> new FAQCommandNotFoundException(faqCommandName));
|
||||
List<FAQCommandUsage> commandUsages = Arrays.asList(getFAQCommandUsage(faqCommand));
|
||||
return FAQUsageModel
|
||||
.builder()
|
||||
.uses(commandUsages)
|
||||
.build();
|
||||
}
|
||||
|
||||
public FAQUsageModel getFAQUsageModel(AServer server) {
|
||||
List<FAQCommand> allCommands = faqCommandManagementServiceBean.findAllInServer(server);
|
||||
List<FAQCommandUsage> commandUsages = allCommands
|
||||
.stream()
|
||||
.map(this::getFAQCommandUsage)
|
||||
.collect(Collectors.toList());
|
||||
return FAQUsageModel
|
||||
.builder()
|
||||
.uses(commandUsages)
|
||||
.build();
|
||||
}
|
||||
|
||||
private FAQCommandUsage getFAQCommandUsage(FAQCommand command) {
|
||||
List<FAQCommandResponseUsage> channelGroupUsages = command
|
||||
.getGroupResponses()
|
||||
.stream()
|
||||
.map(this::getFAQCommandResponseUsage)
|
||||
.collect(Collectors.toList());
|
||||
return FAQCommandUsage
|
||||
.builder()
|
||||
.faqCommandName(command.getName())
|
||||
.faqChannelGroupUsages(channelGroupUsages)
|
||||
.build();
|
||||
}
|
||||
|
||||
private FAQCommandResponseUsage getFAQCommandResponseUsage(FAQChannelGroupCommand groupCommand) {
|
||||
return FAQCommandResponseUsage
|
||||
.builder()
|
||||
.uses(groupCommand.getUses())
|
||||
.channelGroupName(groupCommand.getChannelGroup().getChannelGroup().getGroupName())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.JSONValidationResult;
|
||||
import dev.sheldan.abstracto.core.service.JSONValidationService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class FAQValidationServiceBean {
|
||||
|
||||
@Autowired
|
||||
private JSONValidationService jsonValidationService;
|
||||
|
||||
@Value("classpath:validation/createScheme.json")
|
||||
private Resource creationValidationResource;
|
||||
|
||||
private String creationValidationSchema;
|
||||
|
||||
public JSONValidationResult validateJSONForCreation(String json) {
|
||||
log.info("Validating FAQ creation schema.");
|
||||
return jsonValidationService.validateJSONSchema(creationValidationSchema, json);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
try {
|
||||
this.creationValidationSchema = IOUtils.toString(creationValidationResource.getInputStream(), StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to load validation schemes.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroup;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.ChannelGroupCommandId;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.repository.FAQChannelGroupCommandRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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 FAQChannelGroupCommandManagementServiceBean {
|
||||
|
||||
@Autowired
|
||||
private FAQChannelGroupCommandRepository repository;
|
||||
|
||||
@Autowired
|
||||
private FAQCommandResponseManagementServiceBean faqCommandResponseManagementServiceBean;
|
||||
|
||||
public FAQChannelGroupCommand createFAQChannelGroupCommand(FAQCommand command, FAQChannelGroup channelGroup) {
|
||||
FAQChannelGroupCommand groupCommand = FAQChannelGroupCommand
|
||||
.builder()
|
||||
.command(command)
|
||||
.uses(0)
|
||||
.channelGroup(channelGroup)
|
||||
.groupCommandId(new ChannelGroupCommandId(channelGroup.getId(), command.getId()))
|
||||
.build();
|
||||
command.getGroupResponses().add(groupCommand);
|
||||
log.info("Creating FAQ channel group command for command {} in channel group {}.", command.getId(), channelGroup.getId());
|
||||
return repository.save(groupCommand);
|
||||
}
|
||||
|
||||
public FAQChannelGroupCommand findChannelGroupCommand(Long commandId, Long channelGroupId) {
|
||||
ChannelGroupCommandId id = ChannelGroupCommandId
|
||||
.builder()
|
||||
.commandId(commandId)
|
||||
.channelGroupId(channelGroupId)
|
||||
.build();
|
||||
return repository.findById(id)
|
||||
.orElseThrow(() -> new AbstractoRunTimeException("Channel group command not found."));
|
||||
}
|
||||
|
||||
public void deleteFAQChannelGroupCommands(List<FAQChannelGroupCommand> faqChannelGroupCommandList) {
|
||||
log.info("Deleting {} faq channel group commands.", faqChannelGroupCommandList.size());
|
||||
faqChannelGroupCommandList
|
||||
.forEach(faqChannelGroupCommand -> faqCommandResponseManagementServiceBean.deleteCommandResponses(faqChannelGroupCommand.getResponses()));
|
||||
repository.deleteAll(faqChannelGroupCommandList);
|
||||
}
|
||||
|
||||
public void deleteFAQChannelGroupCommand(FAQCommand command, FAQChannelGroup channelGroup) {
|
||||
FAQChannelGroupCommand channelGroupCommand = findChannelGroupCommand(command.getId(), channelGroup.getId());
|
||||
faqCommandResponseManagementServiceBean.deleteCommandResponses(channelGroupCommand.getResponses());
|
||||
log.info("Deleting faq channel group command for command {} in channel group {}.", command.getId(), channelGroup.getId());
|
||||
repository.delete(channelGroupCommand);
|
||||
}
|
||||
|
||||
public List<FAQChannelGroupCommand> getGroupCommandsForBasicChannelGroups(List<AChannelGroup> channelGroups) {
|
||||
List<Long> channelGroupIds = channelGroups
|
||||
.stream()
|
||||
.map(AChannelGroup::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return getGroupCommandsForChannelGroupIds(channelGroupIds);
|
||||
}
|
||||
|
||||
public List<FAQChannelGroupCommand> getGroupCommandsForChannelGroupIds(List<Long> channelGroupIds) {
|
||||
return repository.findByChannelGroup_IdIn(channelGroupIds);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroup;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.repository.FAQChannelGroupRepository;
|
||||
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 FAQChannelGroupManagementServiceBean {
|
||||
@Autowired
|
||||
private FAQChannelGroupRepository faqChannelGroupRepository;
|
||||
|
||||
public Optional<FAQChannelGroup> findFAQChannelGroupByIdOptional(Long id) {
|
||||
return faqChannelGroupRepository.findById(id);
|
||||
}
|
||||
|
||||
public FAQChannelGroup getFAQChannelGroupById(Long id) {
|
||||
return findFAQChannelGroupByIdOptional(id).orElseThrow(() -> new AbstractoRunTimeException("FAQ Channel group not found."));
|
||||
}
|
||||
|
||||
public FAQChannelGroup createFAQChannelGroup(AChannelGroup channelGroup) {
|
||||
FAQChannelGroup faqChannelGroup = FAQChannelGroup
|
||||
.builder()
|
||||
.channelGroup(channelGroup)
|
||||
.global(false)
|
||||
.id(channelGroup.getId())
|
||||
.build();
|
||||
log.info("Creating FAQ channel group for channel group {} in server {}.", channelGroup.getId(), channelGroup.getServer().getId());
|
||||
return faqChannelGroupRepository.save(faqChannelGroup);
|
||||
}
|
||||
|
||||
public Optional<FAQChannelGroup> getGlobalChannelGroup(AServer server) {
|
||||
return faqChannelGroupRepository.findByChannelGroup_ServerAndGlobalTrue(server);
|
||||
}
|
||||
|
||||
public void deleteFAQChannelGroup(AChannelGroup channelGroup) {
|
||||
log.info("Deleting FAQ channel group {} in server {}.", channelGroup.getId(), channelGroup.getServer().getId());
|
||||
faqChannelGroupRepository.delete(getFAQChannelGroupById(channelGroup.getId()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandAlias;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.FAQCommandAliasId;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.repository.FAQCommandAliasRepository;
|
||||
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 FAQCommandAliasManagementService {
|
||||
|
||||
@Autowired
|
||||
private FAQCommandAliasRepository commandAliasRepository;
|
||||
|
||||
public FAQCommandAlias createFAQCommandAlias(FAQCommand command, String aliasName) {
|
||||
FAQCommandAlias alias = FAQCommandAlias
|
||||
.builder()
|
||||
.command(command)
|
||||
.id(FAQCommandAliasId
|
||||
.builder()
|
||||
.faqCommandId(command.getId())
|
||||
.alias(aliasName)
|
||||
.build())
|
||||
.build();
|
||||
log.info("Creating faq command alias for command {}.", command.getId());
|
||||
return commandAliasRepository.save(alias);
|
||||
}
|
||||
|
||||
public void deleteFAQCommandAlias(FAQCommand command, String aliasName) {
|
||||
FAQCommandAliasId aliasId = FAQCommandAliasId
|
||||
.builder()
|
||||
.faqCommandId(command.getId())
|
||||
.alias(aliasName)
|
||||
.build();
|
||||
log.info("Deleting faq command alias for command {}.", command.getId());
|
||||
commandAliasRepository.deleteById(aliasId);
|
||||
}
|
||||
|
||||
public void deleteFAQCommandAliases(FAQCommand faqCommand){
|
||||
log.info("deleting all FAQ command aliases for command {}.", faqCommand.getId());
|
||||
commandAliasRepository.deleteAll(faqCommand.getAliases());
|
||||
}
|
||||
|
||||
public Optional<FAQCommandAlias> findByNameAndServer(String name, AServer server) {
|
||||
return commandAliasRepository.findById_AliasAndCommand_Server(name, server);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.config.FaqCommandConfig;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.repository.FAQCommandRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class FAQCommandManagementServiceBean {
|
||||
@Autowired
|
||||
private FAQCommandRepository repository;
|
||||
|
||||
@Autowired
|
||||
private FAQCommandAliasManagementService faqCommandAliasManagementService;
|
||||
|
||||
@Autowired
|
||||
private FAQChannelGroupCommandManagementServiceBean faqChannelGroupCommandManagementServiceBean;
|
||||
|
||||
public Optional<FAQCommand> findByNameAndServer(String name, AServer server) {
|
||||
return repository.findByNameEqualsIgnoreCaseAndServer(name, server);
|
||||
}
|
||||
|
||||
public List<FAQCommand> findAllInServer(AServer server) {
|
||||
return repository.findByServer(server);
|
||||
}
|
||||
|
||||
public FAQCommand createFAQCommand(String name, Boolean global, AServer server) {
|
||||
FAQCommand command = FAQCommand
|
||||
.builder()
|
||||
.name(name)
|
||||
.server(server)
|
||||
.global(global)
|
||||
.build();
|
||||
log.info("Creating FAQ Command in server {}.", server.getId());
|
||||
return repository.save(command);
|
||||
}
|
||||
|
||||
public FAQCommand createFAQCommand(FaqCommandConfig faqCommandConfig, AServer server) {
|
||||
return createFAQCommand(faqCommandConfig.getFaqCommandName(), faqCommandConfig.getGlobal(), server);
|
||||
}
|
||||
|
||||
public void deleteFAQCommand(FAQCommand faqCommand) {
|
||||
faqChannelGroupCommandManagementServiceBean.deleteFAQChannelGroupCommands(faqCommand.getGroupResponses());
|
||||
faqCommandAliasManagementService.deleteFAQCommandAliases(faqCommand);
|
||||
log.info("Deleting FAQ command {}.", faqCommand.getId());
|
||||
repository.delete(faqCommand);
|
||||
}
|
||||
|
||||
public List<FAQCommand> findGlobalCommandsInServer(AServer server) {
|
||||
return repository.findByServerAndGlobalTrue(server);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package dev.sheldan.oneplus.bot.modules.faq.service.management;
|
||||
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.config.FaqCommandResponseEmbedColorConfig;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.config.FaqCommandResponseEmbedConfig;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.command.config.FaqCommandResponseMessageConfig;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandResponse;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.CommandResponseId;
|
||||
import dev.sheldan.oneplus.bot.modules.faq.repository.FAQCommandResponseRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class FAQCommandResponseManagementServiceBean {
|
||||
|
||||
@Autowired
|
||||
private FAQCommandResponseRepository responseRepository;
|
||||
|
||||
public FAQCommandResponse createResponse(FaqCommandResponseMessageConfig config, int position, FAQChannelGroupCommand groupCommand) {
|
||||
CommandResponseId id = CommandResponseId
|
||||
.builder()
|
||||
.commandId(groupCommand.getCommand().getId())
|
||||
.channelGroupId(groupCommand.getChannelGroup().getId())
|
||||
.position(position)
|
||||
.build();
|
||||
FAQCommandResponse.FAQCommandResponseBuilder builder = FAQCommandResponse
|
||||
.builder()
|
||||
.additionalMessage(config.getAdditionalMessage())
|
||||
.id(id);
|
||||
|
||||
FaqCommandResponseEmbedConfig embedConfig = config.getEmbed();
|
||||
if(embedConfig != null) {
|
||||
log.debug("The response to create in command {} has an embed.", groupCommand.getCommand().getId());
|
||||
FaqCommandResponseEmbedColorConfig colorConfig = embedConfig.getColor();
|
||||
if(colorConfig != null) {
|
||||
builder = builder.blue(colorConfig.getBlue())
|
||||
.red(colorConfig.getRed())
|
||||
.green(colorConfig.getGreen());
|
||||
}
|
||||
if(embedConfig.getAuthor() != null) {
|
||||
builder = builder.authorUserId(embedConfig.getAuthor().getUserId());
|
||||
}
|
||||
builder = builder.description(embedConfig.getDescription())
|
||||
.imageURL(embedConfig.getImageUrl());
|
||||
}
|
||||
log.info("Creating faq command response for command {} in server {}. There area already {} responses.",
|
||||
groupCommand.getCommand().getId(), groupCommand.getCommand().getServer().getId(), groupCommand.getResponses().size());
|
||||
FAQCommandResponse builtCommand = builder.build();
|
||||
builtCommand.setGroupCommand(groupCommand);
|
||||
groupCommand.getResponses().add(builtCommand);
|
||||
return responseRepository.save(builtCommand);
|
||||
}
|
||||
|
||||
public void deleteCommandResponse(FAQCommandResponse response) {
|
||||
log.info("Deleting fq command response for command {} in channel group {}.",
|
||||
response.getGroupCommand().getCommand().getId(), response.getGroupCommand().getChannelGroup().getId());
|
||||
responseRepository.delete(response);
|
||||
}
|
||||
|
||||
public void deleteCommandResponses(List<FAQCommandResponse> responseList) {
|
||||
log.info("Deleting {} responses.", responseList.size());
|
||||
responseRepository.deleteAll(responseList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
abstracto.featureFlags.faq.featureName=faq
|
||||
abstracto.featureFlags.faq.enabled=false
|
||||
|
||||
abstracto.faq.globalChannelGroupName=global
|
||||
|
||||
abstracto.featureModes.faqUses.featureName=faq
|
||||
abstracto.featureModes.faqUses.mode=faqUses
|
||||
abstracto.featureModes.faqUses.enabled=false
|
||||
@@ -0,0 +1,11 @@
|
||||
<?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.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
|
||||
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?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.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="faq_channel_group_type-insertion">
|
||||
<insert tableName="channel_group_type">
|
||||
<column name="group_type_key" value="faq"/>
|
||||
<column name="allows_channel_in_multiple" value="true"/>
|
||||
<column name="allows_commands_in_multiple" value="false"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<property name="faqFeature" value="(SELECT id FROM feature WHERE key = 'faq')"/>
|
||||
<property name="faqModule" value="(SELECT id FROM module WHERE name = 'faqModule')"/>
|
||||
<changeSet author="Sheldan" id="faq-commands" >
|
||||
<insert tableName="command">
|
||||
<column name="name" value="faq"/>
|
||||
<column name="module_id" valueComputed="${faqModule}"/>
|
||||
<column name="feature_id" valueComputed="${faqFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="importFAQ"/>
|
||||
<column name="module_id" valueComputed="${faqModule}"/>
|
||||
<column name="feature_id" valueComputed="${faqFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="deleteFAQ"/>
|
||||
<column name="module_id" valueComputed="${faqModule}"/>
|
||||
<column name="feature_id" valueComputed="${faqFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="exportFAQ"/>
|
||||
<column name="module_id" valueComputed="${faqModule}"/>
|
||||
<column name="feature_id" valueComputed="${faqFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="listFAQCommands"/>
|
||||
<column name="module_id" valueComputed="${faqModule}"/>
|
||||
<column name="feature_id" valueComputed="${faqFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="FAQUsage"/>
|
||||
<column name="module_id" valueComputed="${faqModule}"/>
|
||||
<column name="feature_id" valueComputed="${faqFeature}"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?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.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="feature.xml" relativeToChangelogFile="true"/>
|
||||
<include file="module.xml" relativeToChangelogFile="true"/>
|
||||
<include file="command.xml" relativeToChangelogFile="true"/>
|
||||
<include file="channel_group_type.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?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.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="faq_feature-insertion">
|
||||
<insert tableName="feature">
|
||||
<column name="key" value="faq"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?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.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="faq-module-insertion">
|
||||
<insert tableName="module">
|
||||
<column name="name" value="faqModule"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="faq_channel_group-table">
|
||||
<createTable tableName="faq_channel_group">
|
||||
<column name="id" type="BIGINT">
|
||||
<constraints nullable="false" primaryKey="true" primaryKeyName="pk_faq_channel_group"/>
|
||||
</column>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="global" type="BOOLEAN">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
<addForeignKeyConstraint baseColumnNames="id" baseTableName="faq_channel_group" constraintName="fk_faq_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 faq_channel_group_update_trigger ON faq_channel_group;
|
||||
CREATE TRIGGER faq_channel_group_update_trigger BEFORE UPDATE ON faq_channel_group FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS faq_channel_group_insert_trigger ON faq_channel_group;
|
||||
CREATE TRIGGER faq_channel_group_insert_trigger BEFORE INSERT ON faq_channel_group FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?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.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="faq_channel_group_command-table">
|
||||
<createTable tableName="faq_channel_group_command">
|
||||
<column name="channel_group_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="command_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="uses" type="INTEGER">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
<addPrimaryKey columnNames="channel_group_id, command_id" tableName="faq_channel_group_command" constraintName="pk_faq_channel_group_command" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="channel_group_id" baseTableName="faq_channel_group_command" constraintName="fk_faq_channel_group_command_channel_group"
|
||||
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
|
||||
referencedColumnNames="id" referencedTableName="faq_channel_group" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="command_id" baseTableName="faq_channel_group_command" constraintName="fk_faq_channel_group_command_faq_command"
|
||||
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
|
||||
referencedColumnNames="id" referencedTableName="faq_command" validate="true"/>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS faq_channel_group_command_insert_trigger ON faq_channel_group_command;
|
||||
CREATE TRIGGER faq_channel_group_command_insert_trigger BEFORE INSERT ON faq_channel_group_command FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,45 @@
|
||||
<?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.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="faq_command-table">
|
||||
<createTable tableName="faq_command">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints nullable="false" primaryKey="true" primaryKeyName="pk_faq_command"/>
|
||||
</column>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="name" type="VARCHAR(30)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="global" type="BOOLEAN">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="server_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
<createIndex indexName="idx_faq_command_name" tableName="faq_command">
|
||||
<column name="name"/>
|
||||
<column name="server_id"/>
|
||||
</createIndex>
|
||||
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="faq_command" constraintName="fk_faq_command_server"
|
||||
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id"
|
||||
referencedTableName="server" validate="true"/>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS faq_command_update_trigger ON faq_command;
|
||||
CREATE TRIGGER faq_command_update_trigger BEFORE UPDATE ON faq_command FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS faq_command_insert_trigger ON faq_command;
|
||||
CREATE TRIGGER faq_command_insert_trigger BEFORE INSERT ON faq_command FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="faq_command_alias-table">
|
||||
<createTable tableName="faq_command_alias">
|
||||
<column name="command_id" type="BIGINT">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="alias" type="VARCHAR(30)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createIndex indexName="idx_faq_command_alias_name" tableName="faq_command_alias">
|
||||
<column name="alias"/>
|
||||
</createIndex>
|
||||
<addPrimaryKey tableName="faq_command_alias" columnNames="command_id, alias" constraintName="pk_faq_command_alias"/>
|
||||
|
||||
<addForeignKeyConstraint baseColumnNames="command_id" baseTableName="faq_command_alias" constraintName="faq_command_alias_command"
|
||||
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id"
|
||||
referencedTableName="faq_command" validate="true"/>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS faq_command_update_trigger ON faq_command;
|
||||
CREATE TRIGGER faq_command_update_trigger BEFORE UPDATE ON faq_command FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS faq_command_alias_insert_trigger ON faq_command_alias;
|
||||
CREATE TRIGGER faq_command_alias_insert_trigger BEFORE INSERT ON faq_command_alias FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?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.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="faq_command_response-table">
|
||||
<createTable tableName="faq_command_response">
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="description" type="VARCHAR(2000)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="additional_message" type="VARCHAR(2000)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="image_url" type="VARCHAR(2000)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="red" type="INT" />
|
||||
<column name="green" type="INT" />
|
||||
<column name="blue" type="INT" />
|
||||
<column name="author_user_id" type="BIGINT" />
|
||||
<column name="position" type="INT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="channel_group_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="command_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
<addPrimaryKey tableName="faq_command_response" columnNames="channel_group_id, command_id, position" constraintName="pk_faq_command_response"/>
|
||||
<addForeignKeyConstraint baseColumnNames="channel_group_id" baseTableName="faq_channel_group_command" constraintName="fk_faq_command_response_faq_channel_group"
|
||||
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
|
||||
referencedColumnNames="id" referencedTableName="faq_channel_group" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="command_id" baseTableName="faq_channel_group_command" constraintName="fk_faq_command_response_faq_command"
|
||||
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
|
||||
referencedColumnNames="id" referencedTableName="faq_command" validate="true"/>
|
||||
<createIndex indexName="idx_faq_command_response_group_command" tableName="faq_command_response">
|
||||
<column name="command_id"/>
|
||||
<column name="channel_group_id"/>
|
||||
</createIndex>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS faq_command_response_update_trigger ON faq_command_response;
|
||||
CREATE TRIGGER faq_command_response_update_trigger BEFORE UPDATE ON faq_command_response FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS faq_command_response_insert_trigger ON faq_command_response;
|
||||
CREATE TRIGGER faq_command_response_insert_trigger BEFORE INSERT ON faq_command_response FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?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.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="faq_channel_group.xml" relativeToChangelogFile="true"/>
|
||||
<include file="faq_command.xml" relativeToChangelogFile="true"/>
|
||||
<include file="faq_command_alias.xml" relativeToChangelogFile="true"/>
|
||||
<include file="faq_channel_group_command.xml" relativeToChangelogFile="true"/>
|
||||
<include file="faq_command_response.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
<?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.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="1.4.4/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,189 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 30,
|
||||
"items": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"faqCommandName": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 30,
|
||||
"pattern": "\\w*"
|
||||
},
|
||||
"global": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"aliases": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 20,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 30,
|
||||
"pattern": "\\w*"
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 255,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"channelGroupName": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 20,
|
||||
"pattern": "\\w*"
|
||||
},
|
||||
"messages": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 3,
|
||||
"items": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"position": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 2
|
||||
},
|
||||
"additionalMessage": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 2000
|
||||
},
|
||||
"embed": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 2000
|
||||
},
|
||||
"imageUrl": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 2000,
|
||||
"pattern": "\\s*https?:\/\/\\S+"
|
||||
},
|
||||
"color": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"red": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"default": 0,
|
||||
"maximum": 255
|
||||
},
|
||||
"green": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"default": 0,
|
||||
"maximum": 255
|
||||
},
|
||||
"blue": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"default": 0,
|
||||
"maximum": 255
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"red",
|
||||
"green",
|
||||
"blue"
|
||||
]
|
||||
},
|
||||
"author": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"userId": {
|
||||
"minimum": 1,
|
||||
"maximum": 18446744073709551615,
|
||||
"type": "integer"
|
||||
},
|
||||
"useBot": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"anyOf": [
|
||||
{
|
||||
"required": [
|
||||
"userId"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"useBot"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"anyOf": [
|
||||
{
|
||||
"required": [
|
||||
"description",
|
||||
"author"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"author"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"anyOf": [
|
||||
{
|
||||
"required": [
|
||||
"additionalMessage",
|
||||
"position"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"embed",
|
||||
"position"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"additionalMessage",
|
||||
"embed",
|
||||
"position"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"channelGroupName",
|
||||
"messages"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"faqCommandName",
|
||||
"responses"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.oneplus.bot.application.modules</groupId>
|
||||
<artifactId>oneplus-bot-modules</artifactId>
|
||||
<version>1.3.11</version>
|
||||
<version>1.4.4</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.oneplus.bot.modules.news.commands;
|
||||
package dev.sheldan.oneplus.bot.modules.news.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.oneplus.bot.modules.news.commands;
|
||||
package dev.sheldan.oneplus.bot.modules.news.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.oneplus.bot.application</groupId>
|
||||
<artifactId>application</artifactId>
|
||||
<version>1.3.11</version>
|
||||
<version>1.4.4</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<module>news</module>
|
||||
<module>setup</module>
|
||||
<module>referral</module>
|
||||
<module>faq</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.oneplus.bot.application.modules</groupId>
|
||||
<artifactId>oneplus-bot-modules</artifactId>
|
||||
<version>1.3.11</version>
|
||||
<version>1.4.4</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>oneplus-bot-modules</artifactId>
|
||||
<groupId>dev.sheldan.oneplus.bot.application.modules</groupId>
|
||||
<version>1.3.11</version>
|
||||
<version>1.4.4</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.oneplus.bot</groupId>
|
||||
<artifactId>oneplusbot</artifactId>
|
||||
<version>1.3.11</version>
|
||||
<version>1.4.4</version>
|
||||
</parent>
|
||||
|
||||
<groupId>dev.sheldan.oneplus.bot.application</groupId>
|
||||
<artifactId>application</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>1.3.11</version>
|
||||
<version>1.4.4</version>
|
||||
<modules>
|
||||
<module>executable</module>
|
||||
<module>oneplus-bot-customizations</module>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user