From c9557fccc21c29a0cbe3cc174d7de412282e364e Mon Sep 17 00:00:00 2001 From: Sheldan <5037282+Sheldan@users.noreply.github.com> Date: Wed, 1 Apr 2020 23:46:28 +0200 Subject: [PATCH] added configurable warning and success reactions changed that channels dont actually get deleted, but rather with a deleted flag, so the foreign keys are valid added more optionals to server/channel/message/member retrieval added throwing exceptions instead of just returning null fixed filtering of deleted channels while the bot was offline fixed channel listener added message deleted listener structure moved quartz properties to general application properties, because they were not found in the separate one added try catch to reminderJob, so that the job is not in an invalid state we now completely remove the starboard post, in case it falls under the threshold added code to 'ignore' a staroard post form further stars, in case the post in the starboard gets deleted now actually setting the reminded flag on a reminder added handnling in case the channel to remind in does not exist anymore --- ...ner.java => MessageDeleteLogListener.java} | 35 ++------- .../moderation/service/BanServiceBean.java | 14 +++- .../moderation/service/KickServiceBean.java | 14 +++- .../service/SlowModeServiceBean.java | 13 +++- .../moderation/service/WarnServiceBean.java | 8 +- .../abstracto/utility/jobs/ReminderJob.java | 8 +- .../utility/listener/StarboardListener.java | 27 +++---- .../StarboardPostDeletedListener.java | 25 +++++++ .../repository/StarboardPostRepository.java | 1 + .../utility/service/RemindServiceBean.java | 28 ++++--- .../utility/service/StarboardServiceBean.java | 8 +- .../ReminderManagementServiceBean.java | 6 ++ .../StarboardPostManagementServiceBean.java | 23 +++++- .../SuggestionManagementServiceBean.java | 2 +- .../utility/models/StarboardPost.java | 2 +- .../management/ReminderManagementService.java | 1 + .../StarboardPostManagementService.java | 4 + .../management/CommandReceivedHandler.java | 3 +- .../management/config/CommandConfig.java | 10 +++ .../post/ReactionPostExecution.java | 12 ++- .../src/main/resources/commands.properties | 1 + .../abstracto/core/service/BotService.java | 73 ++++++++++++------- .../core/service/EmoteServiceBean.java | 8 +- .../core/service/MessageCacheBean.java | 28 +++++-- .../core/service/MessageServiceBean.java | 29 +++++--- .../core/service/StartupManager.java | 12 ++- .../ChannelManagementServiceBean.java | 18 ++++- .../ConfigManagementServiceBean.java | 4 +- .../EmoteManagementServiceBean.java | 14 ++-- .../management/PostTargetManagementBean.java | 6 +- .../ServerManagementServiceBean.java | 6 +- .../management/UserManagementServiceBean.java | 2 +- .../abstracto/listener/ChannelListener.java | 32 ++++---- .../listener/MessageDeletedListenerBean.java | 46 ++++++++++++ .../listener/MessageEmbedListener.java | 3 +- .../core/exception/NotFoundException.java | 7 ++ .../core/listener/MessageDeletedListener.java | 7 ++ .../management/ChannelManagementService.java | 2 + .../management/ServerManagementService.java | 2 +- .../core/models/database/AChannel.java | 5 ++ .../sheldan/abstracto/core/service/Bot.java | 8 +- .../abstracto/core/utils/ContextUtils.java | 2 +- .../abstracto/core/utils/EmoteUtils.java | 5 +- .../src/main/resources/application.properties | 14 ++++ .../resources/config/application.properties | 12 --- 45 files changed, 409 insertions(+), 181 deletions(-) rename abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/{MessageDeletedListener.java => MessageDeleteLogListener.java} (65%) create mode 100644 abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/listener/StarboardPostDeletedListener.java create mode 100644 abstracto-application/command/command-support/src/main/java/dev/sheldan/abstracto/commands/management/config/CommandConfig.java create mode 100644 abstracto-application/command/command-support/src/main/resources/commands.properties create mode 100644 abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/listener/MessageDeletedListenerBean.java create mode 100644 abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/exception/NotFoundException.java create mode 100644 abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/listener/MessageDeletedListener.java diff --git a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/MessageDeletedListener.java b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/MessageDeleteLogListener.java similarity index 65% rename from abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/MessageDeletedListener.java rename to abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/MessageDeleteLogListener.java index ed1ada5d0..87f006473 100644 --- a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/MessageDeletedListener.java +++ b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/MessageDeleteLogListener.java @@ -1,5 +1,6 @@ package dev.sheldan.abstracto.moderation.listener; +import dev.sheldan.abstracto.core.listener.MessageDeletedListener; import dev.sheldan.abstracto.core.models.CachedMessage; import dev.sheldan.abstracto.core.utils.ContextUtils; import dev.sheldan.abstracto.core.service.MessageCache; @@ -9,19 +10,12 @@ import dev.sheldan.abstracto.moderation.models.template.listener.MessageDeletedL import dev.sheldan.abstracto.core.models.embed.MessageToSend; import dev.sheldan.abstracto.templating.TemplateService; import lombok.extern.slf4j.Slf4j; -import net.dv8tion.jda.api.entities.MessageEmbed; -import net.dv8tion.jda.api.events.message.guild.GuildMessageDeleteEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; - -import javax.annotation.Nonnull; -import java.util.concurrent.ExecutionException; @Component @Slf4j -public class MessageDeletedListener extends ListenerAdapter { +public class MessageDeleteLogListener implements MessageDeletedListener { private static final String DELETE_LOG_TARGET = "deleteLog"; private static String MESSAGE_DELETED_TEMPLATE = "message_deleted"; @@ -39,37 +33,20 @@ public class MessageDeletedListener extends ListenerAdapter { @Autowired private PostTargetService postTargetService; - @Autowired - private MessageDeletedListener self; - @Override - @Transactional - public void onGuildMessageDelete(@Nonnull GuildMessageDeleteEvent event) { - messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong()) - .thenAccept(messageFromCache -> { - try { - self.logMessage(event, messageFromCache); - } catch (Exception e) { - log.error("Error when logging message deletion.", e); - } - }); - - } - - @Transactional - public void logMessage(@Nonnull GuildMessageDeleteEvent event, CachedMessage messageFromCache) { + public void execute(CachedMessage messageFromCache) { MessageDeletedLog logModel = (MessageDeletedLog) contextUtils.fromMessage(messageFromCache, MessageDeletedLog.class); logModel.setMessage(messageFromCache); String simpleMessageUpdatedMessage = templateService.renderTemplate(MESSAGE_DELETED_TEMPLATE, logModel); - postTargetService.sendTextInPostTarget(simpleMessageUpdatedMessage, DELETE_LOG_TARGET, event.getGuild().getIdLong()); + postTargetService.sendTextInPostTarget(simpleMessageUpdatedMessage, DELETE_LOG_TARGET, messageFromCache.getServerId()); MessageToSend message = templateService.renderEmbedTemplate(MESSAGE_DELETED_TEMPLATE, logModel); - postTargetService.sendEmbedInPostTarget(message, DELETE_LOG_TARGET, event.getGuild().getIdLong()); + postTargetService.sendEmbedInPostTarget(message, DELETE_LOG_TARGET, messageFromCache.getServerId()); for (int i = 0; i < messageFromCache.getAttachmentUrls().size(); i++) { MessageDeletedAttachmentLog log = (MessageDeletedAttachmentLog) contextUtils.fromMessage(messageFromCache, MessageDeletedAttachmentLog.class); log.setImageUrl(messageFromCache.getAttachmentUrls().get(i)); log.setCounter(i + 1); MessageToSend attachmentEmbed = templateService.renderEmbedTemplate(MESSAGE_DELETED_ATTACHMENT_TEMPLATE, log); - postTargetService.sendEmbedInPostTarget(attachmentEmbed, DELETE_LOG_TARGET, event.getGuild().getIdLong()); + postTargetService.sendEmbedInPostTarget(attachmentEmbed, DELETE_LOG_TARGET, messageFromCache.getServerId()); } } } diff --git a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/BanServiceBean.java b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/BanServiceBean.java index 865e15891..de87e8324 100644 --- a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/BanServiceBean.java +++ b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/BanServiceBean.java @@ -1,5 +1,6 @@ package dev.sheldan.abstracto.moderation.service; +import dev.sheldan.abstracto.core.exception.NotFoundException; import dev.sheldan.abstracto.core.models.ServerContext; import dev.sheldan.abstracto.core.service.Bot; import dev.sheldan.abstracto.core.service.PostTargetService; @@ -10,6 +11,8 @@ import net.dv8tion.jda.api.entities.Member; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.Optional; + @Component @Slf4j public class BanServiceBean implements BanService { @@ -41,8 +44,13 @@ public class BanServiceBean implements BanService { } private void banUser(Long guildId, Long userId, String reason) { - Guild guildById = bot.getGuildById(guildId); - log.info("Banning user {} in guild {}.", userId, guildId); - guildById.ban(userId.toString(), 0, reason).queue(); + Optional guildByIdOptional = bot.getGuildById(guildId); + if(guildByIdOptional.isPresent()) { + log.info("Banning user {} in guild {}.", userId, guildId); + guildByIdOptional.get().ban(userId.toString(), 0, reason).queue(); + } else { + log.warn("Guild {} not found. Not able to ban user {}", guildId, userId); + throw new NotFoundException(String.format("Guild %s not found. Not able to ban user %s", guildId, userId)); + } } } diff --git a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/KickServiceBean.java b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/KickServiceBean.java index ec2e6e9a4..7ae2cf3b7 100644 --- a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/KickServiceBean.java +++ b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/KickServiceBean.java @@ -1,5 +1,6 @@ package dev.sheldan.abstracto.moderation.service; +import dev.sheldan.abstracto.core.exception.NotFoundException; import dev.sheldan.abstracto.core.service.Bot; import dev.sheldan.abstracto.core.service.PostTargetService; import dev.sheldan.abstracto.moderation.models.template.KickLogModel; @@ -10,6 +11,8 @@ import net.dv8tion.jda.api.entities.Member; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.Optional; + @Component @Slf4j public class KickServiceBean implements KickService { @@ -27,9 +30,14 @@ public class KickServiceBean implements KickService { @Override public void kickMember(Member member, String reason, KickLogModel kickLogModel) { - Guild guildById = bot.getGuildById(kickLogModel.getGuild().getIdLong()); - guildById.kick(member, reason).queue(); - this.sendKickLog(kickLogModel); + Optional guildById = bot.getGuildById(kickLogModel.getGuild().getIdLong()); + if(guildById.isPresent()) { + guildById.get().kick(member, reason).queue(); + this.sendKickLog(kickLogModel); + } else { + log.warn("Not able to kick. Guild {} not found.", kickLogModel.getGuild().getIdLong()); + throw new NotFoundException(String.format("Not able to kick %s. Guild %s not found", kickLogModel.getMember().getIdLong(), kickLogModel.getGuild().getIdLong())); + } } private void sendKickLog(KickLogModel kickLogModel) { diff --git a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/SlowModeServiceBean.java b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/SlowModeServiceBean.java index f1a5cf91f..cebd780dc 100644 --- a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/SlowModeServiceBean.java +++ b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/SlowModeServiceBean.java @@ -1,15 +1,15 @@ package dev.sheldan.abstracto.moderation.service; +import dev.sheldan.abstracto.core.exception.NotFoundException; import dev.sheldan.abstracto.core.models.database.AChannel; import dev.sheldan.abstracto.core.service.Bot; import lombok.extern.slf4j.Slf4j; -import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.TextChannel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.time.Duration; +import java.util.Optional; @Component @Slf4j @@ -29,7 +29,12 @@ public class SlowModeServiceBean implements SlowModeService { @Override public void setSlowMode(AChannel channel, Duration duration) { - TextChannel textChannel = bot.getTextChannelFromServer(channel.getServer().getId(), channel.getId()); - this.setSlowMode(textChannel, duration); + Optional textChannelOptional = bot.getTextChannelFromServer(channel.getServer().getId(), channel.getId()); + if(textChannelOptional.isPresent()) { + TextChannel textChannel = textChannelOptional.get(); + this.setSlowMode(textChannel, duration); + } else { + throw new NotFoundException(String.format("Channel %s not found in guild %s", channel.getId(), channel.getServer().getId())); + } } } diff --git a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/WarnServiceBean.java b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/WarnServiceBean.java index f7142dd5d..e015f2757 100644 --- a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/WarnServiceBean.java +++ b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/service/WarnServiceBean.java @@ -22,6 +22,8 @@ import net.dv8tion.jda.api.entities.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.Optional; + @Slf4j @Component public class WarnServiceBean implements WarnService { @@ -57,10 +59,10 @@ public class WarnServiceBean implements WarnService { Warning warning = warnManagementService.createWarning(warnedAUserInAServer, warningAUserInAServer, reason); JDA instance = bot.getInstance(); User userBeingWarned = instance.getUserById(warnedAUser.getId()); - Guild guildById = bot.getGuildById(serverOfWarning.getId()); + Optional guildById = bot.getGuildById(serverOfWarning.getId()); String guildName = ""; - if(guildById != null) { - guildName = guildById.getName(); + if(guildById.isPresent()) { + guildName = guildById.get().getName(); } WarnNotification warnNotification = WarnNotification.builder().warning(warning).serverName(guildName).build(); if(userBeingWarned != null) { diff --git a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/jobs/ReminderJob.java b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/jobs/ReminderJob.java index 9d02c8ece..4405ba401 100644 --- a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/jobs/ReminderJob.java +++ b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/jobs/ReminderJob.java @@ -23,8 +23,12 @@ public class ReminderJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { - reminderService.executeReminder(reminderId); - log.info("executing reminder job for reminder {}", reminderId); + try { + reminderService.executeReminder(reminderId); + log.info("executing reminder job for reminder {}", reminderId); + } catch (Exception e) { + log.error("Reminder job failed to execute.", e); + } } public Long getReminderId() { diff --git a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/listener/StarboardListener.java b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/listener/StarboardListener.java index c007b7017..2c4f275aa 100644 --- a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/listener/StarboardListener.java +++ b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/listener/StarboardListener.java @@ -32,7 +32,7 @@ import java.util.stream.Collectors; @Slf4j public class StarboardListener implements ReactedAddedListener, ReactedRemovedListener { - public static final String STAR_EMOTE = "STAR"; + public static final String STAR_EMOTE = "star"; @Autowired private EmoteManagementService emoteManagementService; @@ -69,8 +69,8 @@ public class StarboardListener implements ReactedAddedListener, ReactedRemovedLi if(aEmote.isPresent()) { AEmote emote = aEmote.get(); MessageReaction.ReactionEmote reactionEmote = addedReaction.getReactionEmote(); - Emote emoteInGuild = bot.getEmote(guildId, emote); - if(EmoteUtils.isReactionEmoteAEmote(reactionEmote, emote, Optional.ofNullable(emoteInGuild))) { + Optional emoteInGuild = bot.getEmote(guildId, emote); + if(EmoteUtils.isReactionEmoteAEmote(reactionEmote, emote, emoteInGuild.orElse(null))) { Optional reactionOptional = EmoteUtils.getReactionFromMessageByEmote(message, emote); updateStarboardPost(message, reactionOptional.orElse(null), userAdding, true); } @@ -88,6 +88,7 @@ public class StarboardListener implements ReactedAddedListener, ReactedRemovedLi AUserInAServer author = userManagementService.loadUser(message.getServerId(), message.getAuthorId()); if(starboardPostOptional.isPresent()) { StarboardPost starboardPost = starboardPostOptional.get(); + starboardPost.setIgnored(false); starboardService.updateStarboardPost(starboardPost, message, userExceptAuthor); if(adding) { starboardPostReactorManagementService.addReactor(starboardPost, userReacting.getUserReference()); @@ -98,19 +99,19 @@ public class StarboardListener implements ReactedAddedListener, ReactedRemovedLi starboardService.createStarboardPost(message, userExceptAuthor, userReacting, author); } } else { - starboardPostOptional.ifPresent(starboardPost -> { - starboardService.removeStarboardPost(starboardPost); - starboardPostReactorManagementService.removeReactors(starboardPost); - }); + starboardPostOptional.ifPresent(this::completelyRemoveStarboardPost); } } else { - starboardPostOptional.ifPresent(starboardPost -> { - starboardService.removeStarboardPost(starboardPost); - starboardPostReactorManagementService.removeReactors(starboardPost); - }); + starboardPostOptional.ifPresent(this::completelyRemoveStarboardPost); } } + private void completelyRemoveStarboardPost(StarboardPost starboardPost) { + starboardPostReactorManagementService.removeReactors(starboardPost); + starboardService.removeStarboardPost(starboardPost); + starboardPostManagementService.removePost(starboardPost); + } + @Override @Transactional public void executeReactionRemoved(CachedMessage message, MessageReaction removedReaction, AUserInAServer userRemoving) { @@ -122,8 +123,8 @@ public class StarboardListener implements ReactedAddedListener, ReactedRemovedLi if(aEmote.isPresent()) { AEmote emote = aEmote.get(); MessageReaction.ReactionEmote reactionEmote = removedReaction.getReactionEmote(); - Emote emoteInGuild = bot.getEmote(guildId, emote); - if(EmoteUtils.isReactionEmoteAEmote(reactionEmote, emote, Optional.ofNullable(emoteInGuild))) { + Optional emoteInGuild = bot.getEmote(guildId, emote); + if(EmoteUtils.isReactionEmoteAEmote(reactionEmote, emote, emoteInGuild.orElse(null))) { Optional reactionOptional = EmoteUtils.getReactionFromMessageByEmote(message, emote); updateStarboardPost(message, reactionOptional.orElse(null), userRemoving, false); } diff --git a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/listener/StarboardPostDeletedListener.java b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/listener/StarboardPostDeletedListener.java new file mode 100644 index 000000000..740b4ee85 --- /dev/null +++ b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/listener/StarboardPostDeletedListener.java @@ -0,0 +1,25 @@ +package dev.sheldan.abstracto.utility.listener; + +import dev.sheldan.abstracto.core.listener.MessageDeletedListener; +import dev.sheldan.abstracto.core.models.CachedMessage; +import dev.sheldan.abstracto.utility.models.StarboardPost; +import dev.sheldan.abstracto.utility.service.management.StarboardPostManagementService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +@Component +public class StarboardPostDeletedListener implements MessageDeletedListener { + + @Autowired + private StarboardPostManagementService starboardPostManagementService; + + @Override + public void execute(CachedMessage messageBefore) { + Optional byStarboardPostId = starboardPostManagementService.findByStarboardPostId(messageBefore.getMessageId()); + if(byStarboardPostId.isPresent()) { + starboardPostManagementService.setStarboardPostIgnored(messageBefore.getMessageId(), true); + } + } +} diff --git a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/repository/StarboardPostRepository.java b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/repository/StarboardPostRepository.java index 1112de095..8f65a2cf8 100644 --- a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/repository/StarboardPostRepository.java +++ b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/repository/StarboardPostRepository.java @@ -7,6 +7,7 @@ import java.util.List; public interface StarboardPostRepository extends JpaRepository { StarboardPost findByPostMessageId(Long messageId); + StarboardPost findByStarboardMessageId(Long messageId); List findByStarboardChannelServerId(Long serverId); } diff --git a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/RemindServiceBean.java b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/RemindServiceBean.java index e611f799d..896966079 100644 --- a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/RemindServiceBean.java +++ b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/RemindServiceBean.java @@ -26,6 +26,7 @@ import org.springframework.transaction.annotation.Transactional; import java.time.Duration; import java.time.Instant; import java.util.Date; +import java.util.Optional; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -92,16 +93,21 @@ public class RemindServiceBean implements ReminderService { Reminder reminderToRemindFor = reminderManagementService.loadReminder(reminderId); AServer server = reminderToRemindFor.getServer(); AChannel channel = reminderToRemindFor.getChannel(); - AUser userReference = reminderToRemindFor.getToBeReminded().getUserReference(); - Member memberInServer = bot.getMemberInServer(server.getId(), userReference.getId()); - ExecutedReminderModel build = ExecutedReminderModel - .builder() - .reminder(reminderToRemindFor) - .member(memberInServer) - .build(); - MessageToSend messageToSend = templateService.renderEmbedTemplate("remind_reminder", build); - // todo, if channel does not exist anymore - TextChannel channelToAnswerIn = bot.getTextChannelFromServer(server.getId(), channel.getId()); - channelToAnswerIn.sendMessage(messageToSend.getMessage()).embed(messageToSend.getEmbed()).queue(); + Optional channelToAnswerIn = bot.getTextChannelFromServer(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.getToBeReminded().getUserReference(); + Member memberInServer = bot.getMemberInServer(server.getId(), userReference.getId()); + ExecutedReminderModel build = ExecutedReminderModel + .builder() + .reminder(reminderToRemindFor) + .member(memberInServer) + .build(); + MessageToSend messageToSend = templateService.renderEmbedTemplate("remind_reminder", build); + channelToAnswerIn.get().sendMessage(messageToSend.getMessage()).embed(messageToSend.getEmbed()).queue(); + } else { + log.warn("Channel {} in server {} to remind user did not exist anymore. Ignoring.", channel.getId(), server.getId()); + } + reminderManagementService.setReminded(reminderToRemindFor); } } diff --git a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/StarboardServiceBean.java b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/StarboardServiceBean.java index 7df08fba9..fc28ad982 100644 --- a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/StarboardServiceBean.java +++ b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/StarboardServiceBean.java @@ -92,8 +92,8 @@ public class StarboardServiceBean implements StarboardService { private StarboardPostModel buildStarboardPostModel(CachedMessage message, Integer starCount) { Member member = bot.getMemberInServer(message.getServerId(), message.getAuthorId()); - TextChannel channel = bot.getTextChannelFromServer(message.getServerId(), message.getChannelId()); - Guild guild = bot.getGuildById(message.getServerId()); + Optional channel = bot.getTextChannelFromServer(message.getServerId(), message.getChannelId()); + Optional guild = bot.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(); @@ -110,10 +110,10 @@ public class StarboardServiceBean implements StarboardService { .builder() .message(message) .author(member) - .channel(channel) + .channel(channel.orElse(null)) .aChannel(aChannel) .starCount(starCount) - .guild(guild) + .guild(guild.orElse(null)) .user(user) .server(server) .starLevelEmote(emoteText) diff --git a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/management/ReminderManagementServiceBean.java b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/management/ReminderManagementServiceBean.java index 7e4533252..8a2f4c187 100644 --- a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/management/ReminderManagementServiceBean.java +++ b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/management/ReminderManagementServiceBean.java @@ -36,4 +36,10 @@ public class ReminderManagementServiceBean implements ReminderManagementService return reminderRepository.getOne(reminderId); } + @Override + public void setReminded(Reminder reminder) { + reminder.setReminded(true); + reminderRepository.save(reminder); + } + } diff --git a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/management/StarboardPostManagementServiceBean.java b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/management/StarboardPostManagementServiceBean.java index d9da76114..8a32c1351 100644 --- a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/management/StarboardPostManagementServiceBean.java +++ b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/management/StarboardPostManagementServiceBean.java @@ -29,7 +29,6 @@ public class StarboardPostManagementServiceBean implements StarboardPostManageme StarboardPost post = StarboardPost .builder() .author(starredUser.getUserReference()) - .deleted(false) .postMessageId(starredMessage.getMessageId()) .starboardMessageId(starboardPost.getMessageId()) .starboardChannel(starboardPost.getChannel()) @@ -68,5 +67,27 @@ public class StarboardPostManagementServiceBean implements StarboardPostManageme return Optional.ofNullable(repository.findByPostMessageId(messageId)); } + @Override + public Optional findByStarboardPostId(Long postId) { + return Optional.ofNullable(repository.findByStarboardMessageId(postId)); + } + + @Override + public void setStarboardPostIgnored(Long messageId, Boolean newValue) { + StarboardPost post = repository.findByStarboardMessageId(messageId); + post.setIgnored(newValue); + repository.save(post); + } + + @Override + public boolean isStarboardPost(Long messageId) { + return repository.findByStarboardMessageId(messageId) != null; + } + + @Override + public void removePost(StarboardPost starboardPost) { + repository.deleteById(starboardPost.getId()); + } + } diff --git a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/management/SuggestionManagementServiceBean.java b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/management/SuggestionManagementServiceBean.java index 0b05b424d..fcac381e6 100644 --- a/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/management/SuggestionManagementServiceBean.java +++ b/abstracto-application/abstracto-modules/utility/utility-impl/src/main/java/dev/sheldan/abstracto/utility/service/management/SuggestionManagementServiceBean.java @@ -60,7 +60,7 @@ public class SuggestionManagementServiceBean implements SuggestionManagementServ suggestion.setMessageId(message.getIdLong()); AChannel channel = channelManagementService.loadChannel(message.getTextChannel().getIdLong()); suggestion.setChannel(channel); - AServer server = serverManagementService.loadServer(message.getGuild().getIdLong()); + AServer server = serverManagementService.loadOrCreate(message.getGuild().getIdLong()); suggestion.setServer(server); suggestionRepository.save(suggestion); } diff --git a/abstracto-application/abstracto-modules/utility/utility-int/src/main/java/dev/sheldan/abstracto/utility/models/StarboardPost.java b/abstracto-application/abstracto-modules/utility/utility-int/src/main/java/dev/sheldan/abstracto/utility/models/StarboardPost.java index ae6c727cf..3e4a3779d 100644 --- a/abstracto-application/abstracto-modules/utility/utility-int/src/main/java/dev/sheldan/abstracto/utility/models/StarboardPost.java +++ b/abstracto-application/abstracto-modules/utility/utility-int/src/main/java/dev/sheldan/abstracto/utility/models/StarboardPost.java @@ -52,7 +52,7 @@ public class StarboardPost { private Instant starredDate; @Column - private boolean deleted; + private boolean ignored; public int getReactionCount() { if(this.reactions == null) { diff --git a/abstracto-application/abstracto-modules/utility/utility-int/src/main/java/dev/sheldan/abstracto/utility/service/management/ReminderManagementService.java b/abstracto-application/abstracto-modules/utility/utility-int/src/main/java/dev/sheldan/abstracto/utility/service/management/ReminderManagementService.java index d120e7402..97d065ae4 100644 --- a/abstracto-application/abstracto-modules/utility/utility-int/src/main/java/dev/sheldan/abstracto/utility/service/management/ReminderManagementService.java +++ b/abstracto-application/abstracto-modules/utility/utility-int/src/main/java/dev/sheldan/abstracto/utility/service/management/ReminderManagementService.java @@ -8,4 +8,5 @@ import java.time.Instant; public interface ReminderManagementService { Reminder createReminder(AServerAChannelAUser userToBeReminded, String text, Instant timeToBeRemindedAt, Long messageId); Reminder loadReminder(Long reminderId); + void setReminded(Reminder reminder); } diff --git a/abstracto-application/abstracto-modules/utility/utility-int/src/main/java/dev/sheldan/abstracto/utility/service/management/StarboardPostManagementService.java b/abstracto-application/abstracto-modules/utility/utility-int/src/main/java/dev/sheldan/abstracto/utility/service/management/StarboardPostManagementService.java index 76d3ceb32..df9229330 100644 --- a/abstracto-application/abstracto-modules/utility/utility-int/src/main/java/dev/sheldan/abstracto/utility/service/management/StarboardPostManagementService.java +++ b/abstracto-application/abstracto-modules/utility/utility-int/src/main/java/dev/sheldan/abstracto/utility/service/management/StarboardPostManagementService.java @@ -15,4 +15,8 @@ public interface StarboardPostManagementService { List retrieveAllPosts(Long serverId); Integer getPostCount(Long serverId); Optional findByMessageId(Long messageId); + Optional findByStarboardPostId(Long postId); + void setStarboardPostIgnored(Long starboardPostId, Boolean newValue); + boolean isStarboardPost(Long starboardPostId); + void removePost(StarboardPost starboardPost); } diff --git a/abstracto-application/command/command-support/src/main/java/dev/sheldan/abstracto/commands/management/CommandReceivedHandler.java b/abstracto-application/command/command-support/src/main/java/dev/sheldan/abstracto/commands/management/CommandReceivedHandler.java index 4b75e9dfb..6a5305a56 100644 --- a/abstracto-application/command/command-support/src/main/java/dev/sheldan/abstracto/commands/management/CommandReceivedHandler.java +++ b/abstracto-application/command/command-support/src/main/java/dev/sheldan/abstracto/commands/management/CommandReceivedHandler.java @@ -29,7 +29,6 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Nonnull; import java.time.Duration; import java.util.*; -import java.util.stream.Collectors; @Service public class CommandReceivedHandler extends ListenerAdapter { @@ -91,7 +90,7 @@ public class CommandReceivedHandler extends ListenerAdapter { private UserInitiatedServerContext buildTemplateParameter(MessageReceivedEvent event) { AChannel channel = channelManagementService.loadChannel(event.getChannel().getIdLong()); - AServer server = serverManagementService.loadServer(event.getGuild().getIdLong()); + AServer server = serverManagementService.loadOrCreate(event.getGuild().getIdLong()); AUserInAServer user = userManagementService.loadUser(event.getMember()); return UserInitiatedServerContext .builder() diff --git a/abstracto-application/command/command-support/src/main/java/dev/sheldan/abstracto/commands/management/config/CommandConfig.java b/abstracto-application/command/command-support/src/main/java/dev/sheldan/abstracto/commands/management/config/CommandConfig.java new file mode 100644 index 000000000..357acf85e --- /dev/null +++ b/abstracto-application/command/command-support/src/main/java/dev/sheldan/abstracto/commands/management/config/CommandConfig.java @@ -0,0 +1,10 @@ +package dev.sheldan.abstracto.commands.management.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +@Configuration +@PropertySource("classpath:commands.properties") +public class CommandConfig { +} + diff --git a/abstracto-application/command/command-support/src/main/java/dev/sheldan/abstracto/commands/management/post/ReactionPostExecution.java b/abstracto-application/command/command-support/src/main/java/dev/sheldan/abstracto/commands/management/post/ReactionPostExecution.java index 1057a58d1..300d58feb 100644 --- a/abstracto-application/command/command-support/src/main/java/dev/sheldan/abstracto/commands/management/post/ReactionPostExecution.java +++ b/abstracto-application/command/command-support/src/main/java/dev/sheldan/abstracto/commands/management/post/ReactionPostExecution.java @@ -5,20 +5,28 @@ import dev.sheldan.abstracto.command.PostCommandExecution; import dev.sheldan.abstracto.command.execution.CommandContext; import dev.sheldan.abstracto.command.execution.Result; import dev.sheldan.abstracto.command.execution.ResultState; +import dev.sheldan.abstracto.core.service.MessageService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class ReactionPostExecution implements PostCommandExecution { + + public static final String WARN_REACTION_EMOTE = "warnReaction"; + public static final String SUCCESS_REACTION_EMOTE = "successReaction"; + @Autowired + private MessageService messageService; + @Override public void execute(CommandContext commandContext, Result result, Command command) { if(result.getResult().equals(ResultState.ERROR)) { - commandContext.getMessage().addReaction("⚠️").queue(); + messageService.addReactionToMessage(WARN_REACTION_EMOTE, commandContext.getGuild().getIdLong(), commandContext.getMessage()); if(result.getMessage() != null && result.getThrowable() == null){ commandContext.getChannel().sendMessage(result.getMessage()).queue(); } } else { if(command.getConfiguration().isCausesReaction()){ - commandContext.getMessage().addReaction("✅").queue(); + messageService.addReactionToMessage(SUCCESS_REACTION_EMOTE, commandContext.getGuild().getIdLong(), commandContext.getMessage()); } } diff --git a/abstracto-application/command/command-support/src/main/resources/commands.properties b/abstracto-application/command/command-support/src/main/resources/commands.properties new file mode 100644 index 000000000..3b73dbade --- /dev/null +++ b/abstracto-application/command/command-support/src/main/resources/commands.properties @@ -0,0 +1 @@ +abstracto.emoteNames.postReaction=warnReaction,successReaction \ No newline at end of file diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/BotService.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/BotService.java index 62dee7c29..d66f3caac 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/BotService.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/BotService.java @@ -1,7 +1,9 @@ package dev.sheldan.abstracto.core.service; +import dev.sheldan.abstracto.core.exception.NotFoundException; import dev.sheldan.abstracto.core.models.ServerChannelUser; import dev.sheldan.abstracto.core.models.database.AEmote; +import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.Emote; @@ -13,8 +15,10 @@ import org.springframework.stereotype.Service; import javax.security.auth.login.LoginException; import java.util.EnumSet; +import java.util.Optional; @Service +@Slf4j public class BotService implements Bot { private JDA instance; @@ -36,13 +40,21 @@ public class BotService implements Bot { @Override public ServerChannelUser getServerChannelUser(Long serverId, Long channelId, Long userId) { - TextChannel textChannelById = getTextChannelFromServer(serverId, channelId); - Guild guildById = getGuildById(serverId); - if(textChannelById != null) { - Member member = guildById.getMemberById(userId); - return ServerChannelUser.builder().guild(guildById).textChannel(textChannelById).member(member).build(); + Optional guildOptional = getGuildById(serverId); + if(guildOptional.isPresent()) { + Guild guild = guildOptional.get(); + Optional textChannelOptional = this.getTextChannelFromServer(guild, channelId); + if(textChannelOptional.isPresent()) { + TextChannel textChannel = textChannelOptional.get(); + Member member = guild.getMemberById(userId); + return ServerChannelUser.builder().guild(guild).textChannel(textChannel).member(member).build(); + } else { + throw new NotFoundException(String.format("Text channel %s not found in guild %s", channelId, serverId)); + } + } + else { + throw new NotFoundException(String.format("Guild %s not found.", serverId)); } - throw new RuntimeException(String.format("Member %s or text channel %s not found in guild %s", userId, channelId, serverId)); } @@ -59,37 +71,48 @@ public class BotService implements Bot { @Override public void deleteMessage(Long serverId, Long channelId, Long messageId) { - getTextChannelFromServer(serverId, channelId).deleteMessageById(messageId).queue(); + Optional textChannelOptional = getTextChannelFromServer(serverId, channelId); + if(textChannelOptional.isPresent()) { + TextChannel textChannel = textChannelOptional.get(); + textChannel.deleteMessageById(messageId).queue(aVoid -> {}, throwable -> { + log.warn("Failed to delete message {} in channel {} in guild {}", messageId, channelId, serverId, throwable); + }); + } else { + log.warn("Could not find channel {} in guild {} to delete message {} in.", channelId, serverId, messageId); + } } @Override - public Emote getEmote(Long serverId, AEmote emote) { + public Optional getEmote(Long serverId, AEmote emote) { if(!emote.getCustom()) { - return null; + return Optional.empty(); } - Guild guildById = getGuildById(serverId); - return guildById.getEmoteById(emote.getEmoteId()); + Optional guildById = getGuildById(serverId); + if(guildById.isPresent()) { + Guild guild = guildById.get(); + return Optional.ofNullable(guild.getEmoteById(emote.getEmoteId())); + } + throw new NotFoundException(String.format("Not able to find emote %s in server %s", emote.getId(), serverId)); } @Override - public TextChannel getTextChannelFromServer(Long serverId, Long textChannelId) { - Guild guild = getGuildById(serverId); - TextChannel textChannelById = guild.getTextChannelById(textChannelId); - if(textChannelById != null) { - return textChannelById; - } else { - throw new RuntimeException(String.format("Text channel %s in guild %s not found", textChannelId, serverId)); - } + public Optional getTextChannelFromServer(Guild guild, Long textChannelId) { + return Optional.ofNullable(guild.getTextChannelById(textChannelId)); } @Override - public Guild getGuildById(Long serverId) { - Guild guildById = instance.getGuildById(serverId); - if(guildById != null) { - return guildById; - } else { - throw new RuntimeException(String.format("Guild %s not found", serverId)); + public Optional getTextChannelFromServer(Long serverId, Long textChannelId) { + Optional guildOptional = getGuildById(serverId); + if(guildOptional.isPresent()) { + Guild guild = guildOptional.get(); + return Optional.ofNullable(guild.getTextChannelById(textChannelId)); } + throw new NotFoundException(String.format("Not able to find guild %s", serverId)); + } + + @Override + public Optional getGuildById(Long serverId) { + return Optional.ofNullable(instance.getGuildById(serverId)); } @Override diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/EmoteServiceBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/EmoteServiceBean.java index 57803ef56..74c5723b7 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/EmoteServiceBean.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/EmoteServiceBean.java @@ -8,6 +8,8 @@ import net.dv8tion.jda.api.entities.MessageReaction; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.Optional; + @Component @Slf4j public class EmoteServiceBean implements EmoteService { @@ -38,9 +40,9 @@ public class EmoteServiceBean implements EmoteService { @Override public String getEmoteAsMention(AEmote emote, Long serverId, String defaultText) { if(emote != null && emote.getCustom()) { - Emote emote1 = botService.getEmote(serverId, emote); - if (emote1 != null) { - return emote1.getAsMention(); + Optional emoteOptional = botService.getEmote(serverId, emote); + if (emoteOptional.isPresent()) { + return emoteOptional.get().getAsMention(); } else { log.warn("Emote {} with name {} in server {} defined, but not usable.", emote.getEmoteId(), emote.getName(), serverId); return defaultText; diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MessageCacheBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MessageCacheBean.java index 6267c2033..17d68d0bd 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MessageCacheBean.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MessageCacheBean.java @@ -1,5 +1,6 @@ package dev.sheldan.abstracto.core.service; +import dev.sheldan.abstracto.core.exception.NotFoundException; import dev.sheldan.abstracto.core.management.EmoteManagementService; import dev.sheldan.abstracto.core.management.UserManagementService; import dev.sheldan.abstracto.core.models.CachedMessage; @@ -7,10 +8,7 @@ import dev.sheldan.abstracto.core.models.CachedReaction; import dev.sheldan.abstracto.core.models.database.AUser; import dev.sheldan.abstracto.core.models.embed.*; import lombok.extern.slf4j.Slf4j; -import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.MessageEmbed; -import net.dv8tion.jda.api.entities.MessageReaction; -import net.dv8tion.jda.api.entities.TextChannel; +import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.requests.restaction.pagination.ReactionPaginationAction; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CachePut; @@ -22,6 +20,7 @@ import org.springframework.stereotype.Component; import java.awt.*; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -81,10 +80,23 @@ public class MessageCacheBean implements MessageCache { @Async @Override public void loadMessage(CompletableFuture future, Long guildId, Long textChannelId, Long messageId) { - TextChannel textChannelById = bot.getTextChannelFromServer(guildId, textChannelId); - textChannelById.retrieveMessageById(messageId).queue(message -> { - buildCachedMessageFromMessage(future, message); - }); + Optional guildOptional = bot.getGuildById(guildId); + if(guildOptional.isPresent()) { + Optional textChannelByIdOptional = bot.getTextChannelFromServer(guildOptional.get(), textChannelId); + if(textChannelByIdOptional.isPresent()) { + TextChannel textChannel = textChannelByIdOptional.get(); + textChannel.retrieveMessageById(messageId).queue(message -> { + buildCachedMessageFromMessage(future, message); + }); + } else { + log.warn("Not able to load message {} in channel {} in guild {}. Text channel not found.", messageId, textChannelId, guildId); + future.completeExceptionally(new NotFoundException(String.format("Not able to load message %s. Text channel %s not found in guild %s", messageId, textChannelId, guildId))); + } + } else { + log.warn("Not able to load message {} in channel {} in guild {}. Guild not found.", messageId, textChannelId, guildId); + future.completeExceptionally(new NotFoundException(String.format("Not able to load message %s. Guild %s not found.", messageId, guildId))); + + } } @Override diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MessageServiceBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MessageServiceBean.java index 86c011c41..c7f54bb4a 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MessageServiceBean.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MessageServiceBean.java @@ -1,5 +1,6 @@ package dev.sheldan.abstracto.core.service; +import dev.sheldan.abstracto.core.exception.NotFoundException; import dev.sheldan.abstracto.core.management.EmoteManagementService; import dev.sheldan.abstracto.core.models.database.AEmote; import lombok.extern.slf4j.Slf4j; @@ -23,22 +24,30 @@ public class MessageServiceBean implements MessageService { @Override public void addReactionToMessage(String emoteKey, Long serverId, Message message) { - Guild guildById = bot.getGuildById(serverId); + Optional guildByIdOptional = bot.getGuildById(serverId); Optional aEmote = emoteManagementService.loadEmoteByName(emoteKey, serverId); - if(aEmote.isPresent()) { - AEmote emote = aEmote.get(); - if(emote.getCustom()) { - Emote emoteById = guildById.getEmoteById(emote.getEmoteId()); - if(emoteById != null) { - message.addReaction(emoteById).queue(); + if(guildByIdOptional.isPresent()) { + Guild guild = guildByIdOptional.get(); + if(aEmote.isPresent()) { + AEmote emote = aEmote.get(); + if(emote.getCustom()) { + Emote emoteById = guild.getEmoteById(emote.getEmoteId()); + if(emoteById != null) { + message.addReaction(emoteById).queue(); + } else { + log.warn("Emote with key {} and id {} for guild {} was not found.", emoteKey, emote.getEmoteId(), guild.getId()); + throw new NotFoundException(String.format("Emote with key `%s` and id %s in guild %s was not found. Check whether or not the configured emote is available.", emoteKey, emote.getEmoteId(), guild.getIdLong())); + } } else { - log.warn("Emote with key {} and id {} for guild {} was not found.", emoteKey, emote.getEmoteId(), guildById.getId()); + message.addReaction(emote.getEmoteKey()).queue(); } } else { - message.addReaction(emote.getEmoteKey()).queue(); + log.warn("Cannot add reaction, emote {} not defined for server {}.", emoteKey, serverId); + throw new NotFoundException(String.format("Cannot add reaction. Emote `%s` not defined in server %s. Define the emote via the setEmote command.", emoteKey, serverId)); } } else { - log.warn("Cannot add reaction, emote {} not defined for server {}.", emoteKey, serverId); + log.warn("Cannot add reaction, guild not found {}", serverId); + throw new NotFoundException(String.format("Cannot add reaction, guild %s not found.", serverId)); } } } diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/StartupManager.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/StartupManager.java index 020b9b00e..c3c555ff3 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/StartupManager.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/StartupManager.java @@ -23,6 +23,7 @@ import javax.security.auth.login.LoginException; import javax.transaction.Transactional; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; @Slf4j @Service @@ -66,7 +67,7 @@ public class StartupManager implements Startup { List onlineGuilds = instance.getGuilds(); Set availableServers = SnowflakeUtils.getSnowflakeIds(onlineGuilds); availableServers.forEach(aLong -> { - AServer newAServer = serverManagementService.createServer(aLong); + AServer newAServer = serverManagementService.loadOrCreate(aLong); Guild newGuild = instance.getGuildById(aLong); log.debug("Synchronizing server: {}", aLong); if(newGuild != null){ @@ -95,10 +96,10 @@ public class StartupManager implements Startup { private void synchronizeChannelsOf(Guild guild, AServer existingServer){ List available = guild.getChannels(); - List knownChannels = existingServer.getChannels(); + List knownChannels = existingServer.getChannels().stream().filter(aChannel -> !aChannel.getDeleted()).collect(Collectors.toList()); Set knownChannelsIds = SnowflakeUtils.getOwnItemsIds(knownChannels); Set existingChannelsIds = SnowflakeUtils.getSnowflakeIds(available); - Set newChannels = SetUtils.disjunction(existingChannelsIds, knownChannelsIds); + Set newChannels = SetUtils.difference(existingChannelsIds, knownChannelsIds); newChannels.forEach(aLong -> { GuildChannel channel1 = available.stream().filter(channel -> channel.getIdLong() == aLong).findFirst().get(); log.debug("Adding new channel: {}", aLong); @@ -106,5 +107,10 @@ public class StartupManager implements Startup { AChannel newChannel = channelManagementService.createChannel(channel1.getIdLong(), type); serverManagementService.addChannelToServer(existingServer, newChannel); }); + + Set noLongAvailable = SetUtils.difference(knownChannelsIds, existingChannelsIds); + noLongAvailable.forEach(aLong -> { + channelManagementService.markAsDeleted(aLong); + }); } } diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/ChannelManagementServiceBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/ChannelManagementServiceBean.java index dce61c799..c25215fd0 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/ChannelManagementServiceBean.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/ChannelManagementServiceBean.java @@ -4,10 +4,12 @@ import dev.sheldan.abstracto.core.models.database.AChannel; import dev.sheldan.abstracto.core.models.AChannelType; import dev.sheldan.abstracto.core.management.ChannelManagementService; import dev.sheldan.abstracto.repository.ChannelRepository; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service +@Slf4j public class ChannelManagementServiceBean implements ChannelManagementService { @Autowired @@ -20,6 +22,20 @@ public class ChannelManagementServiceBean implements ChannelManagementService { @Override public AChannel createChannel(Long id, AChannelType type) { - return repository.save(AChannel.builder().id(id).type(type).build()); + log.info("Creating channel {} with type {}", id, type); + return repository.save(AChannel.builder().id(id).type(type).deleted(false).build()); + } + + @Override + public void markAsDeleted(Long id) { + AChannel channel = loadChannel(id); + channel.setDeleted(true); + repository.save(channel); + } + + @Override + public void removeChannel(Long id) { + log.info("Deleting channel {}", id); + repository.deleteById(id); } } diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/ConfigManagementServiceBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/ConfigManagementServiceBean.java index c4e8519ea..8378b2b7b 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/ConfigManagementServiceBean.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/ConfigManagementServiceBean.java @@ -41,7 +41,7 @@ public class ConfigManagementServiceBean implements ConfigManagementService { @Override public AConfig createConfig(Long serverId, String name, String value) { - AServer server = serverManagementService.loadServer(serverId); + AServer server = serverManagementService.loadOrCreate(serverId); AConfig config = AConfig .builder() .stringValue(value) @@ -54,7 +54,7 @@ public class ConfigManagementServiceBean implements ConfigManagementService { @Override public AConfig createConfig(Long serverId, String name, Double value) { - AServer server = serverManagementService.loadServer(serverId); + AServer server = serverManagementService.loadOrCreate(serverId); AConfig config = AConfig .builder() .doubleValue(value) diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/EmoteManagementServiceBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/EmoteManagementServiceBean.java index 332ac5e2c..3b137904a 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/EmoteManagementServiceBean.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/EmoteManagementServiceBean.java @@ -33,7 +33,7 @@ public class EmoteManagementServiceBean implements EmoteManagementService { @Override public AEmote createCustomEmote(String name, String emoteKey, Long emoteId, Boolean animated, Long serverId) { - AServer server = serverManagementService.loadServer(serverId); + AServer server = serverManagementService.loadOrCreate(serverId); return this.createCustomEmote(name, emoteKey, emoteId, animated, server); } @@ -55,7 +55,7 @@ public class EmoteManagementServiceBean implements EmoteManagementService { @Override public AEmote createDefaultEmote(String name, String emoteKey, Long serverId) { - AServer server = serverManagementService.loadServer(serverId); + AServer server = serverManagementService.loadOrCreate(serverId); return createDefaultEmote(name, emoteKey, server); } @@ -75,7 +75,7 @@ public class EmoteManagementServiceBean implements EmoteManagementService { @Override public Optional loadEmoteByName(String name, Long serverId) { - AServer server = serverManagementService.loadServer(serverId); + AServer server = serverManagementService.loadOrCreate(serverId); return loadEmoteByName(name, server); } @@ -86,7 +86,7 @@ public class EmoteManagementServiceBean implements EmoteManagementService { @Override public AEmote setEmoteToCustomEmote(String name, String emoteKey, Long emoteId, Boolean animated, Long serverId) { - AServer server = serverManagementService.loadServer(serverId); + AServer server = serverManagementService.loadOrCreate(serverId); AEmote emote; Optional emoteOptional = loadEmoteByName(name, server); if(!emoteOptional.isPresent()) { @@ -104,7 +104,7 @@ public class EmoteManagementServiceBean implements EmoteManagementService { @Override public AEmote setEmoteToCustomEmote(String name, Emote emote, Long serverId) { - AServer server = serverManagementService.loadServer(serverId); + AServer server = serverManagementService.loadOrCreate(serverId); AEmote emoteBeingSet; Optional emoteOptional = loadEmoteByName(name, serverId); if(!emoteOptional.isPresent()) { @@ -122,7 +122,7 @@ public class EmoteManagementServiceBean implements EmoteManagementService { @Override public AEmote setEmoteToDefaultEmote(String name, String emoteKey, Long serverId) { - AServer server = serverManagementService.loadServer(serverId); + AServer server = serverManagementService.loadOrCreate(serverId); AEmote emoteBeingSet; Optional emoteOptional = loadEmoteByName(name, serverId); if(!emoteOptional.isPresent()) { @@ -138,7 +138,7 @@ public class EmoteManagementServiceBean implements EmoteManagementService { @Override public boolean emoteExists(String name, Long serverId) { - AServer server = serverManagementService.loadServer(serverId); + AServer server = serverManagementService.loadOrCreate(serverId); return emoteExists(name, server); } diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/PostTargetManagementBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/PostTargetManagementBean.java index a2a009df8..22664c311 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/PostTargetManagementBean.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/PostTargetManagementBean.java @@ -15,8 +15,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; -import java.util.List; - @Service @Slf4j public class PostTargetManagementBean implements PostTargetManagement { @@ -63,7 +61,7 @@ public class PostTargetManagementBean implements PostTargetManagement { @Override public void createOrUpdate(String name, Long serverId, Long channelId) { AChannel dbChannel = channelManagementService.loadChannel(channelId); - AServer dbServer = serverManagementService.loadServer(serverId); + AServer dbServer = serverManagementService.loadOrCreate(serverId); createOrUpdate(name, dbServer, dbChannel); } @@ -75,7 +73,7 @@ public class PostTargetManagementBean implements PostTargetManagement { @Override public PostTarget getPostTarget(String name, Long serverId) { - AServer server = serverManagementService.loadServer(serverId); + AServer server = serverManagementService.loadOrCreate(serverId); return getPostTarget(name, server); } diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/ServerManagementServiceBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/ServerManagementServiceBean.java index 874648c6b..c734f2d4d 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/ServerManagementServiceBean.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/ServerManagementServiceBean.java @@ -34,7 +34,7 @@ public class ServerManagementServiceBean implements ServerManagementService { } @Override - public AServer loadServer(Long id) { + public AServer loadOrCreate(Long id) { if(repository.existsById(id)) { return repository.getOne(id); } else { @@ -66,13 +66,13 @@ public class ServerManagementServiceBean implements ServerManagementService { @Override public AChannel getPostTarget(Long serverId, String name) { - AServer server = this.loadServer(serverId); + AServer server = this.loadOrCreate(serverId); return getPostTarget(server, name); } @Override public AChannel getPostTarget(Long serverId, PostTarget target) { - AServer server = this.loadServer(serverId); + AServer server = this.loadOrCreate(serverId); return getPostTarget(server, target); } diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/UserManagementServiceBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/UserManagementServiceBean.java index 33ac0fe1c..e260486e2 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/UserManagementServiceBean.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/management/UserManagementServiceBean.java @@ -29,7 +29,7 @@ public class UserManagementServiceBean implements UserManagementService { @Override public AUserInAServer loadUser(Long serverId, Long userId) { AUser user = this.loadUser(userId); - AServer server = serverManagementService.loadServer(serverId); + AServer server = serverManagementService.loadOrCreate(serverId); return loadUser(server, user); } diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/listener/ChannelListener.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/listener/ChannelListener.java index 14c327e71..ffea57bb7 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/listener/ChannelListener.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/listener/ChannelListener.java @@ -1,44 +1,50 @@ package dev.sheldan.abstracto.listener; +import dev.sheldan.abstracto.core.management.ChannelManagementService; +import dev.sheldan.abstracto.core.management.ServerManagementService; +import dev.sheldan.abstracto.core.models.AChannelType; import dev.sheldan.abstracto.core.models.database.AChannel; import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.repository.ServerRepository; +import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.entities.TextChannel; import net.dv8tion.jda.api.events.channel.text.TextChannelCreateEvent; import net.dv8tion.jda.api.events.channel.text.TextChannelDeleteEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import javax.annotation.Nonnull; -import java.util.Optional; @Service +@Slf4j public class ChannelListener extends ListenerAdapter { @Autowired private ServerRepository serverRepository; - private static Logger logger = LoggerFactory.getLogger(ChannelListener.class); + @Autowired + private ChannelManagementService channelManagementService; + + @Autowired + private ServerManagementService serverManagementService; @Override + @Transactional public void onTextChannelDelete(@Nonnull TextChannelDeleteEvent event) { - AServer serverObject = serverRepository.getOne(event.getGuild().getIdLong()); - serverObject.getChannels().add(AChannel.builder().id(event.getChannel().getIdLong()).build()); + log.info("Handling channel delete event. Channel {}, Server {}", event.getChannel().getIdLong(), event.getGuild().getIdLong()); + channelManagementService.markAsDeleted(event.getChannel().getIdLong()); } @Override + @Transactional public void onTextChannelCreate(@Nonnull TextChannelCreateEvent event) { + log.info("Handling channel created event. Channel {}, Server {}", event.getChannel().getIdLong(), event.getGuild().getIdLong()); AServer serverObject = serverRepository.getOne(event.getGuild().getIdLong()); TextChannel createdChannel = event.getChannel(); - Optional possibleChannel = serverObject.getChannels().stream().filter(aChannel -> aChannel.id == createdChannel.getIdLong()).findAny(); - if(possibleChannel.isPresent()){ - serverObject.getChannels().remove(possibleChannel.get()); - logger.info("Adding channel {} with id {}", createdChannel.getName(), createdChannel.getIdLong()); - } else { - logger.warn("Channel removed event for channel which was not in present"); - } + AChannelType type = AChannel.getAChannelType(createdChannel.getType()); + AChannel newChannel = channelManagementService.createChannel(createdChannel.getIdLong(), type); + serverManagementService.addChannelToServer(serverObject, newChannel); } } diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/listener/MessageDeletedListenerBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/listener/MessageDeletedListenerBean.java new file mode 100644 index 000000000..ce4231e01 --- /dev/null +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/listener/MessageDeletedListenerBean.java @@ -0,0 +1,46 @@ +package dev.sheldan.abstracto.listener; + +import dev.sheldan.abstracto.core.listener.MessageDeletedListener; +import dev.sheldan.abstracto.core.models.CachedMessage; +import dev.sheldan.abstracto.core.service.MessageCache; +import lombok.extern.slf4j.Slf4j; +import net.dv8tion.jda.api.events.message.guild.GuildMessageDeleteEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Nonnull; +import java.util.List; + +@Component +@Slf4j +public class MessageDeletedListenerBean extends ListenerAdapter { + @Autowired + private List listener; + + @Autowired + private MessageCache messageCache; + + @Autowired + private MessageDeletedListenerBean self; + + @Override + @Transactional + public void onGuildMessageDelete(@Nonnull GuildMessageDeleteEvent event) { + messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong()).thenAccept(cachedMessage -> { + self.executeListener(cachedMessage); + }); + } + + @Transactional + public void executeListener(CachedMessage cachedMessage) { + listener.forEach(messageDeletedListener -> { + try { + messageDeletedListener.execute(cachedMessage); + } catch (Exception e) { + log.warn("Listener {} failed with exception:", messageDeletedListener.getClass().getName(), e); + } + }); + } +} diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/listener/MessageEmbedListener.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/listener/MessageEmbedListener.java index abaa02e0b..cad812193 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/listener/MessageEmbedListener.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/listener/MessageEmbedListener.java @@ -24,7 +24,6 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Nonnull; -import java.util.concurrent.ExecutionException; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -99,7 +98,7 @@ public class MessageEmbedListener extends ListenerAdapter { private MessageEmbeddedModel buildTemplateParameter(GuildMessageReceivedEvent event, CachedMessage embeddedMessage) { AChannel channel = channelManagementService.loadChannel(event.getChannel().getIdLong()); - AServer server = serverManagementService.loadServer(event.getGuild().getIdLong()); + AServer server = serverManagementService.loadOrCreate(event.getGuild().getIdLong()); AUserInAServer user = userManagementService.loadUser(event.getMember()); Member author = bot.getMemberInServer(embeddedMessage.getServerId(), embeddedMessage.getAuthorId()); return MessageEmbeddedModel diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/exception/NotFoundException.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/exception/NotFoundException.java new file mode 100644 index 000000000..4d19546ea --- /dev/null +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/exception/NotFoundException.java @@ -0,0 +1,7 @@ +package dev.sheldan.abstracto.core.exception; + +public class NotFoundException extends RuntimeException { + public NotFoundException(String message) { + super(message); + } +} diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/listener/MessageDeletedListener.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/listener/MessageDeletedListener.java new file mode 100644 index 000000000..f401faa41 --- /dev/null +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/listener/MessageDeletedListener.java @@ -0,0 +1,7 @@ +package dev.sheldan.abstracto.core.listener; + +import dev.sheldan.abstracto.core.models.CachedMessage; + +public interface MessageDeletedListener { + void execute(CachedMessage messageBefore); +} diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/management/ChannelManagementService.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/management/ChannelManagementService.java index 2491a14ac..8a1a9e4ac 100644 --- a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/management/ChannelManagementService.java +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/management/ChannelManagementService.java @@ -6,4 +6,6 @@ import dev.sheldan.abstracto.core.models.AChannelType; public interface ChannelManagementService { AChannel loadChannel(Long id); AChannel createChannel(Long id, AChannelType type); + void markAsDeleted(Long id); + void removeChannel(Long id); } diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/management/ServerManagementService.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/management/ServerManagementService.java index d7616bbab..3630193be 100644 --- a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/management/ServerManagementService.java +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/management/ServerManagementService.java @@ -6,7 +6,7 @@ import java.util.List; public interface ServerManagementService { AServer createServer(Long id); - AServer loadServer(Long id); + AServer loadOrCreate(Long id); void addChannelToServer(AServer server, AChannel channel); AUserInAServer addUserToServer(AServer server, AUser user); AUserInAServer addUserToServer(Long serverId, Long userId); diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/models/database/AChannel.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/models/database/AChannel.java index b30042bf1..d22b8372e 100644 --- a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/models/database/AChannel.java +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/models/database/AChannel.java @@ -34,6 +34,11 @@ public class AChannel implements SnowFlake { @Enumerated(EnumType.STRING) private AChannelType type; + @Getter + @Setter + @Column + private Boolean deleted; + public static AChannelType getAChannelType(ChannelType type) { switch (type) { case TEXT: return AChannelType.TEXT; diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/service/Bot.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/service/Bot.java index bb1024a8c..af40f57bf 100644 --- a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/service/Bot.java +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/service/Bot.java @@ -10,6 +10,7 @@ import net.dv8tion.jda.api.entities.TextChannel; import org.springframework.stereotype.Service; import javax.security.auth.login.LoginException; +import java.util.Optional; @Service public interface Bot { @@ -18,8 +19,9 @@ public interface Bot { ServerChannelUser getServerChannelUser(Long serverId, Long channelId, Long userId); Member getMemberInServer(Long serverId, Long memberId); void deleteMessage(Long serverId, Long channelId, Long messageId); - Emote getEmote(Long serverId, AEmote emote); - TextChannel getTextChannelFromServer(Long serverId, Long textChannelId); - Guild getGuildById(Long serverId); + Optional getEmote(Long serverId, AEmote emote); + Optional getTextChannelFromServer(Guild serverId, Long textChannelId); + Optional getTextChannelFromServer(Long serverId, Long textChannelId); + Optional getGuildById(Long serverId); void shutdown(); } diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/utils/ContextUtils.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/utils/ContextUtils.java index db90551b4..f9f373e26 100644 --- a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/utils/ContextUtils.java +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/utils/ContextUtils.java @@ -43,7 +43,7 @@ public class ContextUtils { .guild(serverChannelUser.getGuild()) .textChannel(serverChannelUser.getTextChannel()) .channel(channelManagementService.loadChannel(message.getChannelId())) - .server(serverManagementService.loadServer(message.getServerId())) + .server(serverManagementService.loadOrCreate(message.getServerId())) .aUserInAServer(aUserInAServer) .user(aUserInAServer.getUserReference()) .build(); diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/utils/EmoteUtils.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/utils/EmoteUtils.java index e9dd34ecb..8917fb9e7 100644 --- a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/utils/EmoteUtils.java +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/utils/EmoteUtils.java @@ -10,10 +10,9 @@ import java.util.Optional; public class EmoteUtils { - public static boolean isReactionEmoteAEmote(MessageReaction.ReactionEmote reaction, AEmote emote, Optional emoteInGuildOptional) { + public static boolean isReactionEmoteAEmote(MessageReaction.ReactionEmote reaction, AEmote emote, Emote emoteInGuild) { if(reaction.isEmote() && emote.getCustom()) { - if(emoteInGuildOptional.isPresent()) { - Emote emoteInGuild = emoteInGuildOptional.get(); + if(emoteInGuild != null) { return emoteInGuild.equals(reaction.getEmote()); } else { return false; diff --git a/abstracto-application/executable/src/main/resources/application.properties b/abstracto-application/executable/src/main/resources/application.properties index 03a3a24c4..fb968dcb4 100644 --- a/abstracto-application/executable/src/main/resources/application.properties +++ b/abstracto-application/executable/src/main/resources/application.properties @@ -1,2 +1,16 @@ spring.quartz.job-store-type=jdbc spring.quartz.jdbc.initialize-schema=never + + +spring.quartz.properties.org.quartz.scheduler.instanceName=quartz-abstracto-app +spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO +spring.quartz.properties.org.quartz.scheduler.instanceIdGenerator.class=dev.sheldan.abstracto.scheduling.service.IdGenerationService +spring.quartz.properties.org.quartz.threadPool.threadCount=20 +spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX +spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate +spring.quartz.properties.org.quartz.jobStore.useProperties=true +spring.quartz.properties.org.quartz.jobStore.misfireThreshold=60000 +spring.quartz.properties.org.quartz.jobStore.tablePrefix=qrtz_ +spring.quartz.properties.org.quartz.jobStore.isClustered=false +spring.quartz.properties.org.quartz.plugin.shutdownHook.class=org.quartz.plugins.management.ShutdownHookPlugin +spring.quartz.properties.org.quartz.plugin.shutdownHook.cleanShutdown=TRUE \ No newline at end of file diff --git a/abstracto-application/scheduling/scheduling-impl/src/main/resources/config/application.properties b/abstracto-application/scheduling/scheduling-impl/src/main/resources/config/application.properties index 05af1e41a..e69de29bb 100644 --- a/abstracto-application/scheduling/scheduling-impl/src/main/resources/config/application.properties +++ b/abstracto-application/scheduling/scheduling-impl/src/main/resources/config/application.properties @@ -1,12 +0,0 @@ -spring.quartz.properties.org.quartz.scheduler.instanceName=quartz-abstracto-app -spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO -spring.quartz.properties.org.quartz.scheduler.instanceIdGenerator.class=dev.sheldan.abstracto.scheduling.service.IdGenerationService -spring.quartz.properties.org.quartz.threadPool.threadCount=20 -spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX -spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -spring.quartz.properties.org.quartz.jobStore.useProperties=true -spring.quartz.properties.org.quartz.jobStore.misfireThreshold=60000 -spring.quartz.properties.org.quartz.jobStore.tablePrefix=qrtz_ -spring.quartz.properties.org.quartz.jobStore.isClustered=false -spring.quartz.properties.org.quartz.plugin.shutdownHook.class=org.quartz.plugins.management.ShutdownHookPlugin -spring.quartz.properties.org.quartz.plugin.shutdownHook.cleanShutdown=TRUE \ No newline at end of file