[AB-139] changing the places at which there might be an uncached member object

fixing integer validator
fixing syncing roles not working if the role did not change in the database
fixing warn id being flipped
fixing star stats model
This commit is contained in:
Sheldan
2020-10-11 22:04:18 +02:00
parent 1d3c414d6b
commit 36d11371cb
105 changed files with 1762 additions and 1086 deletions

View File

@@ -11,7 +11,6 @@ import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsModel;
import dev.sheldan.abstracto.utility.service.StarboardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -33,9 +32,10 @@ public class StarStats extends AbstractConditionableCommand {
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
StarStatsModel result = starboardService.retrieveStarStats(commandContext.getGuild().getIdLong());
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInChannel(STARSTATS_RESPONSE_TEMPLATE, result, commandContext.getChannel()))
.thenApply(aVoid -> CommandResult.fromSuccess());
return starboardService.retrieveStarStats(commandContext.getGuild().getIdLong())
.thenCompose(starStatsModel ->
FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInChannel(STARSTATS_RESPONSE_TEMPLATE, starStatsModel, commandContext.getChannel()))
).thenApply(o -> CommandResult.fromSuccess());
}
@Override

View File

@@ -47,7 +47,7 @@ public class MessageEmbedListener implements MessageReceivedListener {
continue;
}
messageRaw = messageRaw.replace(messageEmbedLink.getWholeUrl(), "");
Consumer<CachedMessage> cachedMessageConsumer = cachedMessage ->self.loadUserAndEmbed(message, userEmbeddingUserInServerId, cachedMessage);
Consumer<CachedMessage> cachedMessageConsumer = cachedMessage -> self.embedSingleLink(message, userEmbeddingUserInServerId, cachedMessage);
messageCache.getMessageFromCache(messageEmbedLink.getServerId(), messageEmbedLink.getChannelId(), messageEmbedLink.getMessageId())
.thenAccept(cachedMessageConsumer)
.exceptionally(throwable -> {
@@ -62,10 +62,14 @@ public class MessageEmbedListener implements MessageReceivedListener {
}
@Transactional
public void loadUserAndEmbed(Message message, Long cause, CachedMessage cachedMessage) {
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);
messageEmbedService.embedLink(cachedMessage, message.getTextChannel(), cause , message).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;
});
}
@Override

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.utility.repository;
public interface StarStatsUserResult {
// this is the User in Server Id
Long getUserId();
Integer getStarCount();
}

View File

