diff --git a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/command/EmoteStat.java b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/command/EmoteStat.java new file mode 100644 index 000000000..4987a141b --- /dev/null +++ b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/command/EmoteStat.java @@ -0,0 +1,88 @@ +package dev.sheldan.abstracto.statistic.emote.command; + +import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; +import dev.sheldan.abstracto.core.command.config.CommandConfiguration; +import dev.sheldan.abstracto.core.command.config.HelpInfo; +import dev.sheldan.abstracto.core.command.config.Parameter; +import dev.sheldan.abstracto.core.command.execution.CommandContext; +import dev.sheldan.abstracto.core.command.execution.CommandResult; +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import dev.sheldan.abstracto.core.service.ChannelService; +import dev.sheldan.abstracto.core.utils.FutureUtils; +import dev.sheldan.abstracto.statistic.config.StatisticFeatureDefinition; +import dev.sheldan.abstracto.statistic.emote.config.EmoteTrackingModuleDefinition; +import dev.sheldan.abstracto.statistic.emote.model.EmoteStatsResultDisplay; +import dev.sheldan.abstracto.statistic.emote.model.database.TrackedEmote; +import dev.sheldan.abstracto.statistic.emote.service.UsedEmoteService; +import dev.sheldan.abstracto.statistic.emote.service.management.TrackedEmoteManagementService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static dev.sheldan.abstracto.statistic.emote.command.EmoteStats.EMOTE_STATS_NO_STATS_AVAILABLE; + +@Component +@Slf4j +public class EmoteStat extends AbstractConditionableCommand { + + @Autowired + private UsedEmoteService usedEmoteService; + + @Autowired + private ChannelService channelService; + + @Autowired + private TrackedEmoteManagementService trackedEmoteManagementService; + + public static final String EMOTE_STAT_RESPONSE = "emoteStat_response"; + + @Override + public CompletableFuture executeAsync(CommandContext commandContext) { + List 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); + if(emoteStatsModel.getResult().getAmount() == null) { + return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_NO_STATS_AVAILABLE, new Object(), commandContext.getChannel())) + .thenApply(unused -> CommandResult.fromIgnored()); + } + return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STAT_RESPONSE, emoteStatsModel, commandContext.getChannel())) + .thenApply(unused -> CommandResult.fromIgnored()); + } + + @Override + public CommandConfiguration getConfiguration() { + List parameters = new ArrayList<>(); + parameters.add(Parameter.builder().name("trackedEmote").templated(true).type(TrackedEmote.class).build()); + parameters.add(Parameter.builder().name("period").templated(true).optional(true).type(Duration.class).build()); + HelpInfo helpInfo = HelpInfo.builder().templated(true).build(); + return CommandConfiguration.builder() + .name("emoteStat") + .module(EmoteTrackingModuleDefinition.EMOTE_TRACKING) + .templated(true) + .async(true) + .supportsEmbedException(true) + .causesReaction(true) + .parameters(parameters) + .help(helpInfo) + .build(); + } + + @Override + public FeatureDefinition getFeature() { + return StatisticFeatureDefinition.EMOTE_TRACKING; + } +} diff --git a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/command/ShowTrackedEmotes.java b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/command/ShowTrackedEmotes.java index 3125d7f42..120fdf1e5 100644 --- a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/command/ShowTrackedEmotes.java +++ b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/command/ShowTrackedEmotes.java @@ -40,13 +40,13 @@ public class ShowTrackedEmotes extends AbstractConditionableCommand { @Autowired private FeatureModeService featureModeService; - public static final String EMOTE_STATS_STATIC_RESPONSE = "showTrackedEmotes_static_response"; - public static final String EMOTE_STATS_ANIMATED_RESPONSE = "showTrackedEmotes_animated_response"; - public static final String EMOTE_STATS_EXTERNAL_ANIMATED_RESPONSE = "showTrackedEmotes_external_animated_response"; - public static final String EMOTE_STATS_EXTERNAL_STATIC_RESPONSE = "showTrackedEmotes_external_static_response"; - public static final String EMOTE_STATS_DELETED_STATIC_RESPONSE = "showTrackedEmotes_deleted_static_response"; - public static final String EMOTE_STATS_DELETED_ANIMATED_RESPONSE = "showTrackedEmotes_deleted_animated_response"; - public static final String EMOTE_STATS_NO_STATS_AVAILABLE = "showTrackedEmotes_no_emotes_available"; + public static final String SHOW_TRACKED_EMOTES_STATIC_RESPONSE = "showTrackedEmotes_static_response"; + public static final String SHOW_TRACKED_EMOTES_ANIMATED_RESPONSE = "showTrackedEmotes_animated_response"; + public static final String SHOW_TRACKED_EMOTES_EXTERNAL_ANIMATED_RESPONSE = "showTrackedEmotes_external_animated_response"; + public static final String SHOW_TRACKED_EMOTES_EXTERNAL_STATIC_RESPONSE = "showTrackedEmotes_external_static_response"; + public static final String SHOW_TRACKED_EMOTES_DELETED_STATIC_RESPONSE = "showTrackedEmotes_deleted_static_response"; + public static final String SHOW_TRACKED_EMOTES_DELETED_ANIMATED_RESPONSE = "showTrackedEmotes_deleted_animated_response"; + public static final String SHOW_TRACKED_EMOTES_NO_STATS_AVAILABLE = "showTrackedEmotes_no_emotes_available"; @Override public CompletableFuture executeAsync(CommandContext commandContext) { @@ -63,25 +63,25 @@ public class ShowTrackedEmotes extends AbstractConditionableCommand { // only show the embed, if there are static tracked emotes if(!trackedEmoteOverview.getStaticEmotes().isEmpty()) { noTrackedEmotesAvailable = false; - messagePromises.addAll(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_STATIC_RESPONSE, trackedEmoteOverview, commandContext.getChannel())); + messagePromises.addAll(channelService.sendEmbedTemplateInTextChannelList(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.sendEmbedTemplateInTextChannelList(EMOTE_STATS_ANIMATED_RESPONSE, trackedEmoteOverview, commandContext.getChannel())); + messagePromises.addAll(channelService.sendEmbedTemplateInTextChannelList(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.sendEmbedTemplateInTextChannelList(EMOTE_STATS_DELETED_STATIC_RESPONSE, trackedEmoteOverview, commandContext.getChannel())); + messagePromises.addAll(channelService.sendEmbedTemplateInTextChannelList(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.sendEmbedTemplateInTextChannelList(EMOTE_STATS_DELETED_ANIMATED_RESPONSE, trackedEmoteOverview, commandContext.getChannel())); + messagePromises.addAll(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_DELETED_ANIMATED_RESPONSE, trackedEmoteOverview, commandContext.getChannel())); } boolean externalTrackingEnabled = featureModeService.featureModeActive(StatisticFeatureDefinition.EMOTE_TRACKING, commandContext.getGuild().getIdLong(), EmoteTrackingMode.EXTERNAL_EMOTES); @@ -92,19 +92,19 @@ public class ShowTrackedEmotes extends AbstractConditionableCommand { // only show the embed if there are external static emotes if(!trackedEmoteOverview.getExternalStaticEmotes().isEmpty()) { noTrackedEmotesAvailable = false; - messagePromises.addAll(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_EXTERNAL_STATIC_RESPONSE, trackedEmoteOverview, commandContext.getChannel())); + messagePromises.addAll(channelService.sendEmbedTemplateInTextChannelList(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.sendEmbedTemplateInTextChannelList(EMOTE_STATS_EXTERNAL_ANIMATED_RESPONSE, trackedEmoteOverview, commandContext.getChannel())); + messagePromises.addAll(channelService.sendEmbedTemplateInTextChannelList(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.sendEmbedTemplateInTextChannelList(EMOTE_STATS_NO_STATS_AVAILABLE, new Object(), commandContext.getChannel())); + messagePromises.addAll(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_NO_STATS_AVAILABLE, new Object(), commandContext.getChannel())); } return FutureUtils.toSingleFutureGeneric(messagePromises) .thenApply(unused -> CommandResult.fromIgnored()); diff --git a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/converter/EmoteStatsConverter.java b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/converter/EmoteStatsConverter.java index aa30499bc..889922036 100644 --- a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/converter/EmoteStatsConverter.java +++ b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/converter/EmoteStatsConverter.java @@ -36,18 +36,7 @@ public class EmoteStatsConverter { Guild relevantGuild = guildService.getGuildById(resultList.get(0).getServerId()); EmoteStatsModel resultingModel = EmoteStatsModel.builder().build(); resultList.forEach(emoteStatsResult -> { - TrackedEmote trackedEmote = trackedEmoteManagementService.loadByEmoteId(emoteStatsResult.getEmoteId(), emoteStatsResult.getServerId()); - Emote loadedEmote = null; - // if the emote should still exist, we try to load it - if(!trackedEmote.getExternal() && !trackedEmote.getDeleted()) { - loadedEmote = relevantGuild.getEmoteById(trackedEmote.getTrackedEmoteId().getId()); - } - EmoteStatsResultDisplay display = EmoteStatsResultDisplay - .builder() - .emote(loadedEmote) - .result(emoteStatsResult) - .trackedEmote(trackedEmote) - .build(); + EmoteStatsResultDisplay display = convertEmoteStatsResult(relevantGuild, emoteStatsResult); if(display.getTrackedEmote().getAnimated()) { resultingModel.getAnimatedEmotes().add(display); } else { @@ -56,4 +45,24 @@ public class EmoteStatsConverter { }); return resultingModel; } + + public EmoteStatsResultDisplay convertEmoteStatsResultToDisplay(EmoteStatsResult emoteStatsResult) { + Guild relevantGuild = guildService.getGuildById(emoteStatsResult.getServerId()); + return convertEmoteStatsResult(relevantGuild, emoteStatsResult); + } + + private EmoteStatsResultDisplay convertEmoteStatsResult(Guild relevantGuild, EmoteStatsResult emoteStatsResult) { + TrackedEmote trackedEmote = trackedEmoteManagementService.loadByEmoteId(emoteStatsResult.getEmoteId(), emoteStatsResult.getServerId()); + Emote loadedEmote = null; + // if the emote should still exist, we try to load it + if(!trackedEmote.getExternal() && !trackedEmote.getDeleted()) { + loadedEmote = relevantGuild.getEmoteById(trackedEmote.getTrackedEmoteId().getId()); + } + return EmoteStatsResultDisplay + .builder() + .emote(loadedEmote) + .result(emoteStatsResult) + .trackedEmote(trackedEmote) + .build(); + } } diff --git a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/repository/UsedEmoteRepository.java b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/repository/UsedEmoteRepository.java index e12b40768..5fc88e88a 100644 --- a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/repository/UsedEmoteRepository.java +++ b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/repository/UsedEmoteRepository.java @@ -63,6 +63,13 @@ public interface UsedEmoteRepository extends JpaRepository getCurrentlyExistingEmoteStatsForServerSince(@Param("server_id") Long serverId, @Param("start_date") Instant since); + @Query(value = "select :tracked_emote_id as emoteId, :server_id as serverId, sum(us.amount) as amount " + + "from used_emote us " + + "where us.use_date >= date_trunc('day', cast(:start_date AS timestamp)) " + + "and us.server_id = :server_id " + + "and us.emote_id = :tracked_emote_id", nativeQuery = true) + EmoteStatsResult getEmoteStatForTrackedEmote(@Param("tracked_emote_id") Long trackedEmoteId, @Param("server_id") Long serverId, @Param("start_date") Instant since); + void deleteByEmoteId_EmoteIdAndEmoteId_ServerIdAndEmoteId_UseDateGreaterThan(Long emoteId, Long serverId, Instant timestamp); List getByEmoteId_ServerIdAndEmoteId_UseDateGreaterThan(Long emoteId, Instant timestamp); diff --git a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/service/UsedEmoteServiceBean.java b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/service/UsedEmoteServiceBean.java index cdd1c54d8..855794b10 100644 --- a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/service/UsedEmoteServiceBean.java +++ b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/service/UsedEmoteServiceBean.java @@ -4,6 +4,7 @@ import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.statistic.emote.converter.EmoteStatsConverter; import dev.sheldan.abstracto.statistic.emote.model.EmoteStatsModel; import dev.sheldan.abstracto.statistic.emote.model.EmoteStatsResult; +import dev.sheldan.abstracto.statistic.emote.model.EmoteStatsResultDisplay; import dev.sheldan.abstracto.statistic.emote.model.database.TrackedEmote; import dev.sheldan.abstracto.statistic.emote.service.management.UsedEmoteManagementService; import lombok.extern.slf4j.Slf4j; @@ -48,6 +49,12 @@ public class UsedEmoteServiceBean implements UsedEmoteService { return converter.fromEmoteStatsResults(emoteStatsResults); } + @Override + public EmoteStatsResultDisplay getEmoteStatForEmote(TrackedEmote trackedEmote, Instant since) { + EmoteStatsResult emoteStatsResult = usedEmoteManagementService.loadEmoteStatForEmote(trackedEmote, since); + return converter.convertEmoteStatsResultToDisplay(emoteStatsResult); + } + @Override public void purgeEmoteUsagesSince(TrackedEmote emote, Instant since) { log.info("Purging emote {} in server {} since {}.", emote.getTrackedEmoteId().getId(), emote.getTrackedEmoteId().getServerId(), since); diff --git a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/service/management/UsedEmoteManagementServiceBean.java b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/service/management/UsedEmoteManagementServiceBean.java index a789df35b..7c68edfb7 100644 --- a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/service/management/UsedEmoteManagementServiceBean.java +++ b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/java/dev/sheldan/abstracto/statistic/emote/service/management/UsedEmoteManagementServiceBean.java @@ -67,6 +67,11 @@ public class UsedEmoteManagementServiceBean implements UsedEmoteManagementServic return usedEmoteRepository.getCurrentlyExistingEmoteStatsForServerSince(server.getId(), since); } + @Override + public EmoteStatsResult loadEmoteStatForEmote(TrackedEmote trackedEmote, Instant since) { + return usedEmoteRepository.getEmoteStatForTrackedEmote(trackedEmote.getTrackedEmoteId().getId(), trackedEmote.getTrackedEmoteId().getServerId(), since); + } + @Override public void purgeEmoteUsagesSince(TrackedEmote emote, Instant since) { usedEmoteRepository.deleteByEmoteId_EmoteIdAndEmoteId_ServerIdAndEmoteId_UseDateGreaterThan(emote.getTrackedEmoteId().getId(), emote.getTrackedEmoteId().getServerId(), since); diff --git a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/resources/migrations/1.3.10/collection.xml b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/resources/migrations/1.3.10/collection.xml new file mode 100644 index 000000000..121b5aadf --- /dev/null +++ b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/resources/migrations/1.3.10/collection.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/resources/migrations/1.3.10/seedData/command.xml b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/resources/migrations/1.3.10/seedData/command.xml new file mode 100644 index 000000000..2fd1c8b18 --- /dev/null +++ b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/resources/migrations/1.3.10/seedData/command.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/resources/migrations/1.3.10/seedData/data.xml b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/resources/migrations/1.3.10/seedData/data.xml new file mode 100644 index 000000000..c048f6f53 --- /dev/null +++ b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/resources/migrations/1.3.10/seedData/data.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/resources/migrations/statistic-changeLog.xml b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/resources/migrations/statistic-changeLog.xml index f46b3fb15..f602514c6 100644 --- a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/resources/migrations/statistic-changeLog.xml +++ b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/main/resources/migrations/statistic-changeLog.xml @@ -7,4 +7,5 @@ http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" > + \ No newline at end of file diff --git a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/test/java/dev/sheldan/abstracto/statistic/emote/command/ShowTrackedEmotesTest.java b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/test/java/dev/sheldan/abstracto/statistic/emote/command/ShowTrackedEmotesTest.java index 31ff24ccf..d96a5a1a3 100644 --- a/abstracto-application/abstracto-modules/statistic/statistic-impl/src/test/java/dev/sheldan/abstracto/statistic/emote/command/ShowTrackedEmotesTest.java +++ b/abstracto-application/abstracto-modules/statistic/statistic-impl/src/test/java/dev/sheldan/abstracto/statistic/emote/command/ShowTrackedEmotesTest.java @@ -51,7 +51,7 @@ public class ShowTrackedEmotesTest { when(commandContext.getGuild().getIdLong()).thenReturn(SERVER_ID); TrackedEmoteOverview overview = Mockito.mock(TrackedEmoteOverview.class); when(featureModeService.featureModeActive(StatisticFeatureDefinition.EMOTE_TRACKING, SERVER_ID, EmoteTrackingMode.EXTERNAL_EMOTES)).thenReturn(false); - when(channelService.sendEmbedTemplateInTextChannelList(eq(EMOTE_STATS_NO_STATS_AVAILABLE), any(), eq(commandContext.getChannel()))).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(eq(SHOW_TRACKED_EMOTES_NO_STATS_AVAILABLE), any(), eq(commandContext.getChannel()))).thenReturn(CommandTestUtilities.messageFutureList()); when(trackedEmoteService.loadTrackedEmoteOverview(commandContext.getGuild(), false)).thenReturn(overview); CompletableFuture asyncResult = testUnit.executeAsync(commandContext); CommandTestUtilities.checkSuccessfulCompletionAsync(asyncResult); @@ -64,7 +64,7 @@ public class ShowTrackedEmotesTest { when(commandContext.getGuild().getIdLong()).thenReturn(SERVER_ID); TrackedEmoteOverview overview = Mockito.mock(TrackedEmoteOverview.class); when(featureModeService.featureModeActive(StatisticFeatureDefinition.EMOTE_TRACKING, SERVER_ID, EmoteTrackingMode.EXTERNAL_EMOTES)).thenReturn(false); - when(channelService.sendEmbedTemplateInTextChannelList(eq(EMOTE_STATS_NO_STATS_AVAILABLE), any(), eq(commandContext.getChannel()))).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(eq(SHOW_TRACKED_EMOTES_NO_STATS_AVAILABLE), any(), eq(commandContext.getChannel()))).thenReturn(CommandTestUtilities.messageFutureList()); when(trackedEmoteService.loadTrackedEmoteOverview(commandContext.getGuild(), true)).thenReturn(overview); CompletableFuture asyncResult = testUnit.executeAsync(commandContext); CommandTestUtilities.checkSuccessfulCompletionAsync(asyncResult); @@ -78,7 +78,7 @@ public class ShowTrackedEmotesTest { TrackedEmoteOverview overview = Mockito.mock(TrackedEmoteOverview.class); AvailableTrackedEmote staticEmote = Mockito.mock(AvailableTrackedEmote.class); when(featureModeService.featureModeActive(StatisticFeatureDefinition.EMOTE_TRACKING, SERVER_ID, EmoteTrackingMode.EXTERNAL_EMOTES)).thenReturn(false); - when(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_STATIC_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_STATIC_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); when(overview.getStaticEmotes()).thenReturn(Arrays.asList(staticEmote)); when(trackedEmoteService.loadTrackedEmoteOverview(commandContext.getGuild(), false)).thenReturn(overview); CompletableFuture asyncResult = testUnit.executeAsync(commandContext); @@ -94,7 +94,7 @@ public class ShowTrackedEmotesTest { when(featureModeService.featureModeActive(StatisticFeatureDefinition.EMOTE_TRACKING, SERVER_ID, EmoteTrackingMode.EXTERNAL_EMOTES)).thenReturn(false); TrackedEmoteOverview overview = Mockito.mock(TrackedEmoteOverview.class); AvailableTrackedEmote animatedEmote = Mockito.mock(AvailableTrackedEmote.class); - when(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_ANIMATED_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_ANIMATED_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); when(overview.getAnimatedEmotes()).thenReturn(Arrays.asList(animatedEmote)); when(trackedEmoteService.loadTrackedEmoteOverview(commandContext.getGuild(), false)).thenReturn(overview); CompletableFuture asyncResult = testUnit.executeAsync(commandContext); @@ -110,7 +110,7 @@ public class ShowTrackedEmotesTest { TrackedEmoteOverview overview = Mockito.mock(TrackedEmoteOverview.class); when(featureModeService.featureModeActive(StatisticFeatureDefinition.EMOTE_TRACKING, SERVER_ID, EmoteTrackingMode.EXTERNAL_EMOTES)).thenReturn(false); TrackedEmote animatedEmote = Mockito.mock(TrackedEmote.class); - when(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_DELETED_STATIC_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_DELETED_STATIC_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); when(overview.getDeletedStaticEmotes()).thenReturn(Arrays.asList(animatedEmote)); when(trackedEmoteService.loadTrackedEmoteOverview(commandContext.getGuild(), false)).thenReturn(overview); CompletableFuture asyncResult = testUnit.executeAsync(commandContext); @@ -126,7 +126,7 @@ public class ShowTrackedEmotesTest { TrackedEmoteOverview overview = Mockito.mock(TrackedEmoteOverview.class); when(featureModeService.featureModeActive(StatisticFeatureDefinition.EMOTE_TRACKING, SERVER_ID, EmoteTrackingMode.EXTERNAL_EMOTES)).thenReturn(false); TrackedEmote animatedEmote = Mockito.mock(TrackedEmote.class); - when(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_DELETED_ANIMATED_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_DELETED_ANIMATED_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); when(overview.getDeletedAnimatedEmotes()).thenReturn(Arrays.asList(animatedEmote)); when(trackedEmoteService.loadTrackedEmoteOverview(commandContext.getGuild(), false)).thenReturn(overview); CompletableFuture asyncResult = testUnit.executeAsync(commandContext); @@ -143,7 +143,7 @@ public class ShowTrackedEmotesTest { TrackedEmoteOverview overview = Mockito.mock(TrackedEmoteOverview.class); when(featureModeService.featureModeActive(StatisticFeatureDefinition.EMOTE_TRACKING, SERVER_ID, EmoteTrackingMode.EXTERNAL_EMOTES)).thenReturn(true); TrackedEmote animatedEmote = Mockito.mock(TrackedEmote.class); - when(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_EXTERNAL_STATIC_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_EXTERNAL_STATIC_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); when(overview.getExternalStaticEmotes()).thenReturn(Arrays.asList(animatedEmote)); when(trackedEmoteService.loadTrackedEmoteOverview(commandContext.getGuild(), false)).thenReturn(overview); CompletableFuture asyncResult = testUnit.executeAsync(commandContext); @@ -159,7 +159,7 @@ public class ShowTrackedEmotesTest { TrackedEmoteOverview overview = Mockito.mock(TrackedEmoteOverview.class); when(featureModeService.featureModeActive(StatisticFeatureDefinition.EMOTE_TRACKING, SERVER_ID, EmoteTrackingMode.EXTERNAL_EMOTES)).thenReturn(true); TrackedEmote animatedEmote = Mockito.mock(TrackedEmote.class); - when(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_EXTERNAL_ANIMATED_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_EXTERNAL_ANIMATED_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); when(overview.getExternalAnimatedEmotes()).thenReturn(Arrays.asList(animatedEmote)); when(trackedEmoteService.loadTrackedEmoteOverview(commandContext.getGuild(), false)).thenReturn(overview); CompletableFuture asyncResult = testUnit.executeAsync(commandContext); @@ -175,12 +175,12 @@ public class ShowTrackedEmotesTest { TrackedEmoteOverview overview = Mockito.mock(TrackedEmoteOverview.class); when(featureModeService.featureModeActive(StatisticFeatureDefinition.EMOTE_TRACKING, SERVER_ID, EmoteTrackingMode.EXTERNAL_EMOTES)).thenReturn(true); TrackedEmote animatedEmote = Mockito.mock(TrackedEmote.class); - when(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_STATIC_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); - when(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_ANIMATED_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); - when(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_DELETED_STATIC_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); - when(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_DELETED_ANIMATED_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); - when(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_EXTERNAL_STATIC_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); - when(channelService.sendEmbedTemplateInTextChannelList(EMOTE_STATS_EXTERNAL_ANIMATED_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_STATIC_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_ANIMATED_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_DELETED_STATIC_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_DELETED_ANIMATED_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_EXTERNAL_STATIC_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); + when(channelService.sendEmbedTemplateInTextChannelList(SHOW_TRACKED_EMOTES_EXTERNAL_ANIMATED_RESPONSE, overview, commandContext.getChannel())).thenReturn(CommandTestUtilities.messageFutureList()); when(overview.getExternalAnimatedEmotes()).thenReturn(Arrays.asList(animatedEmote)); when(overview.getExternalStaticEmotes()).thenReturn(Arrays.asList(animatedEmote)); AvailableTrackedEmote trackedEmote = Mockito.mock(AvailableTrackedEmote.class); @@ -198,25 +198,25 @@ public class ShowTrackedEmotesTest { private void verifyNoMessage(CommandContext commandContext, boolean noStats, boolean staticEmote, boolean animatedEmote, boolean deletedStatic, boolean deletedAnimated, boolean externalStatic, boolean externalAnimated) { if(noStats) { - verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(EMOTE_STATS_NO_STATS_AVAILABLE), any(), eq(commandContext.getChannel())); + verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(SHOW_TRACKED_EMOTES_NO_STATS_AVAILABLE), any(), eq(commandContext.getChannel())); } if(staticEmote) { - verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(EMOTE_STATS_STATIC_RESPONSE), any(), eq(commandContext.getChannel())); + verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(SHOW_TRACKED_EMOTES_STATIC_RESPONSE), any(), eq(commandContext.getChannel())); } if(animatedEmote) { - verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(EMOTE_STATS_ANIMATED_RESPONSE), any(), eq(commandContext.getChannel())); + verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(SHOW_TRACKED_EMOTES_ANIMATED_RESPONSE), any(), eq(commandContext.getChannel())); } if(deletedStatic) { - verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(EMOTE_STATS_DELETED_STATIC_RESPONSE), any(), eq(commandContext.getChannel())); + verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(SHOW_TRACKED_EMOTES_DELETED_STATIC_RESPONSE), any(), eq(commandContext.getChannel())); } if(deletedAnimated) { - verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(EMOTE_STATS_DELETED_ANIMATED_RESPONSE), any(), eq(commandContext.getChannel())); + verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(SHOW_TRACKED_EMOTES_DELETED_ANIMATED_RESPONSE), any(), eq(commandContext.getChannel())); } if(externalStatic) { - verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(EMOTE_STATS_EXTERNAL_STATIC_RESPONSE), any(), eq(commandContext.getChannel())); + verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(SHOW_TRACKED_EMOTES_EXTERNAL_STATIC_RESPONSE), any(), eq(commandContext.getChannel())); } if(externalAnimated) { - verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(EMOTE_STATS_EXTERNAL_ANIMATED_RESPONSE), any(), eq(commandContext.getChannel())); + verify(channelService, times(0)).sendEmbedTemplateInTextChannelList(eq(SHOW_TRACKED_EMOTES_EXTERNAL_ANIMATED_RESPONSE), any(), eq(commandContext.getChannel())); } } diff --git a/abstracto-application/abstracto-modules/statistic/statistic-int/src/main/java/dev/sheldan/abstracto/statistic/emote/service/UsedEmoteService.java b/abstracto-application/abstracto-modules/statistic/statistic-int/src/main/java/dev/sheldan/abstracto/statistic/emote/service/UsedEmoteService.java index 9348f09da..7a21f34c3 100644 --- a/abstracto-application/abstracto-modules/statistic/statistic-int/src/main/java/dev/sheldan/abstracto/statistic/emote/service/UsedEmoteService.java +++ b/abstracto-application/abstracto-modules/statistic/statistic-int/src/main/java/dev/sheldan/abstracto/statistic/emote/service/UsedEmoteService.java @@ -2,6 +2,7 @@ package dev.sheldan.abstracto.statistic.emote.service; import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.statistic.emote.model.EmoteStatsModel; +import dev.sheldan.abstracto.statistic.emote.model.EmoteStatsResultDisplay; import dev.sheldan.abstracto.statistic.emote.model.database.TrackedEmote; import java.time.Instant; @@ -46,6 +47,7 @@ public interface UsedEmoteService { * @return An {@link EmoteStatsModel} containing the statistics split by animated and static {@link net.dv8tion.jda.api.entities.Emote} */ EmoteStatsModel getActiveEmoteStatsForServerSince(AServer server, Instant since); + EmoteStatsResultDisplay getEmoteStatForEmote(TrackedEmote trackedEmote, Instant since); /** * Removes all {@link dev.sheldan.abstracto.statistic.emote.model.database.UsedEmote} for the given {@link TrackedEmote} which are younger diff --git a/abstracto-application/abstracto-modules/statistic/statistic-int/src/main/java/dev/sheldan/abstracto/statistic/emote/service/management/UsedEmoteManagementService.java b/abstracto-application/abstracto-modules/statistic/statistic-int/src/main/java/dev/sheldan/abstracto/statistic/emote/service/management/UsedEmoteManagementService.java index 2515a62f4..2dc406aee 100644 --- a/abstracto-application/abstracto-modules/statistic/statistic-int/src/main/java/dev/sheldan/abstracto/statistic/emote/service/management/UsedEmoteManagementService.java +++ b/abstracto-application/abstracto-modules/statistic/statistic-int/src/main/java/dev/sheldan/abstracto/statistic/emote/service/management/UsedEmoteManagementService.java @@ -77,6 +77,7 @@ public interface UsedEmoteManagementService { * @return A list of {@link EmoteStatsResult} from the {@link AServer} newer than the given {@link Instant} for all active {@link TrackedEmote} */ List loadActiveEmoteStatsForServerSince(AServer server, Instant since); + EmoteStatsResult loadEmoteStatForEmote(TrackedEmote trackedEmote, Instant since); /** * Deletes all emote usages for the {@link TrackedEmote} which are younger than the given {@link Instant}