Compare commits

...

10 Commits

108 changed files with 612 additions and 90 deletions

2
.env
View File

@@ -1,2 +1,2 @@
REGISTRY_PREFIX=harbor.sheldan.dev/abstracto/
VERSION=1.5.54
VERSION=1.5.56

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>anti-raid</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>anti-raid</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>assignable-roles</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>assignable-roles</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>assignable-roles-int</artifactId>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>abstracto-modules</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>custom-command</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>custom-command</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>dynamic-activity</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>dynamic-activity</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>entertainment</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>entertainment</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>experience-tracking</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>experience-tracking</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>abstracto-modules</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>giveaway</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<artifactId>giveaway-impl</artifactId>

View File

@@ -101,6 +101,7 @@ public class GreateGiveaway extends AbstractConditionableCommand {
.duration(duration)
.targetChannel(target)
.winnerCount(winners)
.serverId(creator.getGuild().getIdLong())
.title(title)
.build();

View File

@@ -58,7 +58,9 @@ public class GiveawayKeyManagementServiceBean implements GiveawayKeyManagementSe
@Override
public void deleteById(Long id, Long serverId) {
GiveawayKey key = giveawayKeyRepository.findById(new GiveawayKeyId(id, serverId)).orElseThrow(GiveawayKeyNotFoundException::new);
key.getGiveaway().setGiveawayKey(null);
if(key.getGiveaway() != null) {
key.getGiveaway().setGiveawayKey(null);
}
giveawayKeyRepository.delete(key);
}

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>giveaway</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<artifactId>giveaway-int</artifactId>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>abstracto-modules</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<artifactId>giveaway</artifactId>

View File

@@ -4,7 +4,7 @@
<parent>
<artifactId>image-generation</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<artifactId>image-generation-impl</artifactId>

View File

@@ -4,7 +4,7 @@
<parent>
<artifactId>image-generation</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<artifactId>image-generation-int</artifactId>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>abstracto-modules</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<artifactId>image-generation</artifactId>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>invite-filter</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>invite-filter</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -18,7 +18,7 @@
<dependency>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>moderation-int</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>link-embed</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>link-embed</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>logging</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>logging</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>moderation</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>moderation</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>abstracto-modules</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>modmail</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>modmail</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>abstracto-modules</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto</groupId>
<artifactId>abstracto-application</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>profanity-filter</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>profanity-filter</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>remind</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>remind</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>repost-detection</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>repost-detection</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>starboard</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>starboard</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>abstracto-modules</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>statistic</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>statistic</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>sticky-roles</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<artifactId>sticky-roles-impl</artifactId>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>sticky-roles</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<artifactId>sticky-roles-int</artifactId>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>suggestion</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>suggestion</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>twitch</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>twitch</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>abstracto-modules</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>utility</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>utility</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>voice-channel-context</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>voice-channel-context</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>abstracto-modules</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>webservices</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -48,6 +48,16 @@
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-youtube</artifactId>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<classifier>jakarta</classifier>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,150 @@
package dev.sheldan.abstracto.webservices.currencyconversion.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.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.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.webservices.config.WebServicesSlashCommandNames;
import dev.sheldan.abstracto.webservices.config.WebserviceFeatureDefinition;
import dev.sheldan.abstracto.webservices.currencyconversion.model.ConvertCurrencyResponseModel;
import dev.sheldan.abstracto.webservices.currencyconversion.model.Currency;
import dev.sheldan.abstracto.webservices.currencyconversion.service.CurrencyConversionApiService;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ConvertCurrency extends AbstractConditionableCommand {
private static final String SOURCE_CURRENCY_PARAMETER = "sourceCurrency";
private static final String TARGET_CURRENCY_PARAMETER = "targetCurrency";
private static final String VALUE_PARAMETER = "value";
private static final String CONVERT_CURRENCY_RESPONSE_TEMPLATE = "convertCurrency_response";
@Autowired
private InteractionService interactionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private CurrencyConversionApiService currencyConversionApiService;
@Autowired
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String sourceCurrencyText = slashCommandParameterService.getCommandOption(SOURCE_CURRENCY_PARAMETER, event, String.class);
String targetCurrencyText = slashCommandParameterService.getCommandOption(TARGET_CURRENCY_PARAMETER, event, String.class);
Double value = slashCommandParameterService.getCommandOption(VALUE_PARAMETER, event, Double.class);
Currency sourceCurrency = currencyConversionApiService.getCurrencyForString(sourceCurrencyText);
Currency targetCurrency = currencyConversionApiService.getCurrencyForString(targetCurrencyText);
Double convertedValue = currencyConversionApiService.convertCurrency(sourceCurrency, targetCurrency, value);
ConvertCurrencyResponseModel responseModel = ConvertCurrencyResponseModel
.builder()
.sourceCurrency(sourceCurrency)
.targetCurrency(targetCurrency)
.sourceValue(value)
.targetValue(convertedValue)
.build();
return interactionService.replyEmbed(CONVERT_CURRENCY_RESPONSE_TEMPLATE, responseModel, event)
.thenApply(interactionHook -> CommandResult.fromSuccess());
}
@Override
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), SOURCE_CURRENCY_PARAMETER)
|| slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), TARGET_CURRENCY_PARAMETER)) {
String input = event.getFocusedOption().getValue().toLowerCase();
List<Currency> supportedCurrencies = currencyConversionApiService.getSupportedCurrencies();
Set<String> currencies = new HashSet<>();
supportedCurrencies.forEach(currency -> {
currencies.add(currency.getCode().toLowerCase());
currencies.add(currency.getName().toLowerCase());
currencies.add(currency.getSymbol().toLowerCase());
if(currency.getSymbolNative() != null) {
currencies.add(currency.getSymbolNative().toLowerCase());
}
});
if(!input.isEmpty()) {
return currencies.stream().filter(s -> s.contains(input)).toList();
} else {
return currencies.stream().toList();
}
} else {
return new ArrayList<>();
}
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
Parameter sourceCurrencyParameter = Parameter
.builder()
.name(SOURCE_CURRENCY_PARAMETER)
.type(String.class)
.supportsAutoComplete(true)
.templated(true)
.build();
parameters.add(sourceCurrencyParameter);
Parameter targetCurrencyParameter = Parameter
.builder()
.name(TARGET_CURRENCY_PARAMETER)
.type(String.class)
.supportsAutoComplete(true)
.templated(true)
.build();
parameters.add(targetCurrencyParameter);
Parameter valueParameter = Parameter
.builder()
.name(VALUE_PARAMETER)
.type(Double.class)
.templated(true)
.build();
parameters.add(valueParameter);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(WebServicesSlashCommandNames.CONVERSION)
.commandName("currency")
.build();
return CommandConfiguration.builder()
.name("convertCurrency")
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.slashCommandConfig(slashCommandConfig)
.async(true)
.supportsEmbedException(true)
.slashCommandOnly(true)
.causesReaction(false)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return WebserviceFeatureDefinition.CURRENCY_CONVERSION;
}
}

