Skip to content

Commit d9a55c1

Browse files
Merge branch 'develop' into oofs_and_lmaos
2 parents 8fac872 + 6b9f572 commit d9a55c1

File tree

17 files changed

+192
-79
lines changed

17 files changed

+192
-79
lines changed

.github/workflows/code-analysis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ jobs:
7272

7373
# Initializes the CodeQL tools for scanning.
7474
- name: Initialize CodeQL
75-
uses: github/codeql-action/init@v1
75+
uses: github/codeql-action/init@v2
7676
with:
7777
languages: ${{ matrix.language }}
7878
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -83,7 +83,7 @@ jobs:
8383
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
8484
# If this step fails, then you should remove it and run the build manually (see below)
8585
#- name: Autobuild
86-
# uses: github/codeql-action/autobuild@v1
86+
# uses: github/codeql-action/autobuild@v2
8787

8888
# ℹ️ Command-line programs to run using the OS shell.
8989
# 📚 https://git.io/JvXDl
@@ -95,4 +95,4 @@ jobs:
9595
./gradlew build
9696
9797
- name: Perform CodeQL Analysis
98-
uses: github/codeql-action/analyze@v1
98+
uses: github/codeql-action/analyze@v2

application/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
buildscript {
22
dependencies {
3-
classpath 'org.xerial:sqlite-jdbc:3.42.0.0'
3+
classpath 'org.xerial:sqlite-jdbc:3.43.0.0'
44
}
55
}
66

