Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion application/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ dependencies {

implementation 'com.github.ben-manes.caffeine:caffeine:3.1.1'

testImplementation 'org.mockito:mockito-core:4.9.0'
testImplementation 'org.mockito:mockito-core:4.10.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.jetbrains.annotations.NotNull;

import org.togetherjava.tjbot.commands.EventReceiver;

Expand All @@ -25,14 +24,14 @@ public LeftoverBookmarksListener(BookmarksSystem bookmarksSystem) {
}

@Override
public void onGuildMemberRemove(@NotNull GuildMemberRemoveEvent event) {
public void onGuildMemberRemove(GuildMemberRemoveEvent event) {
long userID = event.getUser().getIdLong();

bookmarksSystem.startDeletionPeriodForUser(userID);
}

@Override
public void onGuildMemberJoin(@NotNull GuildMemberJoinEvent event) {
public void onGuildMemberJoin(GuildMemberJoinEvent event) {
long userID = event.getUser().getIdLong();

bookmarksSystem.cancelDeletionPeriodForUser(userID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
import java.io.InputStream;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
* Helper class offering certain methods used by the help system.
Expand All @@ -48,6 +50,11 @@ public final class HelpSystemHelper {

private final Predicate<String> isHelpForumName;
private final String helpForumPattern;
/**
* Compares categories by how common they are, ascending. I.e., the most uncommon or specific
* category comes first.
*/
private final Comparator<ForumTag> byCategoryCommonnessAsc;
private final Set<String> categories;
private final Set<String> threadActivityTagNames;
private final String categoryRoleSuffix;
Expand All @@ -66,9 +73,18 @@ public HelpSystemHelper(Config config, Database database) {
helpForumPattern = helpConfig.getHelpForumPattern();
isHelpForumName = Pattern.compile(helpForumPattern).asMatchPredicate();

categories = new HashSet<>(helpConfig.getCategories());
List<String> categoriesList = helpConfig.getCategories();
categories = new HashSet<>(categoriesList);
categoryRoleSuffix = helpConfig.getCategoryRoleSuffix();

Map<String, Integer> categoryToCommonDesc = IntStream.range(0, categoriesList.size())
.boxed()
.collect(Collectors.toMap(categoriesList::get, Function.identity()));
byCategoryCommonnessAsc = Comparator
.<ForumTag>comparingInt(
tag -> categoryToCommonDesc.getOrDefault(tag.getName(), categories.size()))
.reversed();

threadActivityTagNames = Arrays.stream(ThreadActivity.values())
.map(ThreadActivity::getTagName)
.collect(Collectors.toSet());
Expand Down Expand Up @@ -97,10 +113,6 @@ private RestAction<Message> sendExplanationMessage(GuildMessageChannel threadCha
List<MessageEmbed> embeds = List.of(HelpSystemHelper.embedWith(
"Code is much easier to read if posted with **syntax highlighting** and proper formatting.",
useCodeSyntaxExampleImage ? "attachment://" + CODE_SYNTAX_EXAMPLE_PATH : null),
HelpSystemHelper.embedWith(
"""
If your code is **long**, or you have **multiple files** to share, consider posting it on sites \
like https://pastebin.com/ and share the link instead, that is easier to browse for helpers."""),
HelpSystemHelper.embedWith(
"""
If nobody is calling back, that usually means that your question was **not well asked** and \
Expand Down Expand Up @@ -171,12 +183,12 @@ Optional<ForumTag> getActivityTagOfChannel(ThreadChannel channel) {
return getFirstMatchingTagOfChannel(threadActivityTagNames, channel);
}

private static Optional<ForumTag> getFirstMatchingTagOfChannel(Set<String> tagNamesToMatch,
private Optional<ForumTag> getFirstMatchingTagOfChannel(Set<String> tagNamesToMatch,
ThreadChannel channel) {
return channel.getAppliedTags()
.stream()
.filter(tag -> tagNamesToMatch.contains(tag.getName()))
.findFirst();
.min(byCategoryCommonnessAsc);
}

RestAction<Void> changeChannelCategory(ThreadChannel channel, String category) {
Expand All @@ -187,8 +199,8 @@ RestAction<Void> changeChannelActivity(ThreadChannel channel, ThreadActivity act
return changeMatchingTagOfChannel(activity.getTagName(), threadActivityTagNames, channel);
}

private static RestAction<Void> changeMatchingTagOfChannel(String tagName,
Set<String> tagNamesToMatch, ThreadChannel channel) {
private RestAction<Void> changeMatchingTagOfChannel(String tagName, Set<String> tagNamesToMatch,
ThreadChannel channel) {
List<ForumTag> tags = new ArrayList<>(channel.getAppliedTags());

Optional<ForumTag> currentTag = getFirstMatchingTagOfChannel(tagNamesToMatch, channel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
import net.dv8tion.jda.api.events.channel.ChannelCreateEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.requests.RestAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.togetherjava.tjbot.commands.EventReceiver;

import javax.annotation.Nonnull;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
Expand All @@ -25,6 +27,9 @@
* user.
*/
public final class HelpThreadCreatedListener extends ListenerAdapter implements EventReceiver {
private static final Logger logger = LoggerFactory.getLogger(HelpThreadCreatedListener.class);
private static final ScheduledExecutorService SERVICE = Executors.newScheduledThreadPool(2);

private final HelpSystemHelper helper;
private final Cache<Long, Instant> threadIdToCreatedAtCache = Caffeine.newBuilder()
.maximumSize(1_000)
Expand All @@ -41,7 +46,7 @@ public HelpThreadCreatedListener(HelpSystemHelper helper) {
}

@Override
public void onChannelCreate(@Nonnull ChannelCreateEvent createEvent) {
public void onChannelCreate(ChannelCreateEvent createEvent) {
if (!createEvent.getChannelType().isThread()) {
return;
}
Expand Down Expand Up @@ -69,7 +74,20 @@ private boolean wasThreadAlreadyHandled(long threadChannelId) {
private void handleHelpThreadCreated(ThreadChannel threadChannel) {
helper.writeHelpThreadToDatabase(threadChannel.getOwnerIdLong(), threadChannel);

createMessages(threadChannel).queue();
Runnable createMessages = () -> {
try {
createMessages(threadChannel).queue();
} catch (Exception e) {
logger.error(
"Unknown error while creating messages after help-thread ({}) creation",
threadChannel.getId(), e);
}
};

// The creation is delayed, because otherwise it could be too fast and be executed
// after Discord created the thread, but before Discord send OPs initial message.
// Sending messages at that moment is not allowed.
SERVICE.schedule(createMessages, 5, TimeUnit.SECONDS);
}

private RestAction<Message> createMessages(ThreadChannel threadChannel) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* This package offers all functionality for the help system. For example commands that let users
* ask questions, such as {@link org.togetherjava.tjbot.commands.help.AskCommand}.
* This package offers all functionality for the help system. For example commands that handles the
* actions taken after creating a help thread
* {@link org.togetherjava.tjbot.commands.help.HelpThreadCreatedListener}.
*/
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ plugins {
id 'java'
id "com.diffplug.spotless" version "6.12.0"
id "org.sonarqube" version "3.5.0.2730"
id "name.remal.sonarlint" version "2.0.0"
id "name.remal.sonarlint" version "2.1.0"
}

group 'org.togetherjava'
Expand Down