Browse Source

Fix instance binding; add proper documentation

ghorsington 5 năm trước cách đây
mục cha
commit
325e6864f9

+ 2 - 1
bot/package.json

@@ -22,7 +22,8 @@
    "author": "Geoffrey Horsington <geoffrey.hoooooorse@gmail.com>",
    "license": "MIT",
    "_moduleAliases": {
-      "@db": "../db/lib/src"
+      "@db": "../db/lib/src",
+      "src": "./build"
    },
    "dependencies": {
       "@google-cloud/translate": "^4.1.1",

+ 3 - 3
bot/src/commands/contest.ts

@@ -67,7 +67,7 @@ function numberToOrdered(num: number) {
 }
 
 @CommandSet
-export class ContestCommands {
+/*export*/ class ContestCommands {
 
     activeContests: Dict<ActiveContest> = {};
 
@@ -147,7 +147,7 @@ export class ContestCommands {
         if (contest.endDate < new Date()) {
             await this.stopContest(contest.id);
         } else {
-            scheduleJob(contest.endDate, this.stopContest.bind(null, contest.id));
+            scheduleJob(contest.endDate, this.stopContest.bind(this, contest.id));
             this.activeContests[channel.id] = {
                 id: contest.id,
                 voteReaction: contest.voteReaction
@@ -333,7 +333,7 @@ export class ContestCommands {
         await repo.save(contest);
         await msg.channel.send(`${msg.author.toString()} Started contest (ID: ${contest.id})`);
 
-        scheduleJob(contest.endDate, this.stopContest.bind(null, contest.id));
+        scheduleJob(contest.endDate, this.stopContest.bind(this, contest.id));
         this.activeContests[contest.channel] = {
             id: contest.id,
             voteReaction: contest.voteReaction

+ 2 - 2
bot/src/commands/facemorph.ts

@@ -32,7 +32,7 @@ export class Facemorph {
         );
     }
 
-    async morphFaces(faces: cv.Rect[], data: Buffer) {
+    morphFaces = async (faces: cv.Rect[], data: Buffer) => {
         let padoru = Math.random() <= this.getPadoruChance();
         let jimpImage = await Jimp.read(data);
         let emojiKeys = [
@@ -76,7 +76,7 @@ export class Facemorph {
         return caption[0];
     }
 
-    async captionFace(faces: cv.Rect[], data: Buffer) {
+    captionFace = async (faces: cv.Rect[], data: Buffer) => {
         let padoru = Math.random() <= this.getPadoruChance();
         let face = faces[Math.floor(Math.random() * faces.length)];
         let squaredFace = await face.toSquareAsync();

+ 3 - 3
bot/src/commands/forums_news_checker.ts

@@ -44,7 +44,7 @@ export class ForumsNewsChecker {
         return this.turndown.turndown(html).trim();//.replace(/( {2}\n|\n\n){2,}/gm, "\n");
     }
 
-    async checkFeeds() {
+    checkFeeds = async () => {
         console.log(`Checking feeds on ${new Date().toISOString()}`);
         let forumsNewsRepo = getRepository(PostedForumNewsItem);
         let postVerifyMessageRepo = getRepository(PostVerifyMessage);
@@ -164,7 +164,7 @@ export class ForumsNewsChecker {
         await forumsNewsRepo.save(item);
     }
 
-    async collectReaction(reaction: MessageReaction, collector: Collector<string, MessageReaction>) {
+    collectReaction = async (reaction: MessageReaction, collector: Collector<string, MessageReaction>) => {
         let verifyMessageRepo = getRepository(PostVerifyMessage);
         let postRepo = getRepository(PostedForumNewsItem);
 
@@ -204,7 +204,7 @@ export class ForumsNewsChecker {
         await newsPostRepo.save(item);
     }
 
-    isVerifyReaction(reaction: MessageReaction, user: User) {
+    isVerifyReaction = (reaction: MessageReaction, user: User) => {
         return (reaction.emoji.name == "✅" || reaction.emoji.name == "❌") && !user.bot;
     }
 

+ 11 - 5
bot/src/commands/guide.ts

@@ -80,7 +80,10 @@ export class GuideCommands {
     @Command({
         pattern: /^make (\w+)\s+name:(.+)\s*keywords:(.+)\s*contents:((.*[\n\r]*)+)$/i,
         auth: true,
-        documentation: "Creates a new guide of the specified type, the specified keywords and content."
+        documentation: {
+            description: "Creates a new guide of the specified type, the specified keywords and content.",
+            example: "make <GUIDE TYPE> <NEWLINE>name: <NAME> <NEWLINE> keywords: <KEYWORDS> <NEWLINE> contents: <CONTENTS>"
+        }
     })
     async makeGuide(msg: Message, content: string, match: RegExpMatchArray) {
         if (!await isAuthorisedAsync(msg.member)) return;
@@ -159,7 +162,10 @@ export class GuideCommands {
     @Command({
         pattern: /^delete (\w+)\s+(.+)$/i,
         auth: true,
-        documentation: "delete <guidetype> <keywords>"
+        documentation: {
+            example: "delete <guidetype> <keywords>",
+            description: "Deletes a guide with the specified keywords"
+        }
     })
     async deleteGuide(msg: Message, content: string, match: RegExpMatchArray) {
         if (!await isAuthorisedAsync(msg.member)) return;
@@ -196,17 +202,17 @@ export class GuideCommands {
         await msg.channel.send(`${msg.author.toString()} No such ${type} with keywords \`${keywords.join(" ")}\`! Did you forget to specify all keywords?`);
     }
 
-    @Command({ pattern: "guides", documentation: "Lists all guides and keywords that trigger them." })
+    @Command({ pattern: "guides", documentation: { description: "Lists all guides and keywords that trigger them.", example: "guides" } })
     async showGuides(msg: Message) {
         await this.listGuides(msg, "guide", "Here are the guides I have:");
     }
 
-    @Command({ pattern: "memes", documentation: "Lists all memes and keywords that trigger them." })
+    @Command({ pattern: "memes", documentation: {description: "Lists all memes and keywords that trigger them.", example: "memes"} })
     async showMemes(msg: Message) {
         await this.listGuides(msg, "meme", "Here are some random memes I have:")
     }
 
-    @Command({ pattern: "misc", documentation: "Lists all additional keywords the bot reacts to." })
+    @Command({ pattern: "misc", documentation: {description: "Lists all additional keywords the bot reacts to.", example: "misc"} })
     async showMisc(msg: Message) {
         await this.listGuides(msg, "misc", "These are some misc stuff I can also do:")
     }

+ 2 - 2
bot/src/commands/help.ts

@@ -14,9 +14,9 @@ export class Help {
 
         for (let doc of getDocumentation()) {
             if (isAuthed && doc.auth)
-                modCommands = `${modCommands}${doc.name}  -  ${doc.doc}\n`;
+                modCommands = `${modCommands}${doc.example}  -  ${doc.doc}\n`;
             else if (!doc.auth)
-                baseCommands = `${baseCommands}${doc.name} - ${doc.doc}\n`;
+                baseCommands = `${baseCommands}${doc.example} - ${doc.doc}\n`;
         }
 
         let message = `Hello! I am NoctBot! My job is to help with C(O)M-related problems!\nPing me with one of the following commands:\n\`\`\`${baseCommands}\`\`\``;

+ 1 - 1
bot/src/commands/inspire.ts

@@ -12,7 +12,7 @@ export class Inspire {
         });
     }
 
-    @Command({ pattern: "inspire me", documentation: "Generates an inspiring quote just for you"})
+    @Command({ pattern: "inspire me", documentation: {description: "Generates an inspiring quote just for you", example: "inspire me"}})
     inspire(msg: Message) {
         this.doInspire(msg);
     }

+ 1 - 1
bot/src/commands/news_aggregator.ts

@@ -42,7 +42,7 @@ export class NewsAggregator {
         });
     }
 
-    async checkFeeds() {
+    checkFeeds = async () => {
         console.log(`Aggregating feeds on ${new Date().toISOString()}`);
 
         let aggregatorJobs = [];

+ 4 - 4
bot/src/commands/quote.ts

@@ -16,7 +16,7 @@ export class QuoteCommand {
         return result;
     }
 
-    @Command({ pattern: "add quote", auth: true, documentation: "Adds a quote" })
+    @Command({ pattern: "add quote", auth: true, documentation: {description: "Adds a quote", example: "add quote by \"<NAME>\" <NEWLINE> <QUOTE>"} })
     async addQuote(msg: Message, c: string) {
         if (!isAuthorisedAsync(msg.member))
             return;
@@ -39,7 +39,7 @@ export class QuoteCommand {
         msg.channel.send(`${msg.author.toString()} Added quote (ID: ${newQuote.id})!`);
     }
 
-    @Command({ pattern: "random quote", documentation: "Shows a random quote by someone special..." })
+    @Command({ pattern: "random quote", documentation: {description: "Shows a random quote by someone special...", example: "random quote"} })
     async postRandomQuote(msg: Message) {
         let repo = getRepository(Quote);
 
@@ -57,7 +57,7 @@ export class QuoteCommand {
         msg.channel.send(`Quote #${quote.id}:\n*"${quote.message}"*\n- ${quote.author}`);
     }
 
-    @Command({ pattern: "remove quote", auth: true, documentation: "Removes quote. Use \"quotes\" to get the <quote_index>!" })
+    @Command({ pattern: "remove quote", auth: true, documentation: {description: "Removes quote. Use \"quotes\" to get the <quote_index>!", example: "remove quote <quote_index>"} })
     async removeQuote(msg: Message, c: string) {
         let quoteNum = c.substring("remove quote".length).trim();
         let val = parseInt(quoteNum);
@@ -73,7 +73,7 @@ export class QuoteCommand {
         msg.channel.send(`${msg.author.toString()} Removed quote #${val}!`);
     }
 
-    @Command({ pattern: "quotes", documentation: "Lists all known quotes.", auth: true })
+    @Command({ pattern: "quotes", documentation: {description: "Lists all known quotes.", example: "quotes"}, auth: true })
     async listQuotes(msg: Message) {
         if (!isAuthorisedAsync(msg.member)) {
             msg.channel.send(`${msg.author.toString()} To prevent spamming, only bot moderators can view all quotes!`);

+ 2 - 2
bot/src/commands/rcg.ts

@@ -7,9 +7,9 @@ const rcgRe = /<input id="rcg_image".+value="([^"]+)".*\/>/i;
 @CommandSet
 export class Rcg {
     @Command({
-        pattern: "random comid",
+        pattern: "random comic",
         auth: false,
-        documentation: "Generates a comic just for you!"
+        documentation: {description: "Generates a comic just for you!", example: "random comic"}
     })
     async randomComic(msg: Message) {
         let result = await request("http://explosm.net/rcg/view/?promo=false");

+ 3 - 3
bot/src/commands/react.ts

@@ -28,7 +28,7 @@ async function getRandomEmotes(allowedTypes: ReactionType[], limit: number) {
 @CommandSet
 export class ReactCommands {
 
-    @Command({ pattern: "react to", auth: true, documentation: "React to <message> with <emote>." })
+    @Command({ pattern: "react to", auth: true, documentation: {description: "React to <message> with <emote>.", example: "react to \"<message>\" with <emote>"} })
     async addReaction(msg: Message, s: string) {
         if (!await isAuthorisedAsync(msg.member))
             return;
@@ -55,7 +55,7 @@ export class ReactCommands {
         }
     }
 
-    @Command({ pattern: "remove reaction to", auth: true, documentation: "Stops reacting to <message>." })
+    @Command({ pattern: "remove reaction to", auth: true, documentation: {description: "Stops reacting to <message>.", example: "remove reaction to <message>"} })
     async removeReaction(msg: Message, s: string) {
         if (!await isAuthorisedAsync(msg.member))
             return;
@@ -71,7 +71,7 @@ export class ReactCommands {
         msg.channel.send(`${msg.author.toString()} Removed reaction!`);
     }
 
-    @Command({ pattern: "reactions", documentation: "Lists all known messages this bot can react to." })
+    @Command({ pattern: "reactions", documentation: {description: "Lists all known messages this bot can react to.", example: "reactions"} })
     async listReactions(msg: Message) {
         let reactionsRepo = getRepository(MessageReaction);
 

+ 4 - 8
bot/src/main.ts

@@ -122,7 +122,7 @@ function loadCommand(mod: any) {
         commandSets.push(cmd);
 
         if (cmd._botCommands)
-            botCommands.concat(cmd._botCommands.map(c => ({ ...c, action: c.action.bind(cmd) })));
+            botCommands.push(...cmd._botCommands.map(c => ({ ...c, action: c.action.bind(cmd) })));
 
         if (cmd._botEvents)
             for (let [i, event] of Object.entries(cmd._botEvents)) {
@@ -130,14 +130,15 @@ function loadCommand(mod: any) {
             }
 
         if(cmd.onStart)
-            startActions.push(cmd.onStart);
+            startActions.push(cmd.onStart.bind(cmd));
     }
 }
 
 export function getDocumentation() {
     return botCommands.filter(m => m.documentation !== undefined).map(m => ({
         name: m.pattern.toString(),
-        doc: m.documentation,
+        doc: m.documentation.description,
+        example: m.documentation.example,
         auth: m.auth || false
     }));
 }
@@ -153,11 +154,6 @@ async function main() {
 
     for (const file of files) {
         let ext = path.extname(file);
-        let name = path.basename(file);
-
-        if (name == "command.js")
-            continue;
-
         if (ext != ".js")
             continue;
 

+ 6 - 1
bot/src/model/command.ts

@@ -1,8 +1,13 @@
 import { Message } from "discord.js";
 
+export interface CommandDocumentation {
+    description: string;
+    example: string;
+}
+
 export interface CommandOptions {
     pattern: string | RegExp;
-    documentation?: string;
+    documentation?: CommandDocumentation;
     auth?: boolean;
 };
 

+ 0 - 3
bot/src/util.ts

@@ -1,5 +1,4 @@
 import { GuildMember } from "discord.js";
-import { DocumentationSet } from "./commands/command";
 import { getRepository } from "typeorm";
 import { KnownUser } from "@db/entity/KnownUser";
 
@@ -10,8 +9,6 @@ const VALID_EXTENSIONS = new Set([
     "bmp",
 ]);
 
-export let documentation : DocumentationSet = {};
-
 export function isDevelopment() {
     return process.env.NODE_ENV == "dev";
 }