[AB-182] added member parameter to starStats to show the starboard statistics for an individual member

This commit is contained in:
Sheldan
2021-02-14 23:43:44 +01:00
parent 876fbc01d9
commit 909dc87d94
24 changed files with 393 additions and 140 deletions

View File

@@ -11,11 +11,13 @@ import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.MemberStarStatsModel;
import dev.sheldan.abstracto.utility.service.StarboardService;
import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@@ -23,6 +25,7 @@ import java.util.concurrent.CompletableFuture;
public class StarStats extends AbstractConditionableCommand {
public static final String STARSTATS_RESPONSE_TEMPLATE = "starStats_response";
public static final String STARSTATS_SINGLE_MEMBER_RESPONSE_TEMPLATE = "starStats_single_member_response";
@Autowired
private StarboardService starboardService;
@@ -32,15 +35,24 @@ public class StarStats extends AbstractConditionableCommand {
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
return starboardService.retrieveStarStats(commandContext.getGuild().getIdLong())
.thenCompose(starStatsModel ->
FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInChannel(STARSTATS_RESPONSE_TEMPLATE, starStatsModel, commandContext.getChannel()))
).thenApply(o -> CommandResult.fromIgnored());
List<Object> parameters = commandContext.getParameters().getParameters();
if(parameters.isEmpty()) {
return starboardService.retrieveStarStats(commandContext.getGuild().getIdLong())
.thenCompose(starStatsModel ->
FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInChannel(STARSTATS_RESPONSE_TEMPLATE, starStatsModel, commandContext.getChannel()))
).thenApply(o -> CommandResult.fromIgnored());
} else {
Member targetMember = (Member) parameters.get(0);
MemberStarStatsModel memberStarStatsModel = starboardService.retrieveStarStatsForMember(targetMember);
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInChannel(STARSTATS_SINGLE_MEMBER_RESPONSE_TEMPLATE, memberStarStatsModel, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
Parameter memberParameter = Parameter.builder().templated(true).name("member").type(Member.class).optional(true).build();
List<Parameter> parameters = Collections.singletonList(memberParameter);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("starStats")

View File

@@ -25,7 +25,7 @@ public class StarboardPostDeletedListener implements AsyncMessageDeletedListener
if(byStarboardPostId.isPresent()) {
StarboardPost post = byStarboardPostId.get();
log.info("Removing starboard post: message {}, channel {}, server {}, because the message was deleted",
post.getPostMessageId(), post.getSourceChanel().getId(), messageBefore.getServerId());
post.getPostMessageId(), post.getSourceChannel().getId(), messageBefore.getServerId());
starboardPostManagementService.setStarboardPostIgnored(messageBefore.getMessageId(), true);
}
}

View File

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

View File

@@ -21,7 +21,7 @@ public interface StarboardPostReactionRepository extends JpaRepository<Starboard
"GROUP BY r.reactor_user_in_server_id \n" +
"ORDER BY starCount DESC \n" +
"LIMIT :count", nativeQuery = true)
List<StarStatsUserResult> findTopStarGiverInServer(Long serverId, Integer count);
List<StarStatsGuildUserResult> findTopStarGiverInServer(Long serverId, Integer count);
@Query(value = "SELECT COUNT(*) \n" +
"FROM starboard_post_reaction r \n" +
@@ -37,5 +37,5 @@ public interface StarboardPostReactionRepository extends JpaRepository<Starboard
"GROUP BY p.author_user_in_server_id \n" +
"ORDER BY starCount DESC \n" +
"LIMIT :count", nativeQuery = true)
List<StarStatsUserResult> retrieveTopStarReceiverInServer(Long serverId, Integer count);
List<StarStatsGuildUserResult> retrieveTopStarReceiverInServer(Long serverId, Integer count);
}

View File

