Skip to content

Commit 70fafef

Browse files
committed
chore: spotless fix
1 parent a1e9ab5 commit 70fafef

File tree

1 file changed

+98
-59
lines changed

1 file changed

+98
-59
lines changed

application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadStatsCommand.java

Lines changed: 98 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.jooq.DSLContext;
88
import org.jooq.OrderField;
99
import org.jooq.Record1;
10+
1011
import org.togetherjava.tjbot.db.Database;
1112
import org.togetherjava.tjbot.features.CommandVisibility;
1213
import org.togetherjava.tjbot.features.SlashCommandAdapter;
@@ -20,18 +21,19 @@
2021
import static org.togetherjava.tjbot.db.generated.Tables.HELP_THREADS;
2122

2223
/**
23-
* Implements the '/help-thread-stats' command which provides analytical insights into the
24-
* help forum's activity over a specific duration.
24+
* Implements the '/help-thread-stats' command which provides analytical insights into the help
25+
* forum's activity over a specific duration.
2526
* <p>
2627
* Example usage:
28+
*
2729
* <pre>
2830
* {@code
2931
* /help-thread-stats duration-option: 7 Days
3032
* }
3133
* </pre>
3234
* <p>
33-
* The command aggregates data such as response rates, engagement metrics (messages/helpers),
34-
* tag popularity, and resolution speeds.
35+
* The command aggregates data such as response rates, engagement metrics (messages/helpers), tag
36+
* popularity, and resolution speeds.
3537
*/
3638
public class HelpThreadStatsCommand extends SlashCommandAdapter {
3739
public static final String COMMAND_NAME = "help-thread-stats";
@@ -47,12 +49,13 @@ public class HelpThreadStatsCommand extends SlashCommandAdapter {
4749
public HelpThreadStatsCommand(Database database) {
4850
super(COMMAND_NAME, "Display Help Thread Statistics", CommandVisibility.GUILD);
4951

50-
OptionData durationOption = new OptionData(OptionType.INTEGER, DURATION_OPTION, "The time range for statistics", false)
51-
.addChoice("1 Day", 1)
52-
.addChoice("7 Days", 7)
53-
.addChoice("30 Days", 30)
54-
.addChoice("90 Days", 90)
55-
.addChoice("180 Days", 180);
52+
OptionData durationOption = new OptionData(OptionType.INTEGER, DURATION_OPTION,
53+
"The time range for statistics", false)
54+
.addChoice("1 Day", 1)
55+
.addChoice("7 Days", 7)
56+
.addChoice("30 Days", 30)
57+
.addChoice("90 Days", 90)
58+
.addChoice("180 Days", 180);
5659

5760
getData().addOptions(durationOption);
5861
this.database = database;
@@ -68,105 +71,141 @@ public void onSlashCommand(SlashCommandInteractionEvent event) {
6871
event.deferReply().queue();
6972

7073
database.read(context -> {
71-
var statsRecord = context.select(
72-
count().as("total_created"),
73-
count().filterWhere(HELP_THREADS.TICKET_STATUS.eq(HelpSystemHelper.TicketStatus.ACTIVE.val)).as("open_now"),
74-
count().filterWhere(HELP_THREADS.PARTICIPANTS.eq(1)).as("ghost_count"),
75-
avg(HELP_THREADS.PARTICIPANTS).as("avg_parts"),
76-
avg(HELP_THREADS.MESSAGE_COUNT).as("avg_msgs"),
77-
avg(field("unixepoch({0}) - unixepoch({1})", Double.class, HELP_THREADS.CLOSED_AT, HELP_THREADS.CREATED_AT)).as("avg_sec"),
78-
min(field("unixepoch({0}) - unixepoch({1})", Double.class, HELP_THREADS.CLOSED_AT, HELP_THREADS.CREATED_AT)).as("min_sec"),
79-
max(field("unixepoch({0}) - unixepoch({1})", Double.class, HELP_THREADS.CLOSED_AT, HELP_THREADS.CREATED_AT)).as("max_sec")
80-
)
81-
.from(HELP_THREADS)
82-
.where(HELP_THREADS.CREATED_AT.ge(startDate))
83-
.fetchOne();
74+
var statsRecord = context
75+
.select(count().as("total_created"), count()
76+
.filterWhere(
77+
HELP_THREADS.TICKET_STATUS.eq(HelpSystemHelper.TicketStatus.ACTIVE.val))
78+
.as("open_now"),
79+
count().filterWhere(HELP_THREADS.PARTICIPANTS.eq(1)).as("ghost_count"),
80+
avg(HELP_THREADS.PARTICIPANTS).as("avg_parts"),
81+
avg(HELP_THREADS.MESSAGE_COUNT).as("avg_msgs"),
82+
avg(field("unixepoch({0}) - unixepoch({1})", Double.class,
83+
HELP_THREADS.CLOSED_AT, HELP_THREADS.CREATED_AT))
84+
.as("avg_sec"),
85+
min(field("unixepoch({0}) - unixepoch({1})", Double.class,
86+
HELP_THREADS.CLOSED_AT, HELP_THREADS.CREATED_AT))
87+
.as("min_sec"),
88+
max(field("unixepoch({0}) - unixepoch({1})", Double.class,
89+
HELP_THREADS.CLOSED_AT, HELP_THREADS.CREATED_AT))
90+
.as("max_sec"))
91+
.from(HELP_THREADS)
92+
.where(HELP_THREADS.CREATED_AT.ge(startDate))
93+
.fetchOne();
8494

8595
if (statsRecord == null || statsRecord.get("total_created", Integer.class) == 0) {
86-
event.getHook().editOriginal("No stats available for the last " + days + " days.").queue();
96+
event.getHook()
97+
.editOriginal("No stats available for the last " + days + " days.")
98+
.queue();
8799
return null;
88100
}
89101

90102
int totalCreated = statsRecord.get("total_created", Integer.class);
91103
int openThreads = statsRecord.get("open_now", Integer.class);
92104
long ghostThreads = statsRecord.get("ghost_count", Number.class).longValue();
93105

94-
double rawResRate = totalCreated > 0 ? ((double) (totalCreated - ghostThreads) / totalCreated) * 100 : 0;
106+
double rawResRate =
107+
totalCreated > 0 ? ((double) (totalCreated - ghostThreads) / totalCreated) * 100
108+
: 0;
95109

96110
String highVolumeTag = getTopTag(context, startDate, count().desc());
97-
String highActivityTag = getTopTag(context, startDate, avg(HELP_THREADS.MESSAGE_COUNT).desc());
98-
String lowActivityTag = getTopTag(context, startDate, avg(HELP_THREADS.MESSAGE_COUNT).asc());
111+
String highActivityTag =
112+
getTopTag(context, startDate, avg(HELP_THREADS.MESSAGE_COUNT).desc());
113+
String lowActivityTag =
114+
getTopTag(context, startDate, avg(HELP_THREADS.MESSAGE_COUNT).asc());
99115

100116
String peakHourRange = getPeakHour(context, startDate);
101117

102-
EmbedBuilder embed = new EmbedBuilder()
103-
.setTitle("📊 Help Thread Stats (Last " + days + " Days)")
104-
.setColor(getStatusColor(totalCreated, ghostThreads))
105-
.setTimestamp(Instant.now())
106-
.setDescription("\u200B")
107-
.setFooter("Together Java Community Stats", Objects.requireNonNull(event.getGuild()).getIconUrl());
118+
EmbedBuilder embed =
119+
new EmbedBuilder().setTitle("📊 Help Thread Stats (Last " + days + " Days)")
120+
.setColor(getStatusColor(totalCreated, ghostThreads))
121+
.setTimestamp(Instant.now())
122+
.setDescription("\u200B")
123+
.setFooter("Together Java Community Stats",
124+
Objects.requireNonNull(event.getGuild()).getIconUrl());
108125

109126
embed.addField("📝 THREAD ACTIVITY",
110127
"Created: `%d`\nCurrently Open: `%d`\nResponse Rate: %.1f%%\nPeak Hours: `%s`"
111-
.formatted(totalCreated, openThreads, rawResRate, peakHourRange), false);
128+
.formatted(totalCreated, openThreads, rawResRate, peakHourRange),
129+
false);
112130

113131
embed.addField("💬 ENGAGEMENT",
114132
"Avg Messages: `%s`\nAvg Helpers: `%s`\nUnanswered (Ghost): `%d`".formatted(
115133
formatDouble(Objects.requireNonNull(statsRecord.get("avg_msgs"))),
116134
formatDouble(Objects.requireNonNull(statsRecord.get("avg_parts"))),
117-
ghostThreads), false);
135+
ghostThreads),
136+
false);
118137

119138
embed.addField("🏷️ TAG ACTIVITY",
120-
"Most Used: `%s`\nMost Active: `%s`\nNeeds Love: `%s`".formatted(
121-
highVolumeTag, highActivityTag, lowActivityTag), false);
139+
"Most Used: `%s`\nMost Active: `%s`\nNeeds Love: `%s`".formatted(highVolumeTag,
140+
highActivityTag, lowActivityTag),
141+
false);
122142

123143
embed.addField("⚡ RESOLUTION SPEED",
124144
"Average: `%s`\nFastest: `%s`\nSlowest: `%s`".formatted(
125145
smartFormat(statsRecord.get("avg_sec", Double.class)),
126146
smartFormat(statsRecord.get("min_sec", Double.class)),
127-
smartFormat(statsRecord.get("max_sec", Double.class))), false);
147+
smartFormat(statsRecord.get("max_sec", Double.class))),
148+
false);
128149

