mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-03-24 13:44:33 +00:00
added setup command which includes an interactive process in order to setup features
the current supported features are post targets and system config the wizard includes a summary step where the user can confirm the changes removed some unnecessary validators, which were basically just validating the system config from some features fixed post target name
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
package dev.sheldan.abstracto.core.commands.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatures;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.service.management.FeatureManagementService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.interactive.InteractiveService;
|
||||
import dev.sheldan.abstracto.core.models.AServerChannelUserId;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.SetupService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class Setup extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private InteractiveService interactiveService;
|
||||
|
||||
@Autowired
|
||||
private FeatureManagementService featureManagementService;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private SetupService setupService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String name = (String) commandContext.getParameters().getParameters().get(0);
|
||||
if(featureManagementService.featureExists(name)) {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(name);
|
||||
AServerChannelUserId initiatingUser = AServerChannelUserId
|
||||
.builder()
|
||||
.guildId(commandContext.getGuild().getIdLong())
|
||||
.channelId(commandContext.getChannel().getIdLong())
|
||||
.userId(commandContext.getAuthor().getIdLong())
|
||||
.build();
|
||||
setupService.performSetup(feature, initiatingUser, commandContext.getMessage().getIdLong());
|
||||
}
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter newPrefixParameter = Parameter.builder().name("feature").type(String.class).build();
|
||||
List<Parameter> parameters = Arrays.asList(newPrefixParameter);
|
||||
HelpInfo helpInfo = HelpInfo.builder().build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("setup")
|
||||
.module(ConfigModuleInterface.CONFIG)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
return CoreFeatures.CORE_FEATURE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package dev.sheldan.abstracto.core.interactive;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.SetupStepException;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class AbstractConfigSetupStep implements SetupStep {
|
||||
|
||||
@Autowired
|
||||
private InteractiveService interactiveService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
protected SetupExecution nextStep;
|
||||
|
||||
@Autowired
|
||||
private InteractiveUtils interactiveUtils;
|
||||
|
||||
|
||||
protected Runnable getTimeoutRunnable(Long serverId, Long channelId) {
|
||||
return () -> {
|
||||
interactiveUtils.sendTimeoutMessage(serverId, channelId);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package dev.sheldan.abstracto.core.interactive;
|
||||
|
||||
import com.jagrosh.jdautilities.commons.waiter.EventWaiter;
|
||||
import com.jagrosh.jdautilities.menu.ButtonMenu;
|
||||
import dev.sheldan.abstracto.core.models.FullUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AEmote;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.EmoteService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class InteractiveServiceBean implements InteractiveService {
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private EventWaiter eventWaiter;
|
||||
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Override
|
||||
public void createMessageWithResponse(String templateKey, AUserInAServer responder, AChannel channel, Long messageId, Consumer<MessageReceivedEvent> action, Runnable finalAction) {
|
||||
String message = templateService.renderSimpleTemplate(templateKey);
|
||||
channelService.sendTextToAChannel(message, channel);
|
||||
eventWaiter.waitForEvent(MessageReceivedEvent.class, event -> {
|
||||
if(event != null) {
|
||||
return event.getAuthor().getIdLong() == responder.getUserReference().getId() && event.getMessage().getIdLong() != messageId;
|
||||
}
|
||||
return false;
|
||||
}, action, 1, TimeUnit.MINUTES, finalAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createMessageWithResponse(MessageToSend messageToSend, AUserInAServer responder, AChannel channel, Long messageId, Consumer<MessageReceivedEvent> action, Runnable finalAction) {
|
||||
channelService.sendMessageToSendToAChannel(messageToSend, channel);
|
||||
Long userId = responder.getUserReference().getId();
|
||||
eventWaiter.waitForEvent(MessageReceivedEvent.class, event -> {
|
||||
if(event != null) {
|
||||
return event.getAuthor().getIdLong() == userId && event.getMessage().getIdLong() != messageId;
|
||||
}
|
||||
return false;
|
||||
}, action, 1, TimeUnit.MINUTES, finalAction);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void createMessageWithConfirmation(String text, AUserInAServer responder, AChannel channel, Long messageId, Consumer<Void> confirmation, Consumer<Void> denial, Runnable finalAction) {
|
||||
Long serverId = responder.getServerReference().getId();
|
||||
ButtonMenu.Builder builder = new ButtonMenu.Builder();
|
||||
HashMap<String, Consumer<Void>> actions = new HashMap<>();
|
||||
|
||||
addEmoteToBuilder("confirmation", confirmation, serverId, builder, actions);
|
||||
addEmoteToBuilder("denial", denial, serverId, builder, actions);
|
||||
|
||||
ButtonMenu menu = builder
|
||||
.setEventWaiter(eventWaiter)
|
||||
.setDescription(text)
|
||||
.setAction(reactionEmote -> {
|
||||
if(reactionEmote.isEmoji()) {
|
||||
actions.get(reactionEmote.getEmoji()).accept(null);
|
||||
} else {
|
||||
actions.get(reactionEmote.getEmote().getId()).accept(null);
|
||||
}
|
||||
})
|
||||
.build();
|
||||
Optional<TextChannel> textChannelInGuild = channelService.getTextChannelInGuild(serverId, channel.getId());
|
||||
textChannelInGuild.ifPresent(menu::display);
|
||||
}
|
||||
|
||||
private void addEmoteToBuilder(String key, Consumer<Void> consumer, Long serverId, ButtonMenu.Builder builder, HashMap<String, Consumer<Void>> actions) {
|
||||
AEmote emoteOrFakeEmote = emoteService.getEmoteOrFakeEmote(key, serverId);
|
||||
if(emoteOrFakeEmote.getCustom()){
|
||||
Optional<Emote> emote = botService.getEmote(serverId, emoteOrFakeEmote);
|
||||
emote.ifPresent(emote1 -> {
|
||||
builder.addChoice(emote1);
|
||||
actions.put(emote1.getId(), consumer);
|
||||
});
|
||||
} else {
|
||||
builder.addChoice(emoteOrFakeEmote.getEmoteKey());
|
||||
actions.put(emoteOrFakeEmote.getEmoteKey(), consumer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package dev.sheldan.abstracto.core.interactive;
|
||||
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class InteractiveUtils {
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Transactional
|
||||
public void sendTimeoutMessage(Long serverId, Long channelId) {
|
||||
String s = templateService.renderSimpleTemplate("setup_configuration_timeout");
|
||||
Optional<TextChannel> channelOptional = channelService.getTextChannelInGuild(serverId, channelId);
|
||||
channelOptional.ifPresent(channel -> {
|
||||
channelService.sendTextToChannelNoFuture(s, channel);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package dev.sheldan.abstracto.core.interactive;
|
||||
|
||||
import dev.sheldan.abstracto.core.service.management.PostTargetManagement;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class PostTargetDelayedAction implements DelayedAction {
|
||||
|
||||
@Autowired
|
||||
private PostTargetManagement postTargetManagement;
|
||||
|
||||
@Override
|
||||
public void execute(DelayedActionConfig delayedActionConfig) {
|
||||
PostTargetDelayedActionConfig concrete = (PostTargetDelayedActionConfig) delayedActionConfig;
|
||||
postTargetManagement.createOrUpdate(concrete.getPostTargetKey(), concrete.getServerId(), concrete.getChannelId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(DelayedActionConfig delayedActionConfig) {
|
||||
return delayedActionConfig instanceof PostTargetDelayedActionConfig;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package dev.sheldan.abstracto.core.interactive;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.template.commands.PostTargetActionModel;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class PostTargetDelayedActionConfig implements DelayedActionConfig {
|
||||
|
||||
private String postTargetKey;
|
||||
private Long serverId;
|
||||
private Long channelId;
|
||||
private TextChannel textChannel;
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "setup_post_target_action";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return PostTargetActionModel
|
||||
.builder()
|
||||
.channelId(channelId)
|
||||
.channel(textChannel)
|
||||
.postTargetKey(postTargetKey)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package dev.sheldan.abstracto.core.interactive;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.ChannelNotFoundException;
|
||||
import dev.sheldan.abstracto.core.models.AServerChannelUserId;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class PostTargetSetupStep extends AbstractConfigSetupStep {
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private InteractiveService interactiveService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Autowired
|
||||
private PostTargetSetupStep self;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<DelayedActionConfig>> execute(AServerChannelUserId user, SetupStepParameter parameter) {
|
||||
PostTargetStepParameter systemConfigStepParameter = (PostTargetStepParameter) parameter;
|
||||
String messageTemplateKey = "setup_posttarget_" + systemConfigStepParameter.getPostTargetKey();
|
||||
Optional<AChannel> channel = channelManagementService.loadChannel(user.getChannelId());
|
||||
CompletableFuture<List<DelayedActionConfig>> future = new CompletableFuture<>();
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(user.getGuildId(), user.getUserId());
|
||||
if(channel.isPresent()) {
|
||||
Runnable finalAction = super.getTimeoutRunnable(user.getGuildId(), user.getChannelId());
|
||||
Consumer<MessageReceivedEvent> configAction = (MessageReceivedEvent event) -> {
|
||||
try {
|
||||
if(event.getMessage().getMentionedChannels().size() == 0) {
|
||||
future.completeExceptionally(new RuntimeException());
|
||||
}
|
||||
TextChannel textChannel = event.getMessage().getMentionedChannels().get(0);
|
||||
PostTargetDelayedActionConfig build = PostTargetDelayedActionConfig
|
||||
.builder()
|
||||
.postTargetKey(systemConfigStepParameter.getPostTargetKey())
|
||||
.serverId(user.getGuildId())
|
||||
.textChannel(textChannel)
|
||||
.channelId(textChannel.getIdLong())
|
||||
.build();
|
||||
List<DelayedActionConfig> delayedSteps = Arrays.asList(build);
|
||||
future.complete(delayedSteps);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to handle post target step.", e);
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
};
|
||||
interactiveService.createMessageWithResponse(messageTemplateKey, aUserInAServer, channel.get(), parameter.getPreviousMessageId(), configAction, finalAction);
|
||||
} else {
|
||||
future.completeExceptionally(new ChannelNotFoundException(user.getGuildId(), user.getChannelId()));
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.abstracto.core.interactive;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class PostTargetStepParameter implements SetupStepParameter {
|
||||
private Long previousMessageId;
|
||||
private String postTargetKey;
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package dev.sheldan.abstracto.core.interactive;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.ChannelNotFoundException;
|
||||
import dev.sheldan.abstracto.core.models.AServerChannelUserId;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.SetupSummaryModel;
|
||||
import dev.sheldan.abstracto.core.service.DelayedActionService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SetupSummaryStep extends AbstractConfigSetupStep {
|
||||
|
||||
@Autowired
|
||||
private InteractiveService interactiveService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private DelayedActionService delayedActionService;
|
||||
|
||||
@Autowired
|
||||
private SetupSummaryStep self;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<DelayedActionConfig>> execute(AServerChannelUserId user, SetupStepParameter generalParameter) {
|
||||
SetupSummaryStepParameter parameter = (SetupSummaryStepParameter) generalParameter;
|
||||
SetupSummaryModel model = SetupSummaryModel
|
||||
.builder()
|
||||
.actionConfigs(parameter.getDelayedActionList())
|
||||
.build();
|
||||
String messageToSend = templateService.renderTemplate("setup_confirmation", model);
|
||||
Optional<AChannel> channel = channelManagementService.loadChannel(user.getChannelId());
|
||||
CompletableFuture<List<DelayedActionConfig>> future = new CompletableFuture<>();
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(user.getGuildId(), user.getUserId());
|
||||
if(channel.isPresent()) {
|
||||
Runnable finalAction = super.getTimeoutRunnable(user.getGuildId(), user.getChannelId());
|
||||
Consumer<Void> confirmation = (Void none) -> {
|
||||
try {
|
||||
self.executeDelayedSteps(parameter);
|
||||
future.complete(null);
|
||||
} catch (Exception e) {
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
};
|
||||
|
||||
Consumer<Void> denial = (Void none) -> {
|
||||
log.info("Stopped wizard.");
|
||||
};
|
||||
interactiveService.createMessageWithConfirmation(messageToSend, aUserInAServer, channel.get(), parameter.getPreviousMessageId(), confirmation, denial, finalAction);
|
||||
} else {
|
||||
future.completeExceptionally(new ChannelNotFoundException(user.getGuildId(), user.getChannelId()));
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void executeDelayedSteps(SetupSummaryStepParameter parameter) {
|
||||
delayedActionService.executeDelayedActions(parameter.getDelayedActionList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.core.interactive;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class SetupSummaryStepParameter implements SetupStepParameter {
|
||||
private Long previousMessageId;
|
||||
private List<DelayedActionConfig> delayedActionList;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package dev.sheldan.abstracto.core.interactive;
|
||||
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SystemConfigDelayedAction implements DelayedAction {
|
||||
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Override
|
||||
public void execute(DelayedActionConfig delayedActionConfig) {
|
||||
SystemConfigDelayedActionConfig concrete = (SystemConfigDelayedActionConfig) delayedActionConfig;
|
||||
configService.setConfigValue(concrete.getConfigKey(), concrete.getServerId(), concrete.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(DelayedActionConfig delayedActionConfig) {
|
||||
return delayedActionConfig instanceof SystemConfigDelayedActionConfig;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package dev.sheldan.abstracto.core.interactive;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.template.commands.SystemConfigActionModel;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class SystemConfigDelayedActionConfig implements DelayedActionConfig {
|
||||
private String configKey;
|
||||
private Long serverId;
|
||||
private String value;
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "setup_system_config_action";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return SystemConfigActionModel
|
||||
.builder()
|
||||
.configKey(this.configKey)
|
||||
.newValue(this.value)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package dev.sheldan.abstracto.core.interactive;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.ChannelNotFoundException;
|
||||
import dev.sheldan.abstracto.core.models.AServerChannelUserId;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SystemConfigSetupStep extends AbstractConfigSetupStep {
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private InteractiveService interactiveService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Autowired
|
||||
private SystemConfigSetupStep self;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<DelayedActionConfig>> execute(AServerChannelUserId user, SetupStepParameter parameter) {
|
||||
SystemConfigStepParameter systemConfigStepParameter = (SystemConfigStepParameter) parameter;
|
||||
String messageTemplateKey = "setup_config_" + systemConfigStepParameter.getConfigKey();
|
||||
Optional<AChannel> channel = channelManagementService.loadChannel(user.getChannelId());
|
||||
CompletableFuture<List<DelayedActionConfig>> future = new CompletableFuture<>();
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(user.getGuildId(), user.getUserId());
|
||||
if(channel.isPresent()) {
|
||||
Runnable finalAction = super.getTimeoutRunnable(user.getGuildId(), user.getChannelId());
|
||||
Consumer<MessageReceivedEvent> configAction = (MessageReceivedEvent event) -> {
|
||||
try {
|
||||
self.checkValidity(user, systemConfigStepParameter, event);
|
||||
SystemConfigDelayedActionConfig build = SystemConfigDelayedActionConfig
|
||||
.builder()
|
||||
.configKey(systemConfigStepParameter.getConfigKey())
|
||||
.serverId(user.getGuildId())
|
||||
.value(event.getMessage().getContentRaw())
|
||||
.build();
|
||||
List<DelayedActionConfig> delayedSteps = Arrays.asList(build);
|
||||
future.complete(delayedSteps);
|
||||
} catch (Exception e) {
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
};
|
||||
interactiveService.createMessageWithResponse(messageTemplateKey, aUserInAServer, channel.get(), parameter.getPreviousMessageId(), configAction, finalAction);
|
||||
} else {
|
||||
future.completeExceptionally(new ChannelNotFoundException(user.getGuildId(), user.getChannelId()));
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void checkValidity(AServerChannelUserId user, SystemConfigStepParameter systemConfigStepParameter, MessageReceivedEvent event) {
|
||||
configService.validateConfig(systemConfigStepParameter.getConfigKey(), user.getGuildId(), event.getMessage().getContentRaw());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.abstracto.core.interactive;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class SystemConfigStepParameter implements SetupStepParameter {
|
||||
private Long previousMessageId;
|
||||
private String configKey;
|
||||
}
|
||||
@@ -182,7 +182,7 @@ public class ChannelServiceBean implements ChannelService {
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public List<CompletableFuture<Message>> sendTemplateInChannel(String templateKey, Object model, MessageChannel channel) {
|
||||
public List<CompletableFuture<Message>> sendEmbedTemplateInChannel(String templateKey, Object model, MessageChannel channel) {
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(templateKey, model);
|
||||
return sendMessageToSendToChannel(messageToSend, channel);
|
||||
}
|
||||
|
||||
@@ -92,4 +92,28 @@ public class ConfigServiceBean implements ConfigService{
|
||||
throw new ConfigurationKeyNotFoundException(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configIsFitting(String name, Long serverId, String value) {
|
||||
try {
|
||||
validateConfig(name, serverId, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateConfig(String name, Long serverId, String value) {
|
||||
if(configManagementService.configExists(serverId, name)) {
|
||||
AConfig existing = configManagementService.loadConfig(serverId, name);
|
||||
if(existing.getDoubleValue() != null) {
|
||||
Double.parseDouble(value);
|
||||
} else if(existing.getLongValue() != null) {
|
||||
Long.parseLong(value);
|
||||
}
|
||||
} else {
|
||||
throw new ConfigurationKeyNotFoundException(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.interactive.DelayedAction;
|
||||
import dev.sheldan.abstracto.core.interactive.DelayedActionConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class DelayedActionServiceBean implements DelayedActionService {
|
||||
|
||||
@Autowired
|
||||
private List<DelayedAction> delayedActions;
|
||||
|
||||
@Override
|
||||
public void executeDelayedActions(List<DelayedActionConfig> delayedActionConfigList) {
|
||||
delayedActionConfigList.forEach(delayedActionConfig -> {
|
||||
delayedActions.stream()
|
||||
.filter(delayedAction -> delayedAction.handles(delayedActionConfig))
|
||||
.findFirst()
|
||||
.ifPresent(delayedAction -> delayedAction.execute(delayedActionConfig));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@@ -37,27 +39,42 @@ public class MessageServiceBean implements MessageService {
|
||||
|
||||
@Override
|
||||
public void addReactionToMessage(String emoteKey, Long serverId, Message message) {
|
||||
addReactionToMessageWithFuture(emoteKey, serverId, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addReactionToMessageWithFuture(String emoteKey, Long serverId, Message message) {
|
||||
Optional<Guild> guildByIdOptional = botService.getGuildById(serverId);
|
||||
AEmote emote = emoteService.getEmoteOrFakeEmote(emoteKey, serverId);
|
||||
if(guildByIdOptional.isPresent()) {
|
||||
Guild guild = guildByIdOptional.get();
|
||||
if(emote.getCustom()) {
|
||||
Emote emoteById = botService.getInstance().getEmoteById(emote.getEmoteId());
|
||||
if(emoteById != null) {
|
||||
message.addReaction(emoteById).queue();
|
||||
} else {
|
||||
log.error("Emote with key {} and id {} for guild {} was not found.", emoteKey, emote.getEmoteId(), guild.getId());
|
||||
throw new EmoteNotDefinedException(emoteKey);
|
||||
}
|
||||
if(emote.getCustom()) {
|
||||
Emote emoteById = botService.getInstance().getEmoteById(emote.getEmoteId());
|
||||
if(emoteById != null) {
|
||||
return message.addReaction(emoteById).submit();
|
||||
} else {
|
||||
message.addReaction(emote.getEmoteKey()).queue();
|
||||
log.error("Emote with key {} and id {} for guild {} was not found.", emoteKey, emote.getEmoteId(), guild.getId());
|
||||
throw new EmoteNotDefinedException(emoteKey);
|
||||
}
|
||||
} else {
|
||||
return message.addReaction(emote.getEmoteKey()).submit();
|
||||
}
|
||||
} else {
|
||||
log.error("Cannot add reaction, guild not found {}", serverId);
|
||||
throw new GuildException(serverId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CompletableFuture<Void>> addReactionsToMessageWithFuture(List<String> emoteKeys, Long serverId, Message message) {
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
emoteKeys.forEach(s -> {
|
||||
futures.add(addReactionToMessageWithFuture(s, serverId, message));
|
||||
});
|
||||
return futures;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteMessageInChannelInServer(Long serverId, Long channelId, Long messageId) {
|
||||
return botService.deleteMessage(serverId, channelId, messageId);
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.interactive.DelayedActionConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.interactive.*;
|
||||
import dev.sheldan.abstracto.core.models.AServerChannelUserId;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.SetupCompletedNotificationModel;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SetupServiceBean implements SetupService {
|
||||
|
||||
@Autowired
|
||||
private SystemConfigSetupStep systemConfigSetupStep;
|
||||
|
||||
@Autowired
|
||||
private PostTargetSetupStep postTargetSetupStep;
|
||||
|
||||
@Autowired
|
||||
private DelayedActionService delayedActionService;
|
||||
|
||||
@Autowired
|
||||
private SetupServiceBean self;
|
||||
|
||||
@Autowired
|
||||
private SetupSummaryStep setupSummaryStep;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Override
|
||||
public void performSetup(FeatureConfig featureConfig, AServerChannelUserId user, Long initialMessageId) {
|
||||
List<String> requiredSystemConfigKeys = featureConfig.getRequiredSystemConfigKeys();
|
||||
List<SetupExecution> steps = new ArrayList<>();
|
||||
requiredSystemConfigKeys.forEach(s -> {
|
||||
SetupExecution execution = SetupExecution
|
||||
.builder()
|
||||
.step(systemConfigSetupStep)
|
||||
.parameter(SystemConfigStepParameter.builder().configKey(s).build())
|
||||
.build();
|
||||
steps.add(execution);
|
||||
});
|
||||
featureConfig.getRequiredPostTargets().forEach(postTargetEnum -> {
|
||||
SetupExecution execution = SetupExecution
|
||||
.builder()
|
||||
.step(postTargetSetupStep)
|
||||
.parameter(PostTargetStepParameter.builder().postTargetKey(postTargetEnum.getKey()).build())
|
||||
.build();
|
||||
steps.add(execution);
|
||||
});
|
||||
for (int i = 0; i < steps.size(); i++) {
|
||||
SetupExecution setupExecution = steps.get(i);
|
||||
setupExecution.getParameter().setPreviousMessageId(initialMessageId);
|
||||
if(i < steps.size() - 1) {
|
||||
setupExecution.setNextStep(steps.get(i + 1));
|
||||
}
|
||||
}
|
||||
executeSetup(featureConfig, steps, user, new ArrayList<>());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeSetup(FeatureConfig featureConfig, List<SetupExecution> steps, AServerChannelUserId user, List<DelayedActionConfig> delayedActionConfigs) {
|
||||
steps.stream().findFirst().ifPresent(execution -> executeStep(user, execution, delayedActionConfigs, featureConfig));
|
||||
}
|
||||
|
||||
private void executeStep(AServerChannelUserId aUserInAServer, SetupExecution execution, List<DelayedActionConfig> delayedActionConfigs, FeatureConfig featureConfig) {
|
||||
execution.getStep().execute(aUserInAServer, execution.getParameter()).thenAccept(aVoid -> {
|
||||
delayedActionConfigs.addAll(aVoid);
|
||||
if(execution.getNextStep() != null) {
|
||||
executeStep(aUserInAServer, execution.getNextStep(), delayedActionConfigs, featureConfig);
|
||||
} else {
|
||||
self.executePostSetupSteps(delayedActionConfigs, aUserInAServer, execution.getParameter().getPreviousMessageId(), featureConfig);
|
||||
}
|
||||
}).exceptionally(throwable -> {
|
||||
executeStep(aUserInAServer, execution, delayedActionConfigs, featureConfig);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void executePostSetupSteps(List<DelayedActionConfig> delayedActionConfigs, AServerChannelUserId user, Long initialMessage, FeatureConfig featureConfig) {
|
||||
SetupSummaryStepParameter parameter = SetupSummaryStepParameter
|
||||
.builder()
|
||||
.delayedActionList(delayedActionConfigs)
|
||||
.previousMessageId(initialMessage)
|
||||
.build();
|
||||
setupSummaryStep.execute(user, parameter).thenAccept(ignored -> {
|
||||
self.notifyAboutCompletion(user, featureConfig);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void notifyAboutCompletion(AServerChannelUserId aServerChannelUserId, FeatureConfig featureConfig) {
|
||||
String templateName = "setup_completion_notification";
|
||||
SetupCompletedNotificationModel model = SetupCompletedNotificationModel
|
||||
.builder()
|
||||
.completedFeature(featureConfig)
|
||||
.build();
|
||||
String text = templateService.renderTemplate(templateName, model);
|
||||
Optional<TextChannel> textChannel = channelService.getTextChannelInGuild(aServerChannelUserId.getGuildId(), aServerChannelUserId.getChannelId());
|
||||
textChannel.ifPresent(channel -> channelService.sendTextToChannel(text, channel));
|
||||
}
|
||||
}
|
||||
@@ -4,4 +4,8 @@ abstracto.parameter.lowerBound=50
|
||||
|
||||
abstracto.features.core.enabled=true
|
||||
abstracto.prefix=!
|
||||
abstracto.eventWaiter.threads=10
|
||||
abstracto.eventWaiter.threads=10
|
||||
|
||||
abstracto.emoteNames.confirmation=confirmation,denial
|
||||
abstracto.defaultEmotes.confirmation=\u2705
|
||||
abstracto.defaultEmotes.denial=\u274c
|
||||
@@ -0,0 +1 @@
|
||||
<#assign featureName><#include "${completedFeature.feature.key}_feature"></#assign><#include "setup_completion_message">
|
||||
@@ -0,0 +1,5 @@
|
||||
<#list actionConfigs as actionConfig>
|
||||
<#assign param=actionConfig.templateModel>
|
||||
<#include "${actionConfig.templateName}">
|
||||
|
||||
</#list>
|
||||
@@ -0,0 +1 @@
|
||||
<#assign postTargetKey>${param.postTargetKey}</#assign><#assign channel>${param.channel.asMention}</#assign><#include "setup_post_target_action_display">
|
||||
@@ -0,0 +1 @@
|
||||
<#assign configKey>${param.configKey}</#assign><#assign newValue>${param.newValue}</#assign><#include "setup_system_config_action_display">
|
||||
Reference in New Issue
Block a user