77
plugins {
88
id 'application'
9-
id 'com.google.cloud.tools.jib' version '3.3.0'
9+
id 'com.google.cloud.tools.jib' version '3.4.0'
1010
id 'com.github.johnrengelman.shadow' version '8.1.0'
1111
id 'database-settings'
1212
}
@@ -74,7 +74,7 @@ dependencies {
7474

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

77-
implementation 'org.kohsuke:github-api:1.315'
77+
implementation 'org.kohsuke:github-api:1.316'
7878

7979
testImplementation 'org.mockito:mockito-core:5.3.1'
8080
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.0'

application/config.json.template

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
"databasePath": "local-database.db",
55
"projectWebsite": "https://github.com/Together-Java/TJ-Bot",
66
"discordGuildInvite": "https://discord.com/invite/XXFUXzK",
7-
"modAuditLogChannelPattern": "mod_audit_log",
7+
"modAuditLogChannelPattern": "mod-audit-log",
88
"modMailChannelPattern": "modmail",
99
"mutedRolePattern": "Muted",
1010
"heavyModerationRolePattern": "Moderator",
1111
"softModerationRolePattern": "Moderator|Community Ambassador",
1212
"tagManageRolePattern": "Moderator|Community Ambassador|Top Helpers .+",
1313
"excludeCodeAutoDetectionRolePattern": "Top Helpers .+|Moderator|Community Ambassador|Expert",
1414
"suggestions": {
15-
"channelPattern": "tj_suggestions",
15+
"channelPattern": "tj-suggestions",
1616
"upVoteEmoteName": "peepo_yes",
1717
"downVoteEmoteName": "peepo_no"
1818
},
@@ -89,11 +89,24 @@
8989
"logInfoChannelWebhook": "<put_your_webhook_here>",
9090
"logErrorChannelWebhook": "<put_your_webhook_here>",
9191
"openaiApiKey": "<check pins in #tjbot_discussion for the key>",
92-
"sourceCodeBaseUrl": "<https://github.com/<your_account_here>/<your_repo_here>/blob/master/application/src/main/java/>"
92+
"sourceCodeBaseUrl": "https://github.com/Together-Java/TJ-Bot/blob/master/application/src/main/java/",
9393
"jshell": {
9494
"baseUrl": "<put_jshell_rest_api_url_here>",
9595
"rateLimitWindowSeconds": 10,
9696
"rateLimitRequestsInWindow": 3
97+
},
98+
"helperPruneConfig": {
99+
"roleFullLimit": 100,
100+
"roleFullThreshold": 95,
101+
"pruneMemberAmount": 7,
102+
"inactivateAfterDays": 90,
103+
"recentlyJoinedDays": 4
104+
},
105+
"featureBlacklist": {
106+
"normal": [
107+
],
108+
"special": [
109+
]
97110
}
98111
"starboard": {
99112
"emojiNames" : ["star"],

application/src/main/java/org/togetherjava/tjbot/config/Config.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public final class Config {
4040
private final String sourceCodeBaseUrl;
4141
private final JShellConfig jshell;
4242
private final StarboardConfig starboard;
43+
private final HelperPruneConfig helperPruneConfig;
44+
private final FeatureBlacklistConfig featureBlacklistConfig;
45+
4346

4447
@SuppressWarnings("ConstructorWithTooManyParameters")
4548
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
@@ -78,7 +81,11 @@ private Config(@JsonProperty(value = "token", required = true) String token,
7881
@JsonProperty(value = "openaiApiKey", required = true) String openaiApiKey,
7982
@JsonProperty(value = "sourceCodeBaseUrl", required = true) String sourceCodeBaseUrl,
8083
@JsonProperty(value = "jshell", required = true) JShellConfig jshell,
81-
@JsonProperty(value = "starboard", required = true) StarboardConfig starboard) {
84+
@JsonProperty(value = "starboard", required = true) StarboardConfig starboard,
85+
@JsonProperty(value = "helperPruneConfig",
86+
required = true) HelperPruneConfig helperPruneConfig,
87+
@JsonProperty(value = "featureBlacklist",
88+
required = true) FeatureBlacklistConfig featureBlacklistConfig) {
8289
this.token = Objects.requireNonNull(token);
8390
this.gistApiKey = Objects.requireNonNull(gistApiKey);
8491
this.databasePath = Objects.requireNonNull(databasePath);
@@ -105,6 +112,8 @@ private Config(@JsonProperty(value = "token", required = true) String token,
105112
this.sourceCodeBaseUrl = Objects.requireNonNull(sourceCodeBaseUrl);
106113
this.jshell = Objects.requireNonNull(jshell);
107114
this.starboard = Objects.requireNonNull(starboard);
115+
this.helperPruneConfig = Objects.requireNonNull(helperPruneConfig);
116+
this.featureBlacklistConfig = Objects.requireNonNull(featureBlacklistConfig);
108117
}
109118

110119
/**
@@ -347,12 +356,30 @@ public JShellConfig getJshell() {
347356
}
348357

349358
/**
359+
350360
* Gets the config for the Starboard Contains the List of emoji names recognized by the
351361
* starboard as well as the name of the channel with the starboard.
352362
*
353363
* @return the config of the Starboard
354364
*/
355365
public StarboardConfig getStarboard() {
356366
return starboard;
367+
368+
* Gets the config for automatic pruning of helper roles.
369+
*
370+
* @return the configuration
371+
*/
372+
public HelperPruneConfig getHelperPruneConfig() {
373+
return helperPruneConfig;
374+
}
375+
376+
/**
377+
* The configuration of blacklisted features.
378+
*
379+
* @return configuration of blacklisted features
380+
*/
381+
public FeatureBlacklistConfig getFeatureBlacklistConfig() {
382+
return featureBlacklistConfig;
383+
357384
}
358385
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package org.togetherjava.tjbot.config;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
5+
import java.util.Set;
6+
7+
/**
8+
* Blacklist of features, use {@link FeatureBlacklist#isEnabled(T)} to test if a feature is enabled.
9+
* If a feature is blacklisted, it won't be enabled by the bot, and so will be ignored.
10+
*
11+
* @param <T> the type of the feature identifier
12+
*/
13+
public class FeatureBlacklist<T> {
14+
private final Set<T> featureIdentifierBlacklist;
15+
16+
/**
17+
* Creates a feature blacklist
18+
*
19+
* @param featureIdentifierBlacklist a set of identifiers which are blacklisted
20+
*/
21+
@JsonCreator
22+
public FeatureBlacklist(Set<T> featureIdentifierBlacklist) {
23+
this.featureIdentifierBlacklist = Set.copyOf(featureIdentifierBlacklist);
24+
}
25+
26+
/**
27+
* Returns if a feature is enabled or not.
28+
*
29+
* @param featureId the identifier of the feature
30+
* @return true if a feature is enabled, false otherwise
31+
*/
32+
public boolean isEnabled(T featureId) {
33+
return !featureIdentifierBlacklist.contains(featureId);
34+
}
35+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.togetherjava.tjbot.config;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
import java.util.Objects;
6+
7+
/**
8+
* Configuration of the feature blacklist, any feature present here will be disabled.
9+
*
10+
* @param normal the normal features, which are present in
11+
* {@link org.togetherjava.tjbot.features.Features}
12+
* @param special the special features, which require special code
13+
*/
14+
public record FeatureBlacklistConfig(
15+
@JsonProperty(value = "normal", required = true) FeatureBlacklist<Class<?>> normal,
16+
@JsonProperty(value = "special", required = true) FeatureBlacklist<String> special) {
17+
18+
/**
19+
* Creates a FeatureBlacklistConfig.
20+
*
21+
* @param normal the list of normal features, must be not null
22+
* @param special the list of special features, must be not null
23+
*/
24+
public FeatureBlacklistConfig {
25+
Objects.requireNonNull(normal);
26+
Objects.requireNonNull(special);
27+
}
28+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.togetherjava.tjbot.config;
2+
3+
4+
/**
5+
* Config for automatic pruning of helper roles, see
6+
* {@link org.togetherjava.tjbot.features.help.AutoPruneHelperRoutine}.
7+
*
8+
* @param roleFullLimit if a helper role contains that many users, it is considered full and pruning
9+
* must occur
10+
* @param roleFullThreshold if a helper role contains that many users, pruning will start to occur
11+
* to prevent reaching the limit
12+
* @param pruneMemberAmount amount of users to remove from helper roles during a prune
13+
* @param inactivateAfterDays after how many days of inactivity a user is eligible for pruning
14+
* @param recentlyJoinedDays if a user is with the server for just this amount of days, they are
15+
* protected from pruning
16+
*/
17+
public record HelperPruneConfig(int roleFullLimit, int roleFullThreshold, int pruneMemberAmount,
18+
int inactivateAfterDays, int recentlyJoinedDays) {
19+
}

application/src/main/java/org/togetherjava/tjbot/features/Features.java

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import net.dv8tion.jda.api.JDA;
44

55
import org.togetherjava.tjbot.config.Config;
6+
import org.togetherjava.tjbot.config.FeatureBlacklist;
7+
import org.togetherjava.tjbot.config.FeatureBlacklistConfig;
68
import org.togetherjava.tjbot.db.Database;
79
import org.togetherjava.tjbot.features.basic.PingCommand;
810
import org.togetherjava.tjbot.features.basic.RoleSelectCommand;
@@ -19,32 +21,13 @@
1921
import org.togetherjava.tjbot.features.code.CodeMessageHandler;
2022
import org.togetherjava.tjbot.features.code.CodeMessageManualDetection;
2123
import org.togetherjava.tjbot.features.filesharing.FileSharingMessageListener;
22-
import org.togetherjava.tjbot.features.help.AutoPruneHelperRoutine;
23-
import org.togetherjava.tjbot.features.help.GuildLeaveCloseThreadListener;
24-
import org.togetherjava.tjbot.features.help.HelpSystemHelper;
25-
import org.togetherjava.tjbot.features.help.HelpThreadActivityUpdater;
26-
import org.togetherjava.tjbot.features.help.HelpThreadAutoArchiver;
27-
import org.togetherjava.tjbot.features.help.HelpThreadCommand;
28-
import org.togetherjava.tjbot.features.help.HelpThreadCreatedListener;
29-
import org.togetherjava.tjbot.features.help.HelpThreadMetadataPurger;
24+
import org.togetherjava.tjbot.features.help.*;
3025
import org.togetherjava.tjbot.features.jshell.JShellCommand;
3126
import org.togetherjava.tjbot.features.jshell.JShellEval;
3227
import org.togetherjava.tjbot.features.mathcommands.TeXCommand;
3328
import org.togetherjava.tjbot.features.mathcommands.wolframalpha.WolframAlphaCommand;
3429
import org.togetherjava.tjbot.features.mediaonly.MediaOnlyChannelListener;
35-
import org.togetherjava.tjbot.features.moderation.BanCommand;
36-
import org.togetherjava.tjbot.features.moderation.KickCommand;
37-
import org.togetherjava.tjbot.features.moderation.ModerationActionsStore;
38-
import org.togetherjava.tjbot.features.moderation.MuteCommand;
39-
import org.togetherjava.tjbot.features.moderation.NoteCommand;
40-
import org.togetherjava.tjbot.features.moderation.QuarantineCommand;
41-
import org.togetherjava.tjbot.features.moderation.RejoinModerationRoleListener;
42-
import org.togetherjava.tjbot.features.moderation.ReportCommand;
43-
import org.togetherjava.tjbot.features.moderation.UnbanCommand;
44-
import org.togetherjava.tjbot.features.moderation.UnmuteCommand;
45-
import org.togetherjava.tjbot.features.moderation.UnquarantineCommand;
46-
import org.togetherjava.tjbot.features.moderation.WarnCommand;
47-
import org.togetherjava.tjbot.features.moderation.WhoIsCommand;
30+
import org.togetherjava.tjbot.features.moderation.*;
4831
import org.togetherjava.tjbot.features.moderation.attachment.BlacklistedAttachmentListener;
4932
import org.togetherjava.tjbot.features.moderation.audit.AuditCommand;
5033
import org.togetherjava.tjbot.features.moderation.audit.ModAuditLogRoutine;
@@ -94,14 +77,16 @@ private Features() {
9477
* @return a collection of all features
9578
*/
9679
public static Collection<Feature> createFeatures(JDA jda, Database database, Config config) {
80+
FeatureBlacklistConfig blacklistConfig = config.getFeatureBlacklistConfig();
9781
JShellEval jshellEval = new JShellEval(config.getJshell());
9882

9983
TagSystem tagSystem = new TagSystem(database);
10084
BookmarksSystem bookmarksSystem = new BookmarksSystem(config, database);
10185
ModerationActionsStore actionsStore = new ModerationActionsStore(database);
10286
ModAuditLogWriter modAuditLogWriter = new ModAuditLogWriter(config);
10387
ScamHistoryStore scamHistoryStore = new ScamHistoryStore(database);
104-
CodeMessageHandler codeMessageHandler = new CodeMessageHandler(jshellEval);
88+
CodeMessageHandler codeMessageHandler =
89+
new CodeMessageHandler(blacklistConfig.special(), jshellEval);
10590
ChatGptService chatGptService = new ChatGptService(config);
10691
HelpSystemHelper helpSystemHelper = new HelpSystemHelper(config, database, chatGptService);
10792

@@ -174,6 +159,8 @@ public static Collection<Feature> createFeatures(JDA jda, Database database, Con
174159
features.add(new BookmarksCommand(bookmarksSystem));
175160
features.add(new ChatGptCommand(chatGptService));
176161
features.add(new JShellCommand(jshellEval));
177-
return features;
162+
163+
FeatureBlacklist<Class<?>> blacklist = blacklistConfig.normal();
164+
return features.stream().filter(f -> blacklist.isEnabled(f.getClass())).toList();
178165
}
179166
}

application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptService.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ public class ChatGptService {
2323
private static final Duration TIMEOUT = Duration.ofSeconds(90);
2424
private static final int MAX_TOKENS = 3_000;
2525
private static final String AI_MODEL = "gpt-3.5-turbo";
26+
2627
private boolean isDisabled = false;
27-
private final OpenAiService openAiService;
28+
private OpenAiService openAiService;
2829

2930
/**
3031
* Creates instance of ChatGPTService
@@ -33,8 +34,10 @@ public class ChatGptService {
3334
*/
3435
public ChatGptService(Config config) {
3536
String apiKey = config.getOpenaiApiKey();
36-
if (apiKey.isBlank()) {
37+
boolean keyIsDefaultDescription = apiKey.startsWith("<") && apiKey.endsWith(">");
38+
if (apiKey.isBlank() || keyIsDefaultDescription) {
3739
isDisabled = true;
40+
return;
3841
}
3942

4043
openAiService = new OpenAiService(apiKey, TIMEOUT);

application/src/main/java/org/togetherjava/tjbot/features/code/CodeMessageHandler.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.slf4j.Logger;
1616
import org.slf4j.LoggerFactory;
1717

18+
import org.togetherjava.tjbot.config.FeatureBlacklist;
1819
import org.togetherjava.tjbot.features.MessageReceiverAdapter;
1920
import org.togetherjava.tjbot.features.UserInteractionType;
2021
import org.togetherjava.tjbot.features.UserInteractor;
@@ -30,6 +31,7 @@
3031
import java.util.*;
3132
import java.util.function.Function;
3233
import java.util.stream.Collectors;
34+
import java.util.stream.Stream;
3335

3436
/**
3537
* Handles code in registered messages and offers code actions to the user, such as formatting their
@@ -63,14 +65,18 @@ public final class CodeMessageHandler extends MessageReceiverAdapter implements
6365

6466
/**
6567
* Creates a new instance.
66-
*
68+
*
69+
* @param blacklist the feature blacklist, used to test if certain code actions should be
70+
* disabled
6771
* @param jshellEval used to execute java code and build visual result
6872
*/
69-
public CodeMessageHandler(JShellEval jshellEval) {
73+
public CodeMessageHandler(FeatureBlacklist<String> blacklist, JShellEval jshellEval) {
7074
componentIdInteractor = new ComponentIdInteractor(getInteractionType(), getName());
7175

7276
List<CodeAction> codeActions =
73-
List.of(new FormatCodeCommand(), new EvalCodeCommand(jshellEval));
77+
Stream.of(new FormatCodeCommand(), new EvalCodeCommand(jshellEval))
78+
.filter(a -> blacklist.isEnabled(a.getClass().getSimpleName()))
79+
.toList();
7480

7581
labelToCodeAction = codeActions.stream()
7682
.collect(Collectors.toMap(CodeAction::getLabel, Function.identity(), (x, y) -> y,

0 commit comments

Comments
 (0)