Skip to content

Commit e59239f

Browse files
authored
Merge pull request #490 from danthe1st/tagsort
Tag sorting and searching
2 parents 8f13ee5 + 003ac1d commit e59239f

File tree

7 files changed

+104
-15
lines changed

7 files changed

+104
-15
lines changed

src/main/java/net/discordjug/javabot/systems/staff_commands/tags/CustomTagManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,13 @@ public class CustomTagManager {
8484
Set<RestAction<?>> actions = new HashSet<>();
8585
if (tag.isEmbed()) {
8686
if (tag.isReply()) {
87-
actions.add(event.getHook().sendMessageEmbeds(tag.toEmbed()));
87+
actions.add(event.replyEmbeds(tag.toEmbed()));
8888
} else {
8989
actions.add(event.getChannel().sendMessageEmbeds(tag.toEmbed()));
9090
}
9191
} else {
9292
if (tag.isReply()) {
93-
actions.add(event.getHook().sendMessage(tag.getResponse()).setAllowedMentions(List.of()));
93+
actions.add(event.reply(tag.getResponse()).setAllowedMentions(List.of()));
9494
} else {
9595
actions.add(event.getChannel().sendMessage(tag.getResponse()).setAllowedMentions(List.of()));
9696
}

src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagListSubcommand.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import java.util.stream.Collectors;
1919

2020
/**
21-
* <h3>This class represents the /tags command.</h3>
21+
* <h3>This class represents the /tag list command.</h3>
2222
*/
2323
public class TagListSubcommand extends TagsSubcommand {
2424
private final ExecutorService asyncPool;
@@ -43,11 +43,16 @@ public ReplyCallbackAction handleCustomTagsSubcommand(@NotNull SlashCommandInter
4343
asyncPool.execute(()->{
4444
try {
4545
List<CustomTag> tags = customTagRepository.getCustomTagsByGuildId(event.getGuild().getIdLong());
46-
String tagList = tags.stream().map(CustomTag::getName).map(MarkdownUtil::monospace).collect(Collectors.joining(", "));
46+
String tagList = tags
47+
.stream()
48+
.map(CustomTag::getName)
49+
.map(MarkdownUtil::monospace)
50+
.collect(Collectors.joining(", "));
4751
Responses.info(event.getHook(), "Custom Tag List",
4852
String.format(tagList.length() > 0 ? tagList : "No Custom Tags created yet.")).queue();
4953
} catch (DataAccessException e) {
5054
ExceptionLogger.capture(e, TagListSubcommand.class.getSimpleName());
55+
Responses.error(event.getHook(), "An error occured trying to list tags").queue();
5156
}
5257
});
5358
return event.deferReply(false);
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package net.discordjug.javabot.systems.staff_commands.tags.commands;
2+
3+
import java.sql.SQLException;
4+
import java.util.List;
5+
import java.util.concurrent.ExecutorService;
6+
import java.util.stream.Collectors;
7+
8+
import net.discordjug.javabot.data.config.BotConfig;
9+
import net.discordjug.javabot.systems.staff_commands.tags.dao.CustomTagRepository;
10+
import net.discordjug.javabot.systems.staff_commands.tags.model.CustomTag;
11+
import net.discordjug.javabot.util.ExceptionLogger;
12+
import net.discordjug.javabot.util.Responses;
13+
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
14+
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
15+
import net.dv8tion.jda.api.interactions.commands.OptionType;
16+
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
17+
import net.dv8tion.jda.api.requests.restaction.interactions.InteractionCallbackAction;
18+
import net.dv8tion.jda.api.utils.MarkdownUtil;
19+
import org.jetbrains.annotations.NotNull;
20+
import org.springframework.dao.DataAccessException;
21+
22+
/**
23+
* The /tag search command which lists all tags matching a query.
24+
*/
25+
public class TagSearchSubcommand extends TagsSubcommand {
26+
27+
private final ExecutorService asyncPool;
28+
private final CustomTagRepository customTagRepository;
29+
30+
/**
31+
* The constructor of this class, which sets the corresponding {@link net.dv8tion.jda.api.interactions.commands.build.SlashCommandData}.
32+
* @param botConfig The main configuration of the bot.
33+
* @param asyncPool Thread pool for asynchronous operations.
34+
* @param customTagRepository The repository for accessing tags in the database.
35+
*/
36+
public TagSearchSubcommand(BotConfig botConfig, ExecutorService asyncPool, CustomTagRepository customTagRepository) {
37+
super(botConfig);
38+
this.asyncPool = asyncPool;
39+
this.customTagRepository = customTagRepository;
40+
setCommandData(
41+
new SubcommandData("search", "Searches for tags using a query")
42+
.addOption(OptionType.STRING, "query", "The search query", true));
43+
setRequiredStaff(false);
44+
}
45+
46+
@Override
47+
protected InteractionCallbackAction<?> handleCustomTagsSubcommand(@NotNull SlashCommandInteractionEvent event)
48+
throws SQLException {
49+
50+
String query = event.getOption("query", "", OptionMapping::getAsString);
51+
52+
asyncPool.execute(()->{
53+
try {
54+
List<CustomTag> tags = customTagRepository.search(event.getGuild().getIdLong(), query);
55+
String tagList = tags
56+
.stream()
57+
.map(CustomTag::getName)
58+
.map(MarkdownUtil::monospace)
59+
.collect(Collectors.joining(", "));
60+
Responses.info(event.getHook(), "Custom tags containing \"" + query + "\"",
61+
String.format(tagList.length() > 0 ? tagList : "No Custom Tags have been found.")).queue();
62+
} catch (DataAccessException e) {
63+
ExceptionLogger.capture(e, TagListSubcommand.class.getSimpleName());
64+
Responses.error(event.getHook(), "An error occured trying to search for tags").queue();
65+
}
66+
});
67+
return event.deferReply(false);
68+
}
69+
70+
}

src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagViewSubcommand.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
1212
import net.dv8tion.jda.api.interactions.commands.OptionType;
1313
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
14-
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
14+
import net.dv8tion.jda.api.requests.RestAction;
1515

1616
import org.jetbrains.annotations.NotNull;
1717

1818
import java.util.Optional;
1919

2020
/**
21-
* <h3>This class represents the /tag command.</h3>
21+
* <h3>This class represents the /tag view command.</h3>
2222
*/
2323
public class TagViewSubcommand extends TagsSubcommand implements AutoCompletable {
2424
private final CustomTagManager tagManager;
@@ -38,18 +38,17 @@ public TagViewSubcommand(CustomTagManager tagManager, BotConfig botConfig) {
3838
}
3939

4040
@Override
41-
public ReplyCallbackAction handleCustomTagsSubcommand(@NotNull SlashCommandInteractionEvent event) {
41+
public RestAction<?> handleCustomTagsSubcommand(@NotNull SlashCommandInteractionEvent event) {
4242
OptionMapping nameMapping = event.getOption("name");
4343
if (nameMapping == null) {
4444
return Responses.replyMissingArguments(event);
4545
}
4646
Optional<CustomTag> tagOptional = tagManager.getByName(event.getGuild().getIdLong(), nameMapping.getAsString());
4747
if (tagOptional.isPresent()) {
48-
CustomTagManager.handleCustomTag(event, tagOptional.get()).queue();
48+
return CustomTagManager.handleCustomTag(event, tagOptional.get());
4949
} else {
50-
Responses.error(event.getHook(), "Could not find Custom Tag with name `%s`.", nameMapping.getAsString()).queue();
50+
return Responses.error(event, "Could not find Custom Tag with name `%s`.", nameMapping.getAsString());
5151
}
52-
return event.deferReply(false);
5352
}
5453

5554
@Override

src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagsCommand.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ public class TagsCommand extends SlashCommand {
1313
* adds the corresponding {@link net.dv8tion.jda.api.interactions.commands.Command.Subcommand}s.
1414
* @param tagViewSubcommand /tag view
1515
* @param tagListSubcommand /tag list
16+
* @param tagSearchSubcommand /tag search
1617
*/
17-
public TagsCommand(TagViewSubcommand tagViewSubcommand, TagListSubcommand tagListSubcommand) {
18+
public TagsCommand(TagViewSubcommand tagViewSubcommand, TagListSubcommand tagListSubcommand, TagSearchSubcommand tagSearchSubcommand) {
1819
setCommandData(Commands.slash("tag", "Commands for interacting with Custom Tags.")
1920
.setGuildOnly(true)
2021
);
21-
addSubcommands(tagViewSubcommand, tagListSubcommand);
22+
addSubcommands(tagViewSubcommand, tagListSubcommand, tagSearchSubcommand);
2223
}
2324
}

src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagsSubcommand.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import net.discordjug.javabot.util.ExceptionLogger;
99
import net.discordjug.javabot.util.Responses;
1010
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
11-
import net.dv8tion.jda.api.requests.restaction.interactions.InteractionCallbackAction;
11+
import net.dv8tion.jda.api.requests.RestAction;
1212

1313
import org.jetbrains.annotations.NotNull;
1414

@@ -45,5 +45,5 @@ protected void setRequiredStaff(boolean requireStaff) {
4545
this.requireStaff = requireStaff;
4646
}
4747

48-
protected abstract InteractionCallbackAction<?> handleCustomTagsSubcommand(@NotNull SlashCommandInteractionEvent event) throws SQLException;
48+
protected abstract RestAction<?> handleCustomTagsSubcommand(@NotNull SlashCommandInteractionEvent event) throws SQLException;
4949
}

src/main/java/net/discordjug/javabot/systems/staff_commands/tags/dao/CustomTagRepository.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,23 @@ public Optional<CustomTag> findById(long id) throws DataAccessException {
117117
* @return A List with all custom commands.
118118
*/
119119
public List<CustomTag> getCustomTagsByGuildId(long guildId) {
120-
return jdbcTemplate.query("SELECT * FROM custom_tags WHERE guild_id = ?", (rs, row)->this.read(rs),
120+
return jdbcTemplate.query("SELECT * FROM custom_tags WHERE guild_id = ? ORDER BY name", (rs, row)->this.read(rs),
121121
guildId);
122122
}
123+
124+
/**
125+
* Gets all custom commands for the given guild matching a specified query.
126+
* A tag matches the query if the name or reply contains the query.
127+
*
128+
* @param guildId The id of the guild.
129+
* @param query The search query.
130+
* @return A List with all custom commands.
131+
*/
132+
public List<CustomTag> search(long guildId, String query) {
133+
String enhancedQuery = "%" + query + "%";
134+
return jdbcTemplate.query("SELECT * FROM custom_tags WHERE guild_id = ? AND (name LIKE ? OR response LIKE ?) ORDER BY name", (rs, row)->this.read(rs),
135+
guildId, enhancedQuery, enhancedQuery);
136+
}
123137

124138
/**
125139
* Reads the given {@link ResultSet} and constructs a new {@link CustomTag} object.

0 commit comments

Comments
 (0)