@@ -1,7 +1,9 @@
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.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsUser;
import dev.sheldan.abstracto.utility.repository.StarStatsUserResult;
import org.springframework.beans.factory.annotation.Autowired;
@@ -9,6 +11,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class StarStatsUserConverter {
@@ -16,17 +19,26 @@ public class StarStatsUserConverter {
@Autowired
private BotService botService;
public List<StarStatsUser> convertToStarStatsUser(List<StarStatsUserResult> users, Long serverId) {
List<StarStatsUser> result = new ArrayList<>();
users.forEach(starStatsUserResult -> {
StarStatsUser newUser = StarStatsUser
.builder()
.starCount(starStatsUserResult.getStarCount())
.member(botService.getMemberInServer(serverId, starStatsUserResult.getUserId()))
.user(AUser.builder().id(starStatsUserResult.getUserId()).build())
.build();
result.add(newUser);
});
@Autowired
private UserInServerManagementService userInServerManagementService;
public List<CompletableFuture<StarStatsUser>> convertToStarStatsUser(List<StarStatsUserResult> users, Long serverId) {
List<CompletableFuture<StarStatsUser>> result = new ArrayList<>();
users.forEach(starStatsUserResult ->
result.add(createStarStatsUser(serverId, starStatsUserResult))
);
return result;
}
private CompletableFuture<StarStatsUser> createStarStatsUser(Long serverId, StarStatsUserResult starStatsUserResult) {
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(starStatsUserResult.getUserId());
return botService.getMemberInServerAsync(serverId, aUserInAServer.getUserReference().getId()).thenApply(member ->
StarStatsUser
.builder()
.starCount(starStatsUserResult.getStarCount())
.member(member)
.user(AUser.builder().id(starStatsUserResult.getUserId()).build())
.build()
);
}
}

View File

@@ -28,7 +28,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.CompletionStage;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -60,7 +60,7 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
private ChannelService channelService;
@Autowired
private MessageEmbedService self;
private MessageEmbedServiceBean self;
@Autowired
private MessageCache messageCache;
@@ -102,7 +102,7 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
.thenAccept(cachedMessage -> self.embedLink(cachedMessage, target, userEmbeddingUserInServerId, embeddingMessage)
).exceptionally(throwable -> {
log.error("Message retrieval from cache failed for message {}.", messageEmbedLink.getMessageId(), throwable);
log.error("Message embedding from cache failed for message {}.", messageEmbedLink.getMessageId(), throwable);
return null;
})
);
@@ -110,42 +110,50 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
@Override
@Transactional
public void embedLink(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage) {
public CompletableFuture<Void> embedLink(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage) {
Optional<AUserInAServer> causeOpt = userInServerManagementService.loadUserConditional(userEmbeddingUserInServerId);
if(causeOpt.isPresent()) {
AUserInAServer cause = causeOpt.get();
MessageEmbeddedModel messageEmbeddedModel = buildTemplateParameter(embeddingMessage, cachedMessage);
MessageToSend embed = templateService.renderEmbedTemplate(MESSAGE_EMBED_TEMPLATE, messageEmbeddedModel);
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();
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenAccept(aVoid -> {
try {
Message createdMessage = completableFutures.get(0).get();
Optional<AUserInAServer> innerCauseOpt = userInServerManagementService.loadUserConditional(userInServerId);
innerCauseOpt.ifPresent(aUserInAServer -> {
messageEmbedPostManagementService.createMessageEmbed(cachedMessage, createdMessage, aUserInAServer);
messageService.addReactionToMessage(REMOVAL_EMOTE, cachedMessage.getServerId(), createdMessage);
});
} catch (InterruptedException | ExecutionException e) {
log.error("Failed to post message embed.", e);
Thread.currentThread().interrupt();
}
}).exceptionally(throwable -> {
log.error("Failed to send message for embedding the link for message {} in channel {} in server {}",
cachedMessage.getMessageId(), cachedMessage.getChannelId(), cachedMessage.getServerId(), throwable);
return null;
});
return buildTemplateParameter(embeddingMessage, cachedMessage).thenCompose(messageEmbeddedModel ->
self.sendEmbeddingMessage(cachedMessage, target, userEmbeddingUserInServerId, messageEmbeddedModel)
);
} else {
log.warn("User {} which was not found in database wanted to embed link in message {}.", userEmbeddingUserInServerId, embeddingMessage.getJumpUrl());
return CompletableFuture.completedFuture(null);
}
}
private MessageEmbeddedModel buildTemplateParameter(Message message, CachedMessage embeddedMessage) {
@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);
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 ->
self.loadUserAndPersistMessage(cachedMessage, userInServerId, createdMessage)
);
});
}
@Transactional
public void loadUserAndPersistMessage(CachedMessage cachedMessage, Long userInServerId, Message createdMessage) {
AUserInAServer innerCause = userInServerManagementService.loadUser(userInServerId);
messageEmbedPostManagementService.createMessageEmbed(cachedMessage, createdMessage, innerCause);
}
private CompletableFuture<MessageEmbeddedModel> buildTemplateParameter(Message message, CachedMessage embeddedMessage) {
return botService.getMemberInServerAsync(embeddedMessage.getServerId(), embeddedMessage.getAuthorId()).thenApply(member ->
self.loadMessageEmbedModel(message, embeddedMessage, member)
);
}
@Transactional
public MessageEmbeddedModel loadMessageEmbedModel(Message message, CachedMessage embeddedMessage, Member member) {
AServer server = serverManagementService.loadOrCreate(message.getGuild().getIdLong());
AUserInAServer user = userInServerManagementService.loadUser(message.getMember());
Member author = botService.getMemberInServer(embeddedMessage.getServerId(), embeddedMessage.getAuthorId());
Optional<TextChannel> textChannelFromServer = botService.getTextChannelFromServerOptional(embeddedMessage.getServerId(), embeddedMessage.getChannelId());
TextChannel sourceChannel = textChannelFromServer.orElse(null);
AChannel channel = channelManagementService.loadChannel(message.getChannel().getIdLong());
@@ -155,7 +163,7 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
.server(server)
.member(message.getMember())
.aUserInAServer(user)
.author(author)
.author(member)
.sourceChannel(sourceChannel)
.embeddingUser(message.getMember())
.user(user.getUserReference())

View File

@@ -5,8 +5,8 @@ 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.AUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
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;
@@ -36,6 +36,7 @@ import java.util.concurrent.*;
@Slf4j
public class RemindServiceBean implements ReminderService {
public static final String REMINDER_TEMPLATE_TEXT = "remind_reminder";
@Autowired
private ReminderManagementService reminderManagementService;
@@ -52,7 +53,7 @@ public class RemindServiceBean implements ReminderService {
private BotService botService;
@Autowired
private ReminderService self;
private RemindServiceBean self;
@Autowired
private ChannelService channelService;
@@ -61,6 +62,7 @@ public class RemindServiceBean implements ReminderService {
@Qualifier("reminderScheduler")
private ScheduledExecutorService instantReminderScheduler;
@Override
public Reminder createReminderInForUser(AUserInAServer user, String remindText, Duration remindIn, Message message) {
AChannel channel = channelManagementService.loadChannel(message.getChannel().getIdLong());
@@ -99,7 +101,7 @@ public class RemindServiceBean implements ReminderService {
@Override
@Transactional
public void executeReminder(Long reminderId) {
Reminder reminderToRemindFor = reminderManagementService.loadReminder(reminderId).orElseThrow(() -> new ReminderNotFoundException(reminderId));
Reminder reminderToRemindFor = reminderManagementService.loadReminder(reminderId);
if(reminderToRemindFor.isReminded()) {
return;
}
@@ -107,22 +109,15 @@ 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.getGuildById(server.getId());
Optional<Guild> guildToAnswerIn = botService.getGuildByIdOptional(server.getId());
if(guildToAnswerIn.isPresent()) {
Optional<TextChannel> channelToAnswerIn = botService.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()) {
AUser userReference = reminderToRemindFor.getRemindedUser().getUserReference();
Member memberInServer = botService.getMemberInServer(server.getId(), userReference.getId());
log.trace("Reminding user {}", userReference.getId());
ExecutedReminderModel build = ExecutedReminderModel
.builder()
.reminder(reminderToRemindFor)
.member(memberInServer)
.duration(Duration.between(reminderToRemindFor.getReminderDate(), reminderToRemindFor.getTargetDate()))
.build();
MessageToSend messageToSend = templateService.renderEmbedTemplate("remind_reminder", build);
channelService.sendMessageToSendToChannel(messageToSend, channelToAnswerIn.get());
botService.getMemberInServerAsync(server.getId(), reminderToRemindFor.getRemindedUser().getUserReference().getId()).thenAccept(member ->
self.sendReminderText(reminderId, channelToAnswerIn.get(), member)
);
} else {
log.warn("Channel {} in server {} to remind user did not exist anymore. Ignoring reminder {}", channel.getId(), server.getId(), reminderId);
}
@@ -132,6 +127,20 @@ public class RemindServiceBean implements ReminderService {
reminderManagementService.setReminded(reminderToRemindFor);
}
@Transactional
public CompletableFuture<Void> sendReminderText(Long reminderId, TextChannel channelToAnswerIn, Member member) {
Reminder reminder = reminderManagementService.loadReminder(reminderId);
log.trace("Sending remind message for reminder {} to user user {} in server {}.", reminderId, member.getIdLong(), member.getGuild().getIdLong());
ExecutedReminderModel build = ExecutedReminderModel
.builder()
.reminder(reminder)
.member(member)
.duration(Duration.between(reminder.getReminderDate(), reminder.getTargetDate()))
.build();
MessageToSend messageToSend = templateService.renderEmbedTemplate(REMINDER_TEMPLATE_TEXT, build);
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, channelToAnswerIn));
}
@Override
public void unRemind(Long reminderId, AUserInAServer aUserInAServer) {
log.info("Trying to end reminder {} for user {} in server {}.", reminderId, aUserInAServer.getUserReference().getId(),aUserInAServer.getServerReference().getId());

View File

@@ -8,6 +8,7 @@ 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;
@@ -32,6 +33,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
@@ -80,22 +82,24 @@ public class StarboardServiceBean implements StarboardService {
private StarboardServiceBean self;
@Override
public void createStarboardPost(CachedMessage message, List<AUserInAServer> userExceptAuthor, AUserInAServer userReacting, AUserInAServer starredUser) {
StarboardPostModel starboardPostModel = buildStarboardPostModel(message, userExceptAuthor.size());
List<Long> userExceptAuthorIds = new ArrayList<>();
userExceptAuthor.forEach(aUserInAServer -> userExceptAuthorIds.add(aUserInAServer.getUserInServerId()));
public CompletableFuture<Void> createStarboardPost(CachedMessage message, List<AUserInAServer> userExceptAuthor, AUserInAServer userReacting, AUserInAServer starredUser) {
Long starredUserId = starredUser.getUserInServerId();
List<Long> userExceptAuthorIds = userExceptAuthor.stream().map(AUserInAServer::getUserInServerId).collect(Collectors.toList());
return buildStarboardPostModel(message, userExceptAuthor.size()).thenCompose(starboardPostModel ->
self.sendStarboardPostAndStore(message, starredUserId, userExceptAuthorIds, starboardPostModel)
);
}
@Transactional
public CompletionStage<Void> sendStarboardPostAndStore(CachedMessage message, Long starredUserId, List<Long> userExceptAuthorIds, StarboardPostModel starboardPostModel) {
MessageToSend messageToSend = templateService.renderEmbedTemplate(STARBOARD_POST_TEMPLATE, starboardPostModel);
PostTarget starboard = postTargetManagement.getPostTarget(StarboardPostTarget.STARBOARD.getKey(), message.getServerId());
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(messageToSend, StarboardPostTarget.STARBOARD, message.getServerId());
Long starboardChannelId = starboard.getChannelReference().getId();
Long starredUserId = starredUser.getUserInServerId();
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenAccept(aVoid ->
self.persistPost(message, userExceptAuthorIds, completableFutures, starboardChannelId, starredUserId)
) .exceptionally(throwable -> {
log.error("Failed to create starboard post for message {} in channel {} in server {}", message.getMessageId(), message.getChannelId(), message.getServerId(), throwable);
return null;
});
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenAccept(aVoid ->
self.persistPost(message, userExceptAuthorIds, completableFutures, starboardChannelId, starredUserId)
);
}
@Transactional
@@ -120,41 +124,41 @@ public class StarboardServiceBean implements StarboardService {
});
}
private StarboardPostModel buildStarboardPostModel(CachedMessage message, Integer starCount) {
Member member = botService.getMemberInServer(message.getServerId(), message.getAuthorId());
Optional<TextChannel> channel = botService.getTextChannelFromServerOptional(message.getServerId(), message.getChannelId());
Optional<Guild> guild = botService.getGuildById(message.getServerId());
AChannel aChannel = AChannel.builder().id(message.getChannelId()).build();
AUser user = AUser.builder().id(message.getAuthorId()).build();
AServer server = AServer.builder().id(message.getServerId()).build();
String starLevelEmote = getAppropriateEmote(message.getServerId(), starCount);
return StarboardPostModel
.builder()
.message(message)
.author(member)
.channel(channel.orElse(null))
.aChannel(aChannel)
.starCount(starCount)
.guild(guild.orElse(null))
.user(user)
.server(server)
.starLevelEmote(starLevelEmote)
.build();
private CompletableFuture<StarboardPostModel> buildStarboardPostModel(CachedMessage message, Integer starCount) {
return botService.getMemberInServerAsync(message.getServerId(), message.getAuthorId()).thenApply(member -> {
Optional<TextChannel> channel = botService.getTextChannelFromServerOptional(message.getServerId(), message.getChannelId());
Optional<Guild> guild = botService.getGuildByIdOptional(message.getServerId());
AChannel aChannel = AChannel.builder().id(message.getChannelId()).build();
AUser user = AUser.builder().id(message.getAuthorId()).build();
AServer server = AServer.builder().id(message.getServerId()).build();
String starLevelEmote = getAppropriateEmote(message.getServerId(), starCount);
return StarboardPostModel
.builder()
.message(message)
.author(member)
.channel(channel.orElse(null))
.aChannel(aChannel)
.starCount(starCount)
.guild(guild.orElse(null))
.user(user)
.server(server)
.starLevelEmote(starLevelEmote)
.build();
});
}
@Override
public void updateStarboardPost(StarboardPost post, CachedMessage message, List<AUserInAServer> userExceptAuthor) {
log.info("Updating starboard post {} in server {} with reactors {}.", post.getId(), post.getSourceChanel().getServer().getId(), userExceptAuthor.size());
StarboardPostModel starboardPostModel = buildStarboardPostModel(message, userExceptAuthor.size());
MessageToSend messageToSend = templateService.renderEmbedTemplate(STARBOARD_POST_TEMPLATE, starboardPostModel);
List<CompletableFuture<Message>> futures = postTargetService.editOrCreatedInPostTarget(post.getStarboardMessageId(), messageToSend, StarboardPostTarget.STARBOARD, message.getServerId());
Long starboardPostId = post.getId();
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenAccept(aVoid -> {
Optional<StarboardPost> innerPost = starboardPostManagementService.findByStarboardPostId(starboardPostId);
innerPost.ifPresent(starboardPost -> starboardPostManagementService.setStarboardPostMessageId(starboardPost, futures.get(0).join().getIdLong()));
}).exceptionally(throwable -> {
log.error("Failed to update starboard post {}.", post.getId(), throwable);
return null;
public CompletableFuture<Void> updateStarboardPost(StarboardPost post, CachedMessage message, List<AUserInAServer> userExceptAuthor) {
int starCount = userExceptAuthor.size();
log.info("Updating starboard post {} in server {} with reactors {}.", post.getId(), post.getSourceChanel().getServer().getId(), starCount);
return buildStarboardPostModel(message, starCount).thenCompose(starboardPostModel -> {
MessageToSend messageToSend = templateService.renderEmbedTemplate(STARBOARD_POST_TEMPLATE, starboardPostModel);
List<CompletableFuture<Message>> futures = postTargetService.editOrCreatedInPostTarget(post.getStarboardMessageId(), messageToSend, StarboardPostTarget.STARBOARD, message.getServerId());
Long starboardPostId = post.getId();
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenAccept(aVoid -> {
Optional<StarboardPost> innerPost = starboardPostManagementService.findByStarboardPostId(starboardPostId);
innerPost.ifPresent(starboardPost -> starboardPostManagementService.setStarboardPostMessageId(starboardPost, futures.get(0).join().getIdLong()));
});
});
}
@@ -166,28 +170,35 @@ public class StarboardServiceBean implements StarboardService {
}
@Override
public StarStatsModel retrieveStarStats(Long serverId) {
public CompletableFuture<StarStatsModel> retrieveStarStats(Long serverId) {
int count = 3;
List<StarboardPost> starboardPosts = starboardPostManagementService.retrieveTopPosts(serverId, count);
List<StarStatsUser> topStarGivers = starboardPostReactorManagementService.retrieveTopStarGiver(serverId, count);
List<StarStatsPost> starStatsPosts = starboardPosts.stream().map(this::fromStarboardPost).collect(Collectors.toList());
List<StarStatsUser> topStarReceiver = starboardPostReactorManagementService.retrieveTopStarReceiver(serverId, count);
Integer postCount = starboardPostManagementService.getPostCount(serverId);
Integer reactionCount = starboardPostReactorManagementService.getStarCount(serverId);
List<String> emotes = new ArrayList<>();
for (int i = 1; i < count + 1; i++) {
emotes.add(getStarboardRankingEmote(serverId, i));
}
List<CompletableFuture<StarStatsUser>> topStarGiverFutures = starboardPostReactorManagementService.retrieveTopStarGiver(serverId, count);
List<CompletableFuture<StarStatsUser>> topStarReceiverFutures = starboardPostReactorManagementService.retrieveTopStarReceiver(serverId, count);
List<CompletableFuture> allFutures = new ArrayList<>();
allFutures.addAll(topStarGiverFutures);
allFutures.addAll(topStarReceiverFutures);
return FutureUtils.toSingleFuture(allFutures).thenApply(aVoid -> {
List<StarboardPost> starboardPosts = starboardPostManagementService.retrieveTopPosts(serverId, count);
List<StarStatsPost> starStatsPosts = starboardPosts.stream().map(this::fromStarboardPost).collect(Collectors.toList());
Integer postCount = starboardPostManagementService.getPostCount(serverId);
Integer reactionCount = starboardPostReactorManagementService.getStarCount(serverId);
List<String> emotes = new ArrayList<>();
for (int i = 1; i < count + 1; i++) {
emotes.add(getStarboardRankingEmote(serverId, i));
}
List<StarStatsUser> topStarGivers = topStarGiverFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
List<StarStatsUser> topStarReceiver = topStarReceiverFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
return StarStatsModel
.builder()
.badgeEmotes(emotes)
.starGiver(topStarGivers)
.starReceiver(topStarReceiver)
.topPosts(starStatsPosts)
.starredMessages(postCount)
.totalStars(reactionCount)
.build();
});
return StarStatsModel
.builder()
.badgeEmotes(emotes)
.starGiver(topStarGivers)
.starReceiver(topStarReceiver)
.topPosts(starStatsPosts)
.starredMessages(postCount)
.totalStars(reactionCount)
.build();
}
public StarStatsPost fromStarboardPost(StarboardPost starboardPost) {

View File

@@ -1,10 +1,9 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.exception.ChannelNotFoundException;
import dev.sheldan.abstracto.core.exception.GuildNotFoundException;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.CounterService;
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;
@@ -73,7 +72,7 @@ public class SuggestionServiceBean implements SuggestionService {
long guildId = member.getGuild().getIdLong();
log.info("Creating suggestion with id {} in server {} from member {}.", newSuggestionId, member.getGuild().getId(), member.getId());
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(messageToSend, SuggestionPostTarget.SUGGESTION, guildId);
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenCompose(aVoid -> {
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);
@@ -110,26 +109,22 @@ public class SuggestionServiceBean implements SuggestionService {
suggestionLog.setOriginalMessageId(originalMessageId);
suggestionLog.setOriginalMessageUrl(MessageUtils.buildMessageUrl(serverId, channelId, originalMessageId));
AUserInAServer suggester = suggestion.getSuggester();
Optional<Guild> guildByIdOptional = botService.getGuildById(serverId);
if(guildByIdOptional.isPresent()) {
Guild guildById = guildByIdOptional.get();
Member memberById = guildById.getMemberById(suggester.getUserReference().getId());
suggestionLog.setSuggester(memberById);
suggestionLog.setState(suggestion.getState());
suggestionLog.setSuggestionId(suggestion.getId());
TextChannel textChannelById = guildById.getTextChannelById(channelId);
if(textChannelById != null) {
return textChannelById.retrieveMessageById(originalMessageId).submit().thenCompose(message ->
self.updateSuggestionMessageText(text, suggestionLog, message)
);
} else {
log.warn("Not possible to update suggestion {}, because text channel {} was not found in guild {}.", suggestion.getId(), channelId, serverId);
throw new ChannelNotFoundException(channelId);
TextChannel textChannelById = botService.getTextChannelFromServer(serverId, channelId);
CompletableFuture<Member> memberById = botService.getMemberInServerAsync(serverId, suggester.getUserReference().getId());
suggestionLog.setState(suggestion.getState());
suggestionLog.setSuggestionId(suggestion.getId());
CompletableFuture<Void> finalFuture = new CompletableFuture<>();
memberById.whenComplete((member, throwable) -> {
if(throwable == null) {
suggestionLog.setSuggester(member);
}
} else {
log.warn("Not possible to update suggestion {}, because guild {} was not found.", suggestion.getId(), serverId);
throw new GuildNotFoundException(serverId);
}
textChannelById.retrieveMessageById(originalMessageId).submit().thenCompose(message ->
self.updateSuggestionMessageText(text, suggestionLog, message)
).thenAccept(aVoid -> finalFuture.complete(null));
});
return finalFuture;
}
@Transactional(propagation = Propagation.REQUIRES_NEW)

View File

@@ -2,6 +2,7 @@ package dev.sheldan.abstracto.utility.service.management;
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.utility.exception.ReminderNotFoundException;
import dev.sheldan.abstracto.utility.models.database.Reminder;
import dev.sheldan.abstracto.utility.repository.ReminderRepository;
import lombok.extern.slf4j.Slf4j;
@@ -39,10 +40,15 @@ public class ReminderManagementServiceBean implements ReminderManagementService
}
@Override
public Optional<Reminder> loadReminder(Long reminderId) {
public Optional<Reminder> loadReminderOptional(Long reminderId) {
return reminderRepository.findById(reminderId);
}
@Override
public Reminder loadReminder(Long reminderId) {
return loadReminderOptional(reminderId).orElseThrow(() -> new ReminderNotFoundException(reminderId));
}
@Override
public void setReminded(Reminder reminder) {
reminder.setReminded(true);

View File

@@ -12,6 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
@@ -52,13 +53,13 @@ public class StarboardPostReactorManagementServiceBean implements StarboardPostR
}
@Override
public List<StarStatsUser> retrieveTopStarGiver(Long serverId, Integer count) {
public List<CompletableFuture<StarStatsUser>> retrieveTopStarGiver(Long serverId, Integer count) {
List<StarStatsUserResult> starGivers = repository.findTopStarGiverInServer(serverId, count);
return converter.convertToStarStatsUser(starGivers, serverId);
}
@Override
public List<StarStatsUser> retrieveTopStarReceiver(Long serverId, Integer count) {
public List<CompletableFuture<StarStatsUser>> retrieveTopStarReceiver(Long serverId, Integer count) {
List<StarStatsUserResult> starReceivers = repository.retrieveTopStarReceiverInServer(serverId, count);
return converter.convertToStarStatsUser(starReceivers, serverId);
}