Compare commits

..

8 Commits

Author SHA1 Message Date
Sheldan
a94b9293f7 [maven-release-plugin] prepare release v1.5.21 2023-12-29 00:21:02 +01:00
Sheldan
3c4edf5671 [AB-xxx] fixing check in case no wikipedia article was found 2023-12-29 00:19:29 +01:00
Sheldan
f02f1eac4c [maven-release-plugin] prepare for next development iteration 2023-12-28 22:30:45 +01:00
Sheldan
373ed4cde5 [maven-release-plugin] prepare release v1.5.20 2023-12-28 22:30:41 +01:00
Sheldan
5eb9a0e674 [AB-xxx] preparing for release 2023-12-28 22:29:14 +01:00
Sheldan
d4f07bd719 [AB-xxx] adding wikipedia and dictionary features 2023-12-28 22:27:33 +01:00
Sheldan
8924b75530 [AB-xxx] adding check in case the modmail thread has been closed, this is needed because in thread mode one could potentially still execute commands
removing some message command implementations
refactoring the way modmail threads are loaded
2023-12-28 10:57:07 +01:00
Sheldan
25bdc98944 [maven-release-plugin] prepare for next development iteration 2023-12-26 21:04:49 +01:00
122 changed files with 1004 additions and 145 deletions

2
.env
View File

