mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-01-01 15:28:35 +00:00
[AB-94] adding command to show the state of a server poll
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
package dev.sheldan.abstracto.suggestion.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
|
||||
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.suggestion.config.SuggestionFeatureDefinition;
|
||||
import dev.sheldan.abstracto.suggestion.config.SuggestionSlashCommandNames;
|
||||
import dev.sheldan.abstracto.suggestion.model.template.PollInfoModel;
|
||||
import dev.sheldan.abstracto.suggestion.service.PollService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class ShowPoll extends AbstractConditionableCommand {
|
||||
|
||||
private static final String COMMAND_NAME = "show";
|
||||
private static final String SHOW_POLL_COMMAND_NAME = "showPoll";
|
||||
private static final String POLL_ID_PARAMETER = "pollId";
|
||||
private static final String SHOW_POLL_TEMPLATE_KEY = "showPoll_response";
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private PollService pollService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
Long suggestionId = slashCommandParameterService.getCommandOption(POLL_ID_PARAMETER, event, Long.class, Integer.class).longValue();
|
||||
PollInfoModel pollInfoModel = pollService.getPollInfoModel(suggestionId, event.getGuild().getIdLong());
|
||||
return interactionService.replyEmbed(SHOW_POLL_TEMPLATE_KEY, pollInfoModel, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<ParameterValidator> polldIdValidator = Arrays.asList(MinIntegerValueValidator.min(1L));
|
||||
Parameter pollIdParameter = Parameter
|
||||
.builder()
|
||||
.name(POLL_ID_PARAMETER)
|
||||
.validators(polldIdValidator)
|
||||
.type(Long.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.hasExample(false)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(pollIdParameter);
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(SuggestionSlashCommandNames.POLL)
|
||||
.commandName(COMMAND_NAME)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(SHOW_POLL_COMMAND_NAME)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(false)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return SuggestionFeatureDefinition.POLL;
|
||||
}
|
||||
}
|
||||
@@ -335,7 +335,8 @@ public class PollServiceBean implements PollService {
|
||||
public CompletableFuture<Void> addOptionToServerPoll(Long pollId, Long serverId, Member adder, String label, String description) {
|
||||
Poll poll = pollManagementService.getPollByPollId(pollId, serverId, PollType.STANDARD);
|
||||
log.info("Adding option to server poll {} in server {}.", pollId, serverId);
|
||||
pollOptionManagementService.addOptionToPoll(poll, label, description);
|
||||
AUserInAServer adderUser = userInServerManagementService.loadOrCreateUser(adder);
|
||||
pollOptionManagementService.addOptionToPoll(poll, label, description, adderUser);
|
||||
List<PollMessageOption> options = getOptionsOfPoll(poll);
|
||||
ServerPollMessageModel model = ServerPollMessageModel.fromPoll(poll, options);
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(SERVER_POLL_TEMPLATE_KEY, model);
|
||||
@@ -487,6 +488,37 @@ public class PollServiceBean implements PollService {
|
||||
return messageService.deleteMessageInChannelInServer(serverId, poll.getChannel().getId(), poll.getMessageId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PollInfoModel getPollInfoModel(Long pollId, Long serverId) {
|
||||
Poll poll = pollManagementService.getPollByPollId(pollId, serverId, PollType.STANDARD);
|
||||
Integer totalVotes = getTotalVotesOfPoll(poll);
|
||||
List<PollOptionInfoModel> optionInfoModels = poll.getOptions().stream().map(pollOption -> {
|
||||
Long voteCount = getVotesOfOption(poll, pollOption);
|
||||
return PollOptionInfoModel
|
||||
.builder()
|
||||
.value(pollOption.getValue())
|
||||
.description(pollOption.getDescription())
|
||||
.label(pollOption.getLabel())
|
||||
.votes(voteCount)
|
||||
.percentage(totalVotes > 0 ? (voteCount / (float) totalVotes) * 100 : 0)
|
||||
.adder(pollOption.getAdder() != null ? MemberDisplay.fromAUserInAServer(pollOption.getAdder()) : null)
|
||||
.build();
|
||||
}).toList();
|
||||
return PollInfoModel
|
||||
.builder()
|
||||
.id(poll.getPollId())
|
||||
.description(poll.getDescription())
|
||||
.creationDate(poll.getCreated())
|
||||
.targetDate(poll.getTargetDate())
|
||||
.totalVotes(totalVotes)
|
||||
.allowAdditions(poll.getAllowAddition())
|
||||
.allowMultiple(poll.getAllowMultiple())
|
||||
.options(optionInfoModels)
|
||||
.showDecisions(poll.getShowDecisions())
|
||||
.pollDuration(Duration.between(poll.getCreated(), poll.getTargetDate()))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> updateFinalPollMessage(Long pollId, Guild guild) {
|
||||
Poll poll = pollManagementService.getPollByPollId(pollId, guild.getIdLong(), PollType.STANDARD);
|
||||
@@ -543,22 +575,13 @@ public class PollServiceBean implements PollService {
|
||||
.percentage(0f)
|
||||
.description(description)
|
||||
.build();
|
||||
}).collect(Collectors.toList());
|
||||
}).toList();
|
||||
}
|
||||
|
||||
private List<PollMessageOption> getOptionsOfPoll(Poll poll) {
|
||||
Integer totalVotes = poll
|
||||
.getDecisions()
|
||||
.stream()
|
||||
.map(userDecision -> userDecision.getOptions().size())
|
||||
.mapToInt(Integer::intValue)
|
||||
.sum();
|
||||
Integer totalVotes = getTotalVotesOfPoll(poll);
|
||||
return poll.getOptions().stream().map(option -> {
|
||||
Long voteCount = poll
|
||||
.getDecisions()
|
||||
.stream()
|
||||
.filter(decision -> decision.getOptions().stream().anyMatch(pollUserDecisionOption -> pollUserDecisionOption.getPollOption().equals(option)))
|
||||
.count();
|
||||
Long voteCount = getVotesOfOption(poll, option);
|
||||
return PollMessageOption
|
||||
.builder()
|
||||
.value(option.getValue())
|
||||
@@ -567,7 +590,24 @@ public class PollServiceBean implements PollService {
|
||||
.percentage(totalVotes > 0 ? (voteCount / (float) totalVotes) * 100 : 0)
|
||||
.description(option.getDescription())
|
||||
.build();
|
||||
}).collect(Collectors.toList());
|
||||
}).toList();
|
||||
}
|
||||
|
||||
private Long getVotesOfOption(Poll poll, PollOption option) {
|
||||
return poll
|
||||
.getDecisions()
|
||||
.stream()
|
||||
.filter(decision -> decision.getOptions().stream().anyMatch(pollUserDecisionOption -> pollUserDecisionOption.getPollOption().equals(option)))
|
||||
.count();
|
||||
}
|
||||
|
||||
private Integer getTotalVotesOfPoll(Poll poll) {
|
||||
return poll
|
||||
.getDecisions()
|
||||
.stream()
|
||||
.map(userDecision -> userDecision.getOptions().size())
|
||||
.mapToInt(Integer::intValue)
|
||||
.sum();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.suggestion.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.suggestion.model.PollCreationRequest;
|
||||
import dev.sheldan.abstracto.suggestion.model.database.Poll;
|
||||
import dev.sheldan.abstracto.suggestion.model.database.PollOption;
|
||||
@@ -32,12 +33,18 @@ public class PollOptionManagementServiceBean implements PollOptionManagementServ
|
||||
|
||||
@Override
|
||||
public void addOptionToPoll(Poll poll, String label, String description) {
|
||||
addOptionToPoll(poll, label, description, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOptionToPoll(Poll poll, String label, String description, AUserInAServer adder) {
|
||||
PollOption option = PollOption
|
||||
.builder()
|
||||
.poll(poll)
|
||||
.label(label)
|
||||
.value(label)
|
||||
.server(poll.getServer())
|
||||
.adder(adder)
|
||||
.description(description)
|
||||
.build();
|
||||
pollOptionRepository.save(option);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<property name="utilityModule" value="(SELECT id FROM module WHERE name = 'utility')"/>
|
||||
<property name="pollFeature" value="(SELECT id FROM feature WHERE key = 'poll')"/>
|
||||
|
||||
<changeSet author="Sheldan" id="showPoll-command">
|
||||
<insert tableName="command">
|
||||
<column name="name" value="showPoll"/>
|
||||
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||
<column name="feature_id" valueComputed="${pollFeature}"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="command.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -13,4 +13,5 @@
|
||||
<include file="1.4.0/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.4.8/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.4.26/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.5.6/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,25 @@
|
||||
package dev.sheldan.abstracto.suggestion.model.template;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class PollInfoModel {
|
||||
private Long id;
|
||||
private String description;
|
||||
private Boolean allowMultiple;
|
||||
private Boolean showDecisions;
|
||||
private Boolean allowAdditions;
|
||||
private Instant creationDate;
|
||||
private Integer totalVotes;
|
||||
private Instant targetDate;
|
||||
private Duration pollDuration;
|
||||
private List<PollOptionInfoModel> options;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.sheldan.abstracto.suggestion.model.template;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class PollOptionInfoModel {
|
||||
private String value;
|
||||
private String label;
|
||||
private String description;
|
||||
private Long votes;
|
||||
private Float percentage;
|
||||
private MemberDisplay adder;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.sheldan.abstracto.suggestion.service;
|
||||
|
||||
import dev.sheldan.abstracto.suggestion.model.database.PollType;
|
||||
import dev.sheldan.abstracto.suggestion.model.template.PollInfoModel;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.interactions.InteractionHook;
|
||||
|
||||
@@ -26,4 +27,5 @@ public interface PollService {
|
||||
CompletableFuture<Void> evaluateQuickPoll(Long pollId, Long serverId);
|
||||
CompletableFuture<Void> closePoll(Long pollId, Long serverId, String text, Member cause);
|
||||
CompletableFuture<Void> cancelPoll(Long pollId, Long serverId, Member cause);
|
||||
PollInfoModel getPollInfoModel(Long pollId, Long serverId);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.suggestion.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.suggestion.model.PollCreationRequest;
|
||||
import dev.sheldan.abstracto.suggestion.model.database.Poll;
|
||||
import dev.sheldan.abstracto.suggestion.model.database.PollOption;
|
||||
@@ -9,5 +10,6 @@ import java.util.Optional;
|
||||
public interface PollOptionManagementService {
|
||||
void addOptionsToPoll(Poll poll, PollCreationRequest pollCreationRequest);
|
||||
void addOptionToPoll(Poll poll, String label, String description);
|
||||
void addOptionToPoll(Poll poll, String label, String description, AUserInAServer adder);
|
||||
Optional<PollOption> getPollOptionByName(Poll poll, String key);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user