Skip to content

Commit

Permalink
Add a stats module. Track trick uses
Browse files Browse the repository at this point in the history
  • Loading branch information
Matyrobbrt committed May 30, 2024
1 parent cd7057f commit 7885660
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package net.neoforged.camelot.config.module

import groovy.transform.CompileStatic

/**
* The module tracking different statistics.
*/
@CompileStatic
class Statistics extends ModuleConfiguration {
/**
* Track trick statistics (number of uses, and type).
*/
boolean tricks = true
}
13 changes: 13 additions & 0 deletions src/main/java/net/neoforged/camelot/BotMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import net.neoforged.camelot.configuration.ConfigMigrator;
import net.neoforged.camelot.db.transactionals.LoggingChannelsDAO;
import net.neoforged.camelot.db.transactionals.PendingUnbansDAO;
import net.neoforged.camelot.db.transactionals.StatsDAO;
import net.neoforged.camelot.listener.CountersListener;
import net.neoforged.camelot.listener.DismissListener;
import net.neoforged.camelot.listener.ReferencingListener;
Expand All @@ -29,11 +30,13 @@
import net.neoforged.camelot.log.MessageLogging;
import net.neoforged.camelot.log.ModerationActionRecorder;
import net.neoforged.camelot.module.CamelotModule;
import net.neoforged.camelot.module.StatsModule;
import net.neoforged.camelot.util.AuthUtil;
import net.neoforged.camelot.util.Utils;
import net.neoforged.camelot.util.jda.ButtonManager;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.customizers.ImportCustomizer;
import org.jdbi.v3.core.extension.ExtensionConsumer;
import org.jetbrains.annotations.NotNull;
import org.kohsuke.github.GitHubBuilder;
import org.slf4j.Logger;
Expand Down Expand Up @@ -302,4 +305,14 @@ private static <T> T newInstance(Class<T> type) {
throw new RuntimeException(e);
}
}

