Skip to content

Commit

Permalink
Merge pull request #529 from aternosorg/safe-search
Browse files Browse the repository at this point in the history
make likelihood required to delete safe search images configurable
  • Loading branch information
JulianVennen authored Nov 2, 2022
2 parents 0f5ace9 + c0b49c6 commit 2b3a541
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 22 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "modbot",
"version": "3.0.10",
"version": "3.1.0",
"description": "Discord Bot for the Aternos Discord server",
"main": "index.js",
"type": "module",
Expand Down
2 changes: 1 addition & 1 deletion src/automod/AutoModManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export class AutoModManager {

const guildSettings = await GuildSettings.get(message.guild.id);
const likelihood = await this.#safeSearch.detect(message);
if (!likelihood || likelihood.value < 0) {
if (!likelihood || likelihood.value < (guildSettings.safeSearch.likelihood ?? 1)) {
return false;
}

Expand Down
20 changes: 18 additions & 2 deletions src/commands/settings/SafeSearchCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,37 @@ export default class SafeSearchCommand extends Command {
.setMinValue(0)
.setMaxValue(100)
);
builder.addIntegerOption(strikes => strikes
.setName('likelihood')
.setRequired(false)
.setDescription('Likelihood required to delete an image')
.setChoices({
name: 'possible',
value: 0,
},{
name: 'likely',
value: 1,
}, {
name: 'very likely',
value: 2,
})
);
return super.buildOptions(builder);
}

async execute(interaction) {
const enabled = interaction.options.getBoolean('enabled', true);
const guildSettings = await GuildSettings.get(interaction.guild.id);
const strikes = interaction.options.getInteger('strikes') ?? guildSettings.safeSearch.strikes;
const likelihood = interaction.options.getInteger('likelihood') ?? guildSettings.safeSearch.likelihood;

guildSettings.safeSearch = {enabled, strikes};
guildSettings.safeSearch = {enabled, strikes, likelihood};
await guildSettings.save();

const embed = new LineEmbed();
if (enabled) {
embed.setColor(colors.GREEN)
.addLine(`Images containing adult, violent, medical or racy content ${bold('will be deleted')}.`);
.addLine(`Images ${guildSettings.displayLikelihood()} adult, violent, medical or racy content ${bold('will be deleted')}.`);

if (strikes) {
embed.addLine(`If the detection is ${bold('very likely')} to be correct the user will receive ${bold(strikes + ' strikes')}`);
Expand Down
70 changes: 52 additions & 18 deletions src/settings/GuildSettings.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import Settings from './Settings.js';
import TypeChecker from './TypeChecker.js';
import {channelMention, Collection, EmbedBuilder, roleMention} from 'discord.js';
import {bold, channelMention, Collection, EmbedBuilder, roleMention} from 'discord.js';
import Punishment, {PunishmentAction} from '../database/Punishment.js';
import Zendesk from '../apis/Zendesk.js';
import colors from '../util/colors.js';
import {formatTime, parseTime} from '../util/timeutils.js';
import YouTubePlaylist from '../apis/YouTubePlaylist.js';
import {inlineEmojiIfExists} from '../util/format.js';
import config from '../bot/Config.js';
import {deepMerge} from '../util/util.js';

/**
* @typedef {Object} SafeSearchSettings
* @property {boolean} enabled
* @property {number} strikes
* @property {number} likelihood likelihood required for a message deletion (-3 to 2)
*/

/**
Expand All @@ -34,6 +36,20 @@ export default class GuildSettings extends Settings {
11: Punishment.from(PunishmentAction.BAN),
};

#defaults = {
invites: true,
linkCooldown: parseTime('10s'),
attachmentCooldown: parseTime('10s'),
caps: false,
antiSpam: 10,
similarMessages: 3,
safeSearch: {
enabled: true,
strikes: 1,
likelihood: 1,
},
};

#protectedRoles = [];

/**
Expand All @@ -59,29 +75,36 @@ export default class GuildSettings extends Settings {
*/
constructor(id, json = {}) {
super(id);
json = deepMerge(json, this.#defaults);

for (const setting of [
// logging
'logChannel',
'messageLogChannel',
'joinLogChannel',
// roles
'mutedRole',
// external
'playlist',
'helpcenter',
// automod
'invites',
'linkCooldown',
'attachmentCooldown',
'caps',
'antiSpam',
'similarMessages',
'safeSearch',
]) {
this[setting] = json[setting];
}

this.logChannel = json.logChannel;
this.messageLogChannel = json.messageLogChannel;
this.joinLogChannel = json.joinLogChannel;

this.mutedRole = json.mutedRole;
if (json.protectedRoles instanceof Array)
this.#protectedRoles = json.protectedRoles;
if (json.modRoles instanceof Array)
this.#protectedRoles.push(...json.modRoles);

this.#punishments = json.punishments ?? this.#punishments;

this.playlist = json.playlist;
this.helpcenter = json.helpcenter;

this.invites = json.invites ?? true;
this.linkCooldown = json.linkCooldown ?? parseTime('10s');
this.attachmentCooldown = json.attachmentCooldown ?? parseTime('10s');
this.caps = json.caps ?? false;
this.antiSpam = json.antiSpam ?? 10;
this.similarMessages = json.similarMessages ?? 3;
this.safeSearch = json.safeSearch ?? {enabled: true, strikes: 1};
}

/**
Expand Down Expand Up @@ -184,7 +207,7 @@ export default class GuildSettings extends Settings {

if (this.isFeatureWhitelisted) {
if (this.safeSearch.enabled) {
lines.push(`Safe search: enabled (${this.safeSearch.strikes} strikes)`);
lines.push(`Safe search: enabled for images ${this.displayLikelihood()} nsfw content (${this.safeSearch.strikes} strikes)`);
}
else {
lines.push('Safe search: disabled');
Expand All @@ -194,6 +217,17 @@ export default class GuildSettings extends Settings {
return lines.join('\n');
}

displayLikelihood() {
switch (this.safeSearch.likelihood) {
case 0:
return `${bold('possibly')} containing`;
case 1:
return `${bold('likely')} to contain`;
case 2:
return `${bold('very likely')} to contain`;
}
}

/**
* is this guild in the feature whitelist
* @return {boolean}
Expand Down
20 changes: 20 additions & 0 deletions src/util/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,24 @@ export function inLimits(value, min, max) {
}

return Math.min(Math.max(value, min), max);
}

/**
* deep merge two objects
* @param {Object} target
* @param {Object} source
* @return {Object}
*/
export function deepMerge(target, source) {
for (const key in source) {
switch (typeof target[key]) {
case 'undefined':
target[key] = source[key];
break;
case 'object':
target[key] = deepMerge(target[key], source[key]);
break;
}
}
return target;
}

0 comments on commit 2b3a541

Please sign in to comment.