Skip to content

Commit

Permalink
feat: role/channel statistics mappings, linting
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobiah committed Jan 20, 2020
1 parent 0dcc038 commit 5c79a0e
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 7 deletions.
2 changes: 1 addition & 1 deletion commands.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/EventHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ class EventHandler {
* @returns {Promise} resolution of handlers execution
*/
async handleEvent(args) {
return Promise.all(this.handlers.filter(handler => handler.event === args.event)
return Promise.all(this.handlers
.filter(handler => handler.event === args.event)
.map(async handler => handler.execute(...args.args)));
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class Genesis {
* @private
*/
this.client = new Client({
fetchAllMembers: false,
fetchAllMembers: true,
ws: {
compress: true,
},
Expand Down Expand Up @@ -192,6 +192,7 @@ class Genesis {
this.client.on('messageDelete', async message => this.eventHandler.handleEvent({ event: 'messageDelete', args: [message] }));
this.client.on('messageDeleteBulk', async messages => this.eventHandler.handleEvent({ event: 'messageDeleteBulk', args: [messages] }));

this.client.on('guildMemberUpdate', async (oldMember, newMember) => this.eventHandler.handleEvent({ event: 'guildMemberUpdate', args: [oldMember, newMember] }));
this.client.on('guildMemberAdd', async guildMember => this.eventHandler.handleEvent({ event: 'guildMemberAdd', args: [guildMember] }));
this.client.on('guildMemberRemove', async guildMember => this.eventHandler.handleEvent({ event: 'guildMemberRemove', args: [guildMember] }));
this.client.on('guildBanAdd', async (guild, user) => this.eventHandler.handleEvent({ event: 'guildBanAdd', args: [guild, user] }));
Expand Down
55 changes: 55 additions & 0 deletions src/commands/Roles/TrackRole.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict';

const Command = require('../../models/Command.js');
const { captures: { channel: cc, role: rc } } = require('../../CommonFunctions');

class TrackRole extends Command {
/**
* Constructs a callable command
* @param {Genesis} bot The bot object
*/
constructor(bot) {
super(bot, 'settings.roles.track', 'r track', 'Track a role in a server', 'UTIL');
this.requiresAuth = true;
this.allowDM = false;
this.regex = new RegExp(`^${this.call} ${cc} ${rc}`, 'i');
this.usages = [
{
description: 'Add a new channel <-> role stats binding',
parameters: ['channel', 'role'],
},
];
}

/**
* Run the command
* @param {Message} message Message with a command to handle, reply to,
* or perform an action based on parameters.
* @returns {string} success status
*/
async run(message) {
const { guild } = message;
const channelId = (message.strippedContent.match(cc) || [])[0]
.replace('<#', '')
.replace('>', '');

if (!channelId) return this.messageManager.statuses.FAILURE;
const channel = guild.channels.get(channelId);
if (!channel) return this.messageManager.statuses.FAILURE;

const roleId = (message.strippedContent.replace(channelId, '')
.match(rc) || [])[0]
.replace('<@&', '')
.replace('>', '');

if (!roleId) return this.messageManager.statuses.FAILURE;
const role = guild.roles.get(roleId);
if (!role) return this.messageManager.statuses.FAILURE;

await this.settings.trackRole(guild, channel, role);
this.messageManager.notifySettingsChange(message, true, true);
return this.messageManager.statuses.SUCCESS;
}
}

module.exports = TrackRole;
48 changes: 48 additions & 0 deletions src/commands/Roles/UntrackRole.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict';


const Command = require('../../models/Command.js');
const { captures: { role: rc } } = require('../../CommonFunctions');

class UntrackRole extends Command {
/**
* Constructs a callable command
* @param {Genesis} bot The bot object
*/
constructor(bot) {
super(bot, 'settings.roles.untrack', 'r untrack', 'Untrack a role in a server', 'UTIL');
this.requiresAuth = true;
this.allowDM = false;
this.regex = new RegExp(`^${this.call} ${rc}`, 'i');
this.usages = [
{
description: 'Remove an existing role channel binding',
parameters: ['channel', 'role'],
},
];
}

/**
* Run the command
* @param {Message} message Message with a command to handle, reply to,
* or perform an action based on parameters.
* @returns {string} success status
*/
async run(message) {
const { guild } = message;

const roleId = (message.strippedContent.match(rc) || [])[0]
.replace('<@&', '')
.replace('>', '');

if (!roleId) return this.messageManager.statuses.FAILURE;
const role = guild.roles.get(roleId);
if (!role) return this.messageManager.statuses.FAILURE;

await this.settings.untrackRole(guild, role);
this.messageManager.notifySettingsChange(message, true, true);
return this.messageManager.statuses.SUCCESS;
}
}

module.exports = UntrackRole;
4 changes: 2 additions & 2 deletions src/commands/Settings/Enable.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict';

const Command = require('../../models/Command.js');
const EnableUsageEmbed = require('../../embeds/EnableUsageEmbed.js');
const EnableInfoEmbed = require('../../embeds/EnableInfoEmbed.js');
const EnableUsageEmbed = require('../../embeds/EnableUsageEmbed');
const EnableInfoEmbed = require('../../embeds/EnableInfoEmbed');
const {
getTarget, getChannels, captures, createGroupedArray,
} = require('../../CommonFunctions.js');
Expand Down
13 changes: 13 additions & 0 deletions src/commands/Settings/Settings.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
'use strict';

const { MessageEmbed } = require('discord.js');

const BaseEmbed = require('../../embeds/BaseEmbed');
const Command = require('../../models/Command.js');
const {
getChannels, setupPages, constructTypeEmbeds, constructItemEmbeds,
Expand Down Expand Up @@ -165,6 +167,17 @@ class Settings extends Command {
.map(obj => `**${obj.command}** ${obj.isAllowed ? 'allowed' : 'denied'} for ${this.evalAppliesTo(obj.type, obj.appliesToId, message)}`).join('\n');
checkAndMergeEmbeds(pages, createChunkedEmbed(guildParts, 'Guild Permissions', '\n'));

const trackedRoles = await this.settings.getTrackedRoles(message.guild);
const trackedRolePage = new BaseEmbed();
trackedRolePage.setTitle('Role Stats Channels');
Object.keys(trackedRoles).forEach((role) => {
trackedRolePage.addField(
message.guild.roles.get(role).name,
message.guild.channels.get(trackedRoles[role]).name,
);
});
pages.push(trackedRolePage);

pages = pages.filter(page => JSON.stringify(page) !== '{}');

if (pages.length) {
Expand Down
4 changes: 2 additions & 2 deletions src/eventHandlers/Ready.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const FeedsNotifier = require('../notifications/FeedsNotifier');
const TwitchNotifier = require('../notifications/TwitchNotifier');
const MessageManager = require('../settings/MessageManager');

const { timeDeltaToMinutesString, fromNow, games, giveawayDefaults } = require('../CommonFunctions');
const { timeDeltaToMinutesString, fromNow, games } = require('../CommonFunctions');

const max = {
cetus: {
Expand Down Expand Up @@ -101,7 +101,7 @@ class OnReadyHandle extends Handler {
embedColor: '#748BD7',
embedColorEnd: '#FF0000',
reaction: '🎉',
}
},
});
this.logger.info('Giveaways initialized!');
}
Expand Down
26 changes: 26 additions & 0 deletions src/eventHandlers/UpdateGuildStatistics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

const { games } = require('../CommonFunctions');

class UpdateGuildStatistics extends require('../models/BaseEventHandler') {
constructor(bot) {
super(bot, 'handlers.statsupdate', 'guildMemberUpdate');
}

async execute(...[, newMember]) {
if (!games.includes('UTIL')) return;
this.logger.debug(`Running ${this.id} for ${this.event}. Params: ${newMember.guild}`);

const { guild } = newMember;
const mappedRoles = await this.settings.getTrackedRoles(guild);

guild.roles
.filter(r => Object.keys(mappedRoles).includes(r.id))
.each((role) => {
const channel = guild.channels.get(mappedRoles[role.id]);
channel.setName(`${role.name} :: ${role.members.size}`);
});
}
}

module.exports = UpdateGuildStatistics;
37 changes: 37 additions & 0 deletions src/settings/DatabaseQueries/StatisticsQueries.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict';

const SQL = require('sql-template-strings');

class StatisticsQueries {
constructor(db) {
this.db = db;
}

async trackRole(guild, channel, role) {
return this.db.query(SQL`
INSERT IGNORE INTO role_stats
(guild_id, channel_id, role_id)
VALUES (${guild.id}, ${channel.id}, ${role.id})
`);
}

async untrackRole(guild, role) {
return this.db.query(SQL`
DELETE FROM role_stats
WHERE guild_id = ${guild.id}
AND role_id = ${role.id}
`);
}

async getTrackedRoles(guild) {
const q = SQL`SELECT role_id, channel_id FROM role_stats WHERE guild_id = ${guild.id}`;
const map = {};
const res = (await this.db.query(q))[0];
res.forEach(({ role_id: roleId, channel_id: channelId }) => {
map[roleId] = channelId;
});
return map;
}
}

module.exports = StatisticsQueries;

0 comments on commit 5c79a0e

Please sign in to comment.