Skip to content

Commit

Permalink
Merge pull request #574 from aternosorg/import-cache
Browse files Browse the repository at this point in the history
update or invalidate caches when importing data, validate roles (Fixes #573)
  • Loading branch information
JulianVennen authored May 23, 2023
2 parents 8acefb2 + e0b0404 commit da3cb9b
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/database/export/Exporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default class Exporter {
dataType = 'modbot-1.0.0';

/**
* @type {GuildSettings}
* @type {GuildSettingsJSON}
*/
guildConfig;

Expand Down
35 changes: 29 additions & 6 deletions src/database/export/ModBotImporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import BadWord from '../BadWord.js';
import Moderation from '../Moderation.js';
import {EmbedBuilder} from 'discord.js';
import GuildWrapper from '../../discord/GuildWrapper.js';
import {asyncFilter} from '../../util/util.js';

export default class ModBotImporter extends Importer {

Expand Down Expand Up @@ -88,13 +89,25 @@ export default class ModBotImporter extends Importer {
}
}

if (!await guildWrapper.fetchRole(this.data.guildConfig.mutedRole)) {
this.data.guildConfig.mutedRole = null;
}
this.data.guildConfig.protectedRoles = await asyncFilter(this.data.guildConfig.protectedRoles, async id => {
return !!await guildWrapper.fetchRole(id);
});

const guildConfig = new GuildSettings(this.guildID, this.data.guildConfig);
return guildConfig.save();
await guildConfig.save();
GuildSettings.getCache().set(this.guildID, guildConfig);
}

async _importChannelConfigs() {
const channels = this.data.channels;
return this.data.channels = await Promise.all(channels.map(c => ChannelSettings.import(this.guildID, c)));
this.data.channels = await Promise.all(channels.map(c => ChannelSettings.import(this.guildID, c)));

for (const channel of this.data.channels) {
ChannelSettings.getCache().set(channel.id, channel);
}
}

_importModerations() {
Expand All @@ -105,14 +118,24 @@ export default class ModBotImporter extends Importer {
}));
}

