mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-03-30 15:11:38 +00:00
added starboard functionality (starboard/starstats)
added module to store/retrieve configuration (double and string values) replaced a few null values with optionals (emote loading) fixed creating channels on startup added delete message/get emote utility to bot service extended emote service to have utility methods to use emotes added reactions to message cache added empty message handling to post target service, in case the template evaluates to empty added ability to edit a message in a post target (standard message and embed) added principle of config listeners, so default config can be created, for example starboard thresholds added abstract reaction listeners for adding/removing/clearing fixed foreign keys between channel and server added emote utils to handle AEmote and Emotes renamed emotes to be camelCase, so they are easier to type
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
package dev.sheldan.abstracto.utility.command;
|
||||
|
||||
import dev.sheldan.abstracto.command.Command;
|
||||
import dev.sheldan.abstracto.command.HelpInfo;
|
||||
import dev.sheldan.abstracto.command.execution.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.command.execution.Parameter;
|
||||
import dev.sheldan.abstracto.command.execution.Result;
|
||||
import dev.sheldan.abstracto.core.models.embed.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.TemplateService;
|
||||
import dev.sheldan.abstracto.utility.Utility;
|
||||
import dev.sheldan.abstracto.utility.models.template.starboard.StarStatsModel;
|
||||
import dev.sheldan.abstracto.utility.service.StarboardService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class StarStats implements Command {
|
||||
|
||||
public static final String STARSTATS_RESPONSE_TEMPLATE = "starStats_response";
|
||||
@Autowired
|
||||
private StarboardService starboardService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Override
|
||||
public Result execute(CommandContext commandContext) {
|
||||
StarStatsModel result = starboardService.retrieveStarStats(commandContext.getGuild().getIdLong());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(STARSTATS_RESPONSE_TEMPLATE, result);
|
||||
commandContext.getChannel().sendMessage(messageToSend.getEmbed()).queue();
|
||||
return Result.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("starStats")
|
||||
.module(Utility.UTILITY)
|
||||
.templated(true)
|
||||
.causesReaction(false)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.sheldan.abstracto.utility.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Getter
|
||||
@Setter
|
||||
@ConfigurationProperties(prefix = "abstracto.starboard")
|
||||
public class StarboardConfig {
|
||||
private List<Integer> lvl = new ArrayList<>();
|
||||
private List<String> badge = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package dev.sheldan.abstracto.utility.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.ServerConfigListener;
|
||||
import dev.sheldan.abstracto.core.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.management.ConfigManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class StarboardConfigListener implements ServerConfigListener {
|
||||
|
||||
@Autowired
|
||||
private StarboardConfig starboardConfig;
|
||||
|
||||
@Autowired
|
||||
private ConfigManagementService configManagementService;
|
||||
|
||||
@Override
|
||||
public void updateServerConfig(AServer server) {
|
||||
for (int i = 0; i < starboardConfig.getLvl().size(); i++) {
|
||||
Integer value = starboardConfig.getLvl().get(i);
|
||||
configManagementService.createIfNotExists(server.getId(), "starLvl" + ( i + 1 ), Double.valueOf(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package dev.sheldan.abstracto.utility.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.ReactedAddedListener;
|
||||
import dev.sheldan.abstracto.core.listener.ReactedRemovedListener;
|
||||
import dev.sheldan.abstracto.core.management.EmoteManagementService;
|
||||
import dev.sheldan.abstracto.core.management.UserManagementService;
|
||||
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.CachedReaction;
|
||||
import dev.sheldan.abstracto.core.models.database.AEmote;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.Bot;
|
||||
import dev.sheldan.abstracto.core.management.ConfigManagementService;
|
||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import dev.sheldan.abstracto.core.utils.EmoteUtils;
|
||||
import dev.sheldan.abstracto.utility.models.StarboardPost;
|
||||
import dev.sheldan.abstracto.utility.service.StarboardService;
|
||||
import dev.sheldan.abstracto.utility.service.management.StarboardPostManagementService;
|
||||
import dev.sheldan.abstracto.utility.service.management.StarboardPostReactorManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
import net.dv8tion.jda.api.entities.MessageReaction;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class StarboardListener implements ReactedAddedListener, ReactedRemovedListener {
|
||||
|
||||
public static final String STAR_EMOTE = "STAR";
|
||||
|
||||
@Autowired
|
||||
private EmoteManagementService emoteManagementService;
|
||||
|
||||
@Autowired
|
||||
private Bot bot;
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private ConfigManagementService configManagementService;
|
||||
|
||||
@Autowired
|
||||
private StarboardService starboardService;
|
||||
|
||||
@Autowired
|
||||
private StarboardPostManagementService starboardPostManagementService;
|
||||
|
||||
@Autowired
|
||||
private StarboardPostReactorManagementService starboardPostReactorManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserManagementService userManagementService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void executeReactionAdded(CachedMessage message, MessageReaction addedReaction, AUserInAServer userAdding) {
|
||||
if(userAdding.getUserReference().getId().equals(message.getAuthorId())) {
|
||||
return;
|
||||
}
|
||||
Long guildId = message.getServerId();
|
||||
Optional<AEmote> aEmote = emoteManagementService.loadEmoteByName(STAR_EMOTE, guildId);
|
||||
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<CachedReaction> reactionOptional = EmoteUtils.getReactionFromMessageByEmote(message, emote);
|
||||
updateStarboardPost(message, reactionOptional.orElse(null), userAdding, true);
|
||||
}
|
||||
} else {
|
||||
log.warn("Emote {} is not defined for guild {}. Starboard not functional.", STAR_EMOTE, guildId);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStarboardPost(CachedMessage message, CachedReaction reaction, AUserInAServer userReacting, boolean adding) {
|
||||
Optional<StarboardPost> starboardPostOptional = starboardPostManagementService.findByMessageId(message.getMessageId());
|
||||
if(reaction != null) {
|
||||
List<AUser> userExceptAuthor = getUsersExcept(reaction.getUsers(), message.getAuthorId());
|
||||
Double starMinimum = getFromConfig("starLvl1", message.getServerId());
|
||||
if (userExceptAuthor.size() >= starMinimum) {
|
||||
AUserInAServer author = userManagementService.loadUser(message.getServerId(), message.getAuthorId());
|
||||
if(starboardPostOptional.isPresent()) {
|
||||
StarboardPost starboardPost = starboardPostOptional.get();
|
||||
starboardService.updateStarboardPost(starboardPost, message, userExceptAuthor);
|
||||
if(adding) {
|
||||
starboardPostReactorManagementService.addReactor(starboardPost, userReacting.getUserReference());
|
||||
} else {
|
||||
starboardPostReactorManagementService.removeReactor(starboardPost, userReacting.getUserReference());
|
||||
}
|
||||
} else {
|
||||
starboardService.createStarboardPost(message, userExceptAuthor, userReacting, author);
|
||||
}
|
||||
} else {
|
||||
starboardPostOptional.ifPresent(starboardPost -> {
|
||||
starboardService.removeStarboardPost(starboardPost);
|
||||
starboardPostReactorManagementService.removeReactors(starboardPost);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
starboardPostOptional.ifPresent(starboardPost -> {
|
||||
starboardService.removeStarboardPost(starboardPost);
|
||||
starboardPostReactorManagementService.removeReactors(starboardPost);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void executeReactionRemoved(CachedMessage message, MessageReaction removedReaction, AUserInAServer userRemoving) {
|
||||
if(message.getAuthorId().equals(userRemoving.getUserReference().getId())) {
|
||||
return;
|
||||
}
|
||||
Long guildId = message.getServerId();
|
||||
Optional<AEmote> aEmote = emoteManagementService.loadEmoteByName(STAR_EMOTE, guildId);
|
||||
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<CachedReaction> reactionOptional = EmoteUtils.getReactionFromMessageByEmote(message, emote);
|
||||
updateStarboardPost(message, reactionOptional.orElse(null), userRemoving, false);
|
||||
}
|
||||
} else {
|
||||
log.warn("Emote {} is not defined for guild {}. Starboard not functional.", STAR_EMOTE, guildId);
|
||||
}
|
||||
}
|
||||
|
||||
private Double getFromConfig(String key, Long guildId) {
|
||||
return configManagementService.loadConfig(guildId, key).getDoubleValue();
|
||||
}
|
||||
|
||||
private List<AUser> getUsersExcept(List<AUser> users, Long userId) {
|
||||
return users.stream().filter(user -> !user.getId().equals(userId)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.abstracto.utility.repository;
|
||||
|
||||
public interface StarStatsUserResult {
|
||||
Long getUserId();
|
||||
Integer getStarCount();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package dev.sheldan.abstracto.utility.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.utility.models.StarboardPost;
|
||||
import dev.sheldan.abstracto.utility.models.StarboardPostReaction;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface StarboardPostReactionRepository extends JpaRepository<StarboardPostReaction, Long> {
|
||||
void deleteByReactorAndStarboardPost(AUser user, StarboardPost post);
|
||||
void deleteByStarboardPost(StarboardPost post);
|
||||
|
||||
@Query(value = "SELECT r.reactor_id as userId, COUNT(*) AS starCount \n" +
|
||||
"FROM starboard_post_reaction r \n" +
|
||||
"INNER JOIN starboard_post p ON p.id = r.post_id\n" +
|
||||
"INNER JOIN channel c ON c.id = p.channel_id\n" +
|
||||
"WHERE c.server_id = :serverId\n" +
|
||||
"GROUP BY r.reactor_id \n" +
|
||||
"ORDER BY starCount DESC \n" +
|
||||
"LIMIT :count", nativeQuery = true)
|
||||
List<StarStatsUserResult> findTopStarGiverInServer(Long serverId, Integer count);
|
||||
|
||||
@Query(value = "SELECT COUNT(*) \n" +
|
||||
"FROM starboard_post_reaction r \n" +
|
||||
"INNER JOIN starboard_post p ON p.id = r.post_id\n" +
|
||||
"INNER JOIN channel c ON c.id = p.channel_id\n" +
|
||||
"WHERE c.server_id = :serverId\n"
|
||||
, nativeQuery = true)
|
||||
Integer getReactionCountByServer(Long serverId);
|
||||
|
||||
@Query(value = "SELECT p.poster as userId, COUNT(*) AS starCount \n" +
|
||||
"FROM starboard_post_reaction r \n" +
|
||||
"INNER JOIN starboard_post p ON p.id = r.post_id\n" +
|
||||
"INNER JOIN channel c ON c.id = p.channel_id\n" +
|
||||
"WHERE c.server_id = :serverId\n" +
|
||||
"GROUP BY p.poster \n" +
|
||||
"ORDER BY starCount DESC \n" +
|
||||
"LIMIT :count", nativeQuery = true)
|
||||
List<StarStatsUserResult> retrieveTopStarReceiverInServer(Long serverId, Integer count);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.abstracto.utility.repository;
|
||||
|
||||
import dev.sheldan.abstracto.utility.models.StarboardPost;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface StarboardPostRepository extends JpaRepository<StarboardPost, Long> {
|
||||
StarboardPost findByPostMessageId(Long messageId);
|
||||
List<StarboardPost> findByStarboardChannelServerId(Long serverId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package dev.sheldan.abstracto.utility.repository.converter;
|
||||
|
||||
import dev.sheldan.abstracto.core.management.UserManagementService;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.service.Bot;
|
||||
import dev.sheldan.abstracto.utility.models.template.starboard.StarStatsUser;
|
||||
import dev.sheldan.abstracto.utility.repository.StarStatsUserResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class StarStatsUserConverter {
|
||||
|
||||
@Autowired
|
||||
private UserManagementService userManagementService;
|
||||
|
||||
@Autowired
|
||||
private Bot bot;
|
||||
|
||||
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(bot.getMemberInServer(serverId, starStatsUserResult.getUserId()))
|
||||
.user(AUser.builder().id(starStatsUserResult.getUserId()).build())
|
||||
.build();
|
||||
result.add(newUser);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import dev.sheldan.abstracto.utility.service.management.ReminderManagementServic
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -66,7 +67,12 @@ public class RemindServiceBean implements ReminderService {
|
||||
Reminder reminder = reminderManagementService.createReminder(aServerAChannelAUser, remindText, remindAt, reminderModel.getMessage().getIdLong());
|
||||
reminderModel.setReminder(reminder);
|
||||
MessageToSend message = templateService.renderEmbedTemplate(REMINDER_EMBED_KEY, reminderModel);
|
||||
reminderModel.getTextChannel().sendMessage(message.getMessage()).embed(message.getEmbed()).queue();
|
||||
String messageText = message.getMessage();
|
||||
if(StringUtils.isBlank(messageText)) {
|
||||
reminderModel.getTextChannel().sendMessage(message.getEmbed()).queue();
|
||||
} else {
|
||||
reminderModel.getTextChannel().sendMessage(messageText).embed(message.getEmbed()).queue();
|
||||
}
|
||||
|
||||
if(remindIn.getSeconds() < 60) {
|
||||
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
package dev.sheldan.abstracto.utility.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.management.EmoteManagementService;
|
||||
import dev.sheldan.abstracto.core.management.PostTargetManagement;
|
||||
import dev.sheldan.abstracto.core.management.UserManagementService;
|
||||
import dev.sheldan.abstracto.core.models.AServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.*;
|
||||
import dev.sheldan.abstracto.core.models.embed.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.service.Bot;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import dev.sheldan.abstracto.core.service.EmoteService;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.templating.TemplateService;
|
||||
import dev.sheldan.abstracto.utility.config.StarboardConfig;
|
||||
import dev.sheldan.abstracto.utility.models.StarboardPost;
|
||||
import dev.sheldan.abstracto.utility.models.template.starboard.StarStatsModel;
|
||||
import dev.sheldan.abstracto.utility.models.template.starboard.StarStatsPost;
|
||||
import dev.sheldan.abstracto.utility.models.template.starboard.StarStatsUser;
|
||||
import dev.sheldan.abstracto.utility.models.template.starboard.StarboardPostModel;
|
||||
import dev.sheldan.abstracto.utility.service.management.StarboardPostManagementService;
|
||||
import dev.sheldan.abstracto.utility.service.management.StarboardPostReactorManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class StarboardServiceBean implements StarboardService {
|
||||
|
||||
@Autowired
|
||||
private Bot bot;
|
||||
|
||||
@Autowired
|
||||
private PostTargetService postTargetService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private EmoteManagementService emoteManagementService;
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private StarboardPostManagementService starboardPostManagementService;
|
||||
|
||||
@Autowired
|
||||
private StarboardConfig starboardConfig;
|
||||
|
||||
@Autowired
|
||||
private UserManagementService userManagementService;
|
||||
|
||||
@Autowired
|
||||
private StarboardPostReactorManagementService starboardPostReactorManagementService;
|
||||
|
||||
@Autowired
|
||||
private PostTargetManagement postTargetManagement;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Override
|
||||
public void createStarboardPost(CachedMessage message, List<AUser> userExceptAuthor, AUserInAServer userReacting, AUserInAServer starredUser) {
|
||||
StarboardPostModel starboardPostModel = buildStarboardPostModel(message, userExceptAuthor.size());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("starboard_post", starboardPostModel);
|
||||
PostTarget starboard = postTargetManagement.getPostTarget("starboard", message.getServerId());
|
||||
postTargetService.sendEmbedInPostTarget(messageToSend, "starboard", message.getServerId()).thenAccept(message1 -> {
|
||||
AServerChannelMessage aServerChannelMessage = AServerChannelMessage
|
||||
.builder()
|
||||
.messageId(message1.getIdLong())
|
||||
.channel(starboard.getChannelReference())
|
||||
.server(userReacting.getServerReference())
|
||||
.build();
|
||||
StarboardPost starboardPost = starboardPostManagementService.createStarboardPost(message, starredUser, userReacting, aServerChannelMessage);
|
||||
// TODO maybe in bulk, but numbers should be small enough
|
||||
userExceptAuthor.forEach(user -> {
|
||||
starboardPostReactorManagementService.addReactor(starboardPost, user);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
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());
|
||||
AChannel aChannel = AChannel.builder().id(message.getChannelId()).build();
|
||||
AUser user = AUser.builder().id(message.getAuthorId()).build();
|
||||
AServer server = AServer.builder().id(message.getServerId()).build();
|
||||
Optional<AEmote> appropriateEmoteOptional = getAppropriateEmote(message.getServerId(), starCount);
|
||||
String emoteText;
|
||||
if(appropriateEmoteOptional.isPresent()) {
|
||||
AEmote emote = appropriateEmoteOptional.get();
|
||||
emoteText = emoteService.getEmoteAsMention(emote, message.getServerId(), "⭐");
|
||||
} else {
|
||||
log.warn("No emote defined to be used for starboard post. Falling back to default.");
|
||||
emoteText = "⭐";
|
||||
}
|
||||
return StarboardPostModel
|
||||
.builder()
|
||||
.message(message)
|
||||
.author(member)
|
||||
.channel(channel)
|
||||
.aChannel(aChannel)
|
||||
.starCount(starCount)
|
||||
.guild(guild)
|
||||
.user(user)
|
||||
.server(server)
|
||||
.starLevelEmote(emoteText)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStarboardPost(StarboardPost post, CachedMessage message, List<AUser> userExceptAuthor) {
|
||||
StarboardPostModel starboardPostModel = buildStarboardPostModel(message, userExceptAuthor.size());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("starboard_post", starboardPostModel);
|
||||
CompletableFuture<Message> future = new CompletableFuture<>();
|
||||
postTargetService.editOrCreatedInPostTarget(post.getStarboardMessageId(), messageToSend, "starboard", message.getServerId(), future);
|
||||
future.thenAccept(newOrOldMessage -> {
|
||||
starboardPostManagementService.setStarboardPostMessageId(post, newOrOldMessage.getIdLong());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeStarboardPost(StarboardPost message) {
|
||||
AChannel starboardChannel = message.getStarboardChannel();
|
||||
bot.deleteMessage(starboardChannel.getServer().getId(), starboardChannel.getId(), message.getStarboardMessageId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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(StarStatsPost::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++) {
|
||||
Optional<AEmote> starboardRankingEmote = getStarboardRankingEmote(serverId, i);
|
||||
AEmote emote = starboardRankingEmote.orElse(null);
|
||||
String defaultEmoji = starboardConfig.getBadge().get(i - 1);
|
||||
emotes.add(emoteService.getEmoteAsMention(emote, serverId, defaultEmoji));
|
||||
}
|
||||
|
||||
return StarStatsModel
|
||||
.builder()
|
||||
.badgeEmotes(emotes)
|
||||
.starGiver(topStarGivers)
|
||||
.starReceiver(topStarReceiver)
|
||||
.topPosts(starStatsPosts)
|
||||
.starredMessages(postCount)
|
||||
.totalStars(reactionCount)
|
||||
.build();
|
||||
}
|
||||
|
||||
private Optional<AEmote> getStarboardRankingEmote(Long serverId, Integer position) {
|
||||
return emoteManagementService.loadEmoteByName("starboardBadge" + position, serverId);
|
||||
}
|
||||
|
||||
private Optional<AEmote> getAppropriateEmote(Long serverId, Integer starCount) {
|
||||
for(int i = starboardConfig.getLvl().size(); i > 0; i--) {
|
||||
Double starMinimum = configService.getDoubleValue("starLvl" + i, serverId);
|
||||
if(starCount >= starMinimum) {
|
||||
return emoteManagementService.loadEmoteByName("star" + i, serverId);
|
||||
}
|
||||
}
|
||||
return emoteManagementService.loadEmoteByName("star0", serverId);
|
||||
}
|
||||
}
|
||||
@@ -27,8 +27,8 @@ import java.util.Optional;
|
||||
public class SuggestionServiceBean implements SuggestionService {
|
||||
|
||||
public static final String SUGGESTION_LOG_TEMPLATE = "suggest_log";
|
||||
private static final String SUGGESTION_YES_EMOTE = "SUGGESTION_YES";
|
||||
private static final String SUGGESTION_NO_EMOTE = "SUGGESTION_NO";
|
||||
private static final String SUGGESTION_YES_EMOTE = "suggestionYes";
|
||||
private static final String SUGGESTION_NO_EMOTE = "suggestionNo";
|
||||
public static final String SUGGESTIONS_TARGET = "suggestions";
|
||||
@Autowired
|
||||
private SuggestionManagementService suggestionManagementService;
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package dev.sheldan.abstracto.utility.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.AServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.utility.models.StarboardPost;
|
||||
import dev.sheldan.abstracto.utility.repository.StarboardPostRepository;
|
||||
import dev.sheldan.abstracto.utility.repository.converter.StarStatsUserConverter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class StarboardPostManagementServiceBean implements StarboardPostManagementService {
|
||||
|
||||
@Autowired
|
||||
private StarboardPostRepository repository;
|
||||
|
||||
@Autowired
|
||||
private StarStatsUserConverter converter;
|
||||
|
||||
@Override
|
||||
public StarboardPost createStarboardPost(CachedMessage starredMessage, AUserInAServer starredUser, AUserInAServer starringUser, AServerChannelMessage starboardPost) {
|
||||
StarboardPost post = StarboardPost
|
||||
.builder()
|
||||
.author(starredUser.getUserReference())
|
||||
.deleted(false)
|
||||
.postMessageId(starredMessage.getMessageId())
|
||||
.starboardMessageId(starboardPost.getMessageId())
|
||||
.starboardChannel(starboardPost.getChannel())
|
||||
.starredDate(Instant.now())
|
||||
.build();
|
||||
repository.save(post);
|
||||
return post;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStarboardPostMessageId(StarboardPost post, Long messageId) {
|
||||
post.setStarboardMessageId(messageId);
|
||||
repository.save(post);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StarboardPost> retrieveTopPosts(Long serverId, Integer count) {
|
||||
List<StarboardPost> posts = retrieveAllPosts(serverId);
|
||||
posts.sort(Comparator.comparingInt(o -> o.getReactions().size()));
|
||||
Collections.reverse(posts);
|
||||
return posts.subList(0, Math.min(count, posts.size()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StarboardPost> retrieveAllPosts(Long serverId) {
|
||||
return repository.findByStarboardChannelServerId(serverId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPostCount(Long serverId) {
|
||||
return retrieveAllPosts(serverId).size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<StarboardPost> findByMessageId(Long messageId) {
|
||||
return Optional.ofNullable(repository.findByPostMessageId(messageId));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package dev.sheldan.abstracto.utility.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.utility.models.StarboardPost;
|
||||
import dev.sheldan.abstracto.utility.models.StarboardPostReaction;
|
||||
import dev.sheldan.abstracto.utility.models.template.starboard.StarStatsUser;
|
||||
import dev.sheldan.abstracto.utility.repository.StarStatsUserResult;
|
||||
import dev.sheldan.abstracto.utility.repository.StarboardPostReactionRepository;
|
||||
import dev.sheldan.abstracto.utility.repository.converter.StarStatsUserConverter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class StarboardPostReactorManagementServiceBean implements StarboardPostReactorManagementService {
|
||||
|
||||
@Autowired
|
||||
private StarboardPostReactionRepository repository;
|
||||
|
||||
@Autowired
|
||||
private StarStatsUserConverter converter;
|
||||
|
||||
@Override
|
||||
public void addReactor(StarboardPost post, AUser user) {
|
||||
StarboardPostReaction reactor = StarboardPostReaction
|
||||
.builder()
|
||||
.starboardPost(post)
|
||||
.reactor(user)
|
||||
.build();
|
||||
repository.save(reactor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeReactor(StarboardPost post, AUser user) {
|
||||
repository.deleteByReactorAndStarboardPost(user, post);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeReactors(StarboardPost post) {
|
||||
repository.deleteByStarboardPost(post);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getStarCount(Long serverId) {
|
||||
return repository.getReactionCountByServer(serverId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<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) {
|
||||
List<StarStatsUserResult> starReceivers = repository.retrieveTopStarReceiverInServer(serverId, count);
|
||||
return converter.convertToStarStatsUser(starReceivers, serverId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Shows the current leaderboard of starboard posts.
|
||||
@@ -0,0 +1 @@
|
||||
Shows the current leaderboard of starboard posts.
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"title": {
|
||||
"title": "Server starboard stats"
|
||||
},
|
||||
"color" : {
|
||||
"r": 200,
|
||||
"g": 0,
|
||||
"b": 255
|
||||
},
|
||||
"description": "${starredMessages} starred messages with ${totalStars} stars in total",
|
||||
"fields": [
|
||||
{
|
||||
"name": "Top starred posts",
|
||||
"value": "
|
||||
<#list topPosts as post>
|
||||
${badgeEmotes[post?index]} - ${post.starCount} :star: [Jump!](${post.messageUrl})
|
||||
<#else>
|
||||
No starred messages.
|
||||
</#list>
|
||||
"
|
||||
},
|
||||
{
|
||||
"name": "Top starrer",
|
||||
"value": "
|
||||
<#list starGiver as starrer>
|
||||
<#if starrer.member?has_content>
|
||||
${badgeEmotes[starrer?index]} - ${starrer.starCount} :star: ${starrer.member.asMention}
|
||||
<#else>
|
||||
${badgeEmotes[starrer?index]} - ${starrer.starCount} :star: ${starrer.user.id?c} (Left the guild)
|
||||
</#if>
|
||||
<#else>
|
||||
No starred messages.
|
||||
</#list>
|
||||
"
|
||||
},
|
||||
{
|
||||
"name": "Top star receiver",
|
||||
"value": "
|
||||
<#list starReceiver as starred>
|
||||
<#if starred.member?has_content>
|
||||
${badgeEmotes[starred?index]} - ${starred.starCount} :star: ${starred.member.asMention}
|
||||
<#else>
|
||||
${badgeEmotes[starred?index]} - ${starred.starCount} :star: ${starred.user.id?c} (Left the guild)
|
||||
</#if>
|
||||
<#else>
|
||||
No starred messages.
|
||||
</#list>
|
||||
"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
starStats
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"author": {
|
||||
<#if author?has_content>
|
||||
"name": "${author.effectiveName}",
|
||||
"avatar": "${author.user.effectiveAvatarUrl}"
|
||||
<#else>
|
||||
"name": "${user.id?c} (Has left the server)"
|
||||
</#if>
|
||||
},
|
||||
"color" : {
|
||||
"r": 200,
|
||||
"g": 0,
|
||||
"b": 255
|
||||
},
|
||||
<#if message.content?has_content || message.embeds?size gt 0>
|
||||
"description": "${message.content}
|
||||
<#list message.embeds>
|
||||
Embeds:
|
||||
<#items as embed>
|
||||
Description: ${embed.description} <#if embed.imageUrl?has_content> ImageUrl: ${embed.imageUrl} </#if>
|
||||
</#items>
|
||||
</#list>
|
||||
",
|
||||
</#if>
|
||||
<#if channel?has_content>
|
||||
"additionalMessage": "${starLevelEmote} ${starCount} ${channel.asMention} ID: ${message.messageId?c}",
|
||||
<#else>
|
||||
"additionalMessage": "${starLevelEmote} ${starCount} ${aChannel.id?c} ID: ${message.messageId?c}",
|
||||
</#if>
|
||||
<#if message.attachmentUrls?size gt 0>
|
||||
"imageUrl": "${message.attachmentUrls[0]}",
|
||||
</#if>
|
||||
"fields": [
|
||||
{
|
||||
"name": "Original",
|
||||
<#if channel?has_content>
|
||||
"value": "[${channel.name}](${message.messageUrl})"
|
||||
<#else>
|
||||
"value": "[${aChannel.id?c}](${message.messageUrl})"
|
||||
</#if>
|
||||
}
|
||||
],
|
||||
"timeStamp": "${message.timeCreated}"
|
||||
}
|
||||
@@ -1,8 +1,16 @@
|
||||
abstracto.postTargets.utility=suggestions
|
||||
abstracto.emoteNames.suggestion=SUGGESTION_YES,SUGGESTION_NO
|
||||
abstracto.postTargets.utility=suggestions,starboard
|
||||
abstracto.emoteNames.suggestion=suggestionYes,suggestionNo
|
||||
abstracto.emoteNames.starboard=star,star1,star2,star3,star4,starboardBadge1,starboardBadge2,starboardBadge3
|
||||
abstracto.starboard.lvl[0]=5
|
||||
abstracto.starboard.lvl[1]=8
|
||||
abstracto.starboard.lvl[2]=13
|
||||
abstracto.starboard.lvl[3]=17
|
||||
abstracto.starboard.badge[0]=\ud83e\udd47
|
||||
abstracto.starboard.badge[1]=\ud83e\udd48
|
||||
abstracto.starboard.badge[2]=\ud83e\udd49
|
||||
|
||||
abstracto.scheduling.jobs.reminderJob.name=reminderJob
|
||||
abstracto.scheduling.jobs.reminderJob.group=utility
|
||||
abstracto.scheduling.jobs.reminderJob.clazz=dev.sheldan.abstracto.utility.jobs.ReminderJob
|
||||
abstracto.scheduling.jobs.reminderJob.standAlone=false
|
||||
abstracto.scheduling.jobs.reminderJob.active=true
|
||||
abstracto.scheduling.jobs.reminderJob.active=true
|
||||
|
||||
Reference in New Issue
Block a user