View File

@@ -0,0 +1,28 @@
package dev.sheldan.abstracto.webservices.currencyconversion.config;
import java.net.URL;
import lombok.extern.slf4j.Slf4j;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.jsr107.Eh107Configuration;
import org.ehcache.xml.XmlConfiguration;
import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Slf4j
public class CurrencyCacheConfig {
@Bean
public JCacheManagerCustomizer currencyCacheManagerCustomizer() {
URL myUrl = getClass().getResource("/currency-cache-config.xml");
XmlConfiguration xmlConfig = new XmlConfiguration(myUrl);
org.ehcache.CacheManager myCacheManager = CacheManagerBuilder.newCacheManager(xmlConfig);
return cm -> {
myCacheManager.getRuntimeConfiguration().getCacheConfigurations().entrySet().forEach(cacheConfiguration -> {
javax.cache.configuration.Configuration<?, ?> jConfiguration = Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration.getValue());
log.info("Creating custom cache: " + cacheConfiguration.getKey());
cm.createCache(cacheConfiguration.getKey(), jConfiguration);
});
};
}
}

View File

@@ -0,0 +1,11 @@
package dev.sheldan.abstracto.webservices.currencyconversion.model.api;
import java.util.Map;
import lombok.Builder;
import lombok.Getter;
@Builder
@Getter
public class CurrencyLatestExchangeResponse {
private Map<String, Double> data;
}