129150
event.getHook().editOriginalEmbeds(embed.build()).queue();
130151
return null;
131152
});
132153
}
133154

134155
private static Color getStatusColor(int totalCreated, long ghostThreads) {
135-
double rawResRate = totalCreated > 0 ? ((double) (totalCreated - ghostThreads) / totalCreated) * 100 : -1;
136-
137-
if (rawResRate >= 70) return Color.GREEN;
138-
if (rawResRate >= 30) return Color.YELLOW;
139-
if (rawResRate >= 0) return Color.RED;
156+
double rawResRate =
157+
totalCreated > 0 ? ((double) (totalCreated - ghostThreads) / totalCreated) * 100
158+
: -1;
159+
160+
if (rawResRate >= 70)
161+
return Color.GREEN;
162+
if (rawResRate >= 30)
163+
return Color.YELLOW;
164+
if (rawResRate >= 0)
165+
return Color.RED;
140166
return Color.GRAY;
141167
}
142168

143169
private String getTopTag(DSLContext context, Instant start, OrderField<?> order) {
144-
return context.select(HELP_THREADS.TAGS).from(HELP_THREADS)
145-
.where(HELP_THREADS.CREATED_AT.ge(start)).and(HELP_THREADS.TAGS.ne("none"))
146-
.groupBy(HELP_THREADS.TAGS).orderBy(order).limit(1)
147-
.fetchOptional(HELP_THREADS.TAGS).orElse("N/A");
170+
return context.select(HELP_THREADS.TAGS)
171+
.from(HELP_THREADS)
172+
.where(HELP_THREADS.CREATED_AT.ge(start))
173+
.and(HELP_THREADS.TAGS.ne("none"))
174+
.groupBy(HELP_THREADS.TAGS)
175+
.orderBy(order)
176+
.limit(1)
177+
.fetchOptional(HELP_THREADS.TAGS)
178+
.orElse("N/A");
148179
}
149180