/**
* Use the stats extension of the given {@code type}.
*/
public static <T extends StatsDAO> void stats(Class<T> type, ExtensionConsumer<T, RuntimeException> dao) {
var module = getModule(StatsModule.class);
if (module != null) {
module.use(type, dao);
}
}
}
14 changes: 12 additions & 2 deletions src/main/java/net/neoforged/camelot/Database.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class Database {
/**
* Static JDBI main instance. Can be accessed via {@link #main()}.
*/
public static Jdbi main;
private static Jdbi main;

/**
* {@return the static main JDBI instance}
Expand All @@ -54,7 +54,7 @@ public static Jdbi pings() {
return pings;
}

public static Jdbi appeals;
private static Jdbi appeals;

/**
* {@return the static appeals DB JDBI instance}
Expand All @@ -63,6 +63,15 @@ public static Jdbi appeals() {
return appeals;
}

private static Jdbi stats;

/**
* {@return the stats DB JDBI instance}
*/
public static Jdbi stats() {
return stats;
}

/**
* Initialises the databases.
*/
Expand All @@ -83,6 +92,7 @@ static void init() throws IOException {
main = createDatabaseConnection(mainDb, "main");
pings = createDatabaseConnection(dir.resolve("pings.db"), "pings");
appeals = createDatabaseConnection(dir.resolve("appeals.db"), "appeals");
stats = createDatabaseConnection(dir.resolve("stats.db"), "stats");
CustomPingListener.requestRefresh();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import net.neoforged.camelot.db.schemas.SlashTrick;
import net.neoforged.camelot.db.schemas.Trick;
import net.neoforged.camelot.db.transactionals.SlashTricksDAO;
import net.neoforged.camelot.db.transactionals.StatsDAO;
import net.neoforged.camelot.db.transactionals.TricksDAO;
import net.neoforged.camelot.listener.ReferencingListener;
import net.neoforged.camelot.module.TricksModule;
Expand Down Expand Up @@ -440,12 +441,18 @@ protected void execute(SlashCommandEvent event) {

try {
embed.addField("Description", ScriptUtils.getInformation(trick.script()).description(), false);
} catch (CannotRetrieveInformationException ignored) {
} catch (CannotRetrieveInformationException _) {

}

embed.addField("Owner", "<@" + trick.owner() + "> (" + trick.owner() + ")", false);

BotMain.stats(StatsDAO.Tricks.class, extension -> {
final int prefix = extension.getPrefixUses(trick.id());
final int slash = extension.getSlashUses(trick.id());
embed.addField("Stats", "Uses: **" + (prefix + slash) + "** total: **" + prefix + "** prefix, **" + slash + "** slash", false);
});

event.getHook().editOriginalEmbeds(embed.build()).queue();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
import net.dv8tion.jda.api.utils.messages.MessageEditData;
import net.neoforged.camelot.BotMain;
import net.neoforged.camelot.db.schemas.Trick;
import net.neoforged.camelot.db.transactionals.StatsDAO;
import net.neoforged.camelot.script.ScriptContext;
import net.neoforged.camelot.script.ScriptReplier;
import net.neoforged.camelot.script.ScriptUtils;
Expand Down Expand Up @@ -49,6 +51,8 @@ protected RestAction<?> doSend(MessageCreateData createData) {
}, trick.privileged());

ScriptUtils.submitExecution(context, trick.script(), args);

BotMain.stats(StatsDAO.Tricks.class, extension -> extension.incrementSlashUses(trick.id()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package net.neoforged.camelot.db.transactionals;

import org.jdbi.v3.sqlobject.customizer.Bind;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
import org.jdbi.v3.sqlobject.transaction.Transactional;

/**
* Transactionals used to interact with statistics.
*/
public interface StatsDAO {
/**
* Trick statistics
*/
interface Tricks extends Transactional<Tricks>, StatsDAO {
@SqlUpdate("insert into trick_stats (trick, prefix_uses, slash_uses) values(:trick, 1, 0) on conflict(trick) do update set prefix_uses = prefix_uses + 1")
void incrementPrefixUses(@Bind("trick") int trickId);
@SqlUpdate("insert into trick_stats (trick, prefix_uses, slash_uses) values(:trick, 0, 1) on conflict(trick) do update set slash_uses = slash_uses + 1")
void incrementSlashUses(@Bind("trick") int trickId);

default int getPrefixUses(int trickId) {
return getHandle().createQuery("select prefix_uses from trick_stats where trick = ?")
.bind(0, trickId)
.execute((statementSupplier, _) -> statementSupplier.get().getResultSet().getInt("prefix_uses"));
}

default int getSlashUses(int trickId) {
return getHandle().createQuery("select slash_uses from trick_stats where trick = ?")
.bind(0, trickId)
.execute((statementSupplier, _) -> statementSupplier.get().getResultSet().getInt("slash_uses"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import net.neoforged.camelot.Database;
import net.neoforged.camelot.db.schemas.SlashTrick;
import net.neoforged.camelot.db.transactionals.SlashTricksDAO;
import net.neoforged.camelot.db.transactionals.StatsDAO;
import net.neoforged.camelot.module.TricksModule;
import net.neoforged.camelot.script.ScriptContext;
import net.neoforged.camelot.script.ScriptReplier;
Expand Down Expand Up @@ -96,6 +97,8 @@ protected RestAction<?> doSend(MessageCreateData createData) {
}, trick.privileged());

ScriptUtils.submitExecution(context, trick.script(), args);

BotMain.stats(StatsDAO.Tricks.class, extension -> extension.incrementPrefixUses(trick.id()));
}
}
}
30 changes: 30 additions & 0 deletions src/main/java/net/neoforged/camelot/module/StatsModule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package net.neoforged.camelot.module;

import com.google.auto.service.AutoService;
import net.neoforged.camelot.Database;
import net.neoforged.camelot.config.module.Statistics;
import net.neoforged.camelot.db.transactionals.StatsDAO;
import org.jdbi.v3.core.extension.ExtensionConsumer;

/**
* The module used to track statistics.
*/
@AutoService(CamelotModule.class)
public class StatsModule extends CamelotModule.Base<Statistics> {
public StatsModule() {
super(Statistics.class);
}

@Override
public String id() {
return "stats";
}

/**
* Use the extension of the given {@code type}.
*/
public <T extends StatsDAO> void use(Class<T> type, ExtensionConsumer<T, RuntimeException> dao) {
if (type == StatsDAO.Tricks.class && !config().isTricks()) return;
Database.stats().useExtension(type, dao);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction;
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
import net.dv8tion.jda.api.utils.messages.MessageEditData;
import net.neoforged.camelot.BotMain;
import net.neoforged.camelot.db.schemas.SlashTrick;
import net.neoforged.camelot.db.schemas.Trick;
import net.neoforged.camelot.db.transactionals.SlashTricksDAO;
import net.neoforged.camelot.db.transactionals.StatsDAO;
import net.neoforged.camelot.db.transactionals.TricksDAO;
import net.neoforged.camelot.module.TricksModule;
import net.neoforged.camelot.script.option.EnumOptionHandler;
Expand Down Expand Up @@ -142,6 +144,8 @@ protected RestAction<?> doSend(MessageCreateData createData) {
}, trick.privileged());

ScriptUtils.submitExecution(context, trick.script(), options);

BotMain.stats(StatsDAO.Tricks.class, extension -> extension.incrementSlashUses(trick.id()));
}
default -> {}
}
Expand Down
8 changes: 8 additions & 0 deletions src/main/resources/db/stats/V1__trick_stats.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
create table trick_stats
(
-- the trick these stats are associated with
trick integer not null primary key,

prefix_uses integer,
slash_uses integer
) without rowid;

0 comments on commit 7885660

Please sign in to comment.