Skip to content

Commit

Permalink
feat(Moderation): added image support (skyra-project#1019)
Browse files Browse the repository at this point in the history
* feat(Moderation): added image support

* chore(Version): bump to 5.4.1
  • Loading branch information
kyranet authored Jun 4, 2020
1 parent 2b84a70 commit 620236b
Show file tree
Hide file tree
Showing 33 changed files with 200 additions and 137 deletions.
92 changes: 47 additions & 45 deletions database/5.4.0.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,48 @@
import type { CustomCommand } from '@lib/types/settings/GuildSettings';
import type { RawGuildSettings } from '@lib/types/settings/raw/RawGuildSettings';
import type { AnyObject } from '@lib/types/util';
import { Pool, PoolClient } from 'pg';
/**
* import type { CustomCommand } from '@lib/types/settings/GuildSettings';
* import type { RawGuildSettings } from '@lib/types/settings/raw/RawGuildSettings';
* import type { AnyObject } from '@lib/types/util';
* import { Pool, PoolClient } from 'pg';
*
* export default async function main(PGSQL_DATABASE_OPTIONS: any) {
* const pgsql = new Pool(PGSQL_DATABASE_OPTIONS)
* .on('error', console.error);
* const guilds = (await pgsql.query(`SELECT * FROM guilds;`)).rows as RawGuildSettings[];
* await pgsql.query(`ALTER TABLE guilds RENAME COLUMN "tags" TO "custom-commands";`);
*
* const connection = await pgsql.connect();
* await connection.query('BEGIN;');
* await Promise.all(guilds.map(guild => migrateGuild(connection, guild)));
* await connection.query('COMMIT;');
* connection.release();
* await pgsql.end();
* }
*
* async function migrateGuild(connection: PoolClient, guild: RawGuildSettings) {
* const customCommands = (Reflect.get(guild, 'tags') as [string, string][]).map((v): CustomCommand => ({
* id: v[0],
* content: v[1],
* embed: false,
* color: 0,
* args: []
* }));
* if (customCommands.length === 0) return;
*
* await connection.query(`
* UPDATE guilds
* SET "custom-commands" = ${cArrayJson(customCommands)}
* WHERE id = ${cString(guild.id)};
* `);
* }
*
* function cString(value: string) {
* const escaped = value.replace(/'/g, "''");
* return `'${escaped}'`;
* }
*
* function cArrayJson(value: AnyObject[]) {
* return `ARRAY[${value.map(json => cString(JSON.stringify(json)))}]::JSON[]`;
* }
*/

export default async function main(PGSQL_DATABASE_OPTIONS: any) {
const pgsql = new Pool(PGSQL_DATABASE_OPTIONS)
.on('error', console.error);
const guilds = (await pgsql.query(`SELECT * FROM guilds;`)).rows as RawGuildSettings[];
await pgsql.query(`ALTER TABLE guilds RENAME COLUMN "tags" TO "custom-commands";`);

const connection = await pgsql.connect();
await connection.query('BEGIN;');
await Promise.all(guilds.map(guild => migrateGuild(connection, guild)));
await connection.query('COMMIT;');
connection.release();
await pgsql.end();
}

async function migrateGuild(connection: PoolClient, guild: RawGuildSettings) {
const customCommands = (Reflect.get(guild, 'tags') as [string, string][]).map((v): CustomCommand => ({
id: v[0],
content: v[1],
embed: false,
color: 0,
args: []
}));
if (customCommands.length === 0) return;

await connection.query(`
UPDATE guilds
SET "custom-commands" = ${cArrayJson(customCommands)}
WHERE id = ${cString(guild.id)};
`);
}

function cString(value: string) {
const escaped = value.replace(/'/g, "''");
return `'${escaped}'`;
}

function cArrayJson(value: AnyObject[]) {
return `ARRAY[${value.map(json => cString(JSON.stringify(json)))}]::JSON[]`;
}

export const DEPRECATED = false;
export const DEPRECATED = true;
10 changes: 10 additions & 0 deletions database/5.4.1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Pool } from 'pg';

export default async function main(PGSQL_DATABASE_OPTIONS: any) {
const pgsql = new Pool(PGSQL_DATABASE_OPTIONS)
.on('error', console.error);
await pgsql.query(`ALTER TABLE moderation ADD COLUMN image_url VARCHAR(2000);`);
await pgsql.end();
}

export const DEPRECATED = false;
2 changes: 1 addition & 1 deletion database/main.example.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import moduleAlias from 'module-alias';
import { resolve } from 'path';
import migration from './5.4.0';
import migration from './5.4.1';
const PROJECT_ROOT = resolve(__dirname, '..', '..');
moduleAlias.addPath(resolve(PROJECT_ROOT, 'src'));
moduleAlias.addAliases({
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "skyra",
"version": "5.2.3",
"version": "5.4.1",
"description": "Multipurpose Discord Bot built on Klasa",
"main": "dist/Skyra.js",
"scripts": {
Expand Down
7 changes: 4 additions & 3 deletions src/commands/Moderation/Restriction/restrictAttachment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PermissionLevels } from '@lib/types/Enums';
import { GuildSettings } from '@lib/types/settings/GuildSettings';
import { ApplyOptions } from '@skyra/decorators';
import { ModerationSetupRestriction } from '@utils/Security/ModerationActions';
import { ArgumentTypes } from '@utils/util';
import { ArgumentTypes, getImage } from '@utils/util';
import { Role } from 'discord.js';
import { KlasaMessage } from 'klasa';

Expand Down Expand Up @@ -49,8 +49,9 @@ export default class extends ModerationCommand {
return message.guild!.security.actions.restrictAttachment({
user_id: context.target.id,
moderator_id: message.author.id,
duration: context.duration,
reason: context.reason
reason: context.reason,
image_url: getImage(message),
duration: context.duration
}, this.getTargetDM(message, context.target));
}

Expand Down
7 changes: 4 additions & 3 deletions src/commands/Moderation/Restriction/restrictEmbed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PermissionLevels } from '@lib/types/Enums';
import { GuildSettings } from '@lib/types/settings/GuildSettings';
import { ApplyOptions } from '@skyra/decorators';
import { ModerationSetupRestriction } from '@utils/Security/ModerationActions';
import { ArgumentTypes } from '@utils/util';
import { ArgumentTypes, getImage } from '@utils/util';
import { Role } from 'discord.js';
import { KlasaMessage } from 'klasa';

Expand Down Expand Up @@ -49,8 +49,9 @@ export default class extends ModerationCommand {
return message.guild!.security.actions.restrictEmbed({
user_id: context.target.id,
moderator_id: message.author.id,
duration: context.duration,
reason: context.reason
reason: context.reason,
image_url: getImage(message),
duration: context.duration
}, this.getTargetDM(message, context.target));
}

Expand Down
7 changes: 4 additions & 3 deletions src/commands/Moderation/Restriction/restrictReaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PermissionLevels } from '@lib/types/Enums';
import { GuildSettings } from '@lib/types/settings/GuildSettings';
import { ApplyOptions } from '@skyra/decorators';
import { ModerationSetupRestriction } from '@utils/Security/ModerationActions';
import { ArgumentTypes } from '@utils/util';
import { ArgumentTypes, getImage } from '@utils/util';
import { Role } from 'discord.js';
import { KlasaMessage } from 'klasa';

Expand Down Expand Up @@ -49,8 +49,9 @@ export default class extends ModerationCommand {
return message.guild!.security.actions.restrictReaction({
user_id: context.target.id,
moderator_id: message.author.id,
duration: context.duration,
reason: context.reason
reason: context.reason,
image_url: getImage(message),
duration: context.duration
}, this.getTargetDM(message, context.target));
}

Expand Down
7 changes: 4 additions & 3 deletions src/commands/Moderation/Restriction/restrictVoice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PermissionLevels } from '@lib/types/Enums';
import { GuildSettings } from '@lib/types/settings/GuildSettings';
import { ApplyOptions } from '@skyra/decorators';
import { ModerationSetupRestriction } from '@utils/Security/ModerationActions';
import { ArgumentTypes } from '@utils/util';
import { ArgumentTypes, getImage } from '@utils/util';
import { Role } from 'discord.js';
import { KlasaMessage } from 'klasa';

