diff --git a/migrations/20180707152000_create_mutes_table.js b/migrations/20180707152000_create_mutes_table.js new file mode 100644 index 00000000..59da8db6 --- /dev/null +++ b/migrations/20180707152000_create_mutes_table.js @@ -0,0 +1,17 @@ +exports.up = async function(knex) { + if (! await knex.schema.hasTable('mutes')) { + await knex.schema.createTable('mutes', table => { + table.bigInteger('guild_id').unsigned().notNullable(); + table.bigInteger('user_id').unsigned().notNullable(); + table.dateTime('created_at'); + table.dateTime('expires_at'); + + table.primary(['guild_id', 'user_id']); + table.index(['expires_at']); + }); + } +}; + +exports.down = async function(knex) { + await knex.schema.dropTableIfExists('mutes'); +}; diff --git a/src/data/GuildMutes.ts b/src/data/GuildMutes.ts new file mode 100644 index 00000000..ebcb3570 --- /dev/null +++ b/src/data/GuildMutes.ts @@ -0,0 +1,78 @@ +import knex from "../knex"; +import moment from "moment-timezone"; +import Mute from "../models/Mute"; + +export class GuildMutes { + protected guildId: string; + + constructor(guildId) { + this.guildId = guildId; + } + + async getExpiredMutes(): Promise { + const result = await knex("mutes") + .where("guild_id", this.guildId) + .where("expires_at", "<=", "CURDATE()") + .whereNotNull("expires_at") + .select(); + + return result.map(r => new Mute(r)); + } + + async findExistingMuteForUserId(userId: string): Promise { + const result = await knex("mutes") + .where("guild_id", this.guildId) + .where("user_id", userId) + .first(); + + return result.map(r => new Mute(r)); + } + + async addMute(userId, expiryTime) { + const expiresAt = expiryTime + ? moment() + .add(expiryTime, "ms") + .format("YYYY-MM-DD HH:mm:ss") + : null; + + return knex + .insert({ + guild_id: this.guildId, + user_id: userId, + expires_at: expiresAt + }) + .into("mutes"); + } + + async updateExpiryTime(userId, newExpiryTime) { + const expiresAt = newExpiryTime + ? moment() + .add(newExpiryTime, "ms") + .format("YYYY-MM-DD HH:mm:ss") + : null; + + return knex("mutes") + .where("guild_id", this.guildId) + .where("user_id", userId) + .update({ + expires_at: expiresAt + }); + } + + async addOrUpdateMute(userId, expiryTime) { + const existingMute = await this.findExistingMuteForUserId(userId); + + if (existingMute) { + return this.updateExpiryTime(userId, expiryTime); + } else { + return this.addMute(userId, expiryTime); + } + } + + async unmute(userId) { + return knex + .where("guild_id", this.guildId) + .where("user_id", userId) + .delete(); + } +} diff --git a/src/models/Mute.ts b/src/models/Mute.ts new file mode 100644 index 00000000..385bf6f9 --- /dev/null +++ b/src/models/Mute.ts @@ -0,0 +1,8 @@ +import Model from "./Model"; + +export default class Mute extends Model { + public guild_id: string; + public user_id: string; + public created_at: string; + public expires_at: string; +}