From 8faffdebc73686328ea6b43dfc0d3c9f2ef9ad23 Mon Sep 17 00:00:00 2001 From: Sayak Mukhopadhyay Date: Tue, 23 Oct 2018 18:06:03 +0530 Subject: [PATCH] Added chart genaration and its themes settings --- package-lock.json | 38 ++--- package.json | 4 +- src/db/interfaces/guild.ts | 9 +- src/db/schemas/guild.ts | 1 + src/modules/discord/client.ts | 4 +- src/modules/discord/commands/chart.ts | 107 ++++++++++++++ src/modules/discord/commands/index.ts | 2 + src/modules/discord/commands/theme.ts | 202 ++++++++++++++++++++++++++ 8 files changed, 338 insertions(+), 29 deletions(-) create mode 100644 src/modules/discord/commands/chart.ts create mode 100644 src/modules/discord/commands/theme.ts diff --git a/package-lock.json b/package-lock.json index aad51aa..591d63a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "bgsbot", - "version": "1.3.0", + "version": "1.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -209,6 +209,12 @@ "@types/node": "*" } }, + "@types/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-GMyw/RJoCOSYqCDLgUnAByorkGY=", + "dev": true + }, "@types/cron": { "version": "1.3.0", "resolved": "http://registry.npmjs.org/@types/cron/-/cron-1.3.0.tgz", @@ -2114,14 +2120,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2136,20 +2140,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -2266,8 +2267,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -2279,7 +2279,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2294,7 +2293,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2302,14 +2300,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -2328,7 +2324,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -2409,8 +2404,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -2422,7 +2416,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -2544,7 +2537,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4590,7 +4582,7 @@ "dependencies": { "eventemitter2": { "version": "0.4.14", - "resolved": "http://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", "dev": true } diff --git a/package.json b/package.json index 9f77732..e8c9f7a 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,13 @@ { "name": "bgsbot", - "version": "1.3.0", + "version": "1.4.0", "license": "Apache-2.0", "scripts": { "start": "gulp scripts && cross-env PORT=4002 pm2 start process.json --env production", "startdev": "cross-env NODE_ENV=development gulp" }, "dependencies": { + "content-disposition": "^0.5.2", "cron": "^1.4.1", "debug": "^4.1.0", "discord.js": "^11.4.2", @@ -17,6 +18,7 @@ "request": "^2.88.0" }, "devDependencies": { + "@types/content-disposition": "^0.5.2", "@types/cron": "^1.3.0", "@types/debug": "0.0.31", "@types/express": "^4.16.0", diff --git a/src/db/interfaces/guild.ts b/src/db/interfaces/guild.ts index 4c78719..7fbb653 100644 --- a/src/db/interfaces/guild.ts +++ b/src/db/interfaces/guild.ts @@ -21,11 +21,12 @@ export interface IGuild { bgs_time: string, sort: string, sort_order: number, + theme: string, admin_roles_id: string[], forbidden_roles_id: string[], created_at: Date, updated_at: Date, - monitor_systems: [{ + monitor_systems: { primary: boolean, system_name: string, system_name_lower: string, @@ -34,12 +35,12 @@ export interface IGuild { y: number, z: number } - }], - monitor_factions: [{ + }[], + monitor_factions: { primary: boolean, faction_name: string, faction_name_lower: string - }], + }[], custom: { set: boolean, requester_user_id: string diff --git a/src/db/schemas/guild.ts b/src/db/schemas/guild.ts index ed338cc..1210c2c 100644 --- a/src/db/schemas/guild.ts +++ b/src/db/schemas/guild.ts @@ -26,6 +26,7 @@ export let guildSchema: Schema = new Schema({ bgs_time: String, sort: String, sort_order: Number, // 1 of increasing and -1 for decreasing and 0 for disable + theme: String, admin_roles_id: [String], forbidden_roles_id: [String], created_at: { diff --git a/src/modules/discord/client.ts b/src/modules/discord/client.ts index 6e86315..f17f7e4 100644 --- a/src/modules/discord/client.ts +++ b/src/modules/discord/client.ts @@ -17,7 +17,7 @@ import * as discord from 'discord.js'; import { DiscordSecrets } from '../../secrets'; import { Responses } from './responseDict'; -import { Hi, Help, MyGuild, BGSRole, AdminRoles, ForbiddenRoles, BGSChannel, MonitorSystems, MonitorFactions, SystemStatus, FactionStatus, BGSReport, Sort } from './commands'; +import { Hi, Help, MyGuild, BGSRole, AdminRoles, ForbiddenRoles, BGSChannel, MonitorSystems, MonitorFactions, SystemStatus, FactionStatus, BGSReport, Sort, Chart, Theme } from './commands'; import { HouseKeeping } from './houseKeeping'; import { HelpSchema } from '../../interfaces/typings'; import App from '../../server'; @@ -109,6 +109,8 @@ export class DiscordClient { this.commandsMap.set("factionstatus", new FactionStatus()); this.commandsMap.set("bgsreport", new BGSReport()); this.commandsMap.set("sort", new Sort()); + this.commandsMap.set("chart", new Chart()); + this.commandsMap.set("theme", new Theme()); } private initiateCustom(): void { diff --git a/src/modules/discord/commands/chart.ts b/src/modules/discord/commands/chart.ts new file mode 100644 index 0000000..adfbdc7 --- /dev/null +++ b/src/modules/discord/commands/chart.ts @@ -0,0 +1,107 @@ +/* + * KodeBlox Copyright 2018 Sayak Mukhopadhyay + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http: //www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as discord from 'discord.js'; +import * as request from 'request'; +import * as contentDisposition from 'content-disposition'; +import App from '../../../server'; +import { Responses } from '../responseDict'; +import { DB } from '../../../db/index'; +import { Access } from './../access'; +import { OptionsWithUrl } from 'request'; + +export class Chart { + db: DB; + constructor() { + this.db = App.db; + } + exec(message: discord.Message, commandArguments: string): void { + let argsArray: string[] = []; + if (commandArguments.length !== 0) { + argsArray = commandArguments.split(" "); + } + if (argsArray.length > 0) { + let command = argsArray[0].toLowerCase(); + if (this[command]) { + this[command](message, argsArray); + } else { + message.channel.send(Responses.getResponse(Responses.NOTACOMMAND)); + } + } else { + message.channel.send(Responses.getResponse(Responses.NOPARAMS)); + } + } + + get(message: discord.Message, argsArray: string[]): void { + Access.has(message.member, [Access.ADMIN, Access.BGS, Access.FORBIDDEN]) + .then(() => { + if (argsArray.length >= 4) { + let systemName: string = argsArray.slice(3).join(" ").toLowerCase(); + let timenow = Date.now(); + + this.db.model.guild.findOne({ guild_id: message.guild.id }) + .then(guild => { + if (guild) { + let theme = 'light'; + if (guild.theme) { + theme = guild.theme; + } + let requestOptions: OptionsWithUrl = { + url: `http://elitebgs.kodeblox.com/chartgenerator/${argsArray[1]}/${argsArray[2]}`, + method: "GET", + qs: { + name: systemName, + timemin: timenow - 10 * 24 * 60 * 60 * 1000, + timemax: timenow, + theme: theme + }, + encoding: null + } + + request(requestOptions, (error, response, body: Buffer) => { + if (!error && response.statusCode == 200) { + let attachment = new discord.Attachment(body, contentDisposition.parse(response.headers['content-disposition']).parameters.filename); + message.channel.send(attachment); + } else { + if (error) { + console.log(error); + } else { + console.log(response.statusMessage); + } + } + }); + } + }) + .catch(err => { + message.channel.send(Responses.getResponse(Responses.FAIL)); + console.log(err); + }); + } + }) + } + + help() { + return [ + 'chart', + 'Generates a chart for the last 7 days', + 'chart get ', + [ + '`@BGSBot chart get systems influence qa\'wakana`', + '`@BGSBot chart get factions state knights of karma`' + ] + ]; + } +} diff --git a/src/modules/discord/commands/index.ts b/src/modules/discord/commands/index.ts index 351d371..052efe8 100644 --- a/src/modules/discord/commands/index.ts +++ b/src/modules/discord/commands/index.ts @@ -27,3 +27,5 @@ export * from './systemStatus'; export * from './factionStatus'; export * from './bgsReport'; export * from './sort'; +export * from './chart'; +export * from './theme'; diff --git a/src/modules/discord/commands/theme.ts b/src/modules/discord/commands/theme.ts new file mode 100644 index 0000000..fceb896 --- /dev/null +++ b/src/modules/discord/commands/theme.ts @@ -0,0 +1,202 @@ +/* + * KodeBlox Copyright 2018 Sayak Mukhopadhyay + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http: //www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as discord from 'discord.js'; +import App from '../../../server'; +import { Responses } from '../responseDict'; +import { DB } from '../../../db/index'; +import { Access } from './../access'; + +export class Theme { + db: DB; + constructor() { + this.db = App.db; + } + exec(message: discord.Message, commandArguments: string): void { + let argsArray: string[] = []; + if (commandArguments.length !== 0) { + argsArray = commandArguments.split(" "); + } + if (argsArray.length > 0) { + let command = argsArray[0].toLowerCase(); + if (this[command]) { + this[command](message, argsArray); + } else { + message.channel.send(Responses.getResponse(Responses.NOTACOMMAND)); + } + } else { + message.channel.send(Responses.getResponse(Responses.NOPARAMS)); + } + } + + set(message: discord.Message, argsArray: string[]) { + Access.has(message.member, [Access.ADMIN, Access.FORBIDDEN]) + .then(() => { + if (argsArray.length === 2) { + let guildId = message.guild.id; + let theme = argsArray[1].toLowerCase(); + + if ((theme === 'light' || theme === 'dark')) { + this.db.model.guild.findOneAndUpdate( + { guild_id: guildId }, + { + updated_at: new Date(), + theme: theme + }) + .then(guild => { + if (guild) { + message.channel.send(Responses.getResponse(Responses.SUCCESS)); + } else { + message.channel.send(Responses.getResponse(Responses.FAIL)) + .then(() => { + message.channel.send("Your guild is not set yet"); + }) + .catch(err => { + console.log(err); + }); + } + }) + .catch(err => { + message.channel.send(Responses.getResponse(Responses.FAIL)); + console.log(err); + }) + } else { + message.channel.send(Responses.getResponse(Responses.FAIL)) + .then(() => { + message.channel.send("Theme name is incorrect."); + }) + .catch(err => { + console.log(err); + }); + } + } else if (argsArray.length > 3) { + message.channel.send(Responses.getResponse(Responses.TOOMANYPARAMS)); + } else { + message.channel.send(Responses.getResponse(Responses.NOPARAMS)); + } + }) + .catch(() => { + message.channel.send(Responses.getResponse(Responses.INSUFFICIENTPERMS)); + }) + } + + remove(message: discord.Message, argsArray: string[]) { + Access.has(message.member, [Access.ADMIN, Access.FORBIDDEN]) + .then(() => { + if (argsArray.length === 1) { + let guildId = message.guild.id; + + this.db.model.guild.findOneAndUpdate( + { guild_id: guildId }, + { + updated_at: new Date(), + $unset: { + theme: 1 + } + }) + .then(guild => { + if (guild) { + message.channel.send(Responses.getResponse(Responses.SUCCESS)); + } else { + message.channel.send(Responses.getResponse(Responses.FAIL)) + .then(() => { + message.channel.send("Your guild is not set yet"); + }) + .catch(err => { + console.log(err); + }); + } + }) + .catch(err => { + message.channel.send(Responses.getResponse(Responses.FAIL)); + console.log(err); + }) + } else { + message.channel.send(Responses.getResponse(Responses.TOOMANYPARAMS)); + } + }) + .catch(() => { + message.channel.send(Responses.getResponse(Responses.INSUFFICIENTPERMS)); + }) + } + + show(message: discord.Message, argsArray: string[]) { + Access.has(message.member, [Access.ADMIN, Access.FORBIDDEN]) + .then(() => { + if (argsArray.length === 1) { + let guildId = message.guild.id; + + this.db.model.guild.findOne({ guild_id: guildId }) + .then(guild => { + if (guild) { + if (guild.theme) { + let embed = new discord.RichEmbed(); + embed.setTitle("Theme"); + embed.setColor([255, 0, 255]); + embed.addField("Theme: ", guild.theme); + embed.setTimestamp(new Date()); + message.channel.send(embed) + .catch(err => { + console.log(err); + }); + } else { + message.channel.send(Responses.getResponse(Responses.FAIL)) + .then(() => { + message.channel.send("You don't have sorting set up"); + }) + .catch(err => { + console.log(err); + }); + } + } else { + message.channel.send(Responses.getResponse(Responses.FAIL)) + .then(() => { + message.channel.send("Your guild is not set yet"); + }) + .catch(err => { + console.log(err); + }); + } + }) + .catch(err => { + message.channel.send(Responses.getResponse(Responses.FAIL)); + console.log(err); + }) + } else if (argsArray.length > 1) { + message.channel.send(Responses.getResponse(Responses.TOOMANYPARAMS)); + } else { + message.channel.send(Responses.getResponse(Responses.NOPARAMS)); + } + }) + .catch(() => { + message.channel.send(Responses.getResponse(Responses.INSUFFICIENTPERMS)); + }) + } + + help() { + return [ + 'theme', + 'Sets, removes or shows your current theme. Used in charts and other areas. Defaults to light', + 'theme ', + [ + '`@BGSBot theme set name dark`', + '`@BGSBot theme set name light`', + '`@BGSBot theme remove`', + '`@BGSBot theme show`' + ] + ]; + } +}