Expand Down Expand Up @@ -49,8 +49,9 @@ export default class extends ModerationCommand {
return message.guild!.security.actions.restrictVoice({
user_id: context.target.id,
moderator_id: message.author.id,
duration: context.duration,
reason: context.reason
reason: context.reason,
image_url: getImage(message),
duration: context.duration
}, this.getTargetDM(message, context.target));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export default class extends ModerationCommand {
return message.guild!.security.actions.unRestrictAttachment({
user_id: context.target.id,
moderator_id: message.author.id,
duration: context.duration,
reason: context.reason
}, this.getTargetDM(message, context.target));
}
Expand Down
1 change: 0 additions & 1 deletion src/commands/Moderation/Restriction/unrestrictEmbed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export default class extends ModerationCommand {
return message.guild!.security.actions.unRestrictEmbed({
user_id: context.target.id,
moderator_id: message.author.id,
duration: context.duration,
reason: context.reason
}, this.getTargetDM(message, context.target));
}
Expand Down
1 change: 0 additions & 1 deletion src/commands/Moderation/Restriction/unrestrictReaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export default class extends ModerationCommand {
return message.guild!.security.actions.unRestrictReaction({
user_id: context.target.id,
moderator_id: message.author.id,
duration: context.duration,
reason: context.reason
}, this.getTargetDM(message, context.target));
}
Expand Down
1 change: 0 additions & 1 deletion src/commands/Moderation/Restriction/unrestrictVoice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export default class extends ModerationCommand {
return message.guild!.security.actions.unRestrictVoice({
user_id: context.target.id,
moderator_id: message.author.id,
duration: context.duration,
reason: context.reason
}, this.getTargetDM(message, context.target));
}
Expand Down
3 changes: 3 additions & 0 deletions src/commands/Moderation/Utilities/reason.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { SkyraCommand, SkyraCommandOptions } from '@lib/structures/SkyraCommand'
import { Events, PermissionLevels } from '@lib/types/Enums';
import { ApplyOptions } from '@skyra/decorators';
import { KlasaMessage } from 'klasa';
import { getImage } from '@utils/util';

@ApplyOptions<SkyraCommandOptions>({
cooldown: 5,
Expand All @@ -26,11 +27,13 @@ export default class extends SkyraCommand {
const entries = await message.guild!.moderation.fetch(cases);
if (!entries.size) throw message.language.tget(cases.length === 1 ? 'MODERATION_CASE_NOT_EXISTS' : 'MODERATION_CASES_NOT_EXIST');

const imageURL = getImage(message);
await this.client.queries.updateModerationLogReasonBulk(message.guild!.id, entries.map(ml => ml.case!), reason);
await message.guild!.moderation.fetchChannelMessages();
for (const entry of entries.values()) {
const clone = entry.clone();
entry.setReason(reason);
if (imageURL) entry.setImageURL(imageURL);
this.client.emit(Events.ModerationEntryEdit, clone, entry);
}

Expand Down
2 changes: 2 additions & 0 deletions src/commands/Moderation/addrole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { PermissionLevels } from '@lib/types/Enums';
import { ApplyOptions } from '@skyra/decorators';
import { Role, User } from 'discord.js';
import { KlasaMessage } from 'klasa';
import { getImage } from '@utils/util';

@ApplyOptions<ModerationCommandOptions>({
aliases: ['ar'],
Expand Down Expand Up @@ -32,6 +33,7 @@ export default class extends ModerationCommand {
user_id: context.target.id,
moderator_id: message.author.id,
reason: context.reason,
image_url: getImage(message),
duration: context.duration
}, context.role, this.getTargetDM(message, context.target));
}
Expand Down
3 changes: 2 additions & 1 deletion src/commands/Moderation/ban.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ModerationCommand, ModerationCommandOptions } from '@lib/structures/Mod
import { GuildSettings } from '@lib/types/settings/GuildSettings';
import { ApplyOptions } from '@skyra/decorators';
import { Moderation } from '@utils/constants';
import { ArgumentTypes } from '@utils/util';
import { ArgumentTypes, getImage } from '@utils/util';
import { KlasaMessage } from 'klasa';

@ApplyOptions<ModerationCommandOptions>({
Expand All @@ -25,6 +25,7 @@ export default class extends ModerationCommand {
user_id: context.target.id,
moderator_id: message.author.id,
duration: context.duration,
image_url: getImage(message),
reason: context.reason
}, this.getDays(message), this.getTargetDM(message, context.target));
}
Expand Down
5 changes: 3 additions & 2 deletions src/commands/Moderation/kick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ModerationCommand, ModerationCommandOptions } from '@lib/structures/Mod
import { GuildSettings } from '@lib/types/settings/GuildSettings';
import { ApplyOptions } from '@skyra/decorators';
import { Moderation } from '@utils/constants';
import { ArgumentTypes } from '@utils/util';
import { ArgumentTypes, getImage } from '@utils/util';

@ApplyOptions<ModerationCommandOptions>({
aliases: ['k'],
Expand All @@ -21,7 +21,8 @@ export default class extends ModerationCommand {
return message.guild!.security.actions.kick({
user_id: context.target.id,
moderator_id: message.author.id,
reason: context.reason
reason: context.reason,
image_url: getImage(message)
}, this.getTargetDM(message, context.target));
}

Expand Down
7 changes: 4 additions & 3 deletions src/commands/Moderation/mute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ModerationCommand, ModerationCommandOptions } from '@lib/structures/Mod
import { PermissionLevels } from '@lib/types/Enums';
import { GuildSettings } from '@lib/types/settings/GuildSettings';
import { ApplyOptions } from '@skyra/decorators';
import { ArgumentTypes } from '@utils/util';
import { ArgumentTypes, getImage } from '@utils/util';
import { Role } from 'discord.js';
import { KlasaMessage } from 'klasa';

Expand Down Expand Up @@ -49,8 +49,9 @@ export default class extends ModerationCommand {
return message.guild!.security.actions.mute({
user_id: context.target.id,
moderator_id: message.author.id,
duration: context.duration,
reason: context.reason
reason: context.reason,
image_url: getImage(message),
duration: context.duration
}, this.getTargetDM(message, context.target));
}

Expand Down
2 changes: 2 additions & 0 deletions src/commands/Moderation/removerole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { PermissionLevels } from '@lib/types/Enums';
import { ApplyOptions } from '@skyra/decorators';
import { Role, User } from 'discord.js';
import { KlasaMessage } from 'klasa';
import { getImage } from '@utils/util';

@ApplyOptions<ModerationCommandOptions>({
aliases: ['rro'],
Expand Down Expand Up @@ -32,6 +33,7 @@ export default class extends ModerationCommand {
user_id: context.target.id,
moderator_id: message.author.id,
reason: context.reason,
image_url: getImage(message),
duration: context.duration
}, context.role, this.getTargetDM(message, context.target));
}
Expand Down
2 changes: 2 additions & 0 deletions src/commands/Moderation/setnickname.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { PermissionLevels } from '@lib/types/Enums';
import { ApplyOptions } from '@skyra/decorators';
import { User } from 'discord.js';
import { KlasaMessage } from 'klasa';
import { getImage } from '@utils/util';

@ApplyOptions<ModerationCommandOptions>({
aliases: ['sn'],
Expand Down Expand Up @@ -36,6 +37,7 @@ export default class extends ModerationCommand {
user_id: context.target.id,
moderator_id: message.author.id,
reason: context.reason,
image_url: getImage(message),
duration: context.duration
}, context.nickname, this.getTargetDM(message, context.target));
}
Expand Down
5 changes: 3 additions & 2 deletions src/commands/Moderation/softban.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ModerationCommand, ModerationCommandOptions } from '@lib/structures/Mod
import { GuildSettings } from '@lib/types/settings/GuildSettings';
import { ApplyOptions } from '@skyra/decorators';
import { Moderation } from '@utils/constants';
import { ArgumentTypes } from '@utils/util';
import { ArgumentTypes, getImage } from '@utils/util';
import { KlasaMessage } from 'klasa';

@ApplyOptions<ModerationCommandOptions>({
Expand All @@ -26,7 +26,8 @@ export default class extends ModerationCommand {
user_id: context.target.id,
moderator_id: message.author.id,
duration: context.duration,
reason: context.reason
reason: context.reason,
image_url: getImage(message)
}, this.getDays(message), this.getTargetDM(message, context.target));
}

Expand Down
Loading

0 comments on commit 620236b

Please sign in to comment.