150181
private String getPeakHour(DSLContext context, Instant start) {
151182
return context.select(field("strftime('%H', {0})", String.class, HELP_THREADS.CREATED_AT))
152-
.from(HELP_THREADS).where(HELP_THREADS.CREATED_AT.ge(start))
153-
.groupBy(field("strftime('%H', {0})", String.class, HELP_THREADS.CREATED_AT))
154-
.orderBy(count().desc()).limit(1).fetchOptional(Record1::value1)
155-
.map(hour -> {
156-
int h = Integer.parseInt(hour);
157-
return "%02d:00 - %02d:00 UTC".formatted(h, (h + 1) % 24);
158-
}).orElse("N/A");
183+
.from(HELP_THREADS)
184+
.where(HELP_THREADS.CREATED_AT.ge(start))
185+
.groupBy(field("strftime('%H', {0})", String.class, HELP_THREADS.CREATED_AT))
186+
.orderBy(count().desc())
187+
.limit(1)
188+
.fetchOptional(Record1::value1)
189+
.map(hour -> {
190+
int h = Integer.parseInt(hour);
191+
return "%02d:00 - %02d:00 UTC".formatted(h, (h + 1) % 24);
192+
})
193+
.orElse("N/A");
159194
}
160195

161196
private String smartFormat(Double seconds) {
162-
if (seconds < 0) return "N/A";
163-
if (seconds < 60) return "%.0f secs".formatted(seconds);
164-
if (seconds < 3600) return "%.1f mins".formatted(seconds / 60.0);
165-
if (seconds < 86400) return "%.1f hrs".formatted(seconds / 3600.0);
197+
if (seconds < 0)
198+
return "N/A";
199+
if (seconds < 60)
200+
return "%.0f secs".formatted(seconds);
201+
if (seconds < 3600)
202+
return "%.1f mins".formatted(seconds / 60.0);
203+
if (seconds < 86400)
204+
return "%.1f hrs".formatted(seconds / 3600.0);
166205
return "%.1f days".formatted(seconds / 86400.0);
167206
}
168207

169208
private String formatDouble(Object val) {
170209
return val instanceof Number num ? "%.2f".formatted(num.doubleValue()) : "0.00";
171210
}
172-
}
211+
}

0 commit comments

Comments
 (0)