20
20
import org .togetherjava .tjbot .db .Database ;
21
21
22
22
import java .time .Instant ;
23
- import java .time .Period ;
23
+ import java .time .ZoneOffset ;
24
+ import java .time .ZonedDateTime ;
25
+ import java .time .format .TextStyle ;
26
+ import java .time .temporal .TemporalAdjusters ;
24
27
import java .util .Collection ;
25
28
import java .util .List ;
29
+ import java .util .Locale ;
26
30
import java .util .Map ;
27
31
import java .util .function .Function ;
28
32
import java .util .function .IntFunction ;
@@ -53,11 +57,11 @@ public final class TopHelpersCommand extends SlashCommandAdapter {
53
57
* @param database the database containing the message counts of top helpers
54
58
*/
55
59
public TopHelpersCommand (@ NotNull Database database ) {
56
- super (COMMAND_NAME , "Lists top helpers for the last 30 days" , SlashCommandVisibility .GUILD );
57
- this .database = database ;
58
-
60
+ super (COMMAND_NAME , "Lists top helpers for the last month" , SlashCommandVisibility .GUILD );
61
+ // TODO Add options to optionally pick a time range once JDA/Discord offers a date-picker
59
62
hasRequiredRole = Pattern .compile (Config .getInstance ().getSoftModerationRolePattern ())
60
63
.asMatchPredicate ();
64
+ this .database = database ;
61
65
}
62
66
63
67
@ Override
@@ -66,11 +70,15 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) {
66
70
return ;
67
71
}
68
72
73
+ TimeRange timeRange = computeDefaultTimeRange ();
69
74
List <TopHelperResult > topHelpers =
70
- computeTopHelpersDescending (event .getGuild ().getIdLong ());
75
+ computeTopHelpersDescending (event .getGuild ().getIdLong (), timeRange );
71
76
72
77
if (topHelpers .isEmpty ()) {
73
- event .reply ("No entries for the selected time range." ).queue ();
78
+ event
79
+ .reply ("No entries for the selected time range (%s)."
80
+ .formatted (timeRange .description ()))
81
+ .queue ();
74
82
return ;
75
83
}
76
84
event .deferReply ().queue ();
@@ -79,7 +87,7 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) {
79
87
event .getGuild ()
80
88
.retrieveMembersByIds (topHelperIds )
81
89
.onError (error -> handleError (error , event ))
82
- .onSuccess (members -> handleTopHelpers (topHelpers , members , event ));
90
+ .onSuccess (members -> handleTopHelpers (topHelpers , members , timeRange , event ));
83
91
}
84
92
85
93
@ SuppressWarnings ("BooleanMethodNameMustStartWithQuestion" )
@@ -93,12 +101,24 @@ private boolean handleHasAuthorRole(@NotNull Member author, @NotNull Interaction
93
101
return false ;
94
102
}
95
103
96
- private @ NotNull List <TopHelperResult > computeTopHelpersDescending (long guildId ) {
104
+ private static @ NotNull TimeRange computeDefaultTimeRange () {
105
+ // Last month
106
+ ZonedDateTime start = Instant .now ()
107
+ .atZone (ZoneOffset .UTC )
108
+ .minusMonths (1 )
109
+ .with (TemporalAdjusters .firstDayOfMonth ());
110
+ ZonedDateTime end = start .with (TemporalAdjusters .lastDayOfMonth ());
111
+ String description = start .getMonth ().getDisplayName (TextStyle .FULL_STANDALONE , Locale .US );
112
+
113
+ return new TimeRange (start .toInstant (), end .toInstant (), description );
114
+ }
115
+
116
+ private @ NotNull List <TopHelperResult > computeTopHelpersDescending (long guildId ,
117
+ @ NotNull TimeRange timeRange ) {
97
118
return database .read (context -> context .select (HELP_CHANNEL_MESSAGES .AUTHOR_ID , DSL .count ())
98
119
.from (HELP_CHANNEL_MESSAGES )
99
120
.where (HELP_CHANNEL_MESSAGES .GUILD_ID .eq (guildId )
100
- .and (HELP_CHANNEL_MESSAGES .SENT_AT
101
- .greaterOrEqual (Instant .now ().minus (Period .ofDays (30 )))))
121
+ .and (HELP_CHANNEL_MESSAGES .SENT_AT .between (timeRange .start (), timeRange .end ())))
102
122
.groupBy (HELP_CHANNEL_MESSAGES .AUTHOR_ID )
103
123
.orderBy (DSL .count ().desc ())
104
124
.limit (TOP_HELPER_LIMIT )
@@ -111,7 +131,8 @@ private static void handleError(@NotNull Throwable error, @NotNull Interaction e
111
131
}
112
132
113
133
private static void handleTopHelpers (@ NotNull Collection <TopHelperResult > topHelpers ,
114
- @ NotNull Collection <? extends Member > members , @ NotNull Interaction event ) {
134
+ @ NotNull Collection <? extends Member > members , @ NotNull TimeRange timeRange ,
135
+ @ NotNull Interaction event ) {
115
136
Map <Long , Member > userIdToMember =
116
137
members .stream ().collect (Collectors .toMap (Member ::getIdLong , Function .identity ()));
117
138
@@ -120,7 +141,8 @@ private static void handleTopHelpers(@NotNull Collection<TopHelperResult> topHel
120
141
userIdToMember .get (topHelper .authorId ())))
121
142
.toList ();
122
143
123
- String message = "```java%n%s%n```" .formatted (dataTableToString (topHelpersDataTable ));
144
+ String message =
145
+ "```java%n%s%n```" .formatted (dataTableToString (topHelpersDataTable , timeRange ));
124
146
125
147
event .getHook ().editOriginal (message ).queue ();
126
148
}
@@ -134,11 +156,14 @@ private static void handleTopHelpers(@NotNull Collection<TopHelperResult> topHel
134
156
return List .of (id , name , messageCount );
135
157
}
136
158
137
- private static @ NotNull String dataTableToString (@ NotNull Collection <List <String >> dataTable ) {
159
+ private static @ NotNull String dataTableToString (@ NotNull Collection <List <String >> dataTable ,
160
+ @ NotNull TimeRange timeRange ) {
138
161
return dataTableToAsciiTable (dataTable ,
139
162
List .of (new ColumnSetting ("Id" , HorizontalAlign .RIGHT ),
140
163
new ColumnSetting ("Name" , HorizontalAlign .RIGHT ),
141
- new ColumnSetting ("Message count (30 days)" , HorizontalAlign .RIGHT )));
164
+ new ColumnSetting (
165
+ "Message count (for %s)" .formatted (timeRange .description ()),
166
+ HorizontalAlign .RIGHT )));
142
167
}
143
168
144
169
private static @ NotNull String dataTableToAsciiTable (
@@ -158,6 +183,9 @@ private static void handleTopHelpers(@NotNull Collection<TopHelperResult> topHel
158
183
return AsciiTable .getTable (AsciiTable .BASIC_ASCII_NO_DATA_SEPARATORS , dataTable , columns );
159
184
}
160
185
186
+ private record TimeRange (Instant start , Instant end , String description ) {
187
+ }
188
+
161
189
private record TopHelperResult (long authorId , int messageCount ) {
162
190
}
163
191
0 commit comments