Skip to content

Commit 60b57ec

Browse files
Started work on implementing user preferences
1 parent 2a9630c commit 60b57ec

File tree

6 files changed

+203
-0
lines changed

6 files changed

+203
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package net.javadiscord.javabot.systems.user_preferences;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import net.javadiscord.javabot.systems.user_preferences.dao.UserPreferenceRepository;
5+
import net.javadiscord.javabot.systems.user_preferences.model.Preference;
6+
import net.javadiscord.javabot.systems.user_preferences.model.UserPreference;
7+
import net.javadiscord.javabot.util.ExceptionLogger;
8+
9+
import javax.sql.DataSource;
10+
import java.sql.Connection;
11+
import java.sql.SQLException;
12+
import java.util.Optional;
13+
14+
/**
15+
* Handles & manages user preferences.
16+
*/
17+
@RequiredArgsConstructor
18+
public class UserPreferenceManager {
19+
private final DataSource dataSource;
20+
21+
/**
22+
* Simply sets the state of the specified {@link Preference} for the specified user.
23+
* If no entry for that user is found, this will simply create a new one.
24+
*
25+
* @param userId The users' id.
26+
* @param preference The {@link Preference} to change the state for.
27+
* @param enabled The preferences' state.
28+
* @return Whether the operation was successful.
29+
*/
30+
public boolean set(long userId, Preference preference, boolean enabled) {
31+
try (Connection con = dataSource.getConnection()) {
32+
UserPreferenceRepository repo = new UserPreferenceRepository(con);
33+
Optional<UserPreference> preferenceOptional = repo.getById(userId, preference);
34+
if (preferenceOptional.isPresent()) {
35+
return repo.updateState(userId, preference, enabled);
36+
} else {
37+
UserPreference userPreference = new UserPreference();
38+
userPreference.setUserId(userId);
39+
userPreference.setOrdinal(preference.ordinal());
40+
userPreference.setEnabled(enabled);
41+
repo.insert(userPreference, false);
42+
return true;
43+
}
44+
} catch (SQLException e) {
45+
ExceptionLogger.capture(e, getClass().getSimpleName());
46+
return false;
47+
}
48+
}
49+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package net.javadiscord.javabot.systems.user_preferences.commands;
2+
3+
import com.dynxsty.dih4jda.interactions.commands.AutoCompletable;
4+
import com.dynxsty.dih4jda.interactions.commands.SlashCommand;
5+
import com.dynxsty.dih4jda.util.AutoCompleteUtils;
6+
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
7+
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
8+
import net.dv8tion.jda.api.interactions.AutoCompleteQuery;
9+
import net.dv8tion.jda.api.interactions.commands.Command;
10+
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
11+
import net.dv8tion.jda.api.interactions.commands.OptionType;
12+
import net.dv8tion.jda.api.interactions.commands.build.Commands;
13+
import net.javadiscord.javabot.Bot;
14+
import net.javadiscord.javabot.systems.user_preferences.UserPreferenceManager;
15+
import net.javadiscord.javabot.systems.user_preferences.model.Preference;
16+
import net.javadiscord.javabot.util.Responses;
17+
import org.jetbrains.annotations.NotNull;
18+
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
22+
/**
23+
* <h3>This class represents the /preferences command.</h3>
24+
*/
25+
public class UserPreferenceCommand extends SlashCommand implements AutoCompletable {
26+
/**
27+
* The constructor of this class, which sets the corresponding {@link net.dv8tion.jda.api.interactions.commands.build.SlashCommandData}.
28+
*/
29+
public UserPreferenceCommand() {
30+
setSlashCommandData(Commands.slash("preferences", "Allows you to set some preferences!")
31+
.addOption(OptionType.INTEGER, "preference", "The preference to set.", true, true)
32+
.addOption(OptionType.BOOLEAN, "state", "The state of the specified preference.", true)
33+
);
34+
}
35+
36+
@Override
37+
public void execute(@NotNull SlashCommandInteractionEvent event) {
38+
OptionMapping preferenceMapping = event.getOption("preference");
39+
OptionMapping stateMapping = event.getOption("state");
40+
if (preferenceMapping == null || stateMapping == null) {
41+
Responses.replyMissingArguments(event).queue();
42+
return;
43+
}
44+
Preference preference = Preference.values()[preferenceMapping.getAsInt()];
45+
boolean state = stateMapping.getAsBoolean();
46+
UserPreferenceManager manager = new UserPreferenceManager(Bot.getDataSource());
47+
if (manager.set(event.getUser().getIdLong(), preference, state)) {
48+
Responses.info(event, "Preference Updated", "Successfully set `%s` to `%s`!", preference, state).queue();
49+
} else {
50+
Responses.error(event, "Could not update `%s` to `%s`.", preference, state).queue();
51+
}
52+
}
53+
54+
private @NotNull List<Command.Choice> getPreferenceChoices() {
55+
List<Command.Choice> choices = new ArrayList<>(Preference.values().length);
56+
for (Preference p : Preference.values()) {
57+
choices.add(new Command.Choice(p.toString(), p.ordinal()));
58+
}
59+
return choices;
60+
}
61+
62+
@Override
63+
public void handleAutoComplete(@NotNull CommandAutoCompleteInteractionEvent event, @NotNull AutoCompleteQuery target) {
64+
event.replyChoices(AutoCompleteUtils.handleChoices(event, e -> getPreferenceChoices())).queue();
65+
}
66+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package net.javadiscord.javabot.systems.user_preferences.dao;
2+
3+
import net.javadiscord.javabot.data.h2db.DatabaseRepository;
4+
import net.javadiscord.javabot.data.h2db.TableProperty;
5+
import net.javadiscord.javabot.systems.user_preferences.model.Preference;
6+
import net.javadiscord.javabot.systems.user_preferences.model.UserPreference;
7+
import org.h2.api.H2Type;
8+
import org.jetbrains.annotations.NotNull;
9+
10+
import java.sql.Connection;
11+
import java.sql.SQLException;
12+
import java.util.List;
13+
import java.util.Optional;
14+
15+
/**
16+
* Dao class that represents the USER_PREFERENCES SQL Table.
17+
*/
18+
public class UserPreferenceRepository extends DatabaseRepository<UserPreference> {
19+
/**
20+
* The constructor of this {@link DatabaseRepository} class which defines all important information
21+
* about the USER_PREFERENCES database table.
22+
*
23+
* @param con The {@link Connection} to use.
24+
*/
25+
public UserPreferenceRepository(Connection con) {
26+
super(con, UserPreference.class, "USER_PREFERENCES", List.of(
27+
TableProperty.of("user_id", H2Type.BIGINT, (x, y) -> x.setUserId((Long) y), UserPreference::getUserId),
28+
TableProperty.of("ordinal", H2Type.INTEGER, (x, y) -> x.setOrdinal((Integer) y), UserPreference::getOrdinal),
29+
TableProperty.of("enabled", H2Type.BOOLEAN, (x, y) -> x.setEnabled((Boolean) y), UserPreference::isEnabled)
30+
));
31+
}
32+
33+
public Optional<UserPreference> getById(long userId, @NotNull Preference preference) throws SQLException {
34+
return querySingle("WHERE user_id = ? AND ordinal = ?", userId, preference.ordinal());
35+
}
36+
37+
public boolean updateState(long userId, @NotNull Preference preference, boolean enabled) throws SQLException {
38+
return update("UPDATE user_preferences SET enabled = ? WHERE user_id = ? AND ordinal = ?", enabled, userId, preference.ordinal()) > 0;
39+
}
40+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package net.javadiscord.javabot.systems.user_preferences.model;
2+
3+
/**
4+
* Contains all preferences users can set.
5+
*/
6+
public enum Preference {
7+
/**
8+
* Enables/Disables QOTW reminders.
9+
*/
10+
QOTW_REMINDER("Question of the Week Reminder");
11+
12+
private final String name;
13+
14+
Preference(String name) {
15+
this.name = name;
16+
}
17+
18+
@Override
19+
public String toString() {
20+
return name;
21+
}
22+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package net.javadiscord.javabot.systems.user_preferences.model;
2+
3+
import lombok.Data;
4+
5+
/**
6+
* Data class which represents a single user preference.
7+
*/
8+
@Data
9+
public class UserPreference {
10+
private long userId;
11+
private int ordinal;
12+
private boolean enabled;
13+
14+
public Preference getPreference() {
15+
return Preference.values()[ordinal];
16+
}
17+
}

src/main/resources/database/schema.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,12 @@ CREATE TABLE message_cache
104104
author_id BIGINT NOT NULL,
105105
message_content VARCHAR(4000) NOT NULL
106106
);
107+
108+
// User Preferences
109+
CREATE TABLE user_preferences
110+
(
111+
user_id BIGINT NOT NULL,
112+
ordinal INTEGER NOT NULL,
113+
enabled BOOLEAN NOT NULL DEFAULT TRUE,
114+
PRIMARY KEY (user_id, ordinal)
115+
)

0 commit comments

Comments
 (0)