@@ -2,6 +2,7 @@ package dev.sheldan.abstracto.utility.repository;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@@ -17,4 +18,31 @@ public interface StarboardPostRepository extends JpaRepository<StarboardPost, Lo
List<StarboardPost> findByServer_Id(Long serverId);
@Query(value = "SELECT p.id, COUNT(*) AS starCount \n" +
" FROM starboard_post p \n" +
" INNER JOIN starboard_post_reaction r ON p.id = r.post_id\n" +
" INNER JOIN user_in_server usi ON usi.user_in_server_id = p.author_user_in_server_id\n" +
" WHERE p.server_id = :serverId\n" +
" AND usi.user_id = :userId\n" +
" GROUP BY p.id \n" +
" ORDER BY starCount DESC \n" +
" LIMIT :count", nativeQuery = true)
List<Long> getTopStarboardPostsForUser(Long serverId, Long userId, Integer count);
@Query(value = "SELECT COUNT(*) AS starCount\n" +
"FROM starboard_post_reaction r \n" +
" INNER JOIN user_in_server usi ON usi.user_in_server_id = r.reactor_user_in_server_id \n" +
" WHERE usi.user_id = :userId \n" +
" AND r.server_id = :serverId", nativeQuery = true)
Long getGivenStarsOfUserInServer(Long serverId, Long userId);
@Query(value = "SELECT COUNT(*) AS starCount\n" +
" FROM starboard_post_reaction r \n" +
" INNER JOIN starboard_post p ON p.id = r.post_id \n" +
" INNER JOIN user_in_server usi ON usi.user_in_server_id = p.author_user_in_server_id \n" +
" WHERE p.author_user_in_server_id = usi.user_in_server_id \n" +
" AND usi.user_id = :userId \n" +
" AND r.server_id = :serverId", nativeQuery = true)
Long getReceivedStarsOfUserInServer(Long serverId, Long userId);
}

View File

