[AB-xxx] adding paginators to emote stats

adding handling for emotes which are only provided as ID to command inputs
removing message commands from emote statistic related commands
This commit is contained in:
Sheldan
2025-01-31 19:03:38 +01:00
parent e952727849
commit 77b97507b3
15 changed files with 120 additions and 364 deletions

View File

@@ -4,7 +4,6 @@ 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.interaction.slash.SlashCommandConfig;
@@ -22,6 +21,7 @@ import java.util.concurrent.CompletableFuture;
import net.dv8tion.jda.api.entities.emoji.CustomEmoji;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -50,24 +50,21 @@ public class DeleteTrackedEmote extends AbstractConditionableCommand {
private static final String DELETE_TRACKED_EMOTE_COMMAND_NAME = "deleteTrackedEmote";
private static final String DELETE_TRACKED_EMOTE_RESPONSE = "deleteTrackedEmote_response";
@Override
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
TrackedEmote fakeTrackedEmote = (TrackedEmote) parameters.get(0);
// need to actually load the TrackedEmote
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByTrackedEmoteServer(fakeTrackedEmote.getTrackedEmoteId());
trackedEmoteService.deleteTrackedEmote(trackedEmote);
return CommandResult.fromSuccess();
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String emote = slashCommandParameterService.getCommandOption(DELETE_TRACKED_EMOTE_TRACKED_EMOTE, event, String.class);
Emoji emoji = slashCommandParameterService.loadEmoteFromString(emote, event.getGuild());
if(!(emoji instanceof CustomEmoji)) {
if(emoji instanceof CustomEmoji) {
Long emoteId = ((CustomEmoji) emoji).getIdLong();
return createResponse(event, emoteId);
} else if(StringUtils.isNumeric(emote)) {
return createResponse(event, Long.parseLong(emote));
} else {
throw new TrackedEmoteNotFoundException();
}
Long emoteId = ((CustomEmoji) emoji).getIdLong();
}
private CompletableFuture<CommandResult> createResponse(SlashCommandInteractionEvent event, Long emoteId) {
ServerSpecificId serverEmoteId = new ServerSpecificId(event.getGuild().getIdLong(), emoteId);
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByTrackedEmoteServer(serverEmoteId);
trackedEmoteService.deleteTrackedEmote(trackedEmote);
@@ -104,7 +101,7 @@ public class DeleteTrackedEmote extends AbstractConditionableCommand {
.templated(true)
.supportsEmbedException(true)
.causesReaction(true)
.messageCommandOnly(true)
.slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig)
.requiresConfirmation(true)
.parameters(parameters)

View File

@@ -4,14 +4,13 @@ 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.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.PaginatorService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.core.utils.ParseUtils;
@@ -24,7 +23,6 @@ import dev.sheldan.abstracto.statistic.emote.service.UsedEmoteService;
import java.util.Arrays;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -48,7 +46,7 @@ public class DeletedEmoteStats extends AbstractConditionableCommand {
private UsedEmoteService usedEmoteService;
@Autowired
private ChannelService channelService;
private PaginatorService paginatorService;
@Autowired
private ServerManagementService serverManagementService;
@@ -64,39 +62,6 @@ public class DeletedEmoteStats extends AbstractConditionableCommand {
private static final String DELETED_EMOTE_STATS_PERIOD = "period";
private static final String DELETED_EMOTE_STATS_USED_EMOTE_TYPE = "type";
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
// default is 1.1.1970
Instant statsSince = Instant.EPOCH;
if(!parameters.isEmpty()) {
// if a duration parameter is available, subtract the current time of this to get the true Instant
Duration duration = (Duration) parameters.get(0);
statsSince = Instant.now().minus(duration);
}
AServer server = serverManagementService.loadServer(commandContext.getGuild());
EmoteStatsModel emoteStatsModel = usedEmoteService.getDeletedEmoteStatsForServerSince(server, statsSince, null);
List<CompletableFuture<Message>> messagePromises = new ArrayList<>();
// only show the embed, if there are static emotes to show
if(!emoteStatsModel.getStaticEmotes().isEmpty()) {
log.debug("Deleted emote stats has {} static emotes since {}.", emoteStatsModel.getStaticEmotes().size(), statsSince);
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(EMOTE_STATS_STATIC_DELETED_RESPONSE, emoteStatsModel, commandContext.getChannel()));
}
// only show the embed, if there are animated emotes to show
if(!emoteStatsModel.getAnimatedEmotes().isEmpty()) {
log.debug("Deleted emote stats has {} animated emotes since {}.", emoteStatsModel.getAnimatedEmotes(), statsSince);
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(EMOTE_STATS_ANIMATED_DELETED_RESPONSE, emoteStatsModel, commandContext.getChannel()));
}
// if neither static nor animated emote stats are available, show an embed indicating so
if(!emoteStatsModel.areStatsAvailable()) {
log.info("No delete emote stats available for guild {} since {}.", commandContext.getGuild().getIdLong(), statsSince);
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(EmoteStats.EMOTE_STATS_NO_STATS_AVAILABLE, new Object(), commandContext.getChannel()));
}
return FutureUtils.toSingleFutureGeneric(messagePromises)
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
UsedEmoteTypeParameter typeEnum;
@@ -116,22 +81,23 @@ public class DeletedEmoteStats extends AbstractConditionableCommand {
}
AServer server = serverManagementService.loadServer(event.getGuild());
EmoteStatsModel emoteStatsModel = usedEmoteService.getDeletedEmoteStatsForServerSince(server, startTime, UsedEmoteTypeParameter.convertToUsedEmoteType(typeEnum));
List<CompletableFuture<Message>> messagePromises = new ArrayList<>();
List<CompletableFuture<Void>> messagePromises = new ArrayList<>();
return event.deferReply().submit().thenCompose(interactionHook -> {
// only show embed if static emote stats are available
if(!emoteStatsModel.getStaticEmotes().isEmpty()) {
log.debug("Deleted emote stats has {} static emotes since {}.", emoteStatsModel.getStaticEmotes().size(), startTime);
messagePromises.addAll(interactionService.sendMessageToInteraction(EMOTE_STATS_STATIC_DELETED_RESPONSE, emoteStatsModel, interactionHook));
messagePromises.add(paginatorService.sendPaginatorToInteraction(EMOTE_STATS_STATIC_DELETED_RESPONSE, emoteStatsModel, interactionHook));
}
// only show embed if animated emote stats are available
if(!emoteStatsModel.getAnimatedEmotes().isEmpty()) {
log.debug("Deleted emote stats has {} animated emotes since {}.", emoteStatsModel.getAnimatedEmotes(), startTime);
messagePromises.addAll(interactionService.sendMessageToInteraction(EMOTE_STATS_ANIMATED_DELETED_RESPONSE, emoteStatsModel, interactionHook));
messagePromises.add(paginatorService.sendPaginatorToInteraction(EMOTE_STATS_ANIMATED_DELETED_RESPONSE, emoteStatsModel, interactionHook));
}
// show an embed if no emote stats are available indicating so
if(!emoteStatsModel.areStatsAvailable()) {
log.info("No delete emote stats available for guild {} since {}.", event.getGuild().getIdLong(), startTime);
messagePromises.addAll(interactionService.sendMessageToInteraction(EmoteStats.EMOTE_STATS_NO_STATS_AVAILABLE, emoteStatsModel, interactionHook));
return FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(EmoteStats.EMOTE_STATS_NO_STATS_AVAILABLE, new Object(), interactionHook))
.thenApply(unused -> CommandResult.fromSuccess());
}
return FutureUtils.toSingleFutureGeneric(messagePromises)
.thenApply(unused -> CommandResult.fromIgnored());
@@ -187,7 +153,7 @@ public class DeletedEmoteStats extends AbstractConditionableCommand {
.async(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true)
.messageCommandOnly(true)
.slashCommandOnly(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)

View File

@@ -4,7 +4,6 @@ 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.interaction.InteractionService;
@@ -14,6 +13,7 @@ import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.statistic.config.StatisticFeatureDefinition;
import dev.sheldan.abstracto.statistic.config.StatisticSlashCommandNames;
import dev.sheldan.abstracto.statistic.emote.config.EmoteTrackingModuleDefinition;
import dev.sheldan.abstracto.statistic.emote.exception.TrackedEmoteNotFoundException;
import dev.sheldan.abstracto.statistic.emote.model.database.TrackedEmote;
import dev.sheldan.abstracto.statistic.emote.service.TrackedEmoteService;
import dev.sheldan.abstracto.statistic.emote.service.management.TrackedEmoteManagementService;
@@ -21,6 +21,7 @@ import java.util.concurrent.CompletableFuture;
import net.dv8tion.jda.api.entities.emoji.CustomEmoji;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -50,29 +51,20 @@ public class DisableEmoteTracking extends AbstractConditionableCommand {
private static final String DISABLE_EMOTE_TRACKING_RESPONSE = "disableEmoteTracking_response";
@Override
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
if(!parameters.isEmpty()) {
TrackedEmote fakeTrackedEmote = (TrackedEmote) parameters.get(0);
// need to reload the tracked emote
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByTrackedEmoteServer(fakeTrackedEmote.getTrackedEmoteId());
trackedEmoteManagementService.disableTrackedEmote(trackedEmote);
} else {
trackedEmoteService.disableEmoteTracking(commandContext.getGuild());
}
return CommandResult.fromSuccess();
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
if(slashCommandParameterService.hasCommandOption(DISABLE_EMOTE_TRACKING_TRACKED_EMOTE, event)) {
String emote = slashCommandParameterService.getCommandOption(DISABLE_EMOTE_TRACKING_TRACKED_EMOTE, event, String.class);
Emoji emoji = slashCommandParameterService.loadEmoteFromString(emote, event.getGuild());
Long emoteId = ((CustomEmoji) emoji).getIdLong();
ServerSpecificId serverEmoteId = new ServerSpecificId(event.getGuild().getIdLong(), emoteId);
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByTrackedEmoteServer(serverEmoteId);
trackedEmoteManagementService.disableTrackedEmote(trackedEmote);
if(emoji instanceof CustomEmoji) {
Long emoteId = ((CustomEmoji) emoji).getIdLong();
disableTracking(event, emoteId);
} else if(StringUtils.isNumeric(emote)) {
disableTracking(event, Long.parseLong(emote));
} else {
throw new TrackedEmoteNotFoundException();
}
} else {
trackedEmoteService.disableEmoteTracking(event.getGuild());
}
@@ -80,6 +72,12 @@ public class DisableEmoteTracking extends AbstractConditionableCommand {
.thenApply(interactionHook -> CommandResult.fromIgnored());
}
private void disableTracking(SlashCommandInteractionEvent event, Long emoteId) {
ServerSpecificId serverEmoteId = new ServerSpecificId(event.getGuild().getIdLong(), emoteId);
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByTrackedEmoteServer(serverEmoteId);
trackedEmoteManagementService.disableTrackedEmote(trackedEmote);
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
@@ -110,7 +108,7 @@ public class DisableEmoteTracking extends AbstractConditionableCommand {
.module(EmoteTrackingModuleDefinition.EMOTE_TRACKING)
.templated(true)
.slashCommandConfig(slashCommandConfig)
.messageCommandOnly(true)
.slashCommandOnly(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -4,15 +4,12 @@ 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.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.core.utils.ParseUtils;
import dev.sheldan.abstracto.statistic.config.StatisticFeatureDefinition;
import dev.sheldan.abstracto.statistic.config.StatisticSlashCommandNames;
@@ -29,6 +26,7 @@ import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.emoji.CustomEmoji;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -47,9 +45,6 @@ public class EmoteStat extends AbstractConditionableCommand {
@Autowired
private UsedEmoteService usedEmoteService;
@Autowired
private ChannelService channelService;
@Autowired
private TrackedEmoteManagementService trackedEmoteManagementService;
@@ -66,27 +61,6 @@ public class EmoteStat extends AbstractConditionableCommand {
private static final String EMOTE_STAT_TRACKED_EMOTE = "trackedEmote";
private static final String EMOTE_STAT_COMMAND_NAME = "emoteStat";
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
// default is 1.1.1970
Instant statsSince = Instant.EPOCH;
TrackedEmote emote = (TrackedEmote) parameters.get(0);
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByTrackedEmoteServer(emote.getTrackedEmoteId());
if(parameters.size() == 2) {
// subtract the given Duration from the current point in time, if there is any
Duration duration = (Duration) parameters.get(1);
statsSince = Instant.now().minus(duration);
}
EmoteStatsResultDisplay emoteStatsModel = usedEmoteService.getEmoteStatForEmote(trackedEmote, statsSince, null);
if(emoteStatsModel.getResult().getAmount() == null) {
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannel(EMOTE_STATS_NO_STATS_AVAILABLE, new Object(), commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannel(EMOTE_STAT_RESPONSE, emoteStatsModel, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
UsedEmoteTypeParameter typeEnum;
@@ -108,19 +82,28 @@ public class EmoteStat extends AbstractConditionableCommand {
Emoji emoji = slashCommandParameterService.loadEmoteFromString(emote, event.getGuild());
if(emoji instanceof CustomEmoji) {
Long emoteId = ((CustomEmoji) emoji).getIdLong();
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByTrackedEmoteServer(new ServerSpecificId(event.getGuild().getIdLong(), emoteId));
EmoteStatsResultDisplay emoteStatsModel = usedEmoteService.getEmoteStatForEmote(trackedEmote, startTime, UsedEmoteTypeParameter.convertToUsedEmoteType(typeEnum));
if(emoteStatsModel.getResult().getAmount() == null) {
return interactionService.replyEmbed(EMOTE_STATS_NO_STATS_AVAILABLE, new Object(), event)
.thenApply(unused -> CommandResult.fromIgnored());
}
return interactionService.replyEmbed(EMOTE_STAT_RESPONSE, emoteStatsModel, event)
.thenApply(unused -> CommandResult.fromIgnored());
return showResponse(event, emoteId, startTime, typeEnum);
} else if(StringUtils.isNumeric(emote)) {
return showResponse(event, Long.parseLong(emote), startTime, typeEnum);
} else {
throw new TrackedEmoteNotFoundException();
}
}
private CompletableFuture<CommandResult> showResponse(SlashCommandInteractionEvent event, Long emoteId, Instant startTime,
UsedEmoteTypeParameter typeEnum)
{
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByTrackedEmoteServer(new ServerSpecificId(event.getGuild().getIdLong(), emoteId));
EmoteStatsResultDisplay emoteStatsModel = usedEmoteService.getEmoteStatForEmote(trackedEmote,
startTime, UsedEmoteTypeParameter.convertToUsedEmoteType(typeEnum));
if(emoteStatsModel.getResult().getAmount() == null) {
return interactionService.replyEmbed(EMOTE_STATS_NO_STATS_AVAILABLE, new Object(), event)
.thenApply(unused -> CommandResult.fromIgnored());
}
return interactionService.replyEmbed(EMOTE_STAT_RESPONSE, emoteStatsModel, event)
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
@@ -176,7 +159,7 @@ public class EmoteStat extends AbstractConditionableCommand {
.templated(true)
.slashCommandConfig(slashCommandConfig)
.async(true)
.messageCommandOnly(true)
.slashCommandOnly(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -4,14 +4,13 @@ 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.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.PaginatorService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.core.utils.ParseUtils;
@@ -24,7 +23,6 @@ import dev.sheldan.abstracto.statistic.emote.service.UsedEmoteService;
import java.util.Arrays;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -47,7 +45,7 @@ public class EmoteStats extends AbstractConditionableCommand {
private UsedEmoteService usedEmoteService;
@Autowired
private ChannelService channelService;
private PaginatorService paginatorService;
@Autowired
private ServerManagementService serverManagementService;
@@ -65,39 +63,6 @@ public class EmoteStats extends AbstractConditionableCommand {
private static final String EMOTE_STATS_DURATION = "period";
private static final String EMOTE_STATS_COMMAND_NAME = "emoteStats";
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
// default is 1.1.1970
Instant statsSince = Instant.EPOCH;
if(!parameters.isEmpty()) {
// subtract the given Duration from the current point in time, if there is any
Duration duration = (Duration) parameters.get(0);
statsSince = Instant.now().minus(duration);
}
AServer server = serverManagementService.loadServer(commandContext.getGuild());
EmoteStatsModel emoteStatsModel = usedEmoteService.getActiveEmoteStatsForServerSince(server, statsSince, null);
List<CompletableFuture<Message>> messagePromises = new ArrayList<>();
// only show embed if static emote stats are available
if(!emoteStatsModel.getStaticEmotes().isEmpty()) {
log.debug("Emote stats has {} static emotes since {}.", emoteStatsModel.getStaticEmotes().size(), statsSince);
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(EMOTE_STATS_STATIC_RESPONSE, emoteStatsModel, commandContext.getChannel()));
}
// only show embed if animated emote stats are available
if(!emoteStatsModel.getAnimatedEmotes().isEmpty()) {
log.debug("Emote stats has {} animated emotes since {}.", emoteStatsModel.getAnimatedEmotes(), statsSince);
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(EMOTE_STATS_ANIMATED_RESPONSE, emoteStatsModel, commandContext.getChannel()));
}
// show an embed if no emote stats are available indicating so
if(!emoteStatsModel.areStatsAvailable()) {
log.info("No emote stats available for guild {} since {}.", commandContext.getGuild().getIdLong(), statsSince);
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(EMOTE_STATS_NO_STATS_AVAILABLE, new Object(), commandContext.getChannel()));
}
return FutureUtils.toSingleFutureGeneric(messagePromises)
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
UsedEmoteTypeParameter typeEnum;
@@ -117,22 +82,23 @@ public class EmoteStats extends AbstractConditionableCommand {
}
AServer server = serverManagementService.loadServer(event.getGuild());
EmoteStatsModel emoteStatsModel = usedEmoteService.getActiveEmoteStatsForServerSince(server, startTime, UsedEmoteTypeParameter.convertToUsedEmoteType(typeEnum));
List<CompletableFuture<Message>> messagePromises = new ArrayList<>();
List<CompletableFuture<Void>> messagePromises = new ArrayList<>();
return event.deferReply().submit().thenCompose(interactionHook -> {
// only show embed if static emote stats are available
if(!emoteStatsModel.getStaticEmotes().isEmpty()) {
log.debug("Emote stats has {} static emotes since {}.", emoteStatsModel.getStaticEmotes().size(), startTime);
messagePromises.addAll(interactionService.sendMessageToInteraction(EMOTE_STATS_STATIC_RESPONSE, emoteStatsModel, interactionHook));
messagePromises.add(paginatorService.sendPaginatorToInteraction(EMOTE_STATS_STATIC_RESPONSE, emoteStatsModel, interactionHook));
}
// only show embed if animated emote stats are available
if(!emoteStatsModel.getAnimatedEmotes().isEmpty()) {
log.debug("Emote stats has {} animated emotes since {}.", emoteStatsModel.getAnimatedEmotes(), startTime);
messagePromises.addAll(interactionService.sendMessageToInteraction(EMOTE_STATS_ANIMATED_RESPONSE, emoteStatsModel, interactionHook));
messagePromises.add(paginatorService.sendPaginatorToInteraction(EMOTE_STATS_ANIMATED_RESPONSE, emoteStatsModel, interactionHook));
}
// show an embed if no emote stats are available indicating so
if(!emoteStatsModel.areStatsAvailable()) {
log.info("No emote stats available for guild {} since {}.", event.getGuild().getIdLong(), startTime);
messagePromises.addAll(interactionService.sendMessageToInteraction(EMOTE_STATS_NO_STATS_AVAILABLE, emoteStatsModel, interactionHook));
return FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(EMOTE_STATS_NO_STATS_AVAILABLE, new Object(), interactionHook))
.thenApply(unused -> CommandResult.fromSuccess());
}
return FutureUtils.toSingleFutureGeneric(messagePromises)
.thenApply(unused -> CommandResult.fromIgnored());
@@ -183,6 +149,7 @@ public class EmoteStats extends AbstractConditionableCommand {
.messageCommandOnly(true)
.async(true)
.slashCommandConfig(slashCommandConfig)
.slashCommandOnly(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -4,7 +4,6 @@ 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;
@@ -12,7 +11,7 @@ import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.PaginatorService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.core.utils.ParseUtils;
@@ -25,7 +24,6 @@ import dev.sheldan.abstracto.statistic.emote.model.EmoteStatsModel;
import dev.sheldan.abstracto.statistic.emote.service.UsedEmoteService;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -48,9 +46,6 @@ public class ExternalEmoteStats extends AbstractConditionableCommand {
@Autowired
private UsedEmoteService usedEmoteService;
@Autowired
private ChannelService channelService;
@Autowired
private ServerManagementService serverManagementService;
@@ -60,6 +55,9 @@ public class ExternalEmoteStats extends AbstractConditionableCommand {
@Autowired
private InteractionService interactionService;
@Autowired
private PaginatorService paginatorService;
public static final String EMOTE_STATS_STATIC_EXTERNAL_RESPONSE = "externalEmoteStats_static_response";
public static final String EMOTE_STATS_ANIMATED_EXTERNAL_RESPONSE = "externalEmoteStats_animated_response";
private static final String EXTERNAL_EMOTE_STATS_USED_EMOTE_TYPE = "type";
@@ -67,42 +65,6 @@ public class ExternalEmoteStats extends AbstractConditionableCommand {
private static final String EXTERNAL_EMOTE_STATS_PERIOD = "period";
private static final String EXTERNAL_EMOTE_STATS_COMMAND_NAME = "externalEmoteStats";
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
// default is 1.1.1970
Instant statsSince = Instant.EPOCH;
if(!parameters.isEmpty()) {
// subtract the given Duration parameter from the current point in time
Duration duration = (Duration) parameters.get(0);
statsSince = Instant.now().minus(duration);
}
AServer server = serverManagementService.loadServer(commandContext.getGuild());
EmoteStatsModel emoteStatsModel = usedEmoteService.getExternalEmoteStatsForServerSince(server, statsSince, null);
List<CompletableFuture<Message>> messagePromises = new ArrayList<>();
// only show embed if static emote stats are available
if(!emoteStatsModel.getStaticEmotes().isEmpty()) {
log.debug("External emote stats has {} static emotes since {}.", emoteStatsModel.getStaticEmotes().size(), statsSince);
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(EMOTE_STATS_STATIC_EXTERNAL_RESPONSE, emoteStatsModel, commandContext.getChannel()));
}
// only show embed if animated emote stats are available
if(!emoteStatsModel.getAnimatedEmotes().isEmpty()) {
log.debug("External emote stats has {} animated emotes since {}.", emoteStatsModel.getAnimatedEmotes(), statsSince);
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(EMOTE_STATS_ANIMATED_EXTERNAL_RESPONSE, emoteStatsModel, commandContext.getChannel()));
}
// show an embed if no emote stats are available indicating so
if(!emoteStatsModel.areStatsAvailable()) {
log.info("No external emote stats available for guild {} since {}.", commandContext.getGuild().getIdLong(), statsSince);
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(EmoteStats.EMOTE_STATS_NO_STATS_AVAILABLE, new Object(), commandContext.getChannel()));
}
return FutureUtils.toSingleFutureGeneric(messagePromises)
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
UsedEmoteTypeParameter typeEnum;
@@ -123,26 +85,25 @@ public class ExternalEmoteStats extends AbstractConditionableCommand {
AServer server = serverManagementService.loadServer(event.getGuild());
EmoteStatsModel emoteStatsModel = usedEmoteService.getExternalEmoteStatsForServerSince(server, startTime, UsedEmoteTypeParameter.convertToUsedEmoteType(typeEnum));
List<CompletableFuture<Message>> messagePromises = new ArrayList<>();
List<CompletableFuture<Void>> messagePromises = new ArrayList<>();
return event.deferReply().submit().thenCompose(interactionHook -> {
// only show embed if static emote stats are available
if (!emoteStatsModel.getStaticEmotes().isEmpty()) {
log.debug("External emote stats has {} static emotes since {}.", emoteStatsModel.getStaticEmotes().size(), startTime);
messagePromises.addAll(
interactionService.sendMessageToInteraction(EMOTE_STATS_STATIC_EXTERNAL_RESPONSE, emoteStatsModel, interactionHook));
messagePromises.add(paginatorService.sendPaginatorToInteraction(EMOTE_STATS_STATIC_EXTERNAL_RESPONSE, emoteStatsModel, interactionHook));
}
// only show embed if animated emote stats are available
if (!emoteStatsModel.getAnimatedEmotes().isEmpty()) {
log.debug("External emote stats has {} animated emotes since {}.", emoteStatsModel.getAnimatedEmotes(), startTime);
messagePromises.addAll(
interactionService.sendMessageToInteraction(EMOTE_STATS_ANIMATED_EXTERNAL_RESPONSE, emoteStatsModel, interactionHook));
messagePromises.add(paginatorService.sendPaginatorToInteraction(EMOTE_STATS_ANIMATED_EXTERNAL_RESPONSE, emoteStatsModel, interactionHook));
}
// show an embed if no emote stats are available indicating so
if (!emoteStatsModel.areStatsAvailable()) {
log.info("No external emote stats available for guild {} since {}.", event.getGuild().getIdLong(), startTime);
messagePromises.addAll(interactionService.sendMessageToInteraction(EmoteStats.EMOTE_STATS_NO_STATS_AVAILABLE, new Object(), interactionHook));
return FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(EmoteStats.EMOTE_STATS_NO_STATS_AVAILABLE, new Object(), interactionHook))
.thenApply(unused -> CommandResult.fromSuccess());
}
return FutureUtils.toSingleFutureGeneric(messagePromises)
@@ -198,6 +159,7 @@ public class ExternalEmoteStats extends AbstractConditionableCommand {
.templated(true)
.messageCommandOnly(true)
.async(true)
.slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true)
.causesReaction(true)

View File

@@ -4,7 +4,6 @@ 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.interaction.slash.SlashCommandConfig;
@@ -23,6 +22,7 @@ import java.util.concurrent.CompletableFuture;
import net.dv8tion.jda.api.entities.emoji.CustomEmoji;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -55,30 +55,21 @@ public class PurgeEmoteStats extends AbstractConditionableCommand {
private static final String PURGE_EMOTE_STATS_PERIOD = "period";
private static final String PURGE_EMOTE_STATS_RESPONSE = "purgeEmoteStats_response";
@Override
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
TrackedEmote fakeTrackedEmote = (TrackedEmote) parameters.get(0);
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByTrackedEmoteServer(fakeTrackedEmote.getTrackedEmoteId());
// default 1.1.1970
Instant since = Instant.EPOCH;
if(parameters.size() > 1) {
// if a Duration is given, subtract it from the current point in time
Duration parameter = (Duration) parameters.get(1);
since = Instant.now().minus(parameter);
}
usedEmoteService.purgeEmoteUsagesSince(trackedEmote, since);
return CommandResult.fromSuccess();
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String emote = slashCommandParameterService.getCommandOption(PURGE_EMOTE_STATS_TRACKED_EMOTE, event, String.class);
Emoji emoji = slashCommandParameterService.loadEmoteFromString(emote, event.getGuild());
if(!(emoji instanceof CustomEmoji)) {
if(emoji instanceof CustomEmoji) {
Long emoteId = ((CustomEmoji) emoji).getIdLong();
return createResponse(event, emoteId);
} else if(StringUtils.isNumeric(emote)) {
return createResponse(event, Long.parseLong(emote));
} else {
throw new TrackedEmoteNotFoundException();
}
Long emoteId = ((CustomEmoji) emoji).getIdLong();
}
private CompletableFuture<CommandResult> createResponse(SlashCommandInteractionEvent event, Long emoteId) {
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByTrackedEmoteServer(new ServerSpecificId(event.getGuild().getIdLong(), emoteId));
// default 1.1.1970
Instant since = Instant.EPOCH;
@@ -128,7 +119,7 @@ public class PurgeEmoteStats extends AbstractConditionableCommand {
.name(PURGE_EMOTE_STATS_COMMAND_NAME)
.module(EmoteTrackingModuleDefinition.EMOTE_TRACKING)
.templated(true)
.messageCommandOnly(true)
.slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true)
.requiresConfirmation(true)

View File

@@ -4,7 +4,6 @@ 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.interaction.slash.SlashCommandConfig;
@@ -37,12 +36,6 @@ public class ResetEmoteStats extends AbstractConditionableCommand {
private static final String RESET_EMOTE_STATS_COMMAND_NAME = "resetEmoteStats";
private static final String RESET_EMOTE_STATS_RESPONSE = "resetEmoteStats_response";
@Override
public CommandResult execute(CommandContext commandContext) {
trackedEmoteService.resetEmoteStats(commandContext.getGuild());
return CommandResult.fromSuccess();
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
trackedEmoteService.resetEmoteStats(event.getGuild());
@@ -71,6 +64,7 @@ public class ResetEmoteStats extends AbstractConditionableCommand {
.messageCommandOnly(true)
.module(EmoteTrackingModuleDefinition.EMOTE_TRACKING)
.templated(true)
.slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true)
.requiresConfirmation(true)

View File

@@ -5,7 +5,6 @@ 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.config.FeatureMode;
@@ -14,7 +13,6 @@ import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.statistic.config.StatisticFeatureDefinition;
import dev.sheldan.abstracto.statistic.config.StatisticSlashCommandNames;
import dev.sheldan.abstracto.statistic.emote.config.EmoteTrackingMode;
@@ -25,6 +23,7 @@ import dev.sheldan.abstracto.statistic.emote.service.management.TrackedEmoteMana
import net.dv8tion.jda.api.entities.emoji.CustomEmoji;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -56,37 +55,29 @@ public class ShowExternalTrackedEmote extends AbstractConditionableCommand {
private static final String SHOW_EXTERNAL_TRACKED_EMOTE_COMMAND_NAME = "showExternalTrackedEmote";
private static final String SHOW_EXTERNAL_TRACKED_EMOTE_TRACKED_EMOTE = "trackedEmote";
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
TrackedEmote fakeTrackedEmote = (TrackedEmote) parameters.get(0);
// load the actual TrackedEmote instance
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByTrackedEmoteServer(fakeTrackedEmote.getTrackedEmoteId());
// the command only works for external emotes
if(!trackedEmote.getExternal()) {
throw new AbstractoTemplatedException("Emote is not external", "showExternalTrackedEmote_emote_is_not_external");
}
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannel(SHOW_EXTERNAL_TRACKED_EMOTE_RESPONSE_TEMPLATE_KEY, trackedEmote, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String emote = slashCommandParameterService.getCommandOption(SHOW_EXTERNAL_TRACKED_EMOTE_TRACKED_EMOTE, event, String.class);
Emoji emoji = slashCommandParameterService.loadEmoteFromString(emote, event.getGuild());
if(emoji instanceof CustomEmoji) {
Long emoteId = ((CustomEmoji) emoji).getIdLong();
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByTrackedEmoteServer(new ServerSpecificId(event.getGuild().getIdLong(), emoteId));
if(!trackedEmote.getExternal()) {
throw new AbstractoTemplatedException("Emote is not external", "showExternalTrackedEmote_emote_is_not_external");
}
return interactionService.replyEmbed(SHOW_EXTERNAL_TRACKED_EMOTE_RESPONSE_TEMPLATE_KEY, trackedEmote, event)
.thenApply(unused -> CommandResult.fromIgnored());
return createResponse(event, emoteId);
} else if(StringUtils.isNumeric(emote)) {
return createResponse(event, Long.parseLong(emote));
} else {
throw new TrackedEmoteNotFoundException();
}
}
private CompletableFuture<CommandResult> createResponse(SlashCommandInteractionEvent event, Long emoteId) {
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByTrackedEmoteServer(new ServerSpecificId(event.getGuild().getIdLong(), emoteId));
if(!trackedEmote.getExternal()) {
throw new AbstractoTemplatedException("Emote is not external", "showExternalTrackedEmote_emote_is_not_external");
}
return interactionService.replyEmbed(SHOW_EXTERNAL_TRACKED_EMOTE_RESPONSE_TEMPLATE_KEY, trackedEmote, event)
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
@@ -117,7 +108,7 @@ public class ShowExternalTrackedEmote extends AbstractConditionableCommand {
.templated(true)
.async(true)
.slashCommandConfig(slashCommandConfig)
.messageCommandOnly(true)
.slashCommandOnly(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -4,13 +4,11 @@ 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.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.FeatureModeService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.statistic.config.StatisticFeatureDefinition;
@@ -39,9 +37,6 @@ public class ShowTrackedEmotes extends AbstractConditionableCommand {
@Autowired
private TrackedEmoteService trackedEmoteService;
@Autowired
private ChannelService channelService;
@Autowired
private FeatureModeService featureModeService;
@@ -62,67 +57,6 @@ public class ShowTrackedEmotes extends AbstractConditionableCommand {
private static final String SHOW_TRACKED_EMOTES_COMMAND_NAME = "showTrackedEmotes";
private static final String SHOW_TRACKED_EMOTES_SHOW_ALL = "showAll";
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
// per default, do not show TrackedEmote for which tracking has been disabled
Boolean showTrackingDisabled = false;
if(!commandContext.getParameters().getParameters().isEmpty()) {
showTrackingDisabled = (Boolean) commandContext.getParameters().getParameters().get(0);
}
TrackedEmoteOverview trackedEmoteOverview = trackedEmoteService.loadTrackedEmoteOverview(commandContext.getGuild(), showTrackingDisabled);
boolean noTrackedEmotesAvailable = true;
List<CompletableFuture<Message>> messagePromises = new ArrayList<>();
// only show the embed, if there are static tracked emotes
if(!trackedEmoteOverview.getStaticEmotes().isEmpty()) {
noTrackedEmotesAvailable = false;
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(SHOW_TRACKED_EMOTES_STATIC_RESPONSE, trackedEmoteOverview, commandContext.getChannel()));
}
// only show the embed if there are animated tracked emotes
if(!trackedEmoteOverview.getAnimatedEmotes().isEmpty()) {
noTrackedEmotesAvailable = false;
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(SHOW_TRACKED_EMOTES_ANIMATED_RESPONSE, trackedEmoteOverview, commandContext.getChannel()));
}
// only show the embed, if there are deleted static emotes
if(!trackedEmoteOverview.getDeletedStaticEmotes().isEmpty()) {
noTrackedEmotesAvailable = false;
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(SHOW_TRACKED_EMOTES_DELETED_STATIC_RESPONSE, trackedEmoteOverview, commandContext.getChannel()));
}
// only show the embed, if there are deleted animated emotes
if(!trackedEmoteOverview.getDeletedAnimatedEmotes().isEmpty()) {
noTrackedEmotesAvailable = false;
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(SHOW_TRACKED_EMOTES_DELETED_ANIMATED_RESPONSE, trackedEmoteOverview, commandContext.getChannel()));
}
boolean externalTrackingEnabled = featureModeService.featureModeActive(StatisticFeatureDefinition.EMOTE_TRACKING, commandContext.getGuild().getIdLong(), EmoteTrackingMode.EXTERNAL_EMOTES);
// only show external emotes if external emotes are enabled
if(externalTrackingEnabled) {
// only show the embed if there are external static emotes
if(!trackedEmoteOverview.getExternalStaticEmotes().isEmpty()) {
noTrackedEmotesAvailable = false;
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(SHOW_TRACKED_EMOTES_EXTERNAL_STATIC_RESPONSE, trackedEmoteOverview, commandContext.getChannel()));
}
// only show the embed if there are external animated emotes
if(!trackedEmoteOverview.getExternalAnimatedEmotes().isEmpty()) {
noTrackedEmotesAvailable = false;
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(SHOW_TRACKED_EMOTES_EXTERNAL_ANIMATED_RESPONSE, trackedEmoteOverview, commandContext.getChannel()));
}
}
// if there are no tracked emotes available, show an embed indicating so
if(noTrackedEmotesAvailable) {
messagePromises.addAll(channelService.sendEmbedTemplateInMessageChannel(SHOW_TRACKED_EMOTES_NO_STATS_AVAILABLE, new Object(), commandContext.getChannel()));
}
return FutureUtils.toSingleFutureGeneric(messagePromises)
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
// per default, do not show TrackedEmote for which tracking has been disabled
@@ -215,7 +149,7 @@ public class ShowTrackedEmotes extends AbstractConditionableCommand {
.templated(true)
.async(true)
.slashCommandConfig(slashCommandConfig)
.messageCommandOnly(true)
.slashCommandOnly(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -4,13 +4,10 @@ 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.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.statistic.config.StatisticFeatureDefinition;
import dev.sheldan.abstracto.statistic.config.StatisticSlashCommandNames;
import dev.sheldan.abstracto.statistic.emote.config.EmoteTrackingModuleDefinition;
@@ -35,23 +32,12 @@ public class SyncTrackedEmotes extends AbstractConditionableCommand {
@Autowired
private TrackedEmoteService trackedEmoteService;
@Autowired
private ChannelService channelService;
@Autowired
private InteractionService interactionService;
static final String SYNC_TRACKED_EMOTES_RESULT_RESPONSE = "syncTrackedEmotes_result_response";
private static final String SYNC_TRACKED_EMOTES_COMMAND_NAME = "syncTrackedEmotes";
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
TrackedEmoteSynchronizationResult syncResult = trackedEmoteService.synchronizeTrackedEmotes(commandContext.getGuild());
// show a result of how many emotes were deleted/added
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannel(SYNC_TRACKED_EMOTES_RESULT_RESPONSE, syncResult, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
TrackedEmoteSynchronizationResult syncResult = trackedEmoteService.synchronizeTrackedEmotes(event.getGuild());
@@ -81,7 +67,7 @@ public class SyncTrackedEmotes extends AbstractConditionableCommand {
.module(EmoteTrackingModuleDefinition.EMOTE_TRACKING)
.templated(true)
.slashCommandConfig(slashCommandConfig)
.messageCommandOnly(true)
.slashCommandOnly(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)

View File

@@ -4,8 +4,6 @@ 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.IncorrectParameterException;
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.interaction.InteractionService;
@@ -62,30 +60,6 @@ public class TrackEmote extends AbstractConditionableCommand {
private static final String TRACK_EMOTE_RESPONSE = "trackEmote_response";
@Override
public CommandResult execute(CommandContext commandContext) {
TrackEmoteParameter emoteToTrack = (TrackEmoteParameter) commandContext.getParameters().getParameters().get(0);
Long emoteId = emoteToTrack.getTrackedEmote().getTrackedEmoteId().getId();
long serverId = commandContext.getGuild().getIdLong();
// if its already a tracked emote, just set the tracking_enabled flag to true
if(trackedEmoteManagementService.trackedEmoteExists(emoteId, serverId)) {
TrackedEmote trackedemote = trackedEmoteManagementService.loadByEmoteId(emoteId, serverId);
trackedEmoteManagementService.enableTrackedEmote(trackedemote);
} else if(emoteToTrack.getEmote() != null) {
// if its a new emote, lets see if its external
boolean external = !emoteService.emoteIsFromGuild(emoteToTrack.getEmote(), commandContext.getGuild());
if(external) {
// this throws an exception if the feature mode is not enabled
featureModeService.validateActiveFeatureMode(serverId, StatisticFeatureDefinition.EMOTE_TRACKING, EmoteTrackingMode.EXTERNAL_EMOTES);
}
trackedEmoteService.createTrackedEmote(emoteToTrack.getEmote(), commandContext.getGuild(), external);
} else {
// in case the ID was not an existing TrackedEmote, and no Emote was given, we need to fail
throw new IncorrectParameterException(this, getConfiguration().getParameters().get(0).getName());
}
return CommandResult.fromSuccess();
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String emote = slashCommandParameterService.getCommandOption(TRACK_EMOTE_EMOTE, event, String.class);
@@ -102,8 +76,7 @@ public class TrackEmote extends AbstractConditionableCommand {
} else {
// if its a new emote, lets see if its external
boolean external = !emoteService.emoteIsFromGuild(customEmoji, event.getGuild());
if (external)
{
if (external) {
// this throws an exception if the feature mode is not enabled
featureModeService.validateActiveFeatureMode(serverId, StatisticFeatureDefinition.EMOTE_TRACKING, EmoteTrackingMode.EXTERNAL_EMOTES);
}
@@ -144,7 +117,7 @@ public class TrackEmote extends AbstractConditionableCommand {
.name(TRACK_EMOTE_COMMAND_NAME)
.module(EmoteTrackingModuleDefinition.EMOTE_TRACKING)
.templated(true)
.messageCommandOnly(true)
.slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true)
.causesReaction(true)

View File

@@ -33,8 +33,8 @@ public class EmoteStatsModel {
private Guild guild;
/**
* Whether or not this model contains *any* stats to render.
* @return Whether or not there are any stats to display
* Whether this model contains *any* stats to render.
* @return Whether there are any stats to display
*/
public boolean areStatsAvailable() {
return !animatedEmotes.isEmpty() || !staticEmotes.isEmpty();

View File

@@ -14,6 +14,7 @@ import dev.sheldan.abstracto.core.templating.model.EmbedFooter;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.templating.service.TemplateServiceBean;
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.scheduling.model.JobParameters;
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
@@ -23,6 +24,7 @@ import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.interactions.InteractionHook;
import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -138,6 +140,16 @@ public class PaginatorServiceBean implements PaginatorService {
.thenAccept(message -> self.setupButtonPayloads(message, setup, serverId));
}
@Override
public CompletableFuture<Void> sendPaginatorToInteraction(String templateKey, Object model, InteractionHook interactionHook) {
Long serverId = interactionHook.getInteraction().getGuild().getIdLong();
PaginatorSetup setup = getPaginatorSetup(templateKey, model, interactionHook.getInteraction().getUser().getIdLong(), serverId);
CompletableFutureList<Message> futures =
new CompletableFutureList<>(interactionService.sendMessageToInteraction(setup.getMessageToSend(), interactionHook));
return futures
.getMainFuture().thenAccept(aVoid -> self.setupButtonPayloads(futures.getFutures().get(0).join(), setup, serverId));
}
private void setupFooters(PaginatorConfiguration configuration, Long serverId) {
for (int i = 0; i < configuration.getEmbedConfigs().size(); i++) {
PaginatorFooterModel paginatorModel = PaginatorFooterModel

View File

@@ -2,6 +2,7 @@ package dev.sheldan.abstracto.core.service;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.interactions.InteractionHook;
import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback;
import java.util.concurrent.CompletableFuture;
@@ -9,4 +10,5 @@ import java.util.concurrent.CompletableFuture;
public interface PaginatorService {
CompletableFuture<Void> createPaginatorFromTemplate(String templateKey, Object model, GuildMessageChannel textChannel, Long userId);
CompletableFuture<Void> createPaginatorFromTemplate(String templateKey, Object model, IReplyCallback callback);
CompletableFuture<Void> sendPaginatorToInteraction(String templateKey, Object model, InteractionHook interactionHook);
}