mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-04-13 19:41:38 +00:00
renamed feature display to feature config
added concept of feature dependencies, if one feature depends on another feature, and it gets enabled, the other feature is enabled as well changed some feature related apis added ability to automatically decay warnings (separate feature) added command to trigger the warn decay manually added command to decay all active warnings added method to scheduler service to directly start a cron job
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
package dev.sheldan.abstracto.experience.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ExperienceFeatureDisplay implements FeatureDisplay {
|
||||
public class ExperienceFeatureConfig implements FeatureConfig {
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
return ExperienceFeature.EXPERIENCE;
|
||||
@@ -0,0 +1,53 @@
|
||||
package dev.sheldan.abstracto.moderation.commands;
|
||||
|
||||
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.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationModule;
|
||||
import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
|
||||
import dev.sheldan.abstracto.moderation.service.WarnService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class DecayAllWarnings extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private WarnService warnService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
Boolean logWarnings = !parameters.isEmpty() ? (Boolean) parameters.get(0) : Boolean.FALSE;
|
||||
warnService.decayAllWarningsForServer(commandContext.getUserInitiatedContext().getServer(), logWarnings);
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
Parameter logWarnings = Parameter.builder().optional(true).type(Boolean.class).build();
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
parameters.add(logWarnings);
|
||||
return CommandConfiguration.builder()
|
||||
.name("decayAllWarnings")
|
||||
.module(ModerationModule.MODERATION)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
return ModerationFeatures.WARNING;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package dev.sheldan.abstracto.moderation.commands;
|
||||
|
||||
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.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationModule;
|
||||
import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
|
||||
import dev.sheldan.abstracto.moderation.service.WarnService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class DecayWarnings extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private WarnService warnService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
warnService.decayWarningsForServer(commandContext.getUserInitiatedContext().getServer());
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("decayWarnings")
|
||||
.module(ModerationModule.MODERATION)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
return ModerationFeatures.AUTOMATIC_WARN_DECAY;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package dev.sheldan.abstracto.moderation.job;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.management.FeatureFlagManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.moderation.config.features.WarningDecayFeature;
|
||||
import dev.sheldan.abstracto.moderation.service.WarnService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.quartz.PersistJobDataAfterExecution;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@DisallowConcurrentExecution
|
||||
@Component
|
||||
@PersistJobDataAfterExecution
|
||||
public class WarnDecayJob extends QuartzJobBean {
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagManagementService featureFlagManagementService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private WarningDecayFeature warningDecayFeature;
|
||||
|
||||
@Autowired
|
||||
private WarnService warnService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
|
||||
List<AServer> allServers = serverManagementService.getAllServers();
|
||||
allServers.forEach(server -> {
|
||||
boolean featureEnabled = featureFlagService.isFeatureEnabled(warningDecayFeature, server);
|
||||
if(featureEnabled) {
|
||||
warnService.decayWarningsForServer(server);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package dev.sheldan.abstracto.moderation.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.ServerConfigListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ConfigManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class WarnDecayConfigListener implements ServerConfigListener {
|
||||
|
||||
@Autowired
|
||||
private ConfigManagementService configManagementService;
|
||||
|
||||
@Value("${abstracto.warnings.warnDecay.days}")
|
||||
private Long decayDays;
|
||||
|
||||
@Override
|
||||
public void updateServerConfig(AServer server) {
|
||||
configManagementService.createIfNotExists(server.getId(), "decayDays", decayDays.doubleValue());
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,14 @@
|
||||
package dev.sheldan.abstracto.moderation.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.moderation.models.database.Warning;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface WarnRepository extends JpaRepository<Warning, Long> {
|
||||
List<Warning> findAllByWarnedUser_ServerReferenceAndDecayedFalseAndWarnDateLessThan(AServer server, Instant cutOffDate);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,11 @@ package dev.sheldan.abstracto.moderation.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.FullUser;
|
||||
import dev.sheldan.abstracto.core.models.context.ServerContext;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.moderation.models.template.job.WarnDecayLogModel;
|
||||
import dev.sheldan.abstracto.moderation.models.template.job.WarnDecayWarning;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.moderation.models.template.commands.WarnLog;
|
||||
import dev.sheldan.abstracto.moderation.models.template.commands.WarnNotification;
|
||||
@@ -17,6 +21,12 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@@ -42,6 +52,9 @@ public class WarnServiceBean implements WarnService {
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
private static final String WARN_LOG_TEMPLATE = "warn_log";
|
||||
private static final String WARN_NOTIFICATION_TEMPLATE = "warn_notification";
|
||||
|
||||
@@ -95,6 +108,54 @@ public class WarnServiceBean implements WarnService {
|
||||
this.sendWarnLog(warnLog);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void decayWarningsForServer(AServer server) {
|
||||
Double days = configService.getDoubleValue("decayDays", server.getId());
|
||||
Instant cutOffDay = Instant.now().minus(days.longValue(), ChronoUnit.DAYS);
|
||||
List<Warning> warningsToDecay = warnManagementService.getActiveWarningsInServerOlderThan(server, cutOffDay);
|
||||
decayWarnings(warningsToDecay);
|
||||
logDecayedWarnings(server, warningsToDecay);
|
||||
}
|
||||
|
||||
private void decayWarnings(List<Warning> warningsToDecay) {
|
||||
Instant now = Instant.now();
|
||||
warningsToDecay.forEach(warning -> {
|
||||
warning.setDecayDate(now);
|
||||
warning.setDecayed(true);
|
||||
});
|
||||
}
|
||||
|
||||
private void logDecayedWarnings(AServer server, List<Warning> warningsToDecay) {
|
||||
List<WarnDecayWarning> warnDecayWarnings = new ArrayList<>();
|
||||
warningsToDecay.forEach(warning -> {
|
||||
WarnDecayWarning warnDecayWarning = WarnDecayWarning
|
||||
.builder()
|
||||
.warnedMember(botService.getMemberInServer(warning.getWarnedUser()))
|
||||
.warningMember(botService.getMemberInServer(warning.getWarningUser()))
|
||||
.warning(warning)
|
||||
.build();
|
||||
warnDecayWarnings.add(warnDecayWarning);
|
||||
});
|
||||
WarnDecayLogModel warnDecayLogModel = WarnDecayLogModel
|
||||
.builder()
|
||||
.guild(botService.getGuildByIdNullable(server.getId()))
|
||||
.server(server)
|
||||
.warnings(warnDecayWarnings)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("warn_decay_log", warnDecayLogModel);
|
||||
postTargetService.sendEmbedInPostTarget(messageToSend, "decayLog", server.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decayAllWarningsForServer(AServer server, Boolean logWarnings) {
|
||||
List<Warning> warningsToDecay = warnManagementService.getActiveWarningsInServerOlderThan(server, Instant.now());
|
||||
decayWarnings(warningsToDecay);
|
||||
if(logWarnings) {
|
||||
logDecayedWarnings(server, warningsToDecay);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendWarnLog(ServerContext warnLogModel) {
|
||||
MessageToSend message = templateService.renderEmbedTemplate(WARN_LOG_TEMPLATE, warnLogModel);
|
||||
postTargetService.sendEmbedInPostTarget(message, WARN_LOG_TARGET, warnLogModel.getServer().getId());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.moderation.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.moderation.models.database.Warning;
|
||||
import dev.sheldan.abstracto.moderation.repository.WarnRepository;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
@@ -7,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class WarnManagementServiceBean implements WarnManagementService {
|
||||
@@ -21,8 +23,14 @@ public class WarnManagementServiceBean implements WarnManagementService {
|
||||
.warnedUser(warnedAUser)
|
||||
.warningUser(warningAUser)
|
||||
.warnDate(Instant.now())
|
||||
.decayed(false)
|
||||
.build();
|
||||
warnRepository.save(warning);
|
||||
return warning;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Warning> getActiveWarningsInServerOlderThan(AServer server, Instant date) {
|
||||
return warnRepository.findAllByWarnedUser_ServerReferenceAndDecayedFalseAndWarnDateLessThan(server, date);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
abstracto.postTargets.moderation=joinLog,leaveLog,warnLog,kickLog,banLog,editLog,deleteLog,muteLog
|
||||
abstracto.postTargets.moderation=joinLog,leaveLog,warnLog,kickLog,banLog,editLog,deleteLog,muteLog,decayLog
|
||||
abstracto.features.moderation=false
|
||||
abstracto.features.warning=false
|
||||
abstracto.features.logging=true
|
||||
abstracto.features.mutes=true
|
||||
abstracto.warnings.warnDecay.days=90
|
||||
|
||||
abstracto.scheduling.jobs.unMuteJob.name=unMuteJob
|
||||
abstracto.scheduling.jobs.unMuteJob.group=moderation
|
||||
abstracto.scheduling.jobs.unMuteJob.clazz=dev.sheldan.abstracto.moderation.job.UnMuteJob
|
||||
abstracto.scheduling.jobs.unMuteJob.standAlone=false
|
||||
abstracto.scheduling.jobs.unMuteJob.active=true
|
||||
abstracto.scheduling.jobs.unMuteJob.recovery=false
|
||||
abstracto.scheduling.jobs.unMuteJob.recovery=false
|
||||
|
||||
abstracto.scheduling.jobs.warnDecayJob.name=warnDecayJob
|
||||
abstracto.scheduling.jobs.warnDecayJob.group=moderation
|
||||
abstracto.scheduling.jobs.warnDecayJob.clazz=dev.sheldan.abstracto.moderation.job.WarnDecayJob
|
||||
abstracto.scheduling.jobs.warnDecayJob.standAlone=true
|
||||
abstracto.scheduling.jobs.warnDecayJob.active=true
|
||||
abstracto.scheduling.jobs.warnDecayJob.cronExpression=0 0 * * * ?
|
||||
abstracto.scheduling.jobs.warnDecayJob.recovery=false
|
||||
@@ -0,0 +1 @@
|
||||
Decays all currently active warnings
|
||||
@@ -0,0 +1 @@
|
||||
Decays all warnings which are currently active on this server, and logs them to the `decayLog` post target, if the parameter was true.
|
||||
@@ -0,0 +1 @@
|
||||
decayAllWarnings [true/false]
|
||||
@@ -0,0 +1 @@
|
||||
Decays the warnings in this server.
|
||||
@@ -0,0 +1 @@
|
||||
Causes the warnings older than the configured threshold in days to be decayed. They are still stored but there is an indication, that they are now longer active.
|
||||
@@ -0,0 +1 @@
|
||||
decayWarnings
|
||||
@@ -0,0 +1 @@
|
||||
Warn decaying
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"title": {
|
||||
"title": "Warnings have been decayed"
|
||||
},
|
||||
"color" : {
|
||||
"r": 200,
|
||||
"g": 0,
|
||||
"b": 255
|
||||
},
|
||||
"description": "<#list warnings as warning>
|
||||
<#if warning.warnedMember??>${warning.warnedMember.asMention} (${warning.warnedMember.id})<#else>${warning.warning.warnedUser.userReference.id?c}</#if> was warned on ${formatInstant(warning.warning.warnDate, "yyyy-MM-dd HH:mm:ss")}
|
||||
with reason `${warning.warning.reason}` by <#if warning.warningMember??>${warning.warningMember.asMention} (${warning.warningMember.id})<#else>${warning.warning.warningUser.userReference.id?c}</#if>
|
||||
|
||||
<#else>
|
||||
No warnings to decay.
|
||||
</#list>"
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package dev.sheldan.abstracto.moderation.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class LoggingFeature implements FeatureDisplay {
|
||||
public class LoggingFeature implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package dev.sheldan.abstracto.moderation.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ModerationFeature implements FeatureDisplay {
|
||||
public class ModerationFeature implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
|
||||
@@ -5,7 +5,7 @@ import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum ModerationFeatures implements FeatureEnum {
|
||||
MODERATION("moderation"), WARNING("warnings"), LOGGING("logging"), MUTING("muting");
|
||||
MODERATION("moderation"), WARNING("warnings"), LOGGING("logging"), MUTING("muting"), AUTOMATIC_WARN_DECAY("warnDecay");
|
||||
|
||||
private String key;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package dev.sheldan.abstracto.moderation.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class MutingFeature implements FeatureDisplay {
|
||||
public class MutingFeature implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package dev.sheldan.abstracto.moderation.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class WarningDecayFeature implements FeatureConfig {
|
||||
|
||||
@Autowired
|
||||
private WarningFeature warningFeature;
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
return ModerationFeatures.AUTOMATIC_WARN_DECAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FeatureConfig> getRequiredFeatures() {
|
||||
return Arrays.asList(warningFeature);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,26 @@
|
||||
package dev.sheldan.abstracto.moderation.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class WarningFeature implements FeatureDisplay {
|
||||
public class WarningFeature implements FeatureConfig {
|
||||
|
||||
@Autowired
|
||||
private WarningDecayFeature warningDecayFeature;
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
return ModerationFeatures.WARNING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FeatureConfig> getDependantFeatures() {
|
||||
return Arrays.asList(warningDecayFeature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package dev.sheldan.abstracto.moderation.models.database;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.Instant;
|
||||
@@ -38,9 +35,11 @@ public class Warning {
|
||||
private Instant warnDate;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Boolean decayed;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Instant decayDate;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.moderation.models.template.job;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.context.ServerContext;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@SuperBuilder
|
||||
public class WarnDecayLogModel extends ServerContext {
|
||||
private List<WarnDecayWarning> warnings;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package dev.sheldan.abstracto.moderation.models.template.job;
|
||||
|
||||
import dev.sheldan.abstracto.moderation.models.database.Warning;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class WarnDecayWarning {
|
||||
private Warning warning;
|
||||
private Member warnedMember;
|
||||
private Member warningMember;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.sheldan.abstracto.moderation.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.FullUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.moderation.models.database.Warning;
|
||||
import dev.sheldan.abstracto.moderation.models.template.commands.WarnLog;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
@@ -13,4 +14,6 @@ public interface WarnService {
|
||||
Warning warnUser(Member warnedMember, Member warningMember, String reason, TextChannel feedbackChannel);
|
||||
Warning warnUser(FullUser warnedUser, FullUser warningUser, String reason, TextChannel feedbackChannel);
|
||||
void warnUserWithLog(Member warnedMember, Member warningMember, String reason, WarnLog warnLog, TextChannel feedbackChannel);
|
||||
void decayWarningsForServer(AServer server);
|
||||
void decayAllWarningsForServer(AServer server, Boolean logWarnings);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package dev.sheldan.abstracto.moderation.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.moderation.models.database.Warning;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
public interface WarnManagementService {
|
||||
Warning createWarning(AUserInAServer warnedAUser, AUserInAServer warningAUser, String reason);
|
||||
List<Warning> getActiveWarningsInServerOlderThan(AServer server, Instant date);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package dev.sheldan.abstracto.utility.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class LinkEmbedFeature implements FeatureDisplay {
|
||||
public class LinkEmbedFeature implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package dev.sheldan.abstracto.utility.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class RemindFeature implements FeatureDisplay {
|
||||
public class RemindFeature implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package dev.sheldan.abstracto.utility.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class StarboardFeature implements FeatureDisplay {
|
||||
public class StarboardFeature implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package dev.sheldan.abstracto.utility.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SuggestionFeature implements FeatureDisplay {
|
||||
public class SuggestionFeature implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package dev.sheldan.abstracto.utility.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class UtilitiesFeature implements FeatureDisplay {
|
||||
public class UtilitiesFeature implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
|
||||
@@ -31,7 +31,7 @@ public class CommandCreationListener {
|
||||
@EventListener
|
||||
@Transactional
|
||||
public void handleContextRefreshEvent(ContextRefreshedEvent ctxStartEvt) {
|
||||
featureFlagService.getAllFeatureDisplays().forEach((featureFlagKey) -> {
|
||||
featureFlagService.getAllFeatureConfigs().forEach((featureFlagKey) -> {
|
||||
String featureKey = featureFlagKey.getFeature().getKey();
|
||||
if(!featureManagementService.featureExists(featureKey)) {
|
||||
featureManagementService.createFeature(featureKey);
|
||||
|
||||
@@ -9,6 +9,7 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleInterface;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.features.CoreFeatures;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.EnableModel;
|
||||
@@ -43,8 +44,13 @@ public class Disable extends AbstractConditionableCommand {
|
||||
channelService.sendTextInAChannel(response, commandContext.getChannel());
|
||||
} else {
|
||||
String flagKey = (String) commandContext.getParameters().getParameters().get(0);
|
||||
FeatureEnum feature = featureFlagService.getFeatureEnum(flagKey);
|
||||
FeatureConfig feature = featureFlagService.getFeatureDisplayForFeature(flagKey);
|
||||
featureFlagService.disableFeature(feature, commandContext.getGuild().getIdLong());
|
||||
if(feature.getDependantFeatures() != null) {
|
||||
feature.getDependantFeatures().forEach(featureDisplay -> {
|
||||
featureFlagService.disableFeature(featureDisplay, commandContext.getUserInitiatedContext().getServer());
|
||||
});
|
||||
}
|
||||
}
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleInterface;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.features.CoreFeatures;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.EnableModel;
|
||||
@@ -42,8 +43,13 @@ public class Enable extends AbstractConditionableCommand {
|
||||
channelService.sendTextInAChannel(response, commandContext.getChannel());
|
||||
} else {
|
||||
String flagKey = (String) commandContext.getParameters().getParameters().get(0);
|
||||
FeatureEnum feature = featureFlagService.getFeatureEnum(flagKey);
|
||||
featureFlagService.enableFeature(feature, commandContext.getGuild().getIdLong());
|
||||
FeatureConfig feature = featureFlagService.getFeatureDisplayForFeature(flagKey);
|
||||
featureFlagService.enableFeature(feature, commandContext.getUserInitiatedContext().getServer());
|
||||
if(feature.getRequiredFeatures() != null) {
|
||||
feature.getRequiredFeatures().forEach(featureDisplay -> {
|
||||
featureFlagService.enableFeature(featureDisplay, commandContext.getUserInitiatedContext().getServer());
|
||||
});
|
||||
}
|
||||
}
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class FeatureFlagListener implements ServerConfigListener {
|
||||
@Override
|
||||
public void updateServerConfig(AServer server) {
|
||||
log.info("Setting up feature flags if necessary.");
|
||||
featureFlagService.getAllFeatureDisplays().forEach((featureFlagKey) -> {
|
||||
featureFlagService.getAllFeatureConfigs().forEach((featureFlagKey) -> {
|
||||
String featureKey = featureFlagKey.getFeature().getKey();
|
||||
AFeature feature = featureManagementService.getFeature(featureKey);
|
||||
boolean featureFlagValue = BooleanUtils.toBoolean(environment.getProperty("abstracto.features." + featureKey, "false"));
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package dev.sheldan.abstracto.core.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class CoreFeature implements FeatureDisplay {
|
||||
public class CoreFeature implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.converter;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.models.database.AFeatureFlag;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.FeatureFlagDisplay;
|
||||
@@ -19,10 +19,10 @@ public class FeatureFlagConverter {
|
||||
|
||||
public FeatureFlagDisplay fromAFeatureFlag(AFeatureFlag featureFlag) {
|
||||
FeatureEnum featureEnum = featureFlagService.getFeatureEnum(featureFlag.getFeature().getKey());
|
||||
FeatureDisplay forFeature = featureFlagService.getFeatureDisplayforFeature(featureEnum);
|
||||
FeatureConfig forFeature = featureFlagService.getFeatureDisplayForFeature(featureEnum);
|
||||
return FeatureFlagDisplay
|
||||
.builder()
|
||||
.featureDisplay(forFeature)
|
||||
.featureConfig(forFeature)
|
||||
.featureFlag(featureFlag)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserManagementService;
|
||||
@@ -31,7 +32,8 @@ public class JoinListenerBean extends ListenerAdapter {
|
||||
@Transactional
|
||||
public void onGuildMemberJoin(@Nonnull GuildMemberJoinEvent event) {
|
||||
listenerList.forEach(joinListener -> {
|
||||
if (!featureFlagService.isFeatureEnabled(joinListener.getFeature(), event.getGuild().getIdLong())) {
|
||||
FeatureConfig feature = featureFlagService.getFeatureDisplayForFeature(joinListener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -26,7 +27,8 @@ public class LeaveListenerBean extends ListenerAdapter {
|
||||
@Transactional
|
||||
public void onGuildMemberLeave(@Nonnull GuildMemberLeaveEvent event) {
|
||||
listenerList.forEach(leaveListener -> {
|
||||
if(!featureFlagService.isFeatureEnabled(leaveListener.getFeature(), event.getGuild().getIdLong())) {
|
||||
FeatureConfig feature = featureFlagService.getFeatureDisplayForFeature(leaveListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
@@ -40,7 +41,8 @@ public class MessageDeletedListenerBean extends ListenerAdapter {
|
||||
@Transactional
|
||||
public void executeListener(CachedMessage cachedMessage) {
|
||||
listener.forEach(messageDeletedListener -> {
|
||||
if(!featureFlagService.isFeatureEnabled(messageDeletedListener.getFeature(), cachedMessage.getServerId())) {
|
||||
FeatureConfig feature = featureFlagService.getFeatureDisplayForFeature(messageDeletedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, cachedMessage.getServerId())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -30,7 +31,8 @@ public class MessageReceivedListenerBean extends ListenerAdapter {
|
||||
public void onGuildMessageReceived(@Nonnull GuildMessageReceivedEvent event) {
|
||||
messageCache.putMessageInCache(event.getMessage());
|
||||
listenerList.forEach(messageReceivedListener -> {
|
||||
if(!featureFlagService.isFeatureEnabled(messageReceivedListener.getFeature(), event.getGuild().getIdLong())) {
|
||||
FeatureConfig feature = featureFlagService.getFeatureDisplayForFeature(messageReceivedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
messageReceivedListener.execute(event.getMessage());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
@@ -44,7 +45,8 @@ public class MessageUpdatedListener extends ListenerAdapter {
|
||||
@Transactional
|
||||
public void executeListener(Message message, CachedMessage cachedMessage) {
|
||||
listener.forEach(messageTextUpdatedListener -> {
|
||||
if(!featureFlagService.isFeatureEnabled(messageTextUpdatedListener.getFeature(), message.getGuild().getIdLong())) {
|
||||
FeatureConfig feature = featureFlagService.getFeatureDisplayForFeature(messageTextUpdatedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, message.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
@@ -97,7 +98,8 @@ public class ReactionUpdatedListener extends ListenerAdapter {
|
||||
AUserInAServer userInAServer = userManagementService.loadUser(event.getGuild().getIdLong(), event.getUserIdLong());
|
||||
addReactionIfNotThere(cachedMessage, reaction, userInAServer.getUserReference());
|
||||
addedListenerList.forEach(reactedAddedListener -> {
|
||||
if(!featureFlagService.isFeatureEnabled(reactedAddedListener.getFeature(), event.getGuild().getIdLong())) {
|
||||
FeatureConfig feature = featureFlagService.getFeatureDisplayForFeature(reactedAddedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@@ -130,14 +132,15 @@ public class ReactionUpdatedListener extends ListenerAdapter {
|
||||
public void callRemoveListeners(@Nonnull GuildMessageReactionRemoveEvent event, CachedMessage cachedMessage, CachedReaction reaction) {
|
||||
AUserInAServer userInAServer = userManagementService.loadUser(event.getGuild().getIdLong(), event.getUserIdLong());
|
||||
removeReactionIfThere(cachedMessage, reaction, userInAServer.getUserReference());
|
||||
reactionRemovedListener.forEach(reactedAddedListener -> {
|
||||
if(!featureFlagService.isFeatureEnabled(reactedAddedListener.getFeature(), event.getGuild().getIdLong())) {
|
||||
reactionRemovedListener.forEach(reactionRemovedListener -> {
|
||||
FeatureConfig feature = featureFlagService.getFeatureDisplayForFeature(reactionRemovedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
reactedAddedListener.executeReactionRemoved(cachedMessage, event.getReaction(), userInAServer);
|
||||
reactionRemovedListener.executeReactionRemoved(cachedMessage, event.getReaction(), userInAServer);
|
||||
} catch (AbstractoRunTimeException e) {
|
||||
log.warn(String.format("Failed to execute reaction removed listener %s.", reactedAddedListener.getClass().getName()), e);
|
||||
log.warn(String.format("Failed to execute reaction removed listener %s.", reactionRemovedListener.getClass().getName()), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.abstracto.core.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AFeatureFlag;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface FeatureJobTriggerRepository extends JpaRepository<AFeatureJobTrigger, Long> {
|
||||
List<AFeatureJobTrigger> findByFeature(AFeatureFlag featureFlag);
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.exception.FeatureNotFoundException;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.management.FeatureFlagManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -19,28 +21,50 @@ public class FeatureFlagServiceBean implements FeatureFlagService {
|
||||
private FeatureFlagManagementService managementService;
|
||||
|
||||
@Autowired
|
||||
private List<FeatureDisplay> availableFeatures;
|
||||
private List<FeatureConfig> availableFeatures;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isFeatureEnabled(FeatureEnum name, Long serverId) {
|
||||
return managementService.getFeatureFlagValue(name, serverId);
|
||||
public boolean isFeatureEnabled(FeatureConfig name, Long serverId) {
|
||||
return managementService.getFeatureFlagValue(name.getFeature(), serverId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableFeature(FeatureEnum name, Long serverId) {
|
||||
if(!doesFeatureExist(name)) {
|
||||
throw new FeatureNotFoundException("Feature not found.", name.getKey(), getFeaturesAsList());
|
||||
}
|
||||
managementService.updateFeatureFlag(name, serverId, true);
|
||||
public boolean isFeatureEnabled(FeatureConfig name, AServer server) {
|
||||
return managementService.getFeatureFlagValue(name.getFeature(), server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableFeature(FeatureEnum name, Long serverId) {
|
||||
public void enableFeature(FeatureConfig name, Long serverId) {
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
enableFeature(name, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableFeature(FeatureConfig name, AServer server) {
|
||||
FeatureEnum feature = name.getFeature();
|
||||
if(!doesFeatureExist(name)) {
|
||||
throw new FeatureNotFoundException("Feature not found.", name.getKey(), getFeaturesAsList());
|
||||
throw new FeatureNotFoundException("Feature not found.", feature.getKey(), getFeaturesAsList());
|
||||
}
|
||||
managementService.updateFeatureFlag(name, serverId, false);
|
||||
managementService.updateFeatureFlag(feature, server, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableFeature(FeatureConfig name, Long serverId) {
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
disableFeature(name, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableFeature(FeatureConfig name, AServer server) {
|
||||
FeatureEnum feature = name.getFeature();
|
||||
if(!doesFeatureExist(name)) {
|
||||
throw new FeatureNotFoundException("Feature not found.", feature.getKey(), getFeaturesAsList());
|
||||
}
|
||||
managementService.updateFeatureFlag(feature, server, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,13 +76,13 @@ public class FeatureFlagServiceBean implements FeatureFlagService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FeatureDisplay> getAllFeatureDisplays() {
|
||||
public List<FeatureConfig> getAllFeatureConfigs() {
|
||||
return availableFeatures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDisplay getFeatureDisplayforFeature(FeatureEnum featureEnum) {
|
||||
Optional<FeatureDisplay> any = getAllFeatureDisplays().stream().filter(featureDisplay -> featureDisplay.getFeature().equals(featureEnum)).findAny();
|
||||
public FeatureConfig getFeatureDisplayForFeature(FeatureEnum featureEnum) {
|
||||
Optional<FeatureConfig> any = getAllFeatureConfigs().stream().filter(featureDisplay -> featureDisplay.getFeature().equals(featureEnum)).findAny();
|
||||
if(any.isPresent()) {
|
||||
return any.get();
|
||||
}
|
||||
@@ -66,8 +90,13 @@ public class FeatureFlagServiceBean implements FeatureFlagService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesFeatureExist(FeatureEnum name) {
|
||||
return availableFeatures.stream().anyMatch(featureDisplay -> featureDisplay.getFeature().equals(name));
|
||||
public FeatureConfig getFeatureDisplayForFeature(String key) {
|
||||
return getFeatureDisplayForFeature(getFeatureEnum(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesFeatureExist(FeatureConfig name) {
|
||||
return availableFeatures.stream().anyMatch(featureDisplay -> featureDisplay.getFeature().equals(name.getFeature()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -80,7 +109,7 @@ public class FeatureFlagServiceBean implements FeatureFlagService {
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeatureEnum(String key) {
|
||||
Optional<FeatureDisplay> foundFeature = availableFeatures.stream().filter(featureDisplay -> featureDisplay.getFeature().getKey().equals(key)).findAny();
|
||||
Optional<FeatureConfig> foundFeature = availableFeatures.stream().filter(featureDisplay -> featureDisplay.getFeature().getKey().equals(key)).findAny();
|
||||
if(foundFeature.isPresent()) {
|
||||
return foundFeature.get().getFeature();
|
||||
}
|
||||
|
||||
@@ -44,15 +44,27 @@ public class FeatureFlagManagementServiceBean implements FeatureFlagManagementSe
|
||||
|
||||
@Override
|
||||
public boolean getFeatureFlagValue(FeatureEnum key, Long serverId) {
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
return getFeatureFlagValue(key, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFeatureFlagValue(FeatureEnum key, AServer server) {
|
||||
AFeature feature = featureManagementService.getFeature(key.getKey());
|
||||
Optional<AFeatureFlag> featureFlag = getFeatureFlag(feature, serverId);
|
||||
Optional<AFeatureFlag> featureFlag = getFeatureFlag(feature, server);
|
||||
return featureFlag.isPresent() && featureFlag.get().isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFeatureFlag(FeatureEnum key, Long serverId, Boolean newValue) {
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
updateFeatureFlag(key, server, newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFeatureFlag(FeatureEnum key, AServer server, Boolean newValue) {
|
||||
AFeature feature = featureManagementService.getFeature(key.getKey());
|
||||
Optional<AFeatureFlag> existing = getFeatureFlag(feature, serverId);
|
||||
Optional<AFeatureFlag> existing = getFeatureFlag(feature, server);
|
||||
if(existing.isPresent()) {
|
||||
AFeatureFlag flag = existing.get();
|
||||
flag.setEnabled(newValue);
|
||||
@@ -63,7 +75,12 @@ public class FeatureFlagManagementServiceBean implements FeatureFlagManagementSe
|
||||
@Override
|
||||
public Optional<AFeatureFlag> getFeatureFlag(AFeature feature, Long serverId) {
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
return Optional.ofNullable(repository.findByServerAndFeature(server, feature));
|
||||
return getFeatureFlag(feature, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<AFeatureFlag> getFeatureFlag(AFeature key, AServer server) {
|
||||
return Optional.ofNullable(repository.findByServerAndFeature(server, key));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"description": "
|
||||
<#list features as feature>
|
||||
${feature.featureFlag.enabled?string('✅', '❌')} **<#include "${feature.featureDisplay.feature.key}_feature">** Key: `${feature.featureDisplay.feature.key}`
|
||||
${feature.featureFlag.enabled?string('✅', '❌')} **<#include "${feature.featureConfig.feature.key}_feature">** Key: `${feature.featureConfig.feature.key}`
|
||||
</#list>
|
||||
"
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
Feature has been disabled. Necessary feature is: <#include "${featureDisplay.feature.key}_feature">, you can enable it by executing `enable ${featureDisplay.feature.key}`.
|
||||
Feature has been disabled. Necessary feature is: <#include "${featureConfig.feature.key}_feature">, you can enable it by executing `enable ${featureConfig.feature.key}`.
|
||||
@@ -31,7 +31,7 @@ public class FeatureEnabledCondition implements CommandCondition {
|
||||
featureFlagValue = featureFlagManagementService.getFeatureFlagValue(feature, context.getGuild().getIdLong());
|
||||
FeatureDisabledMessage featureDisabledMessage = FeatureDisabledMessage
|
||||
.builder()
|
||||
.featureDisplay(featureFlagService.getFeatureDisplayforFeature(feature))
|
||||
.featureConfig(featureFlagService.getFeatureDisplayForFeature(feature))
|
||||
.build();
|
||||
reason = templateService.renderTemplate("feature_disabled_message", featureDisabledMessage);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.command.models;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -9,5 +9,5 @@ import lombok.Setter;
|
||||
@Getter
|
||||
@Builder
|
||||
public class FeatureDisabledMessage {
|
||||
private FeatureDisplay featureDisplay;
|
||||
private FeatureConfig featureConfig;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.abstracto.core.config;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public interface FeatureConfig {
|
||||
FeatureEnum getFeature();
|
||||
default List<FeatureConfig> getRequiredFeatures() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
default List<FeatureConfig> getDependantFeatures() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package dev.sheldan.abstracto.core.config;
|
||||
|
||||
public interface FeatureDisplay {
|
||||
FeatureEnum getFeature();
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.models.template.commands;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.models.database.AFeatureFlag;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
@@ -11,5 +11,5 @@ import lombok.Setter;
|
||||
@Builder
|
||||
public class FeatureFlagDisplay {
|
||||
private AFeatureFlag featureFlag;
|
||||
private FeatureDisplay featureDisplay;
|
||||
private FeatureConfig featureConfig;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDisplay;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface FeatureFlagService {
|
||||
boolean isFeatureEnabled(FeatureEnum name, Long serverId);
|
||||
void enableFeature(FeatureEnum name, Long serverId);
|
||||
void disableFeature(FeatureEnum name, Long serverId);
|
||||
boolean isFeatureEnabled(FeatureConfig name, Long serverId);
|
||||
boolean isFeatureEnabled(FeatureConfig name, AServer server);
|
||||
void enableFeature(FeatureConfig name, Long serverId);
|
||||
void enableFeature(FeatureConfig name, AServer server);
|
||||
void disableFeature(FeatureConfig name, Long serverId);
|
||||
void disableFeature(FeatureConfig name, AServer server);
|
||||
List<String> getAllFeatures();
|
||||
List<FeatureDisplay> getAllFeatureDisplays();
|
||||
FeatureDisplay getFeatureDisplayforFeature(FeatureEnum featureEnum);
|
||||
boolean doesFeatureExist(FeatureEnum name);
|
||||
List<FeatureConfig> getAllFeatureConfigs();
|
||||
FeatureConfig getFeatureDisplayForFeature(FeatureEnum featureEnum);
|
||||
FeatureConfig getFeatureDisplayForFeature(String key);
|
||||
boolean doesFeatureExist(FeatureConfig name);
|
||||
List<String> getFeaturesAsList();
|
||||
FeatureEnum getFeatureEnum(String key);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,10 @@ public interface FeatureFlagManagementService {
|
||||
void createFeatureFlag(AFeature feature, Long serverId, Boolean newValue);
|
||||
void createFeatureFlag(AFeature feature, AServer server, Boolean newValue);
|
||||
boolean getFeatureFlagValue(FeatureEnum key, Long serverId);
|
||||
boolean getFeatureFlagValue(FeatureEnum key, AServer server);
|
||||
void updateFeatureFlag(FeatureEnum key, Long serverId, Boolean newValue);
|
||||
void updateFeatureFlag(FeatureEnum key, AServer server, Boolean newValue);
|
||||
Optional<AFeatureFlag> getFeatureFlag(AFeature key, Long serverId);
|
||||
Optional<AFeatureFlag> getFeatureFlag(AFeature key, AServer server);
|
||||
List<AFeatureFlag> getFeatureFlagsOfServer(AServer server);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,15 @@ public class QuartzConfigFactory {
|
||||
.build();
|
||||
}
|
||||
|
||||
public CronTrigger createBasicCronTrigger(String jobName, String jobGroup, Date startTime, String cronExpression, JobDataMap jobDataMap) {
|
||||
return newTrigger()
|
||||
.withSchedule(cronSchedule(cronExpression).inTimeZone(TimeZone.getTimeZone("UTC")).withMisfireHandlingInstructionDoNothing())
|
||||
.startAt(startTime)
|
||||
.usingJobData(jobDataMap)
|
||||
.forJob(jobName, jobGroup)
|
||||
.build();
|
||||
}
|
||||
|
||||
public Trigger createSimpleOnceOnlyTrigger(Date startTime) {
|
||||
return newTrigger()
|
||||
.startAt(startTime)
|
||||
|
||||
@@ -159,6 +159,18 @@ public class SchedulerServiceBean implements SchedulerService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String startCronJobWithParameters(String name, String group, JobDataMap dataMap, String cronExpression) {
|
||||
Trigger cronTrigger = scheduleCreator.createBasicCronTrigger(name, group, new Date(), cronExpression, dataMap);
|
||||
try {
|
||||
schedulerFactoryBean.getScheduler().scheduleJob(cronTrigger);
|
||||
return cronTrigger.getKey().getName();
|
||||
} catch (SchedulerException e) {
|
||||
log.error("Failed to start new job - {}", name, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTrigger(String triggerKey) {
|
||||
try {
|
||||
|
||||
@@ -7,24 +7,15 @@ import java.util.Date;
|
||||
|
||||
public interface SchedulerService {
|
||||
void startScheduledJobs();
|
||||
|
||||
void scheduleJob(SchedulerJob job);
|
||||
|
||||
void updateJob(SchedulerJob job, Date startDate);
|
||||
|
||||
boolean unScheduleJob(String jobName);
|
||||
|
||||
boolean deleteJob(SchedulerJob job);
|
||||
|
||||
boolean pauseJob(SchedulerJob job);
|
||||
|
||||
boolean continueJob(SchedulerJob job);
|
||||
|
||||
boolean executeJob(SchedulerJob job);
|
||||
|
||||
String executeJobWithParametersOnce(String name, String group, JobDataMap dataMap, Date date);
|
||||
|
||||
String startCronJobWithParameters(String name, String group, JobDataMap dataMap, String cronExpression);
|
||||
void stopTrigger(String triggerKey);
|
||||
|
||||
void startScheduler();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user