[AB-154] split up private and guild message received handler, split handlers into async and sync handlers

adapting the tests and improving tests to reduce usage of MockUtils
adding some util methods to message bean
extending cache for cached messages
enabling to build cached messages from messages in DM channels (they are not part of the message cache)
splitting multiple listeners to different beans, for better overview (emote updated)
adding convenience service for reactions specifically
split cached reaction and cached reactions, singular only contains one user, while the later contains all users
fixing liquibase configuration for assigned role user
fixing assignable role not having a transaction
moved caching update a bit earlier in various methods
fixing bug that a manual unmute caused duplicate unmute notification
fixing short scheduled unmute not checking the new mute state
limiting parameters for roll
This commit is contained in:
Sheldan
2020-12-20 19:21:24 +01:00
parent 69aa82e26e
commit fb3ed69650
200 changed files with 4253 additions and 1813 deletions

View File

@@ -3,7 +3,8 @@ package dev.sheldan.abstracto.statistic.emotes.listener;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.FeatureMode;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.EmoteCreatedListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncEmoteCreatedListener;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.config.StatisticFeatures;
import dev.sheldan.abstracto.statistic.emotes.config.EmoteTrackingMode;
import dev.sheldan.abstracto.statistic.emotes.service.management.TrackedEmoteManagementService;
@@ -22,16 +23,15 @@ import java.util.List;
*/
@Component
@Slf4j
public class CreateTrackedEmoteListener implements EmoteCreatedListener {
public class CreateTrackedEmoteListener implements AsyncEmoteCreatedListener {
@Autowired
private TrackedEmoteManagementService trackedEmoteManagementService;
@Override
public void emoteCreated(Emote createdEmote) {
// guild should be available, because we are in the emote created event, and the emote object should come from there
log.info("Creating tracked emote {} in server {}.", createdEmote.getGuild().getIdLong(), createdEmote.getIdLong());
trackedEmoteManagementService.createTrackedEmote(createdEmote, createdEmote.getGuild());
public void emoteCreated(CachedEmote createdEmote) {
log.info("Creating tracked emote {} in server {}.", createdEmote.getServerId(), createdEmote.getEmoteId());
trackedEmoteManagementService.createTrackedEmote(createdEmote);
}
@Override

View File

@@ -3,7 +3,8 @@ package dev.sheldan.abstracto.statistic.emotes.listener;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.FeatureMode;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.EmoteDeletedListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncEmoteDeletedListener;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.config.StatisticFeatures;
import dev.sheldan.abstracto.statistic.emotes.config.EmoteTrackingMode;
import dev.sheldan.abstracto.statistic.emotes.service.management.TrackedEmoteManagementService;
@@ -22,15 +23,15 @@ import java.util.List;
*/
@Component
@Slf4j
public class DeleteTrackedEmoteListener implements EmoteDeletedListener {
public class DeleteTrackedEmoteListener implements AsyncEmoteDeletedListener {
@Autowired
private TrackedEmoteManagementService trackedEmoteManagementService;
@Override
public void emoteDeleted(Emote deletedEmote) {
log.info("Marking tracked emote {} in gild {} as deleted.", deletedEmote.getId(), deletedEmote.getGuild().getIdLong());
trackedEmoteManagementService.markAsDeleted(deletedEmote.getGuild().getIdLong(), deletedEmote.getIdLong());
public void emoteDeleted(CachedEmote deletedEmote) {
log.info("Marking tracked emote {} in gild {} as deleted.", deletedEmote.getEmoteId(), deletedEmote.getServerId());
trackedEmoteManagementService.markAsDeleted(deletedEmote.getServerId(), deletedEmote.getEmoteId());
}
@Override

View File

@@ -1,14 +1,12 @@
package dev.sheldan.abstracto.statistic.emotes.listener;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.MessageReceivedListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageReceivedListener;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.statistic.config.StatisticFeatures;
import dev.sheldan.abstracto.statistic.emotes.service.TrackedEmoteService;
import net.dv8tion.jda.api.entities.Emote;
import net.dv8tion.jda.api.entities.ISnowflake;
import net.dv8tion.jda.api.entities.Message;
import org.apache.commons.collections4.Bag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -21,17 +19,19 @@ import java.util.stream.Collectors;
* the runtime storage for emote tracking.
*/
@Component
public class EmoteTrackingListener implements MessageReceivedListener {
public class EmoteTrackingListener implements AsyncMessageReceivedListener {
@Autowired
private TrackedEmoteService trackedEmoteService;
@Autowired
private BotService botService;
@Override
public void execute(Message message) {
Bag<Emote> emotesBag = message.getEmotesBag();
Map<Long, List<Emote>> collect = emotesBag.stream().collect(Collectors.groupingBy(ISnowflake::getIdLong));
public void execute(CachedMessage message) {
Map<Long, List<CachedEmote>> collect = message.getEmotes().stream().collect(Collectors.groupingBy(CachedEmote::getEmoteId));
collect.values().forEach(groupedEmotes ->
trackedEmoteService.addEmoteToRuntimeStorage(groupedEmotes.get(0), message.getGuild(), (long) groupedEmotes.size())
trackedEmoteService.addEmoteToRuntimeStorage(groupedEmotes.get(0), botService.getGuildById(message.getServerId()), (long) groupedEmotes.size())
);
}
@@ -40,8 +40,4 @@ public class EmoteTrackingListener implements MessageReceivedListener {
return StatisticFeatures.EMOTE_TRACKING;
}
@Override
public Integer getPriority() {
return ListenerPriority.LOW;
}
}

View File

@@ -3,12 +3,12 @@ package dev.sheldan.abstracto.statistic.emotes.listener;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.FeatureMode;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.EmoteUpdatedListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncEmoteUpdatedListener;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.config.StatisticFeatures;
import dev.sheldan.abstracto.statistic.emotes.config.EmoteTrackingMode;
import dev.sheldan.abstracto.statistic.emotes.model.database.TrackedEmote;
import dev.sheldan.abstracto.statistic.emotes.service.management.TrackedEmoteManagementService;
import net.dv8tion.jda.api.entities.Emote;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -20,14 +20,14 @@ import java.util.List;
* if the emote is tracked. This is only executed if the EMOTE_TRACKING feature is enabled,and if the AUTO_TRACK feature mode is enabled.
*/
@Component
public class UpdateTrackedEmoteListener implements EmoteUpdatedListener {
public class UpdateTrackedEmoteListener implements AsyncEmoteUpdatedListener {
@Autowired
private TrackedEmoteManagementService trackedEmoteManagementService;
@Override
public void emoteUpdated(Emote updatedEmote, String oldValue, String newValue) {
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByEmote(updatedEmote);
public void emoteUpdated(CachedEmote updatedEmote, String oldValue, String newValue) {
TrackedEmote trackedEmote = trackedEmoteManagementService.loadByEmoteId(updatedEmote.getEmoteId(), updatedEmote.getServerId());
trackedEmoteManagementService.changeName(trackedEmote, newValue);
}

View File

@@ -1,5 +1,6 @@
package dev.sheldan.abstracto.statistic.emotes.service;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.statistic.emotes.model.PersistingEmote;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Emote;
@@ -26,12 +27,12 @@ public class TrackedEmoteRuntimeServiceBean implements TrackedEmoteRuntimeServic
}
@Override
public void addEmoteForServer(Emote emote, Guild guild, boolean external) {
public void addEmoteForServer(CachedEmote emote, Guild guild, boolean external) {
addEmoteForServer(emote, guild, 1L, external);
}
@Override
public void addEmoteForServer(Emote emote, Guild guild, Long count, boolean external) {
public void addEmoteForServer(CachedEmote emote, Guild guild, Long count, boolean external) {
takeLock();
try {
// generate an appropriate key
@@ -46,7 +47,7 @@ public class TrackedEmoteRuntimeServiceBean implements TrackedEmoteRuntimeServic
List<PersistingEmote> persistingEmotes = elementsForKey.get(guild.getIdLong());
Optional<PersistingEmote> existingEmote = persistingEmotes
.stream()
.filter(persistingEmote -> persistingEmote.getEmoteId().equals(emote.getIdLong()))
.filter(persistingEmote -> persistingEmote.getEmoteId().equals(emote.getEmoteId()))
.findFirst();
// if it exists already, just increment the counter by the given amount
existingEmote.ifPresent(persistingEmote -> persistingEmote.setCount(persistingEmote.getCount() + count));
@@ -77,20 +78,20 @@ public class TrackedEmoteRuntimeServiceBean implements TrackedEmoteRuntimeServic
}
@Override
public PersistingEmote createFromEmote(Guild guild, Emote emote, boolean external) {
public PersistingEmote createFromEmote(Guild guild, CachedEmote emote, boolean external) {
return createFromEmote(guild, emote, 1L, external);
}
@Override
public PersistingEmote createFromEmote(Guild guild, Emote emote, Long count, boolean external) {
String url = external ? emote.getImageUrl() : null;
public PersistingEmote createFromEmote(Guild guild, CachedEmote emote, Long count, boolean external) {
String url = external ? emote.getImageURL() : null;
return PersistingEmote
.builder()
.animated(emote.isAnimated())
.emoteId(emote.getIdLong())
.animated(emote.getAnimated())
.emoteId(emote.getEmoteId())
.external(external)
.externalUrl(url)
.emoteName(emote.getName())
.emoteName(emote.getEmoteName())
.count(count)
.serverId(guild.getIdLong())
.build();

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.statistic.emotes.service;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.FeatureModeService;
@@ -48,24 +49,22 @@ public class TrackedEmoteServiceBean implements TrackedEmoteService {
private BotService botService;
@Override
public void addEmoteToRuntimeStorage(List<Emote> emotes, Guild guild) {
public void addEmoteToRuntimeStorage(List<CachedEmote> emotes, Guild guild) {
boolean externalTrackingEnabled = featureModeService.featureModeActive(StatisticFeatures.EMOTE_TRACKING, guild.getIdLong(), EmoteTrackingMode.EXTERNAL_EMOTES);
emotes.forEach(emote -> {
boolean emoteIsFromGuild = emoteService.emoteIsFromGuild(emote, guild);
// either the emote is from the current guild (we always add those) or external emote tracking is enabled (we should always add those)
if(externalTrackingEnabled || emoteIsFromGuild) {
trackedEmoteRuntimeService.addEmoteForServer(emote, guild, !emoteIsFromGuild);
if(externalTrackingEnabled || !emote.getExternal()) {
trackedEmoteRuntimeService.addEmoteForServer(emote, guild, emote.getExternal());
}
});
}
@Override
public void addEmoteToRuntimeStorage(Emote emote, Guild guild, Long count) {
public void addEmoteToRuntimeStorage(CachedEmote emote, Guild guild, Long count) {
boolean externalTrackingEnabled = featureModeService.featureModeActive(StatisticFeatures.EMOTE_TRACKING, guild.getIdLong(), EmoteTrackingMode.EXTERNAL_EMOTES);
boolean emoteIsFromGuild = emoteService.emoteIsFromGuild(emote, guild);
// either the emote is from the current guild (we always add those) or external emote tracking is enabled (we should always add those)
if(externalTrackingEnabled || emoteIsFromGuild) {
trackedEmoteRuntimeService.addEmoteForServer(emote, guild, count, !emoteIsFromGuild);
if(externalTrackingEnabled || !emote.getExternal()) {
trackedEmoteRuntimeService.addEmoteForServer(emote, guild, count, emote.getExternal());
}
}

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.statistic.emotes.service.management;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.statistic.emotes.exception.TrackedEmoteNotFoundException;
@@ -37,6 +38,12 @@ public class TrackedEmoteManagementServiceBean implements TrackedEmoteManagement
return createTrackedEmote(emote.getIdLong(), emote.getName(), emote.isAnimated(), true, server);
}
@Override
public TrackedEmote createTrackedEmote(CachedEmote emote) {
AServer server = serverManagementService.loadServer(emote.getServerId());
return createTrackedEmote(emote.getEmoteId(), emote.getEmoteName(), emote.getAnimated(), true, server);
}
@Override
public TrackedEmote createTrackedEmote(Emote emote, Guild guild, boolean external) {
if(external) {