_importResponses() {
async _importResponses() {
const responses = this.data.responses;
return Promise.all(responses.map(r => (new AutoResponse(this.guildID, r)).save()));
await Promise.all(responses.map(r => (new AutoResponse(this.guildID, r)).save()));
AutoResponse.getGuildCache().delete(this.guildID);
const channelCache = AutoResponse.getChannelCache();
for (const channel of responses.map(r => r.channels).flat()) {
channelCache.delete(channel);
}
}

_importBadWords() {
async _importBadWords() {
const badWords = this.data.badWords;
return Promise.all(badWords.map(b => (new BadWord(this.guildID, b)).save()));
await Promise.all(badWords.map(b => (new BadWord(this.guildID, b)).save()));
BadWord.getGuildCache().delete(this.guildID);
const channelCache = BadWord.getChannelCache();
for (const channel of badWords.map(b => b.channels).flat()) {
channelCache.delete(channel);
}
}

generateEmbed() {
Expand Down
16 changes: 12 additions & 4 deletions src/discord/GuildWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ export default class GuildWrapper {
return await this.guild.members.fetch({user: id, force});
}
catch (e) {
if ([RESTJSONErrorCodes.UnknownMember, RESTJSONErrorCodes.UnknownUser].includes(e.code)) {
if ([
RESTJSONErrorCodes.UnknownMember,
RESTJSONErrorCodes.UnknownUser
].includes(e.code)) {
return null;
}
else {
Expand All @@ -80,7 +83,10 @@ export default class GuildWrapper {
return await this.guild.roles.fetch(id);
}
catch (e) {
if (e.code === RESTJSONErrorCodes.UnknownRole) {
if ([
RESTJSONErrorCodes.UnknownRole,
RESTJSONErrorCodes.MissingAccess,
].includes(e.code)) {
return null;
}
else {
Expand Down Expand Up @@ -118,7 +124,8 @@ export default class GuildWrapper {
return await this.guild.channels.fetch(id);
}
catch (e) {
if ([RESTJSONErrorCodes.UnknownChannel,
if ([
RESTJSONErrorCodes.UnknownChannel,
RESTJSONErrorCodes.MissingAccess,
DiscordjsErrorCodes.GuildChannelUnowned,
].includes(e.code)) {
Expand Down Expand Up @@ -171,7 +178,8 @@ export default class GuildWrapper {
return await channel.send(options);
}
catch (e) {
if ([RESTJSONErrorCodes.MissingPermissions,
if ([
RESTJSONErrorCodes.MissingPermissions,
RESTJSONErrorCodes.MissingAccess,
RESTJSONErrorCodes.UnknownChannel,
].includes(e.code)) {
Expand Down
38 changes: 21 additions & 17 deletions src/settings/GuildSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,26 @@ import {deepMerge} from '../util/util.js';
* @property {number} likelihood likelihood required for a message deletion (-3 to 2)
*/

/**
* @typedef {Object} GuildSettingsJSON
* @property {import('discord.js').Snowflake} [logChannel] id of the log channel
* @property {import('discord.js').Snowflake} [messageLogChannel] id of the message log channel
* @property {import('discord.js').Snowflake} [joinLogChannel] id of the join log channel
* @property {import('discord.js').Snowflake} [mutedRole] id of the muted role
* @property {import('discord.js').Snowflake[]} [modRoles] role ids that can execute commands
* @property {import('discord.js').Snowflake[]} [protectedRoles] role ids that can't be targeted by moderations
* @property {Object} [punishments] automatic punishments for strikes
* @property {String} [playlist] id of YouTube playlist for tutorials
* @property {String} [helpcenter] subdomain of the zendesk help center
* @property {Boolean} [invites] allow invites (can be overwritten per channel)
* @property {Number} [linkCooldown] cooldown on links in s (user based)
* @property {Number} [attachmentCooldown] cooldown on attachments in s (user based)
* @property {Boolean} [caps] should caps be automatically deleted
* @property {Number} [antiSpam] should message spam detection be enabled
* @property {Number} [similarMessages] should similar message detection be enabled
* @property {?SafeSearchSettings} [safeSearch] safe search configuration
*/

/**
* @classdesc settings of a guild
*/
Expand Down Expand Up @@ -54,23 +74,7 @@ export default class GuildSettings extends Settings {

/**
* @param {import('discord.js').Snowflake} id guild id
* @param {Object} [json] options
* @param {import('discord.js').Snowflake} [json.logChannel] id of the log channel
* @param {import('discord.js').Snowflake} [json.messageLogChannel] id of the message log channel
* @param {import('discord.js').Snowflake} [json.joinLogChannel] id of the join log channel
* @param {import('discord.js').Snowflake} [json.mutedRole] id of the muted role
* @param {import('discord.js').Snowflake[]} [json.modRoles] role ids that can execute commands
* @param {import('discord.js').Snowflake[]} [json.protectedRoles] role ids that can't be targeted by moderations
* @param {Object} [json.punishments] automatic punishments for strikes
* @param {String} [json.playlist] id of YouTube playlist for tutorials
* @param {String} [json.helpcenter] subdomain of the zendesk help center
* @param {Boolean} [json.invites] allow invites (can be overwritten per channel)
* @param {Number} [json.linkCooldown] cooldown on links in s (user based)
* @param {Number} [json.attachmentCooldown] cooldown on attachments in s (user based)
* @param {Boolean} [json.caps] should caps be automatically deleted
* @param {Number} [json.antiSpam] should message spam detection be enabled
* @param {Number} [json.similarMessages] should similar message detection be enabled
* @param {?SafeSearchSettings} [json.safeSearch] safe search configuration
* @param {GuildSettingsJSON} [json={}] json object
* @return {GuildSettings}
*/
constructor(id, json = {}) {
Expand Down

0 comments on commit da3cb9b

Please sign in to comment.