@@ -1,2 +1,2 @@
REGISTRY_PREFIX=harbor.sheldan.dev/abstracto/
VERSION=1.5.19
VERSION=1.5.21

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>anti-raid</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</version>
</parent>
<artifactId>giveaway-impl</artifactId>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>giveaway</artifactId>
<version>1.5.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -8,12 +8,12 @@ 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.FeatureDefinition;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.modmail.condition.ModMailContextCondition;
import dev.sheldan.abstracto.modmail.config.ModMailFeatureDefinition;
import dev.sheldan.abstracto.modmail.exception.ModMailThreadClosedException;
import dev.sheldan.abstracto.modmail.model.database.ModMailThread;
import dev.sheldan.abstracto.modmail.model.database.ModMailThreadState;
import dev.sheldan.abstracto.modmail.service.ModMailThreadService;
import dev.sheldan.abstracto.modmail.service.management.ModMailThreadManagementService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -42,18 +42,17 @@ public class AnonReply extends AbstractConditionableCommand {
@Autowired
private MemberService memberService;
@Autowired
private ChannelManagementService channelManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
// text is optional, for example if only an attachment is sent
String text = parameters.size() == 1 ? (String) parameters.get(0) : "";
AChannel channel = channelManagementService.loadChannel(commandContext.getChannel());
ModMailThread thread = modMailThreadManagementService.getByChannel(channel);
Long threadId = thread.getId();
return memberService.getMemberInServerAsync(thread.getUser()).thenCompose(member ->
ModMailThread modMailThread = modMailThreadManagementService.getByChannelId(commandContext.getChannel().getIdLong());
if(ModMailThreadState.CLOSED.equals(modMailThread.getState()) || ModMailThreadState.CLOSING.equals(modMailThread.getState())) {
throw new ModMailThreadClosedException();
}
Long threadId = modMailThread.getId();
return memberService.getMemberInServerAsync(modMailThread.getUser()).thenCompose(member ->
modMailThreadService.loadExecutingMemberAndRelay(threadId, text, commandContext.getMessage(), true, member)
).thenApply(aVoid -> CommandResult.fromSuccess());
}

View File

@@ -11,13 +11,13 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.modmail.condition.ModMailContextCondition;
import dev.sheldan.abstracto.modmail.config.ModMailFeatureDefinition;
import dev.sheldan.abstracto.modmail.config.ModMailSlashCommandNames;
import dev.sheldan.abstracto.modmail.exception.ModMailThreadClosedException;
import dev.sheldan.abstracto.modmail.model.ClosingContext;
import dev.sheldan.abstracto.modmail.model.database.ModMailThread;
import dev.sheldan.abstracto.modmail.model.database.ModMailThreadState;
import dev.sheldan.abstracto.modmail.service.ModMailThreadService;
import dev.sheldan.abstracto.modmail.service.management.ModMailThreadManagementService;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
@@ -59,9 +59,6 @@ public class Close extends AbstractConditionableCommand {
@Autowired
private TemplateService templateService;
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private InteractionService interactionService;
@@ -76,8 +73,10 @@ public class Close extends AbstractConditionableCommand {
List<Object> parameters = commandContext.getParameters().getParameters();
// the default value of the note is configurable via template
String note = parameters.size() == 1 ? (String) parameters.get(0) : templateService.renderTemplate(MODMAIL_CLOSE_DEFAULT_NOTE_TEMPLATE_KEY, new Object());
AChannel channel = channelManagementService.loadChannel(commandContext.getChannel());
ModMailThread thread = modMailThreadManagementService.getByChannel(channel);
ModMailThread modMailThread = modMailThreadManagementService.getByChannelId(commandContext.getChannel().getIdLong());
if(ModMailThreadState.CLOSED.equals(modMailThread.getState()) || ModMailThreadState.CLOSING.equals(modMailThread.getState())) {
throw new ModMailThreadClosedException();
}
ClosingContext context = ClosingContext
.builder()
.closingMember(commandContext.getAuthor())
@@ -86,7 +85,7 @@ public class Close extends AbstractConditionableCommand {
.log(true)
.note(note)
.build();
return modMailThreadService.closeModMailThread(thread, context, commandContext.getUndoActions())
return modMailThreadService.closeModMailThread(modMailThread, context, commandContext.getUndoActions())
.thenApply(aVoid -> CommandResult.fromIgnored());
}
@@ -125,9 +124,11 @@ public class Close extends AbstractConditionableCommand {
@Transactional
public CompletableFuture<Void> closeThread(ClosingContext closingContext) {
AChannel channel = channelManagementService.loadChannel(closingContext.getChannel());
ModMailThread thread = modMailThreadManagementService.getByChannel(channel);
return modMailThreadService.closeModMailThread(thread, closingContext, new ArrayList<>());
ModMailThread modMailThread = modMailThreadManagementService.getByChannelId(closingContext.getChannel().getIdLong());
if(ModMailThreadState.CLOSED.equals(modMailThread.getState()) || ModMailThreadState.CLOSING.equals(modMailThread.getState())) {
throw new ModMailThreadClosedException();
}
return modMailThreadService.closeModMailThread(modMailThread, closingContext, new ArrayList<>());
}
@Override

View File

@@ -8,12 +8,12 @@ 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.FeatureDefinition;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.modmail.condition.ModMailContextCondition;
import dev.sheldan.abstracto.modmail.config.ModMailFeatureDefinition;
import dev.sheldan.abstracto.modmail.exception.ModMailThreadClosedException;
import dev.sheldan.abstracto.modmail.model.ClosingContext;
import dev.sheldan.abstracto.modmail.model.database.ModMailThread;
import dev.sheldan.abstracto.modmail.model.database.ModMailThreadState;
import dev.sheldan.abstracto.modmail.service.ModMailThreadService;
import dev.sheldan.abstracto.modmail.service.management.ModMailThreadManagementService;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
@@ -43,16 +43,15 @@ public class CloseSilently extends AbstractConditionableCommand {
@Autowired
private TemplateService templateService;
@Autowired
private ChannelManagementService channelManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
// default note text is configurable via template, because the note is optional
String note = parameters.size() == 1 ? (String) parameters.get(0) : templateService.renderTemplate("modmail_close_default_note", new Object());
AChannel channel = channelManagementService.loadChannel(commandContext.getChannel());
ModMailThread thread = modMailThreadManagementService.getByChannel(channel);
ModMailThread modMailThread = modMailThreadManagementService.getByChannelId(commandContext.getChannel().getIdLong());
if(ModMailThreadState.CLOSED.equals(modMailThread.getState()) || ModMailThreadState.CLOSING.equals(modMailThread.getState())) {
throw new ModMailThreadClosedException();
}
ClosingContext context = ClosingContext
.builder()
.closingMember(commandContext.getAuthor())
@@ -60,7 +59,7 @@ public class CloseSilently extends AbstractConditionableCommand {
.log(true)
.note(note)
.build();
return modMailThreadService.closeModMailThread(thread, context, commandContext.getUndoActions())
return modMailThreadService.closeModMailThread(modMailThread, context, commandContext.getUndoActions())
.thenApply(aVoid -> CommandResult.fromIgnored());
}

View File

@@ -8,12 +8,12 @@ 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.FeatureDefinition;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.modmail.condition.ModMailContextCondition;
import dev.sheldan.abstracto.modmail.config.ModMailFeatureDefinition;
import dev.sheldan.abstracto.modmail.exception.ModMailThreadClosedException;
import dev.sheldan.abstracto.modmail.model.database.ModMailThread;
import dev.sheldan.abstracto.modmail.model.database.ModMailThreadState;
import dev.sheldan.abstracto.modmail.service.ModMailThreadService;
import dev.sheldan.abstracto.modmail.service.management.ModMailThreadManagementService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -41,17 +41,16 @@ public class Reply extends AbstractConditionableCommand {
@Autowired
private MemberService memberService;
@Autowired
private ChannelManagementService channelManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String text = parameters.size() == 1 ? (String) parameters.get(0) : "";
AChannel channel = channelManagementService.loadChannel(commandContext.getChannel());
ModMailThread thread = modMailThreadManagementService.getByChannel(channel);
Long threadId = thread.getId();
return memberService.getMemberInServerAsync(thread.getUser()).thenCompose(member ->
ModMailThread modMailThread = modMailThreadManagementService.getByChannelId(commandContext.getChannel().getIdLong());
if(ModMailThreadState.CLOSED.equals(modMailThread.getState()) || ModMailThreadState.CLOSING.equals(modMailThread.getState())) {
throw new ModMailThreadClosedException();
}
Long threadId = modMailThread.getId();
return memberService.getMemberInServerAsync(modMailThread.getUser()).thenCompose(member ->
modMailThreadService.loadExecutingMemberAndRelay(threadId, text, commandContext.getMessage(), false, member)
).thenApply(aVoid -> CommandResult.fromSuccess());
}

View File

@@ -5,7 +5,6 @@ import dev.sheldan.abstracto.core.command.condition.CommandCondition;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
@@ -13,7 +12,9 @@ import dev.sheldan.abstracto.core.service.management.UserInServerManagementServi
import dev.sheldan.abstracto.modmail.condition.ModMailContextCondition;
import dev.sheldan.abstracto.modmail.config.ModMailFeatureDefinition;
import dev.sheldan.abstracto.modmail.config.ModMailSlashCommandNames;
import dev.sheldan.abstracto.modmail.exception.ModMailThreadClosedException;
import dev.sheldan.abstracto.modmail.model.database.ModMailThread;
import dev.sheldan.abstracto.modmail.model.database.ModMailThreadState;
import dev.sheldan.abstracto.modmail.service.ModMailSubscriptionService;
import dev.sheldan.abstracto.modmail.service.management.ModMailThreadManagementService;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
@@ -49,16 +50,12 @@ public class Subscribe extends AbstractConditionableCommand {
@Autowired
private InteractionService interactionService;
@Override
public CommandResult execute(CommandContext commandContext) {
ModMailThread modMailThread = modMailThreadManagementService.getByChannelId(commandContext.getChannel().getIdLong());
modMailSubscriptionService.subscribeToThread(userInServerManagementService.loadOrCreateUser(commandContext.getAuthor()), modMailThread);
return CommandResult.fromSuccess();
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
ModMailThread modMailThread = modMailThreadManagementService.getByChannelId(event.getChannel().getIdLong());
if(ModMailThreadState.CLOSED.equals(modMailThread.getState()) || ModMailThreadState.CLOSING.equals(modMailThread.getState())) {
throw new ModMailThreadClosedException();
}
modMailSubscriptionService.subscribeToThread(userInServerManagementService.loadOrCreateUser(event.getMember()), modMailThread);
return interactionService.replyEmbed(SUBSCRIBE_RESPONSE, event)
.thenApply(interactionHook -> CommandResult.fromSuccess());
@@ -83,6 +80,7 @@ public class Subscribe extends AbstractConditionableCommand {
.slashCommandConfig(slashCommandConfig)
.module(ModMailModuleDefinition.MODMAIL)
.help(helpInfo)
.slashCommandOnly(true)
.supportsEmbedException(true)
.templated(true)
.causesReaction(true)

View File

@@ -5,7 +5,6 @@ import dev.sheldan.abstracto.core.command.condition.CommandCondition;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
@@ -14,7 +13,9 @@ import dev.sheldan.abstracto.core.service.management.UserInServerManagementServi
import dev.sheldan.abstracto.modmail.condition.ModMailContextCondition;
import dev.sheldan.abstracto.modmail.config.ModMailFeatureDefinition;
import dev.sheldan.abstracto.modmail.config.ModMailSlashCommandNames;
import dev.sheldan.abstracto.modmail.exception.ModMailThreadClosedException;
import dev.sheldan.abstracto.modmail.model.database.ModMailThread;
import dev.sheldan.abstracto.modmail.model.database.ModMailThreadState;
import dev.sheldan.abstracto.modmail.service.ModMailSubscriptionService;
import dev.sheldan.abstracto.modmail.service.management.ModMailThreadManagementService;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
@@ -50,17 +51,12 @@ public class UnSubscribe extends AbstractConditionableCommand {
@Autowired
private InteractionService interactionService;
@Override
public CommandResult execute(CommandContext commandContext) {
ModMailThread modMailThread = modMailThreadManagementService.getByChannelId(commandContext.getChannel().getIdLong());
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
modMailSubscriptionService.unsubscribeFromThread(aUserInAServer, modMailThread);
return CommandResult.fromSuccess();
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
ModMailThread modMailThread = modMailThreadManagementService.getByChannelId(event.getChannel().getIdLong());
if(ModMailThreadState.CLOSED.equals(modMailThread.getState()) || ModMailThreadState.CLOSING.equals(modMailThread.getState())) {
throw new ModMailThreadClosedException();
}
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(event.getMember());
modMailSubscriptionService.unsubscribeFromThread(aUserInAServer, modMailThread);
return interactionService.replyEmbed(UN_SUBSCRIBE_RESPONSE, event)
@@ -86,6 +82,7 @@ public class UnSubscribe extends AbstractConditionableCommand {
.slashCommandConfig(slashCommandConfig)
.module(ModMailModuleDefinition.MODMAIL)
.help(helpInfo)
.slashCommandOnly(true)
.supportsEmbedException(true)
.templated(true)
.causesReaction(true)

View File

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

View File

@@ -0,0 +1,22 @@
package dev.sheldan.abstracto.modmail.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.templating.Templatable;
public class ModMailThreadClosedException extends AbstractoRunTimeException implements Templatable {
public ModMailThreadClosedException() {
super("Mod mail thread closed");
}
@Override
public String getTemplateName() {
return "modmail_thread_closed_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>abstracto-modules</artifactId>
<version>1.5.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</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.19</version>
<version>1.5.21</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,17 +3,12 @@
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>webservices</artifactId>
<version>1.5.19</version>
<version>1.5.21</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>webservices-impl</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>

View File

@@ -0,0 +1,137 @@
package dev.sheldan.abstracto.webservices.dictionaryapi.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.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.webservices.config.WebServicesSlashCommandNames;
import dev.sheldan.abstracto.webservices.config.WebserviceFeatureDefinition;
import dev.sheldan.abstracto.webservices.dictionaryapi.model.template.DictionaryMeaning;
import dev.sheldan.abstracto.webservices.dictionaryapi.model.template.DictionaryDefinition;
import dev.sheldan.abstracto.webservices.dictionaryapi.model.WordMeaning;
import dev.sheldan.abstracto.webservices.dictionaryapi.service.DictionaryApiService;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class DictionaryApiDefinitionCommand extends AbstractConditionableCommand {
private static final String DICTIONARY_DEFINITION_RESPONSE_MODEL_TEMPLATE_KEY = "dictionaryDefinition_response";
private static final String DICTIONARY_DEFINITION_COMMAND = "dictionaryDefinition";
private static final String SEARCH_QUERY_PARAMETER = "searchQuery";
@Autowired
private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private InteractionService interactionService;
@Autowired
private DictionaryApiService dictionaryApiService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
String parameter = (String) commandContext.getParameters().getParameters().get(0);
try {
MessageToSend message = getMessageToSend(commandContext.getGuild().getIdLong(), parameter);
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(message, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromSuccess());
} catch (IOException e) {
throw new AbstractoRunTimeException(e);
}
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String query = slashCommandParameterService.getCommandOption(SEARCH_QUERY_PARAMETER, event, String.class);
try {
MessageToSend messageToSend = getMessageToSend(event.getGuild().getIdLong(), query);
return interactionService.replyMessageToSend(messageToSend, event)
.thenApply(interactionHook -> CommandResult.fromSuccess());
} catch (IOException e) {
throw new AbstractoRunTimeException(e);
}
}
private MessageToSend getMessageToSend(Long serverId, String searchInput) throws IOException {
WordMeaning meaning = dictionaryApiService.getDefinitions(searchInput);
List<DictionaryDefinition> definitions = meaning
.getDefinitions()
.stream().map(DictionaryDefinition::fromWordDefinition).toList();
DictionaryMeaning model = DictionaryMeaning
.builder()
.definitions(definitions)
.word(meaning.getWord())
.build();
return templateService.renderEmbedTemplate(DICTIONARY_DEFINITION_RESPONSE_MODEL_TEMPLATE_KEY, model, serverId);
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
Parameter searchQueryParameter = Parameter
.builder()
.name(SEARCH_QUERY_PARAMETER)
.type(String.class)
.templated(true)
.remainder(true)
.build();
parameters.add(searchQueryParameter);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
List<String> aliases = Arrays.asList("dict");
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(WebServicesSlashCommandNames.DICTIONARY)
.commandName("definition")
.build();
return CommandConfiguration.builder()
.name(DICTIONARY_DEFINITION_COMMAND)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.slashCommandConfig(slashCommandConfig)
.async(true)
.aliases(aliases)
.supportsEmbedException(true)
.causesReaction(false)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return WebserviceFeatureDefinition.DICTIONARY;
}
}

View File

@@ -0,0 +1,73 @@
package dev.sheldan.abstracto.webservices.dictionaryapi.service;
import com.google.api.client.http.HttpStatusCodes;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import dev.sheldan.abstracto.webservices.dictionaryapi.exception.DictionaryApiRequestException;
import dev.sheldan.abstracto.webservices.dictionaryapi.exception.NoDictionaryApiDefinitionFoundException;
import dev.sheldan.abstracto.webservices.dictionaryapi.model.WordDefinition;
import dev.sheldan.abstracto.webservices.dictionaryapi.model.WordMeaning;
import dev.sheldan.abstracto.webservices.dictionaryapi.model.api.DictionaryApiResponseItem;
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.stereotype.Component;
import java.io.IOException;
import java.util.List;
@Component
@Slf4j
public class DictionaryApiServiceBean implements DictionaryApiService {
@Autowired
private OkHttpClient okHttpClient;
@Value("${abstracto.feature.webservices.dictionaryapi.definitionURL}")
private String dictionaryDefinitionURL;
@Autowired
private Gson gson;
@Override
public WordMeaning getDefinitions(String query) throws IOException {
String formattedUrl = dictionaryDefinitionURL.replace("{1}", query);
Request request = new Request.Builder()
.url(formattedUrl)
.get()
.build();
Response response = okHttpClient.newCall(request).execute();
if(response.code() == HttpStatusCodes.STATUS_CODE_NOT_FOUND) {
throw new NoDictionaryApiDefinitionFoundException();
}
if(!response.isSuccessful()) {
if(log.isDebugEnabled()) {
log.error("Failed to retrieve dictionary api definition. Response had code {} with body {}.",
response.code(), response.body());
}
throw new DictionaryApiRequestException(response.code());
}
List<DictionaryApiResponseItem> dictionaryapiResponse = gson.fromJson(response.body().string(), new TypeToken<List<DictionaryApiResponseItem>>(){}.getType());
DictionaryApiResponseItem selectedWord = dictionaryapiResponse.get(0);
if(dictionaryapiResponse.size() > 1) {
log.warn("Dictionary had multiple words. One example {}.", selectedWord.getWord());
}
List<WordDefinition> wordDefinitions = selectedWord
.getMeanings()
.stream()
.flatMap(dictionaryApiWordMeaning ->
dictionaryApiWordMeaning
.getDefinitions()
.stream()
.map(WordDefinition::fromResponseDefinition))
.toList();
return WordMeaning
.builder()
.word(selectedWord.getWord())
.definitions(wordDefinitions)
.build();
}
}

View File

@@ -26,7 +26,6 @@ import dev.sheldan.abstracto.webservices.openweathermap.service.OpenWeatherMapSe
import dev.sheldan.abstracto.webservices.openweathermap.service.WeatherService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.checkerframework.checker.index.qual.SameLen;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

View File

@@ -0,0 +1,158 @@
package dev.sheldan.abstracto.webservices.wikipedia.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.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.ConfigService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.webservices.config.WebServicesSlashCommandNames;
import dev.sheldan.abstracto.webservices.config.WebserviceFeatureDefinition;
import dev.sheldan.abstracto.webservices.wikipedia.config.WikipediaFeatureConfig;
import dev.sheldan.abstracto.webservices.wikipedia.model.WikipediaArticleSummary;
import dev.sheldan.abstracto.webservices.wikipedia.model.template.WikipediaArticleSummaryModel;
import dev.sheldan.abstracto.webservices.wikipedia.service.WikipediaService;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class WikipediaArticleSummaryCommand extends AbstractConditionableCommand {
private static final String WIKIPEDIA_ARTICLE_SUMMARY_RESPONSE_MODEL_TEMPLATE_KEY = "wikipediaArticleSummary_response";
private static final String WIKIPEDIA_ARTICLE_SUMMARY_COMMAND = "wikipediaArticleSummary";
private static final String SEARCH_QUERY_PARAMETER = "searchQuery";
private static final String LANGUAGE_PARAMETER = "language";
@Autowired
private WikipediaService wikipediaService;
@Autowired
private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private InteractionService interactionService;
@Autowired
private ConfigService configService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
String parameter = (String) commandContext.getParameters().getParameters().get(0);
try {
MessageToSend message = getMessageToSend(commandContext.getGuild().getIdLong(), parameter, null);
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(message, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromSuccess());
} catch (IOException e) {
throw new AbstractoRunTimeException(e);
}
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String query = slashCommandParameterService.getCommandOption(SEARCH_QUERY_PARAMETER, event, String.class);
String language;
if(slashCommandParameterService.hasCommandOption(LANGUAGE_PARAMETER, event)) {
language = slashCommandParameterService.getCommandOption(LANGUAGE_PARAMETER, event, String.class);
} else {
language = null;
}
try {
MessageToSend messageToSend = getMessageToSend(event.getGuild().getIdLong(), query, language);
return interactionService.replyMessageToSend(messageToSend, event)
.thenApply(interactionHook -> CommandResult.fromSuccess());
} catch (IOException e) {
throw new AbstractoRunTimeException(e);
}
}
private MessageToSend getMessageToSend(Long serverId, String searchInput, String language) throws IOException {
String languageKey = language != null ? language :
configService.getStringValueOrConfigDefault(WikipediaFeatureConfig.WIKIPEDIA_LANGUAGE_KEY_SYSTEM_CONFIG_KEY, serverId);
WikipediaArticleSummary definition = wikipediaService.getSummary(searchInput, languageKey);
WikipediaArticleSummaryModel model = WikipediaArticleSummaryModel
.builder()
.summary(definition.getSummary())
.fullURL(definition.getFullURL())
.title(definition.getTitle())
.build();
return templateService.renderEmbedTemplate(WIKIPEDIA_ARTICLE_SUMMARY_RESPONSE_MODEL_TEMPLATE_KEY, model, serverId);
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
Parameter searchQueryParameter = Parameter
.builder()
.name(SEARCH_QUERY_PARAMETER)
.type(String.class)
.remainder(true)
.templated(true)
.build();
parameters.add(searchQueryParameter);
Parameter languageParameter = Parameter
.builder()
.name(LANGUAGE_PARAMETER)
.type(String.class)
.slashCommandOnly(true)
.optional(true)
.templated(true)
.build();
parameters.add(languageParameter);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
List<String> aliases = Arrays.asList("wiki");
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(WebServicesSlashCommandNames.WIKIPEDIA)
.groupName("article")
.commandName("summary")
.build();
return CommandConfiguration.builder()
.name(WIKIPEDIA_ARTICLE_SUMMARY_COMMAND)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.slashCommandConfig(slashCommandConfig)
.async(true)
.aliases(aliases)
.supportsEmbedException(true)
.causesReaction(false)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return WebserviceFeatureDefinition.WIKIPEDIA;
}
}

View File

@@ -0,0 +1,66 @@
package dev.sheldan.abstracto.webservices.wikipedia.service;
import com.google.gson.Gson;
import dev.sheldan.abstracto.webservices.wikipedia.exception.NoWikipediaArticleFoundException;
import dev.sheldan.abstracto.webservices.wikipedia.exception.WikipediaRequestException;
import dev.sheldan.abstracto.webservices.wikipedia.model.WikipediaArticleSummary;
import dev.sheldan.abstracto.webservices.wikipedia.model.api.WikipediaResponse;
import dev.sheldan.abstracto.webservices.wikipedia.model.api.WikipediaResponsePage;
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.stereotype.Component;
import java.io.IOException;
@Component
@Slf4j
public class WikipediaServiceBean implements WikipediaService {
@Autowired
private OkHttpClient okHttpClient;
@Value("${abstracto.feature.webservices.wikipedia.summaryURL}")
private String articleSummaryUrl;
@Autowired
private Gson gson;
@Override
public WikipediaArticleSummary getSummary(String query, String language) throws IOException {
String formattedUrl = articleSummaryUrl.replace("{1}", language).replace("{2}", query);
Request request = new Request.Builder()
.url(formattedUrl)
.get()
.build();
Response response = okHttpClient.newCall(request).execute();
if(!response.isSuccessful()) {
if(log.isDebugEnabled()) {
log.error("Failed to retrieve wikipedia summary. Response had code {} with body {}.",
response.code(), response.body());
}
throw new WikipediaRequestException(response.code());
}
WikipediaResponse wikipediaResponse = gson.fromJson(response.body().string(), WikipediaResponse.class);
if(wikipediaResponse.getQuery() == null
|| wikipediaResponse.getQuery().getPages() == null
|| (wikipediaResponse.getQuery().getPages().stream().anyMatch(wikipediaResponsePageModel ->
wikipediaResponsePageModel.getPageId() == null
|| wikipediaResponsePageModel.getPageId().equals(-1L))
&& wikipediaResponse.getQuery().getPages().size() == 1)
) {
throw new NoWikipediaArticleFoundException();
} else {
WikipediaResponsePage page = wikipediaResponse.getQuery().getPages().get(0);
return WikipediaArticleSummary
.builder()
.title(page.getTitle())
.summary(page.getExtract())
.fullURL(page.getFullUrl())
.build();
}
}
}

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:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd">
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

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

View File

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

View File

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

View File

@@ -9,4 +9,5 @@
<include file="1.2.5-webservices/collection.xml" relativeToChangelogFile="true"/>
<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"/>
</databaseChangeLog>

View File

@@ -27,4 +27,17 @@ abstracto.featureFlags.openWeatherMap.featureName=openWeatherMap
abstracto.featureFlags.openWeatherMap.enabled=false
abstracto.systemConfigs.openWeatherMapLanguageKey.name=openWeatherMapLanguageKey
abstracto.systemConfigs.openWeatherMapLanguageKey.stringValue=en
abstracto.systemConfigs.openWeatherMapLanguageKey.stringValue=en
abstracto.featureFlags.wikipedia.featureName=wikipedia
abstracto.featureFlags.wikipedia.enabled=false
abstracto.feature.webservices.wikipedia.summaryURL=https://{1}.wikipedia.org/w/api.php?action=query&format=json&prop=pageprops%7Cextracts%7Cinfo&list=&meta=&inprop=url&redirects=1&formatversion=2&ppprop=disambiguation&exintro=1&explaintext=1&titles={2}
abstracto.systemConfigs.wikipediaLanguageKey.name=wikipediaLanguageKey
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}

View File

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

View File

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

View File

@@ -8,7 +8,9 @@ public enum WebserviceFeatureDefinition implements FeatureDefinition {
YOUTUBE("youtube"),
URBAN_DICTIONARY("urban"),
THREAD_READER("threadReader"),
OPEN_WEATHER_MAP("openWeatherMap");
OPEN_WEATHER_MAP("openWeatherMap"),
WIKIPEDIA("wikipedia"),
DICTIONARY("dictionary");
private String key;

View File

@@ -0,0 +1,16 @@
package dev.sheldan.abstracto.webservices.dictionaryapi.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 DictionaryApiFeatureConfig implements FeatureConfig {
@Override
public FeatureDefinition getFeature() {
return WebserviceFeatureDefinition.DICTIONARY;
}
}

View File

@@ -0,0 +1,21 @@
package dev.sheldan.abstracto.webservices.dictionaryapi.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.templating.Templatable;
public class DictionaryApiRequestException extends AbstractoRunTimeException implements Templatable {
public DictionaryApiRequestException(Integer responseCode) {
super(String.format("Request failure towards dictionary api %s.", responseCode));
}
@Override
public String getTemplateName() {
return "dictionary_api_request_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -0,0 +1,20 @@
package dev.sheldan.abstracto.webservices.dictionaryapi.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.templating.Templatable;
public class NoDictionaryApiDefinitionFoundException extends AbstractoRunTimeException implements Templatable {
public NoDictionaryApiDefinitionFoundException() {
super("No dictionary api definition found.");
}
@Override
public String getTemplateName() {
return "no_dictionary_api_definition_found_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -0,0 +1,22 @@
package dev.sheldan.abstracto.webservices.dictionaryapi.model;
import dev.sheldan.abstracto.webservices.dictionaryapi.model.api.DictionaryApiWordDefinition;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Builder
@Setter
public class WordDefinition {
private String definition;
private String example;
public static WordDefinition fromResponseDefinition(DictionaryApiWordDefinition responseItem) {
return WordDefinition
.builder()
.example(responseItem.getExample())
.definition(responseItem.getDefinition())
.build();
}
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.webservices.dictionaryapi.model;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Builder
@Setter
public class WordMeaning {
private String word;
private List<WordDefinition> definitions;
}

View File

@@ -0,0 +1,16 @@
package dev.sheldan.abstracto.webservices.dictionaryapi.model.api;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Builder
@Setter
public class DictionaryApiResponseItem {
private String word;
private String origin;
private List<DictionaryApiWordMeaning> meanings;
}

View File

@@ -0,0 +1,13 @@
package dev.sheldan.abstracto.webservices.dictionaryapi.model.api;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class DictionaryApiWordDefinition {
private String definition;
private String example;
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.webservices.dictionaryapi.model.api;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
@Builder
public class DictionaryApiWordMeaning {
private String partOfSpeech;
private List<DictionaryApiWordDefinition> definitions;
}

View File

@@ -0,0 +1,20 @@
package dev.sheldan.abstracto.webservices.dictionaryapi.model.template;
import dev.sheldan.abstracto.webservices.dictionaryapi.model.WordDefinition;
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
public class DictionaryDefinition {
private String definition;
private String example;
public static DictionaryDefinition fromWordDefinition(WordDefinition definition) {
return DictionaryDefinition
.builder()
.example(definition.getExample())
.definition(definition.getDefinition())
.build();
}
}

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