View File

@@ -0,0 +1,20 @@
package dev.sheldan.abstracto.webservices.currencyconversion.model.api;
import com.google.gson.annotations.SerializedName;
import lombok.Builder;
import lombok.Getter;
@Builder
@Getter
public class CurrencyListCurrency {
private String symbol;
private String name;
@SerializedName("symbol_native")
private String symbolNative;
@SerializedName("decimal_digits")
private String decimalDigits;
private String rounding;
private String code;
@SerializedName("name_plural")
private String namePlural;
}

View File

@@ -0,0 +1,11 @@
package dev.sheldan.abstracto.webservices.currencyconversion.model.api;
import java.util.Map;
import lombok.Builder;
import lombok.Getter;
@Builder
@Getter
public class CurrencyListResponse {
private Map<String, CurrencyListCurrency> data;
}

View File

@@ -0,0 +1,120 @@
package dev.sheldan.abstracto.webservices.currencyconversion.service;
import com.google.gson.Gson;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.webservices.currencyconversion.exception.CurrencyNotFoundException;
import dev.sheldan.abstracto.webservices.currencyconversion.model.Currency;
import dev.sheldan.abstracto.webservices.currencyconversion.model.api.CurrencyLatestExchangeResponse;
import dev.sheldan.abstracto.webservices.currencyconversion.model.api.CurrencyListResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class CurrencyConversionApiServiceBean implements CurrencyConversionApiService {
@Autowired
private OkHttpClient okHttpClient;
@Value("${abstracto.feature.webservices.currencyConversion.currencyURL}")
private String currencyUrl;
@Value("${abstracto.feature.webservices.currencyConversion.conversionURL}")
private String conversionUrl;
@Value("${abstracto.feature.webservices.currencyConversion.apiKey}")
private String apiKey;
@Autowired
private Gson gson;
@Autowired
private CurrencyConversionApiService self;
@Autowired
private CurrencyConverter currencyConverter;
@Override
@Cacheable(value = "currency-cache")
public List<Currency> getSupportedCurrencies() {
String formattedUrl = currencyUrl;
Request request = new Request.Builder()
.url(formattedUrl)
.header("apikey", apiKey)
.get()
.build();
Response response = null;
log.info("Loading available currencies.");
try {
response = okHttpClient.newCall(request).execute();
CurrencyListResponse currencyListResponse = gson.fromJson(response.body().string(), CurrencyListResponse.class);
List<Currency> currencies = new ArrayList<>();
currencyListResponse.getData().forEach((s, currencyListCurrency) -> currencies.add(currencyConverter.fromResponseObject(currencyListCurrency)));
return currencies;
} catch (IOException e) {
log.error("Failed to load currencies.", e);
throw new AbstractoRunTimeException(e);
}
}
@Override
public Currency getCurrencyForString(String input) {
List<Currency> supportedCurrencies = self.getSupportedCurrencies();
String lowerInput = input.toLowerCase();
return supportedCurrencies
.stream()
.filter(currency -> currency.getCode().toLowerCase().equals(lowerInput)
|| currency.getName().toLowerCase().equals(lowerInput)
|| currency.getSymbol().toLowerCase().equals(lowerInput)
|| currency.getSymbolNative().toLowerCase().equals(lowerInput))
.findFirst()
.orElseThrow(CurrencyNotFoundException::new);
}
@Override
public Double convertCurrency(String sourceCurrencyString, String targetCurrencyString, Double amount) {
Currency sourceCurrency = getCurrencyForString(sourceCurrencyString);
Currency targetCurrency = getCurrencyForString(targetCurrencyString);
return convertCurrency(sourceCurrency, targetCurrency, amount);
}
@Override
@Cacheable(value = "currency-conversion-cache")
public Map<String, Double> getExchangeRates(Currency sourceCurrency) {
String formattedUrl = String.format(conversionUrl, sourceCurrency.getCode());
Request request = new Request.Builder()
.url(formattedUrl)
.header("apikey", apiKey)
.get()
.build();
log.info("Loading exchange rate for {}.", sourceCurrency);
try {
Response response = okHttpClient.newCall(request).execute();
CurrencyLatestExchangeResponse currencyLatestExchangeResponse = gson.fromJson(response.body().string(), CurrencyLatestExchangeResponse.class);
return currencyLatestExchangeResponse.getData();
} catch (IOException e) {
log.error("Failed to load currency exchange rate for {}.", sourceCurrency, e);
throw new AbstractoRunTimeException(e);
}
}
@Override
public Double convertCurrency(Currency sourceCurrency, Currency targetCurrency, Double amount) {
Map<String, Double> receivedCurrencies = self.getExchangeRates(sourceCurrency);
if(!receivedCurrencies.containsKey(targetCurrency.getCode())) {
throw new CurrencyNotFoundException();
}
Double targetCurrencyValue = receivedCurrencies.get(targetCurrency.getCode());
return amount * targetCurrencyValue;
}
}

