[AB-184] adding various metrics to the system, organizing imports, changing some transactional behaviour

adding okhttp metrics, split bot service into multiple services (guild, message), unified some places that services are used in order to interact with the api, and not directly the objects (this is to make it easier for metric to be accurate)
This commit is contained in:
Sheldan
2021-01-29 17:46:41 +01:00
parent 2a2a3aea70
commit b838678c15
362 changed files with 3045 additions and 1573 deletions

View File

@@ -5,7 +5,9 @@ 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.*;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;

View File

@@ -2,11 +2,11 @@ package dev.sheldan.abstracto.utility.commands;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
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.command.config.Parameter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;

View File

@@ -9,8 +9,8 @@ import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.UserInfoModel;
@@ -32,7 +32,7 @@ public class UserInfo extends AbstractConditionableCommand {
private ChannelService channelService;
@Autowired
private BotService botService;
private MemberService memberService;
@Autowired
private UserInfo self;
@@ -44,7 +44,7 @@ public class UserInfo extends AbstractConditionableCommand {
UserInfoModel model = (UserInfoModel) ContextConverter.slimFromCommandContext(commandContext, UserInfoModel.class);
if(!memberToShow.hasTimeJoined()) {
log.info("Force reloading member {} in guild {} for user info.", memberToShow.getId(), memberToShow.getGuild().getId());
return botService.forceReloadMember(memberToShow).thenCompose(member -> {
return memberService.forceReloadMember(memberToShow).thenCompose(member -> {
model.setMemberInfo(member);
return self.sendResponse(commandContext, model)
.thenApply(aVoid -> CommandResult.fromIgnored());

View File

@@ -5,7 +5,9 @@ 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.*;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
@@ -44,7 +46,7 @@ public class Remind extends AbstractConditionableCommand {
List<Object> parameters = commandContext.getParameters().getParameters();
Duration remindTime = (Duration) parameters.get(0);
String text = (String) parameters.get(1);
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(commandContext.getAuthor());
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
ReminderModel remindModel = (ReminderModel) ContextConverter.fromCommandContext(commandContext, ReminderModel.class);
remindModel.setRemindText(text);
Reminder createdReminder = remindService.createReminderInForUser(aUserInAServer, text, remindTime, commandContext.getMessage());

View File

@@ -39,7 +39,7 @@ public class Reminders extends AbstractConditionableCommand {
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(commandContext.getAuthor());
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
List<Reminder> activeReminders = reminderManagementService.getActiveRemindersForUser(aUserInAServer);
RemindersModel model = (RemindersModel) ContextConverter.fromCommandContext(commandContext, RemindersModel.class);
model.setReminders(activeReminders);

View File

@@ -34,7 +34,7 @@ public class UnRemind extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
Long reminderId = (Long) commandContext.getParameters().getParameters().get(0);
reminderService.unRemind(reminderId, userInServerManagementService.loadUser(commandContext.getAuthor()));
reminderService.unRemind(reminderId, userInServerManagementService.loadOrCreateUser(commandContext.getAuthor()));
return CommandResult.fromSuccess();
}

View File

@@ -32,7 +32,7 @@ public class PurgeImagePosts extends AbstractConditionableCommand {
List<Object> parameters = commandContext.getParameters().getParameters();
if(!parameters.isEmpty()) {
AUserInAServer fakeUser = (AUserInAServer) parameters.get(0);
AUserInAServer actualUser = userInServerManagementService.loadUser(fakeUser.getUserInServerId());
AUserInAServer actualUser = userInServerManagementService.loadOrCreateUser(fakeUser.getUserInServerId());
postedImageService.purgePostedImages(actualUser);
} else {
postedImageService.purgePostedImages(commandContext.getGuild());

View File

@@ -32,7 +32,7 @@ public class PurgeReposts extends AbstractConditionableCommand {
List<Object> parameters = commandContext.getParameters().getParameters();
if(!parameters.isEmpty()) {
AUserInAServer fakeUser = (AUserInAServer) parameters.get(0);
AUserInAServer actualUser = userInServerManagementService.loadUser(fakeUser.getUserInServerId());
AUserInAServer actualUser = userInServerManagementService.loadOrCreateUser(fakeUser.getUserInServerId());
repostService.purgeReposts(actualUser);
} else {
repostService.purgeReposts(commandContext.getGuild());

View File

@@ -55,7 +55,7 @@ public class RepostLeaderboard extends AbstractConditionableCommand {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Integer page = !parameters.isEmpty() ? (Integer) parameters.get(0) : 1;
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(commandContext.getAuthor());
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
List<RepostLeaderboardResult> topRepostingUsersOfServer = repostManagementService.findTopRepostingUsersOfServer(commandContext.getGuild().getIdLong(), page, 5);
RepostLeaderboardResult resultOfUser = repostManagementService.getRepostRankOfUser(aUserInAServer);
CompletableFuture<List<RepostLeaderboardEntryModel>> leaderBoardFuture = converter.fromLeaderBoardResults(topRepostingUsersOfServer);

View File

@@ -2,12 +2,14 @@ package dev.sheldan.abstracto.utility.commands.suggest;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
import dev.sheldan.abstracto.core.command.execution.*;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.SuggestionLog;

View File

@@ -2,12 +2,14 @@ package dev.sheldan.abstracto.utility.commands.suggest;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
import dev.sheldan.abstracto.core.command.execution.*;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.SuggestionLog;

View File

@@ -2,10 +2,12 @@ package dev.sheldan.abstracto.utility.commands.suggest;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
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.*;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.SuggestionLog;

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.utility.converter;
import dev.sheldan.abstracto.core.models.FullChannel;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.utility.models.database.RepostCheckChannelGroup;
import dev.sheldan.abstracto.utility.models.template.commands.RepostCheckChannelGroupDisplayModel;
import dev.sheldan.abstracto.utility.models.template.commands.RepostCheckChannelsModel;
@@ -17,7 +17,7 @@ import java.util.stream.Collectors;
public class RepostCheckChannelModelConverter {
@Autowired
private BotService botService;
private ChannelService channelService;
public RepostCheckChannelsModel fromRepostCheckChannelGroups(List<RepostCheckChannelGroup> channelGroups, Guild guild) {
List<RepostCheckChannelGroupDisplayModel> repostCheckChannelGroups = new ArrayList<>();
@@ -26,7 +26,7 @@ public class RepostCheckChannelModelConverter {
FullChannel
.builder()
.channel(channel)
.serverChannel(botService.getTextChannelFromServerNullable(guild, channel.getId()))
.serverChannel(channelService.getTextChannelFromServerNullable(guild, channel.getId()))
.build()
).collect(Collectors.toList());
repostCheckChannelGroups.add(

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.utility.converter;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.models.RepostLeaderboardEntryModel;
@@ -23,7 +23,7 @@ public class RepostLeaderBoardConverter {
private UserInServerManagementService userInServerManagementService;
@Autowired
private BotService botService;
private MemberService memberService;
@Autowired
private RepostLeaderBoardConverter self;
@@ -40,11 +40,11 @@ public class RepostLeaderBoardConverter {
}
public CompletableFuture<RepostLeaderboardEntryModel> convertSingleUser(RepostLeaderboardResult result) {
AUserInAServer user = userInServerManagementService.loadUser(result.getUserInServerId());
AUserInAServer user = userInServerManagementService.loadOrCreateUser(result.getUserInServerId());
Integer count = result.getRepostCount();
Long userInServerId = result.getUserInServerId();
Integer rank = result.getRank();
return botService.getMemberInServerAsync(user).thenApply(member ->
return memberService.getMemberInServerAsync(user).thenApply(member ->
self.loadUserFromDatabase(member, count, userInServerId, rank)
);
}
@@ -54,7 +54,7 @@ public class RepostLeaderBoardConverter {
return RepostLeaderboardEntryModel
.builder()
.member(member)
.user(userInServerManagementService.loadUser(userInServerId))
.user(userInServerManagementService.loadOrCreateUser(userInServerId))
.count(count)
.rank(rank)
.build();

View File

@@ -2,11 +2,15 @@ package dev.sheldan.abstracto.utility.listener.embed;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.sync.jda.MessageReceivedListener;
import dev.sheldan.abstracto.core.execution.result.ExecutionResult;
import dev.sheldan.abstracto.core.execution.result.MessageReceivedListenerResult;
import dev.sheldan.abstracto.core.listener.sync.jda.MessageReceivedListener;
import dev.sheldan.abstracto.core.metrics.service.CounterMetric;
import dev.sheldan.abstracto.core.metrics.service.MetricService;
import dev.sheldan.abstracto.core.metrics.service.MetricTag;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.service.MessageCache;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.MessageEmbedLink;
@@ -19,6 +23,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
@@ -38,13 +44,27 @@ public class MessageEmbedListener implements MessageReceivedListener {
@Autowired
private MessageEmbedListener self;
@Autowired
private MetricService metricService;
@Autowired
private MessageService messageService;
public static final String MESSAGE_EMBEDDED = "message.embedded";
public static final String MESSAGE_EMBED_ACTION = "action";
private static final CounterMetric MESSAGE_EMBED_CREATED = CounterMetric
.builder()
.name(MESSAGE_EMBEDDED)
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "created")))
.build();
@Override
public MessageReceivedListenerResult execute(Message message) {
String messageRaw = message.getContentRaw();
List<MessageEmbedLink> links = messageEmbedService.getLinksInMessage(messageRaw);
if(!links.isEmpty()) {
log.trace("We found {} links to embed in message {} in channel {} in guild {}.", links.size(), message.getId(), message.getChannel().getId(), message.getGuild().getId());
Long userEmbeddingUserInServerId = userInServerManagementService.loadUser(message.getMember()).getUserInServerId();
Long userEmbeddingUserInServerId = userInServerManagementService.loadOrCreateUser(message.getMember()).getUserInServerId();
for (MessageEmbedLink messageEmbedLink : links) {
if(!messageEmbedLink.getServerId().equals(message.getGuild().getIdLong())) {
log.info("Link for message {} was from a foreign server {}. Do not embed.", messageEmbedLink.getMessageId(), messageEmbedLink.getServerId());
@@ -61,7 +81,7 @@ public class MessageEmbedListener implements MessageReceivedListener {
}
}
if(StringUtils.isBlank(messageRaw) && !links.isEmpty()) {
message.delete().queue();
messageService.deleteMessage(message);
return MessageReceivedListenerResult.DELETED;
}
if(!links.isEmpty()) {
@@ -74,7 +94,9 @@ public class MessageEmbedListener implements MessageReceivedListener {
public void embedSingleLink(Message message, Long cause, CachedMessage cachedMessage) {
log.info("Embedding link to message {} in channel {} in server {} to channel {} and server {}.",
cachedMessage.getMessageId(), cachedMessage.getChannelId(), cachedMessage.getServerId(), message.getChannel().getId(), message.getGuild().getId());
messageEmbedService.embedLink(cachedMessage, message.getTextChannel(), cause , message).exceptionally(throwable -> {
messageEmbedService.embedLink(cachedMessage, message.getTextChannel(), cause , message).thenAccept(unused ->
metricService.incrementCounter(MESSAGE_EMBED_CREATED)
).exceptionally(throwable -> {
log.error("Failed to embed link towards message {} in channel {} in sever {} linked from message {} in channel {} in server {}.", cachedMessage.getMessageId(), cachedMessage.getChannelId(), cachedMessage.getServerId(),
message.getId(), message.getChannel().getId(), message.getGuild().getId(), throwable);
return null;
@@ -95,4 +117,9 @@ public class MessageEmbedListener implements MessageReceivedListener {
public Integer getPriority() {
return ListenerPriority.MEDIUM;
}
@PostConstruct
public void postConstruct() {
metricService.registerCounter(MESSAGE_EMBED_CREATED, "Message embeds created");
}
}

View File

@@ -2,6 +2,9 @@ package dev.sheldan.abstracto.utility.listener.embed;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncReactionAddedListener;
import dev.sheldan.abstracto.core.metrics.service.CounterMetric;
import dev.sheldan.abstracto.core.metrics.service.MetricService;
import dev.sheldan.abstracto.core.metrics.service.MetricTag;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
@@ -16,8 +19,13 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.Optional;
import static dev.sheldan.abstracto.utility.listener.embed.MessageEmbedListener.MESSAGE_EMBEDDED;
import static dev.sheldan.abstracto.utility.listener.embed.MessageEmbedListener.MESSAGE_EMBED_ACTION;
@Component
@Slf4j
public class MessageEmbedRemovalReactionListener implements AsyncReactionAddedListener {
@@ -36,6 +44,22 @@ public class MessageEmbedRemovalReactionListener implements AsyncReactionAddedLi
@Autowired
private EmoteService emoteService;
@Autowired
private MetricService metricService;
private static final CounterMetric MESSAGE_EMBED_REMOVED_CREATOR = CounterMetric
.builder()
.name(MESSAGE_EMBEDDED)
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "removed.creator")))
.build();
private static final CounterMetric MESSAGE_EMBED_REMOVED_SOURCE = CounterMetric
.builder()
.name(MESSAGE_EMBEDDED)
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "removed.source")))
.build();
@Override
public void executeReactionAdded(CachedMessage message, CachedReactions cachedReaction, ServerUser serverUser) {
Long guildId = message.getServerId();
@@ -44,13 +68,18 @@ public class MessageEmbedRemovalReactionListener implements AsyncReactionAddedLi
Optional<EmbeddedMessage> embeddedMessageOptional = messageEmbedPostManagementService.findEmbeddedPostByMessageId(message.getMessageId());
if(embeddedMessageOptional.isPresent()) {
EmbeddedMessage embeddedMessage = embeddedMessageOptional.get();
if(embeddedMessage.getEmbeddedUser().getUserReference().getId().equals(serverUser.getUserId())
|| embeddedMessage.getEmbeddingUser().getUserReference().getId().equals(serverUser.getUserId())
) {
boolean embeddedUserRemoves = embeddedMessage.getEmbeddedUser().getUserReference().getId().equals(serverUser.getUserId());
boolean embeddingUserRemoves = embeddedMessage.getEmbeddingUser().getUserReference().getId().equals(serverUser.getUserId());
if(embeddedUserRemoves || embeddingUserRemoves) {
log.info("Removing embed in message {} in channel {} in server {} because of a user reaction.", message.getMessageId(), message.getChannelId(), message.getServerId());
messageService.deleteMessageInChannelInServer(message.getServerId(), message.getChannelId(), message.getMessageId()).thenAccept(aVoid ->{
messageService.deleteMessageInChannelInServer(message.getServerId(), message.getChannelId(), message.getMessageId()).thenAccept(aVoid -> {
Optional<EmbeddedMessage> innerOptional = messageEmbedPostManagementService.findEmbeddedPostByMessageId(message.getMessageId());
innerOptional.ifPresent(value -> messageEmbedPostManagementService.deleteEmbeddedMessage(value));
if(embeddedUserRemoves) {
metricService.incrementCounter(MESSAGE_EMBED_REMOVED_SOURCE);
} else {
metricService.incrementCounter(MESSAGE_EMBED_REMOVED_CREATOR);
}
});
} else {
log.trace("Somebody besides the original author and the user embedding added the removal reaction to the message {} in channel {} in server {}.",
@@ -68,4 +97,10 @@ public class MessageEmbedRemovalReactionListener implements AsyncReactionAddedLi
return UtilityFeature.LINK_EMBEDS;
}
@PostConstruct
public void postConstruct() {
metricService.registerCounter(MESSAGE_EMBED_REMOVED_CREATOR, "Message embeds which are created by the embedding user.");
metricService.registerCounter(MESSAGE_EMBED_REMOVED_SOURCE, "Message embeds which are created by the embedded user.");
}
}

View File

@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageEmbeddedListener;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.listener.GuildMessageEmbedEventModel;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.service.RepostCheckChannelService;
@@ -36,7 +36,7 @@ public class RepostEmbedListener implements AsyncMessageEmbeddedListener {
private ChannelManagementService channelManagementService;
@Autowired
private BotService botService;
private ChannelService channelService;
@Override
public void execute(GuildMessageEmbedEventModel eventModel) {
@@ -47,9 +47,11 @@ public class RepostEmbedListener implements AsyncMessageEmbeddedListener {
eventModel.getMessageId(), eventModel.getChannelId(), eventModel.getServerId());
return;
}
botService.getTextChannelFromServer(eventModel.getServerId(), eventModel.getChannelId()).retrieveMessageById(eventModel.getMessageId()).queue(message -> {
channelService.retrieveMessageInChannel(eventModel.getServerId(), eventModel.getChannelId(), eventModel.getMessageId()).thenAccept(message -> {
List<MessageEmbed> imageEmbeds = eventModel.getEmbeds().stream().filter(messageEmbed -> messageEmbed.getType().equals(EmbedType.IMAGE)).collect(Collectors.toList());
repostService.processMessageEmbedsRepostCheck(imageEmbeds, message);
if(!imageEmbeds.isEmpty()) {
repostService.processMessageEmbedsRepostCheck(imageEmbeds, message);
}
});
}
}

View File

@@ -4,6 +4,9 @@ import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncReactionAddedListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncReactionClearedListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncReactionRemovedListener;
import dev.sheldan.abstracto.core.metrics.service.CounterMetric;
import dev.sheldan.abstracto.core.metrics.service.MetricService;
import dev.sheldan.abstracto.core.metrics.service.MetricTag;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
@@ -23,6 +26,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -56,6 +61,36 @@ public class StarboardListener implements AsyncReactionAddedListener, AsyncReact
@Autowired
private EmoteService emoteService;
@Autowired
private MetricService metricService;
public static final String STARBOARD_STARS = "starboard.stars";
public static final String STARBOARD_POSTS = "starboard.posts";
public static final String STAR_ACTION = "action";
private static final CounterMetric STARBOARD_STARS_ADDED = CounterMetric
.builder()
.name(STARBOARD_STARS)
.tagList(Arrays.asList(MetricTag.getTag(STAR_ACTION, "added")))
.build();
private static final CounterMetric STARBOARD_STARS_REMOVED = CounterMetric
.builder()
.name(STARBOARD_STARS)
.tagList(Arrays.asList(MetricTag.getTag(STAR_ACTION, "removed")))
.build();
private static final CounterMetric STARBOARD_STARS_THRESHOLD_REACHED = CounterMetric
.builder()
.name(STARBOARD_POSTS)
.tagList(Arrays.asList(MetricTag.getTag(STAR_ACTION, "threshold.reached")))
.build();
private static final CounterMetric STARBOARD_STARS_THRESHOLD_FELL = CounterMetric
.builder()
.name(STARBOARD_POSTS)
.tagList(Arrays.asList(MetricTag.getTag(STAR_ACTION, "threshold.below")))
.build();
@Override
@Transactional
public void executeReactionAdded(CachedMessage message, CachedReactions cachedReaction, ServerUser serverUser) {
@@ -65,6 +100,7 @@ public class StarboardListener implements AsyncReactionAddedListener, AsyncReact
Long guildId = message.getServerId();
AEmote aEmote = emoteService.getEmoteOrDefaultEmote(STAR_EMOTE, guildId);
if(emoteService.compareCachedEmoteWithAEmote(cachedReaction.getEmote(), aEmote)) {
metricService.incrementCounter(STARBOARD_STARS_ADDED);
log.info("User {} in server {} reacted with star to put a message {} from channel {} on starboard.", serverUser.getUserId(), message.getServerId(), message.getMessageId(), message.getChannelId());
Optional<CachedReactions> reactionOptional = emoteService.getReactionFromMessageByEmote(message, aEmote);
handleStarboardPostChange(message, reactionOptional.orElse(null), serverUser, true);
@@ -74,21 +110,23 @@ public class StarboardListener implements AsyncReactionAddedListener, AsyncReact
private void handleStarboardPostChange(CachedMessage message, CachedReactions reaction, ServerUser serverUser, boolean adding) {
Optional<StarboardPost> starboardPostOptional = starboardPostManagementService.findByMessageId(message.getMessageId());
if(reaction != null) {
AUserInAServer author = userInServerManagementService.loadUser(message.getServerId(), message.getAuthor().getAuthorId());
AUserInAServer author = userInServerManagementService.loadOrCreateUser(message.getServerId(), message.getAuthor().getAuthorId());
List<AUserInAServer> userExceptAuthor = getUsersExcept(reaction.getUsers(), author);
Long starMinimum = getFromConfig(FIRST_LEVEL_THRESHOLD_KEY, message.getServerId());
AUserInAServer userAddingReaction = userInServerManagementService.loadUser(serverUser);
AUserInAServer userAddingReaction = userInServerManagementService.loadOrCreateUser(serverUser);
if (userExceptAuthor.size() >= starMinimum) {
log.info("Post reached starboard minimum. Message {} in channel {} in server {} will be starred/updated.",
message.getMessageId(), message.getChannelId(), message.getServerId());
if(starboardPostOptional.isPresent()) {
updateStarboardPost(message, userAddingReaction, adding, starboardPostOptional.get(), userExceptAuthor);
} else {
metricService.incrementCounter(STARBOARD_STARS_THRESHOLD_REACHED);
log.info("Creating starboard post for message {} in channel {} in server {}", message.getMessageId(), message.getChannelId(), message.getServerId());
starboardService.createStarboardPost(message, userExceptAuthor, userAddingReaction, author);
}
} else {
if(starboardPostOptional.isPresent()) {
metricService.incrementCounter(STARBOARD_STARS_THRESHOLD_FELL);
log.info("Removing starboard post for message {} in channel {} in server {}. It fell under the threshold {}", message.getMessageId(), message.getChannelId(), message.getServerId(), starMinimum);
starboardPostOptional.ifPresent(this::completelyRemoveStarboardPost);
}
@@ -128,6 +166,7 @@ public class StarboardListener implements AsyncReactionAddedListener, AsyncReact
Long guildId = message.getServerId();
AEmote aEmote = emoteService.getEmoteOrDefaultEmote(STAR_EMOTE, guildId);
if(emoteService.compareCachedEmoteWithAEmote(removedReaction.getEmote(), aEmote)) {
metricService.incrementCounter(STARBOARD_STARS_REMOVED);
log.info("User {} in server {} removed star reaction from message {} on starboard.",
userRemoving.getUserId(), message.getServerId(), message.getMessageId());
Optional<CachedReactions> reactionOptional = emoteService.getReactionFromMessageByEmote(message, aEmote);
@@ -163,4 +202,12 @@ public class StarboardListener implements AsyncReactionAddedListener, AsyncReact
});
}
@PostConstruct
public void postConstruct() {
metricService.registerCounter(STARBOARD_STARS_ADDED, "Star reaction added");
metricService.registerCounter(STARBOARD_STARS_REMOVED, "Star reaction removed");
metricService.registerCounter(STARBOARD_STARS_THRESHOLD_REACHED, "Starboard posts reaching threshold");
metricService.registerCounter(STARBOARD_STARS_THRESHOLD_FELL, "Starboard posts falling below threshold");
}
}

View File

@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.utility.repository.converter;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsUser;
import dev.sheldan.abstracto.utility.repository.StarStatsUserResult;
@@ -17,7 +17,7 @@ import java.util.concurrent.CompletableFuture;
public class StarStatsUserConverter {
@Autowired
private BotService botService;
private MemberService memberService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@@ -31,8 +31,8 @@ public class StarStatsUserConverter {
}
private CompletableFuture<StarStatsUser> createStarStatsUser(Long serverId, StarStatsUserResult starStatsUserResult) {
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(starStatsUserResult.getUserId());
return botService.getMemberInServerAsync(serverId, aUserInAServer.getUserReference().getId()).thenApply(member ->
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(starStatsUserResult.getUserId());
return memberService.getMemberInServerAsync(serverId, aUserInAServer.getUserReference().getId()).thenApply(member ->
StarStatsUser
.builder()
.starCount(starStatsUserResult.getStarCount())

View File

@@ -1,16 +1,13 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.models.template.listener.MessageEmbeddedModel;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.MessageCache;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.core.models.template.listener.MessageEmbeddedModel;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.utility.models.MessageEmbedLink;
import dev.sheldan.abstracto.utility.service.management.MessageEmbedPostManagementService;
@@ -49,7 +46,7 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
private UserInServerManagementService userInServerManagementService;
@Autowired
private BotService botService;
private MemberService memberService;
@Autowired
private TemplateService templateService;
@@ -67,7 +64,7 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
private MessageEmbedPostManagementService messageEmbedPostManagementService;
@Autowired
private MessageService messageService;
private ReactionService reactionService;
@Override
public List<MessageEmbedLink> getLinksInMessage(String message) {
@@ -123,14 +120,14 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
@Transactional
public CompletionStage<Void> sendEmbeddingMessage(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, MessageEmbeddedModel messageEmbeddedModel) {
MessageToSend embed = templateService.renderEmbedTemplate(MESSAGE_EMBED_TEMPLATE, messageEmbeddedModel);
AUserInAServer cause = userInServerManagementService.loadUser(userEmbeddingUserInServerId);
AUserInAServer cause = userInServerManagementService.loadOrCreateUser(userEmbeddingUserInServerId);
List<CompletableFuture<Message>> completableFutures = channelService.sendMessageToSendToChannel(embed, target);
log.trace("Embedding message {} from channel {} from server {}, because of user {}", cachedMessage.getMessageId(),
cachedMessage.getChannelId(), cachedMessage.getServerId(), cause.getUserReference().getId());
Long userInServerId = cause.getUserInServerId();
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenCompose(aVoid -> {
Message createdMessage = completableFutures.get(0).join();
return messageService.addReactionToMessageWithFuture(REMOVAL_EMOTE, cachedMessage.getServerId(), createdMessage).thenAccept(aVoid1 ->
return reactionService.addReactionToMessageAsync(REMOVAL_EMOTE, cachedMessage.getServerId(), createdMessage).thenAccept(aVoid1 ->
self.loadUserAndPersistMessage(cachedMessage, userInServerId, createdMessage)
);
});
@@ -138,19 +135,19 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
@Transactional
public void loadUserAndPersistMessage(CachedMessage cachedMessage, Long userInServerId, Message createdMessage) {
AUserInAServer innerCause = userInServerManagementService.loadUser(userInServerId);
AUserInAServer innerCause = userInServerManagementService.loadOrCreateUser(userInServerId);
messageEmbedPostManagementService.createMessageEmbed(cachedMessage, createdMessage, innerCause);
}
private CompletableFuture<MessageEmbeddedModel> buildTemplateParameter(Message message, CachedMessage embeddedMessage) {
return botService.getMemberInServerAsync(embeddedMessage.getServerId(), embeddedMessage.getAuthor().getAuthorId()).thenApply(member ->
return memberService.getMemberInServerAsync(embeddedMessage.getServerId(), embeddedMessage.getAuthor().getAuthorId()).thenApply(member ->
self.loadMessageEmbedModel(message, embeddedMessage, member)
);
}
@Transactional
public MessageEmbeddedModel loadMessageEmbedModel(Message message, CachedMessage embeddedMessage, Member member) {
Optional<TextChannel> textChannelFromServer = botService.getTextChannelFromServerOptional(embeddedMessage.getServerId(), embeddedMessage.getChannelId());
Optional<TextChannel> textChannelFromServer = channelService.getTextChannelFromServerOptional(embeddedMessage.getServerId(), embeddedMessage.getChannelId());
TextChannel sourceChannel = textChannelFromServer.orElse(null);
return MessageEmbeddedModel
.builder()

View File

@@ -1,15 +1,16 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.GuildService;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.utility.exception.ReminderNotFoundException;
import dev.sheldan.abstracto.utility.models.database.Reminder;
@@ -30,7 +31,9 @@ import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.Optional;
import java.util.concurrent.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
@@ -50,7 +53,10 @@ public class RemindServiceBean implements ReminderService {
private SchedulerService schedulerService;
@Autowired
private BotService botService;
private MemberService memberService;
@Autowired
private GuildService guildService;
@Autowired
private RemindServiceBean self;
@@ -109,12 +115,12 @@ public class RemindServiceBean implements ReminderService {
AChannel channel = reminderToRemindFor.getChannel();
log.info("Executing reminder {} in channel {} in server {} for user {}.",
reminderId, channel.getId(), server.getId(), reminderToRemindFor.getRemindedUser().getUserReference().getId());
Optional<Guild> guildToAnswerIn = botService.getGuildByIdOptional(server.getId());
Optional<Guild> guildToAnswerIn = guildService.getGuildByIdOptional(server.getId());
if(guildToAnswerIn.isPresent()) {
Optional<TextChannel> channelToAnswerIn = botService.getTextChannelFromServerOptional(server.getId(), channel.getId());
Optional<TextChannel> channelToAnswerIn = channelService.getTextChannelFromServerOptional(server.getId(), channel.getId());
// only send the message if the channel still exists, if not, only set the reminder to reminded.
if(channelToAnswerIn.isPresent()) {
botService.getMemberInServerAsync(server.getId(), reminderToRemindFor.getRemindedUser().getUserReference().getId()).thenAccept(member ->
memberService.getMemberInServerAsync(server.getId(), reminderToRemindFor.getRemindedUser().getUserReference().getId()).thenAccept(member ->
self.sendReminderText(reminderId, channelToAnswerIn.get(), member)
);

View File

@@ -7,10 +7,7 @@ import dev.sheldan.abstracto.core.models.cache.CachedEmbed;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.FeatureModeService;
import dev.sheldan.abstracto.core.service.HashService;
import dev.sheldan.abstracto.core.service.HttpService;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
@@ -25,7 +22,9 @@ import dev.sheldan.abstracto.utility.models.database.result.RepostLeaderboardRes
import dev.sheldan.abstracto.utility.service.management.PostedImageManagement;
import dev.sheldan.abstracto.utility.service.management.RepostManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -64,7 +63,7 @@ public class RepostServiceBean implements RepostService {
private UserInServerManagementService userInServerManagementService;
@Autowired
private MessageService messageService;
private ReactionService reactionService;
@Autowired
private FeatureModeService featureModeService;
@@ -143,7 +142,7 @@ public class RepostServiceBean implements RepostService {
PostedImage existingRepost = potentialRepost.get();
return !existingRepost.getPostId().getMessageId().equals(serverChannelMessageUser.getMessageId()) ? Optional.of(existingRepost) : Optional.empty();
} else {
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(serverChannelMessageUser.getServerId(), serverChannelMessageUser.getUserId());
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(serverChannelMessageUser.getServerId(), serverChannelMessageUser.getUserId());
AServerAChannelAUser cause = AServerAChannelAUser
.builder()
.aUserInAServer(aUserInAServer)
@@ -219,10 +218,10 @@ public class RepostServiceBean implements RepostService {
private void markMessageAndPersist(ServerChannelMessageUser messageUser, Integer index, boolean moreRepostsPossible, PostedImage originalPost) {
log.info("Detected repost in message embed {} of message {} in channel {} in server {}.", index, messageUser.getMessageId(), messageUser.getChannelId(), messageUser.getServerId());
CompletableFuture<Void> markerFuture = messageService.addReactionToMessageWithFuture(REPOST_MARKER_EMOTE_KEY, messageUser.getServerId(), messageUser.getChannelId(), messageUser.getMessageId());
CompletableFuture<Void> markerFuture = reactionService.addReactionToMessageAsync(REPOST_MARKER_EMOTE_KEY, messageUser.getServerId(), messageUser.getChannelId(), messageUser.getMessageId());
CompletableFuture<Void> counterFuture;
if (moreRepostsPossible) {
counterFuture = messageService.addDefaultReactionToMessageAsync(NUMBER_EMOJI.get(index), messageUser.getServerId(), messageUser.getChannelId(), messageUser.getMessageId());
counterFuture = reactionService.addDefaultReactionToMessageAsync(NUMBER_EMOJI.get(index), messageUser.getServerId(), messageUser.getChannelId(), messageUser.getMessageId());
} else {
counterFuture = CompletableFuture.completedFuture(null);
}
@@ -238,7 +237,7 @@ public class RepostServiceBean implements RepostService {
@Transactional
public void persistRepost(Long messageId, Integer position, Long serverId, Long userId) {
PostedImage postedImage = postedImageManagement.getPostFromMessageAndPosition(messageId, position);
AUserInAServer userInAServer = userInServerManagementService.loadUser(serverId, userId);
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(serverId, userId);
Optional<Repost> existingPost = repostManagementService.findRepostOptional(postedImage, userInAServer);
if(existingPost.isPresent()) {
Repost previousRepost = existingPost.get();

View File

@@ -1,19 +1,19 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.exception.UserInServerNotFoundException;
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.database.PostTarget;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.DefaultConfigManagementService;
import dev.sheldan.abstracto.core.service.management.PostTargetManagement;
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.*;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.ConfigService;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.utility.config.posttargets.StarboardPostTarget;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
@@ -24,7 +24,9 @@ import dev.sheldan.abstracto.utility.models.template.commands.starboard.Starboar
import dev.sheldan.abstracto.utility.service.management.StarboardPostManagementService;
import dev.sheldan.abstracto.utility.service.management.StarboardPostReactorManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -46,7 +48,13 @@ public class StarboardServiceBean implements StarboardService {
public static final String STAR_LEVELS_CONFIG_KEY = "starLvls";
@Autowired
private BotService botService;
private MemberService memberService;
@Autowired
private GuildService guildService;
@Autowired
private ChannelService channelService;
@Autowired
private PostTargetService postTargetService;
@@ -78,6 +86,9 @@ public class StarboardServiceBean implements StarboardService {
@Autowired
private DefaultConfigManagementService defaultConfigManagementService;
@Autowired
private MessageService messageService;
@Autowired
private StarboardServiceBean self;
@@ -125,9 +136,9 @@ public class StarboardServiceBean implements StarboardService {
}
private CompletableFuture<StarboardPostModel> buildStarboardPostModel(CachedMessage message, Integer starCount) {
return botService.getMemberInServerAsync(message.getServerId(), message.getAuthor().getAuthorId()).thenApply(member -> {
Optional<TextChannel> channel = botService.getTextChannelFromServerOptional(message.getServerId(), message.getChannelId());
Optional<Guild> guild = botService.getGuildByIdOptional(message.getServerId());
return memberService.getMemberInServerAsync(message.getServerId(), message.getAuthor().getAuthorId()).thenApply(member -> {
Optional<TextChannel> channel = channelService.getTextChannelFromServerOptional(message.getServerId(), message.getChannelId());
Optional<Guild> guild = guildService.getGuildByIdOptional(message.getServerId());
// TODO use model objects instead of building entity models
AChannel aChannel = AChannel.builder().id(message.getChannelId()).build();
AUser user = AUser.builder().id(message.getAuthor().getAuthorId()).build();
@@ -165,7 +176,7 @@ public class StarboardServiceBean implements StarboardService {
public void deleteStarboardMessagePost(StarboardPost message) {
AChannel starboardChannel = message.getStarboardChannel();
log.info("Deleting starboard post {} in server {}", message.getId(), message.getSourceChanel().getServer().getId());
botService.deleteMessage(starboardChannel.getServer().getId(), starboardChannel.getId(), message.getStarboardMessageId());
messageService.deleteMessageInChannelInServer(starboardChannel.getServer().getId(), starboardChannel.getId(), message.getStarboardMessageId());
}
@Override

View File

@@ -2,28 +2,27 @@ package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.CounterService;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.utils.MessageUtils;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.utility.config.posttargets.SuggestionPostTarget;
import dev.sheldan.abstracto.utility.exception.SuggestionNotFoundException;
import dev.sheldan.abstracto.utility.exception.SuggestionUpdateException;
import dev.sheldan.abstracto.utility.models.database.Suggestion;
import dev.sheldan.abstracto.utility.models.SuggestionState;
import dev.sheldan.abstracto.utility.models.database.Suggestion;
import dev.sheldan.abstracto.utility.models.template.commands.SuggestionLog;
import dev.sheldan.abstracto.utility.service.management.SuggestionManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@@ -49,10 +48,13 @@ public class SuggestionServiceBean implements SuggestionService {
private TemplateService templateService;
@Autowired
private BotService botService;
private ChannelService channelService;
@Autowired
private MessageService messageService;
private MemberService memberService;
@Autowired
private ReactionService reactionService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@@ -69,7 +71,7 @@ public class SuggestionServiceBean implements SuggestionService {
@Override
public CompletableFuture<Void> createSuggestionMessage(Member member, String text, SuggestionLog suggestionLog) {
AServer server = serverManagementService.loadServer(member.getGuild());
AUserInAServer suggester = userInServerManagementService.loadUser(member);
AUserInAServer suggester = userInServerManagementService.loadOrCreateUser(member);
Long newSuggestionId = counterService.getNextCounterValue(server, SUGGESTION_COUNTER_KEY);
suggestionLog.setSuggestionId(newSuggestionId);
suggestionLog.setState(SuggestionState.NEW);
@@ -82,8 +84,8 @@ public class SuggestionServiceBean implements SuggestionService {
return FutureUtils.toSingleFutureGeneric(completableFutures).thenCompose(aVoid -> {
Message message = completableFutures.get(0).join();
log.trace("Posted message, adding reaction for suggestion {} to message {}.", newSuggestionId, message.getId());
CompletableFuture<Void> firstReaction = messageService.addReactionToMessageWithFuture(SUGGESTION_YES_EMOTE, guildId, message);
CompletableFuture<Void> secondReaction = messageService.addReactionToMessageWithFuture(SUGGESTION_NO_EMOTE, guildId, message);
CompletableFuture<Void> firstReaction = reactionService.addReactionToMessageAsync(SUGGESTION_YES_EMOTE, guildId, message);
CompletableFuture<Void> secondReaction = reactionService.addReactionToMessageAsync(SUGGESTION_NO_EMOTE, guildId, message);
return CompletableFuture.allOf(firstReaction, secondReaction).thenAccept(aVoid1 -> {
log.trace("Reaction added to message {} for suggestion {}.", message.getId(), newSuggestionId);
self.persistSuggestionInDatabase(member, text, message, newSuggestionId);
@@ -116,8 +118,8 @@ public class SuggestionServiceBean implements SuggestionService {
suggestionLog.setOriginalMessageId(originalMessageId);
suggestionLog.setOriginalMessageUrl(MessageUtils.buildMessageUrl(serverId, channelId, originalMessageId));
AUserInAServer suggester = suggestion.getSuggester();
TextChannel textChannelById = botService.getTextChannelFromServer(serverId, channelId);
CompletableFuture<Member> memberById = botService.getMemberInServerAsync(serverId, suggester.getUserReference().getId());
TextChannel textChannelById = channelService.getTextChannelFromServer(serverId, channelId);
CompletableFuture<Member> memberById = memberService.getMemberInServerAsync(serverId, suggester.getUserReference().getId());
suggestionLog.setState(suggestion.getState());
suggestionLog.setSuggestionId(suggestion.getSuggestionId().getId());
CompletableFuture<Void> finalFuture = new CompletableFuture<>();
@@ -125,8 +127,8 @@ public class SuggestionServiceBean implements SuggestionService {
if(throwable == null) {
suggestionLog.setSuggester(member);
}
textChannelById.retrieveMessageById(originalMessageId).submit().thenCompose(message ->
self.updateSuggestionMessageText(text, suggestionLog, message)
channelService.retrieveMessageInChannel(textChannelById, originalMessageId).thenCompose(message ->
self.updateSuggestionMessageText(text, suggestionLog, message)
).thenAccept(aVoid -> finalFuture.complete(null));
});
@@ -134,7 +136,7 @@ public class SuggestionServiceBean implements SuggestionService {
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Transactional
public CompletableFuture<Void> updateSuggestionMessageText(String text, SuggestionLog suggestionLog, Message message) {
Optional<MessageEmbed> embedOptional = message.getEmbeds().stream().filter(embed -> embed.getDescription() != null).findFirst();
if(embedOptional.isPresent()) {

View File

@@ -44,7 +44,7 @@ public class MessageEmbedPostManagementServiceBean implements MessageEmbedPostMa
}
AChannel embeddingChannel = channelManagementService.loadChannel(messageContainingEmbed.getChannel().getIdLong());
AChannel embeddedChannel = channelManagementService.loadChannel(embeddedMessage.getChannelId());
AUserInAServer embeddedAuthor = userInServerManagementService.loadUser(embeddedMessage.getServerId(), embeddedMessage.getAuthor().getAuthorId());
AUserInAServer embeddedAuthor = userInServerManagementService.loadOrCreateUser(embeddedMessage.getServerId(), embeddedMessage.getAuthor().getAuthorId());
EmbeddedMessage messageEmbedPost = EmbeddedMessage
.builder()
.embeddedMessageId(embeddedMessage.getMessageId())

View File

@@ -1,13 +1,13 @@
package dev.sheldan.abstracto.utility.service.management;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.utility.models.database.Suggestion;
import dev.sheldan.abstracto.utility.models.SuggestionState;
import dev.sheldan.abstracto.utility.models.database.Suggestion;
import dev.sheldan.abstracto.utility.repository.SuggestionRepository;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
@@ -36,7 +36,7 @@ public class SuggestionManagementServiceBean implements SuggestionManagementServ
@Override
public Suggestion createSuggestion(Member suggester, String text, Message message, Long suggestionId) {
AUserInAServer user = userInServerManagementService.loadUser(suggester);
AUserInAServer user = userInServerManagementService.loadOrCreateUser(suggester);
return this.createSuggestion(user, text, message, suggestionId);
}