Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
255 changes: 0 additions & 255 deletions application/config.json.template

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ public static Collection<Feature> createFeatures(JDA jda, Database database, Con
features.add(new GitHubCommand(githubReference));
features.add(new ModMailCommand(jda, config));
features.add(new HelpThreadCommand(config, helpSystemHelper, metrics));
features.add(new ReportCommand(config));
features.add(new ReportCommand(config, actionsStore));
features.add(new BookmarksCommand(bookmarksSystem));

features.add(new ChatGptCommand(chatGptService, helpSystemHelper,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.togetherjava.tjbot.features.moderation;

import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.IPermissionHolder;
Expand All @@ -25,11 +26,17 @@

import java.awt.Color;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
* Utility class offering helpers revolving around user moderation, such as banning or kicking.
Expand Down Expand Up @@ -273,7 +280,7 @@ static boolean handleHasAuthorPermissions(String actionVerb, Permission permissi
* Creates a message to be displayed as response to a moderation action.
* <p>
* Essentially, it informs others about the action, such as "John banned Bob for playing with
* the fire.".
* the fire".
*
* @param author the author executing the action
* @param action the action that is executed
Expand Down Expand Up @@ -442,4 +449,84 @@ static RestAction<Boolean> sendModActionDm(RestAction<EmbedBuilder> embedBuilder
*/
record TemporaryData(Instant expiresAt, String duration) {
}

/**
* Splits a list of moderation records into discrete pages capped at 10 items each.
*
* @param actions the list of chronological actions against a target
* @return a list of sub-lists where each sub-list contains a maximum of 10 items
*/
public static List<List<ActionRecord>> groupActionsByPages(List<ActionRecord> actions) {
List<List<ActionRecord>> groupedActions = new ArrayList<>();
final int maxPageLength = 10;
Comment thread
Zabuzard marked this conversation as resolved.
Outdated

for (int i = 0; i < actions.size(); i++) {
if (i % maxPageLength == 0) {
groupedActions.add(new ArrayList<>(maxPageLength));
}
groupedActions.getLast().add(actions.get(i));
}

return groupedActions;
}

/**
* Generates a structural text overview outlining the count total of each action type.
*
* @param actions a collection of history records
* @return a formatted markdown description summary

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: The "markdown" word should be capitalized, considering you are referring to the formatting language.

*/
public static String createSummaryMessageDescription(Collection<ActionRecord> actions) {
int actionAmount = actions.size();

String shortSummary = "There are **%s actions** against the user."
.formatted(actionAmount == 0 ? "no" : actionAmount);

if (actionAmount == 0) {
return shortSummary;
}

Map<ModerationAction, Long> actionTypeToCount = actions.stream()
.collect(Collectors.groupingBy(ActionRecord::actionType, Collectors.counting()));

String typeCountSummary = actionTypeToCount.entrySet()
.stream()
.filter(typeAndCount -> typeAndCount.getValue() > 0)
.sorted(Map.Entry.<ModerationAction, Long>comparingByValue().reversed())
.map(typeAndCount -> "- **%s**: %d".formatted(typeAndCount.getKey(),
typeAndCount.getValue()))
.collect(Collectors.joining("\n"));

return shortSummary + "\n" + typeCountSummary;
}

/**
* Converts an action record item asynchronously into a formatted embed data field.
*
* @param action the record data item
* @param jda the active JDA instance used to resolve the moderator's handle
* @return a field representation task mapping out the execution card detail
*/
public static RestAction<MessageEmbed.Field> actionToField(ActionRecord action, JDA jda) {
Comment thread
Zabuzard marked this conversation as resolved.
Outdated
return jda.retrieveUserById(action.authorId())
.map(author -> author == null ? "(unknown user)" : author.getName())
.map(authorText -> {
String expiresAtFormatted = action.actionExpiresAt() == null ? ""
: "\nTemporary action, expires at: " + net.dv8tion.jda.api.utils.TimeUtil
.getDateTimeString(action.actionExpiresAt().atOffset(ZoneOffset.UTC));

String fieldName = "%s by %s".formatted(action.actionType().name(), authorText);
String fieldDescription =
"""
%s
Issued at: %s%s
""".formatted(action.reason(),
net.dv8tion.jda.api.utils.TimeUtil
.getDateTimeString(action.issuedAt().atOffset(ZoneOffset.UTC)),
expiresAtFormatted);

return new MessageEmbed.Field(fieldName, fieldDescription, false);
});
}

}
Loading