View File

@@ -0,0 +1,18 @@
package dev.sheldan.abstracto.webservices.currencyconversion.service;
import dev.sheldan.abstracto.webservices.currencyconversion.model.Currency;
import dev.sheldan.abstracto.webservices.currencyconversion.model.api.CurrencyListCurrency;
import org.springframework.stereotype.Component;
@Component
public class CurrencyConverter {
public Currency fromResponseObject(CurrencyListCurrency currencyListCurrency) {
return Currency
.builder()
.code(currencyListCurrency.getCode())
.name(currencyListCurrency.getName())
.symbol(currencyListCurrency.getSymbol())
.symbolNative(currencyListCurrency.getSymbolNative())
.build();
}
}

View File

@@ -0,0 +1,33 @@
<config
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xsi:schemaLocation="
http://www.ehcache.org/v3
http://www.ehcache.org/schema/ehcache-core-3.8-1.xsd">
<cache uses-template="default" alias="currency-cache">
<expiry>
<ttl unit="seconds">43200</ttl>
</expiry>
<resources>
<heap unit="entries">5</heap>
</resources>
</cache>
<cache uses-template="default" alias="currency-conversion-cache">
<expiry>
<ttl unit="seconds">43200</ttl>
</expiry>
<resources>
<heap unit="entries">5</heap>
</resources>
</cache>
<cache-template name="default">
<expiry>
<ttl unit="seconds">43200</ttl>
</expiry>
<resources>
<heap>50</heap>
</resources>
</cache-template>
</config>

View File

@@ -0,0 +1,6 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd">
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,16 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<property name="utilityModule" value="(SELECT id FROM module WHERE name = 'utility')"/>
<property name="currencyConversionFeature" value="(SELECT id FROM feature WHERE key = 'currencyConversion')"/>
<changeSet author="Sheldan" id="currencyConversion-commands">
<insert tableName="command">
<column name="name" value="convertCurrency"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${currencyConversionFeature}"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,7 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<include file="feature.xml" relativeToChangelogFile="true"/>
<include file="command.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<changeSet author="Sheldan" id="currencyConversion_feature-insertion">
<insert tableName="feature">
<column name="key" value="currencyConversion"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -6,4 +6,5 @@
<include file="1.4.7/collection.xml" relativeToChangelogFile="true"/>
<include file="1.4.22/collection.xml" relativeToChangelogFile="true"/>
<include file="1.5.20/collection.xml" relativeToChangelogFile="true"/>
<include file="1.5.57/collection.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -40,4 +40,10 @@ abstracto.systemConfigs.wikipediaLanguageKey.stringValue=en
abstracto.featureFlags.dictionary.featureName=dictionary
abstracto.featureFlags.dictionary.enabled=false
abstracto.feature.webservices.dictionaryapi.definitionURL=https://api.dictionaryapi.dev/api/v2/entries/en/{1}
abstracto.featureFlags.currencyConversion.featureName=currencyConversion
abstracto.featureFlags.currencyConversion.enabled=false
abstracto.feature.webservices.dictionaryapi.definitionURL=https://api.dictionaryapi.dev/api/v2/entries/en/{1}
abstracto.feature.webservices.currencyConversion.currencyURL=https://api.freecurrencyapi.com/v1/currencies
abstracto.feature.webservices.currencyConversion.conversionURL=https://api.freecurrencyapi.com/v1/latest?base_currency=%s
abstracto.feature.webservices.currencyConversion.apiKey=${FREE_CURRENCY_API_API_KEY}

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>webservices</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,5 +5,6 @@ public class WebServicesSlashCommandNames {
public static final String URBAN = "urban";
public static final String WEATHER = "weather";
public static final String WIKIPEDIA = "wikipedia";
public static final String CONVERSION = "conversion";
public static final String DICTIONARY = "dictionary";
}