@@ -5,7 +5,7 @@ import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsUser;
import dev.sheldan.abstracto.utility.repository.StarStatsUserResult;
import dev.sheldan.abstracto.utility.repository.StarStatsGuildUserResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -22,7 +22,7 @@ public class StarStatsUserConverter {
@Autowired
private UserInServerManagementService userInServerManagementService;
public List<CompletableFuture<StarStatsUser>> convertToStarStatsUser(List<StarStatsUserResult> users, Long serverId) {
public List<CompletableFuture<StarStatsUser>> convertToStarStatsUser(List<StarStatsGuildUserResult> users, Long serverId) {
List<CompletableFuture<StarStatsUser>> result = new ArrayList<>();
users.forEach(starStatsUserResult ->
result.add(createStarStatsUser(serverId, starStatsUserResult))
@@ -30,15 +30,15 @@ public class StarStatsUserConverter {
return result;
}
private CompletableFuture<StarStatsUser> createStarStatsUser(Long serverId, StarStatsUserResult starStatsUserResult) {
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(starStatsUserResult.getUserId());
private CompletableFuture<StarStatsUser> createStarStatsUser(Long serverId, StarStatsGuildUserResult starStatsGuildUserResult) {
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(starStatsGuildUserResult.getUserId());
return memberService.getMemberInServerAsync(serverId, aUserInAServer.getUserReference().getId()).thenApply(member ->
StarStatsUser
.builder()
.starCount(starStatsUserResult.getStarCount())
.starCount(starStatsGuildUserResult.getStarCount())
.member(member)
// TODO properly load this instance instead of just building one
.user(AUser.builder().id(starStatsUserResult.getUserId()).build())
.user(AUser.builder().id(starStatsGuildUserResult.getUserId()).build())
.build()
);
}

View File

@@ -23,7 +23,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -118,17 +117,16 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
}
@Transactional
public CompletionStage<Void> sendEmbeddingMessage(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, MessageEmbeddedModel messageEmbeddedModel) {
public CompletableFuture<Void> sendEmbeddingMessage(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, MessageEmbeddedModel messageEmbeddedModel) {
MessageToSend embed = templateService.renderEmbedTemplate(MESSAGE_EMBED_TEMPLATE, messageEmbeddedModel);
AUserInAServer cause = userInServerManagementService.loadOrCreateUser(userEmbeddingUserInServerId);
List<CompletableFuture<Message>> completableFutures = channelService.sendMessageToSendToChannel(embed, target);
log.trace("Embedding message {} from channel {} from server {}, because of user {}", cachedMessage.getMessageId(),
cachedMessage.getChannelId(), cachedMessage.getServerId(), cause.getUserReference().getId());
Long userInServerId = cause.getUserInServerId();
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenCompose(aVoid -> {
Message createdMessage = completableFutures.get(0).join();
return reactionService.addReactionToMessageAsync(REMOVAL_EMOTE, cachedMessage.getServerId(), createdMessage).thenAccept(aVoid1 ->
self.loadUserAndPersistMessage(cachedMessage, userInServerId, createdMessage)
self.loadUserAndPersistMessage(cachedMessage, userEmbeddingUserInServerId, createdMessage)
);
});
}

View File

@@ -19,14 +19,12 @@ import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.utility.config.features.StarboardFeature;
import dev.sheldan.abstracto.utility.config.posttargets.StarboardPostTarget;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsModel;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsPost;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsUser;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarboardPostModel;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.*;
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.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
@@ -160,7 +158,7 @@ public class StarboardServiceBean implements StarboardService {
@Override
public CompletableFuture<Void> updateStarboardPost(StarboardPost post, CachedMessage message, List<AUserInAServer> userExceptAuthor) {
int starCount = userExceptAuthor.size();
log.info("Updating starboard post {} in server {} with reactors {}.", post.getId(), post.getSourceChanel().getServer().getId(), starCount);
log.info("Updating starboard post {} in server {} with reactors {}.", post.getId(), post.getSourceChannel().getServer().getId(), starCount);
return buildStarboardPostModel(message, starCount).thenCompose(starboardPostModel -> {
MessageToSend messageToSend = templateService.renderEmbedTemplate(STARBOARD_POST_TEMPLATE, starboardPostModel);
List<CompletableFuture<Message>> futures = postTargetService.editOrCreatedInPostTarget(post.getStarboardMessageId(), messageToSend, StarboardPostTarget.STARBOARD, message.getServerId());
@@ -175,12 +173,12 @@ public class StarboardServiceBean implements StarboardService {
@Override
public void deleteStarboardMessagePost(StarboardPost message) {
AChannel starboardChannel = message.getStarboardChannel();
log.info("Deleting starboard post {} in server {}", message.getId(), message.getSourceChanel().getServer().getId());
log.info("Deleting starboard post {} in server {}", message.getId(), message.getSourceChannel().getServer().getId());
messageService.deleteMessageInChannelInServer(starboardChannel.getServer().getId(), starboardChannel.getId(), message.getStarboardMessageId());
}
@Override
public CompletableFuture<StarStatsModel> retrieveStarStats(Long serverId) {
public CompletableFuture<GuildStarStatsModel> retrieveStarStats(Long serverId) {
int count = 3;
List<CompletableFuture<StarStatsUser>> topStarGiverFutures = starboardPostReactorManagementService.retrieveTopStarGiver(serverId, count);
List<CompletableFuture<StarStatsUser>> topStarReceiverFutures = starboardPostReactorManagementService.retrieveTopStarReceiver(serverId, count);
@@ -198,7 +196,7 @@ public class StarboardServiceBean implements StarboardService {
}
List<StarStatsUser> topStarGivers = topStarGiverFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
List<StarStatsUser> topStarReceiver = topStarReceiverFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
return StarStatsModel
return GuildStarStatsModel
.builder()
.badgeEmotes(emotes)
.starGiver(topStarGivers)
@@ -211,11 +209,32 @@ public class StarboardServiceBean implements StarboardService {
}
@Override
public MemberStarStatsModel retrieveStarStatsForMember(Member member) {
int count = 3;
Long receivedStars = starboardPostManagementService.retrieveReceivedStarsOfUserInServer(member.getGuild().getIdLong(), member.getIdLong());
Long givenStars = starboardPostManagementService.retrieveGivenStarsOfUserInServer(member.getGuild().getIdLong(), member.getIdLong());
List<StarboardPost> topPosts = starboardPostManagementService.retrieveTopPostsForUserInServer(member.getGuild().getIdLong(), member.getIdLong(), count);
List<StarStatsPost> starStatsPosts = topPosts.stream().map(this::fromStarboardPost).collect(Collectors.toList());
List<String> emotes = new ArrayList<>();
for (int i = 1; i < count + 1; i++) {
emotes.add(getStarboardRankingEmote(member.getGuild().getIdLong(), i));
}
return MemberStarStatsModel
.builder()
.member(member)
.topPosts(starStatsPosts)
.badgeEmotes(emotes)
.receivedStars(receivedStars)
.givenStars(givenStars)
.build();
}
public StarStatsPost fromStarboardPost(StarboardPost starboardPost) {
AChannel channel = starboardPost.getStarboardChannel();
return StarStatsPost
.builder()
.serverId(channel.getServer().getId())
.serverId(starboardPost.getServer().getId())
.channelId(channel.getId())
.messageId(starboardPost.getPostMessageId())
.starCount(starboardPost.getReactions().size())

View File

@@ -34,7 +34,7 @@ public class StarboardPostManagementServiceBean implements StarboardPostManageme
.builder()
.author(starredUser)
.postMessageId(starredMessage.getMessageId())
.sourceChanel(build)
.sourceChannel(build)
.ignored(false)
.server(starboardPost.getServer())
.starboardMessageId(starboardPost.getMessageId())
@@ -63,6 +63,22 @@ public class StarboardPostManagementServiceBean implements StarboardPostManageme
return posts.subList(0, Math.min(count, posts.size()));
}
@Override
public List<StarboardPost> retrieveTopPostsForUserInServer(Long serverId, Long userId, Integer count) {
List<Long> topPostIds = repository.getTopStarboardPostsForUser(serverId, userId, count);
return repository.findAllById(topPostIds);
}
@Override
public Long retrieveGivenStarsOfUserInServer(Long serverId, Long userId) {
return repository.getGivenStarsOfUserInServer(serverId, userId);
}
@Override
public Long retrieveReceivedStarsOfUserInServer(Long serverId, Long userId) {
return repository.getReceivedStarsOfUserInServer(serverId, userId);
}
@Override
public List<StarboardPost> retrieveAllPosts(Long serverId) {
return repository.findByServer_Id(serverId);

View File

@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
import dev.sheldan.abstracto.utility.models.database.StarboardPostReaction;
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsUser;
import dev.sheldan.abstracto.utility.repository.StarStatsUserResult;
import dev.sheldan.abstracto.utility.repository.StarStatsGuildUserResult;
import dev.sheldan.abstracto.utility.repository.StarboardPostReactionRepository;
import dev.sheldan.abstracto.utility.repository.converter.StarStatsUserConverter;
import lombok.extern.slf4j.Slf4j;
@@ -55,13 +55,13 @@ public class StarboardPostReactorManagementServiceBean implements StarboardPostR
@Override
public List<CompletableFuture<StarStatsUser>> retrieveTopStarGiver(Long serverId, Integer count) {
List<StarStatsUserResult> starGivers = repository.findTopStarGiverInServer(serverId, count);
List<StarStatsGuildUserResult> starGivers = repository.findTopStarGiverInServer(serverId, count);
return converter.convertToStarStatsUser(starGivers, serverId);
}
@Override
public List<CompletableFuture<StarStatsUser>> retrieveTopStarReceiver(Long serverId, Integer count) {
List<StarStatsUserResult> starReceivers = repository.retrieveTopStarReceiverInServer(serverId, count);
List<StarStatsGuildUserResult> starReceivers = repository.retrieveTopStarReceiverInServer(serverId, count);
return converter.convertToStarStatsUser(starReceivers, serverId);
}