Skip to content

Commit

Permalink
Add birthdays (#3)
Browse files Browse the repository at this point in the history
* Allow to clear valentines

* Add wip bdays

* Fix duped bdays

* Finish birthdays

* fix prefix
  • Loading branch information
duncte123 authored Aug 22, 2020
1 parent 21122ae commit 284062d
Show file tree
Hide file tree
Showing 10 changed files with 249 additions and 19 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ database.db
!.idea/copyright/profiles_settings.xml
hiro-akiba-8f9a5c0a58a0.json
.env
bday.init.json5
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ repositories {
}

dependencies {
implementation(group = "net.dv8tion", name = "JDA", version = "4.2.0_182")
implementation(group = "net.dv8tion", name = "JDA", version = "4.2.0_195")
implementation(group = "com.jagrosh", name = "jda-utilities-command", version = "3.0.3")

implementation(group = "com.fasterxml.jackson.core", name = "jackson-databind", version = "2.10.1")
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/me/duncte123/hirobot/EventManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package me.duncte123.hirobot;

import com.jagrosh.jdautilities.command.CommandClient;
import me.duncte123.hirobot.database.Database;
import me.duncte123.hirobot.events.FanServerEventHandler;
import net.dv8tion.jda.api.events.GenericEvent;
import net.dv8tion.jda.api.events.guild.GenericGuildEvent;
Expand All @@ -34,9 +35,9 @@ public class EventManager implements IEventManager {

private final EventListener[] fanServerListeners;

public EventManager(CommandClient commandClient, Hiro bot) {
public EventManager(CommandClient commandClient, Hiro bot, Database database) {
fanServerListeners = new EventListener[] {
new FanServerEventHandler(bot),
new FanServerEventHandler(bot, database),
(EventListener) commandClient,
};
}
Expand Down
26 changes: 24 additions & 2 deletions src/main/java/me/duncte123/hirobot/Hiro.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package me.duncte123.hirobot;

import com.fasterxml.jackson.core.type.TypeReference;
import com.jagrosh.jdautilities.command.Command;
import com.jagrosh.jdautilities.command.CommandClient;
import com.jagrosh.jdautilities.command.CommandClientBuilder;
Expand All @@ -26,6 +27,9 @@
import me.duncte123.hirobot.commands.DialogCommand;
import me.duncte123.hirobot.commands.RouteCommand;
import me.duncte123.hirobot.commands.ValentineCommand;
import me.duncte123.hirobot.database.Database;
import me.duncte123.hirobot.database.SQLiteDatabase;
import me.duncte123.hirobot.database.objects.Birthday;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.entities.ChannelType;
Expand All @@ -46,12 +50,17 @@ public class Hiro {
public static final long STANS_ROLE_ID = 670368434017533962L;
public static final long GENERAL_CHANNEL_ID = 670218976932134925L;
public static final long ROLES_CHANNEL_ID = 672361818429325312L;
public static final long DEV_CHANNEL_ID = 677954714825916427L;

private static final Map<String, String> customEnv = new HashMap<>();

public final JDA jda;

private final Database database;

public Hiro() throws LoginException, IOException {
this.database = new SQLiteDatabase();

final CommandClientBuilder builder = new CommandClientBuilder();

ReactionHelpers.load();
Expand All @@ -66,12 +75,12 @@ public Hiro() throws LoginException, IOException {
builder.addCommands(
new CVTCommand(),
new RouteCommand(),
new ValentineCommand(),
new ValentineCommand(database),
new DialogCommand()
);

final CommandClient commandClient = builder.build();
final EventManager eventManager = new EventManager(commandClient, this);
final EventManager eventManager = new EventManager(commandClient, this, database);

this.jda = JDABuilder.create(
GatewayIntent.GUILD_MEMBERS,
Expand All @@ -83,6 +92,8 @@ public Hiro() throws LoginException, IOException {
.setMemberCachePolicy(MemberCachePolicy.NONE)
.disableCache(EnumSet.allOf(CacheFlag.class))
.build();

this.loadBirthdays();
}

// Modified code from CommandClientImpl.java of JDA Utils
Expand Down Expand Up @@ -134,4 +145,15 @@ private static Map<String, String> loadEnvironment() throws IOException {

return env;
}

private void loadBirthdays() throws IOException {
final var bdayInit = new File("bday.init.json5");

// TODO: items are duped on boot, delete file?
if (bdayInit.exists()) {
final List<Birthday> dataArray = ReactionHelpers.MAPPER.readValue(bdayInit, new TypeReference<>() {});

dataArray.forEach(this.database::addBirthday);
}
}
}
27 changes: 18 additions & 9 deletions src/main/java/me/duncte123/hirobot/ReactionHelpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

package me.duncte123.hirobot;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import gnu.trove.map.TLongLongMap;
import gnu.trove.map.hash.TLongLongHashMap;
Expand All @@ -33,6 +33,21 @@
public class ReactionHelpers {
// reaction -> role
private static final TLongLongMap ROLES_MAP = new TLongLongHashMap();
public static final JsonMapper MAPPER;

static {
MAPPER = JsonMapper.builder()
.disable(
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
)
.enable(
JsonReadFeature.ALLOW_TRAILING_COMMA,
JsonReadFeature.ALLOW_JAVA_COMMENTS,
JsonReadFeature.ALLOW_YAML_COMMENTS,
JsonReadFeature.ALLOW_UNQUOTED_FIELD_NAMES
)
.build();
}

/*static {
// Keitaro
Expand Down Expand Up @@ -60,13 +75,7 @@ public class ReactionHelpers {
}*/

public static void load() throws IOException {
final ObjectMapper mapper = new ObjectMapper();

mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.enable(JsonParser.Feature.ALLOW_COMMENTS);
mapper.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES);

final ObjectNode d = mapper.readValue(new File("roles_map.json5"), ObjectNode.class);
final ObjectNode d = (ObjectNode) MAPPER.readTree(new File("roles_map.json5"));

d.fieldNames().forEachRemaining((key) -> {
final long longKey = Long.parseLong(key);
Expand Down
12 changes: 10 additions & 2 deletions src/main/java/me/duncte123/hirobot/commands/ValentineCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import java.util.concurrent.ThreadLocalRandom;

import static me.duncte123.hirobot.Hiro.OWNER_ID;
import static me.duncte123.hirobot.Utils.getUserStaticAvatarUrl;
import static me.duncte123.hirobot.Utils.loadCharactersFromFile;

Expand All @@ -36,19 +37,26 @@ public class ValentineCommand extends Command {

private final Database database;

public ValentineCommand() {
public ValentineCommand(Database database) {
this.name = "valentine";
this.help = "Who from Camp Buddy is your valentine? Find out via this command";
this.cooldown = 20;

this.database = new SQLiteDatabase();
this.database = database;
this.characters = loadCharactersFromFile("valentines.json");
}

@Override
protected void execute(CommandEvent event) {
final Member member = event.getMember();
final long userId = member.getIdLong();

if (!event.getArgs().isEmpty() && "clear".equals(event.getArgs()) && userId == OWNER_ID) {
this.database.clearValentines();
event.reply("Cleared valentines");
return;
}

int valentineIndex = this.database.getValentine(userId);

if (valentineIndex == -1) {
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/me/duncte123/hirobot/database/Database.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@

package me.duncte123.hirobot.database;

import me.duncte123.hirobot.database.objects.Birthday;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.time.LocalDate;

public interface Database {

void setValentine(long userId, int buddyIndex);
Expand All @@ -29,4 +35,10 @@ public interface Database {
*/
int getValentine(long userId);

void clearValentines();

void addBirthday(@Nonnull Birthday birthday);

@Nullable
Birthday getBirthday(LocalDate date);
}
71 changes: 71 additions & 0 deletions src/main/java/me/duncte123/hirobot/database/SQLiteDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import me.duncte123.hirobot.database.objects.Birthday;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.sql.*;
import java.time.LocalDate;
import java.util.concurrent.TimeUnit;

public class SQLiteDatabase implements Database {
Expand Down Expand Up @@ -66,6 +70,12 @@ public SQLiteDatabase() {
"user_id VARCHAR(20) NOT NULL," +
"buddy_index int(2) NOT NULL DEFAULT -1" +
");");
// language=SQLite
statement.execute("CREATE TABLE IF NOT EXISTS birthdays (" +
"id INTEGER PRIMARY KEY AUTOINCREMENT," +
"user_id VARCHAR(20) NOT NULL UNIQUE," +
"date VARCHAR(5) NOT NULL" +
");");

LOGGER.info("Table initialised");
}
Expand Down Expand Up @@ -112,4 +122,65 @@ public int getValentine(long userId) {

return -1;
}

@Override
@SuppressWarnings("SqlWithoutWhere")
public void clearValentines() {
try (final Connection conn = ds.getConnection()) {
try (final Statement smt = conn.createStatement()) {
// language=SQLite
smt.execute("DELETE FROM valentines");
}
} catch (SQLException e) {
e.printStackTrace();
}
}

@Override
public void addBirthday(@NotNull Birthday birthday) {
try (final Connection conn = ds.getConnection()) {
try (final PreparedStatement smt =
// language=SQLite
conn.prepareStatement("INSERT OR IGNORE INTO birthdays (user_id, date) VALUES(? , ?)")) {

final LocalDate date = birthday.getDate();

smt.setLong(1, birthday.getUserId());
smt.setString(2, pre0(date.getMonthValue()) + '-' + pre0(date.getDayOfMonth()));

smt.execute();
}
} catch (SQLException e) {
e.printStackTrace();
}
}

@Nullable
@Override
public Birthday getBirthday(LocalDate date) {
try (final Connection conn = ds.getConnection()) {
try (final PreparedStatement smt =
// language=SQLite
conn.prepareStatement("SELECT * FROM birthdays WHERE date = ?")) {
smt.setString(1, pre0(date.getMonthValue()) + '-' + pre0(date.getDayOfMonth()));

try (final ResultSet resultSet = smt.executeQuery()) {
if (resultSet.next()) {
return new Birthday(
resultSet.getLong("user_id"),
resultSet.getString("date")
);
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}

return null;
}

private String pre0(int in) {
return in < 10 ? "0" + in : String.valueOf(in);
}
}
55 changes: 55 additions & 0 deletions src/main/java/me/duncte123/hirobot/database/objects/Birthday.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Custom bot for the Hiro Akiba fan server on discord
* Copyright (C) 2020 Duncan "duncte123" Sterken
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package me.duncte123.hirobot.database.objects;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import javax.annotation.Nonnull;
import java.time.LocalDate;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Birthday {
private final long userId;
private final LocalDate date;

// day format is day-month
@JsonCreator
public Birthday(@JsonProperty("userId") long userId, @JsonProperty("date") @Nonnull String date) {
this.userId = userId;
this.date = LocalDate.parse("0000-" + date);
}

public long getUserId() {
return userId;
}

public LocalDate getDate() {
return date;
}

@Override
public String toString() {
return "Birthday{" +
"userId=" + userId +
", date=" + date +
'}';
}
}
Loading

0 comments on commit 284062d

Please sign in to comment.