View File

@@ -10,7 +10,8 @@ public enum WebserviceFeatureDefinition implements FeatureDefinition {
THREAD_READER("threadReader"),
OPEN_WEATHER_MAP("openWeatherMap"),
WIKIPEDIA("wikipedia"),
DICTIONARY("dictionary");
DICTIONARY("dictionary"),
CURRENCY_CONVERSION("currencyConversion");
private String key;

View File

@@ -0,0 +1,16 @@
package dev.sheldan.abstracto.webservices.currencyconversion.config;
import dev.sheldan.abstracto.core.config.FeatureConfig;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.webservices.config.WebserviceFeatureDefinition;
import org.springframework.stereotype.Component;
@Component
public class CurrencyConversionApiFeatureConfig implements FeatureConfig {
@Override
public FeatureDefinition getFeature() {
return WebserviceFeatureDefinition.CURRENCY_CONVERSION;
}
}

View File

@@ -0,0 +1,9 @@
package dev.sheldan.abstracto.webservices.currencyconversion.exception;
import dev.sheldan.abstracto.core.command.exception.AbstractoTemplatedException;
public class CurrencyNotFoundException extends AbstractoTemplatedException {
public CurrencyNotFoundException() {
super("Currency not found", "currency_conversion_currency_not_found_exception");
}
}

View File

@@ -0,0 +1,13 @@
package dev.sheldan.abstracto.webservices.currencyconversion.model;
import lombok.Builder;
import lombok.Getter;
@Builder
@Getter
public class ConvertCurrencyResponseModel {
private Currency sourceCurrency;
private Currency targetCurrency;
private Double sourceValue;
private Double targetValue;
}

View File

@@ -0,0 +1,19 @@
package dev.sheldan.abstracto.webservices.currencyconversion.model;
import java.util.Map;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
@Builder
@Getter
@EqualsAndHashCode
@ToString
public class Currency {
private String symbol;
private String symbolNative;
private String name;
private String code;
private Map<String, Double> exchangeRates;
}

View File

@@ -0,0 +1,13 @@
package dev.sheldan.abstracto.webservices.currencyconversion.service;
import dev.sheldan.abstracto.webservices.currencyconversion.model.Currency;
import java.util.List;
import java.util.Map;
public interface CurrencyConversionApiService {
List<Currency> getSupportedCurrencies();
Currency getCurrencyForString(String input);
Double convertCurrency(String sourceCurrency, String targetCurrency, Double amount);
Map<String, Double> getExchangeRates(Currency sourceCurrency);
Double convertCurrency(Currency sourceCurrency, Currency targetCurrency, Double amount);
}

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto</groupId>
<artifactId>abstracto-application</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.core</groupId>
<artifactId>core</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.core</groupId>
<artifactId>core</artifactId>
<version>1.5.55-SNAPSHOT</version>
<version>1.5.57</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>

Some files were not shown because too many files have changed in this diff Show More