From 10e9fc0c020b6f474a71f632f4be8de1b56d449a Mon Sep 17 00:00:00 2001 From: Daniel Odendahl Jr Date: Thu, 8 Mar 2018 22:49:19 +0000 Subject: [PATCH] Face Analyze, Analyze group --- README.md | 14 +++--- Xiao.js | 1 + commands/{other => analyze}/coolness.js | 2 +- commands/analyze/face.js | 44 +++++++++++++++++++ .../gender-guess.js => analyze/gender.js} | 4 +- .../{other => analyze}/severe-toxicity.js | 2 +- commands/{other => analyze}/toxicity.js | 2 +- commands/image-edit/contrast.js | 4 +- commands/image-edit/distort.js | 4 +- commands/image-edit/glitch.js | 4 +- commands/image-edit/greyscale.js | 4 +- commands/image-edit/ifunny.js | 4 +- commands/image-edit/invert.js | 4 +- commands/image-edit/sepia.js | 4 +- commands/image-edit/silhouette.js | 4 +- commands/image-edit/tint.js | 4 +- package.json | 2 +- types/image.js | 2 +- 18 files changed, 88 insertions(+), 21 deletions(-) rename commands/{other => analyze}/coolness.js (98%) create mode 100644 commands/analyze/face.js rename commands/{other/gender-guess.js => analyze/gender.js} (92%) rename commands/{other => analyze}/severe-toxicity.js (98%) rename commands/{other => analyze}/toxicity.js (98%) diff --git a/README.md b/README.md index 80f638d4..60636ccb 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Xiao is a Discord bot coded in JavaScript with 300 commands, she is one of the most feature-filled bots out there, and formerly served over 10,000 servers with a uniquely devoted fanbase. -## Commands (285) +## Commands (286) ### Utility: * **prefix**: Shows or sets the command prefix. @@ -165,6 +165,14 @@ served over 10,000 servers with a uniquely devoted fanbase. * **yu-gi-oh**: Responds with info on a Yu-Gi-Oh! card. * **zodiac-sign**: Responds with the Zodiac Sign for the given month/day. +### Analyzers: + +* **coolness**: Determines a user's coolness. +* **face-analyze**: Determines the age, gender, and race of a face. +* **gender-guess**: Determines the gender of a name. +* **severe-toxicity**: Determines the toxicity of text, but less sensitive to milder language. +* **toxicity**: Determines the toxicity of text. + ### Games: * **akinator**: Think about a real or fictional character, I will try to guess who it is. @@ -316,13 +324,9 @@ served over 10,000 servers with a uniquely devoted fanbase. ### Other: * **cleverbot**: Chat with Cleverbot. -* **coolness**: Determines a user's coolness. -* **gender-guess**: Determines the gender of a name. * **prune**: Deletes up to 99 messages from the current channel. -* **severe-toxicity**: Determines the toxicity of text, but less sensitive to milder language. * **strawpoll**: Generates a Strawpoll with the options you provide. * **timer**: Sets a timer for a certain amount of time. -* **toxicity**: Determines the toxicity of text. ### Roleplay: diff --git a/Xiao.js b/Xiao.js index cd03a021..3a0c8b8f 100644 --- a/Xiao.js +++ b/Xiao.js @@ -23,6 +23,7 @@ client.registry ['single', 'Single Response'], ['events', 'Events'], ['search', 'Search'], + ['analyze', 'Analyzers'], ['games', 'Games'], ['voice', 'Voice Channel'], ['image-edit', 'Image Manipulation'], diff --git a/commands/other/coolness.js b/commands/analyze/coolness.js similarity index 98% rename from commands/other/coolness.js rename to commands/analyze/coolness.js index ea8266e4..a2e0438a 100644 --- a/commands/other/coolness.js +++ b/commands/analyze/coolness.js @@ -4,7 +4,7 @@ module.exports = class CoolnessCommand extends Command { constructor(client) { super(client, { name: 'coolness', - group: 'other', + group: 'analyze', memberName: 'coolness', description: 'Determines a user\'s coolness.', args: [ diff --git a/commands/analyze/face.js b/commands/analyze/face.js new file mode 100644 index 00000000..fcd15c7e --- /dev/null +++ b/commands/analyze/face.js @@ -0,0 +1,44 @@ +const { Command } = require('discord.js-commando'); +const snekfetch = require('snekfetch'); +const { KAIROS_KEY, KAIROS_ID } = process.env; +const races = ['asian', 'black', 'hispanic', 'other', 'white']; + +module.exports = class FaceAnalyzeCommand extends Command { + constructor(client) { + super(client, { + name: 'face-analyze', + aliases: ['analyze-face', 'face'], + group: 'analyze', + memberName: 'face', + description: 'Determines the age, gender, and race of a face.', + args: [ + { + key: 'face', + prompt: 'What face do you want to scan?', + type: 'image', + default: msg => msg.author.displayAvatarURL({ format: 'png', size: 512 }) + } + ] + }); + } + + async run(msg, { face }) { + try { + const { body } = await snekfetch + .post('https://api.kairos.com/detect') + .set({ + app_id: KAIROS_ID, + app_key: KAIROS_KEY + }) + .send({ image: face }); + if (!body.images) return msg.say('There are no faces in this image.'); + if (body.images[0].faces.length > 1) return msg.say('Please provide only one face in the image.'); + const data = body.images[0].faces[0].attributes; + const race = races.sort((a, b) => data[b] - data[a])[0]; + const gender = data.gender.maleConfidence > data.gender.femaleConfidence ? 'man' : 'woman'; + return msg.reply(`I think this is a photo of a ${data.age} year old ${race} ${gender}.`); + } catch (err) { + return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); + } + } +}; diff --git a/commands/other/gender-guess.js b/commands/analyze/gender.js similarity index 92% rename from commands/other/gender-guess.js rename to commands/analyze/gender.js index 560fcff6..aa00b4bd 100644 --- a/commands/other/gender-guess.js +++ b/commands/analyze/gender.js @@ -5,8 +5,8 @@ module.exports = class GenderGuessCommand extends Command { constructor(client) { super(client, { name: 'gender-guess', - aliases: ['gender', 'guess-gender'], - group: 'other', + aliases: ['gender', 'guess-gender', 'analyze-gender', 'gender-analyze'], + group: 'analyze', memberName: 'gender', description: 'Determines the gender of a name.', args: [ diff --git a/commands/other/severe-toxicity.js b/commands/analyze/severe-toxicity.js similarity index 98% rename from commands/other/severe-toxicity.js rename to commands/analyze/severe-toxicity.js index ed018486..3a3add25 100644 --- a/commands/other/severe-toxicity.js +++ b/commands/analyze/severe-toxicity.js @@ -7,7 +7,7 @@ module.exports = class SevereToxicityCommand extends Command { super(client, { name: 'severe-toxicity', aliases: ['severe-perspective', 'severe-comment-toxicity'], - group: 'other', + group: 'analyze', memberName: 'severe-toxicity', description: 'Determines the toxicity of text, but less sensitive to milder language.', args: [ diff --git a/commands/other/toxicity.js b/commands/analyze/toxicity.js similarity index 98% rename from commands/other/toxicity.js rename to commands/analyze/toxicity.js index 3eb081a5..ebb73965 100644 --- a/commands/other/toxicity.js +++ b/commands/analyze/toxicity.js @@ -7,7 +7,7 @@ module.exports = class ToxicityCommand extends Command { super(client, { name: 'toxicity', aliases: ['perspective', 'comment-toxicity'], - group: 'other', + group: 'analyze', memberName: 'toxicity', description: 'Determines the toxicity of text.', args: [ diff --git a/commands/image-edit/contrast.js b/commands/image-edit/contrast.js index 5c32a0ff..6e350b89 100644 --- a/commands/image-edit/contrast.js +++ b/commands/image-edit/contrast.js @@ -34,7 +34,9 @@ module.exports = class ContrastCommand extends Command { const ctx = canvas.getContext('2d'); ctx.drawImage(data, 0, 0); contrast(ctx, 0, 0, data.width, data.height); - return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'contrast.png' }] }); + const attachment = canvas.toBuffer(); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'contrast.png' }] }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/image-edit/distort.js b/commands/image-edit/distort.js index 217af308..60a58a93 100644 --- a/commands/image-edit/distort.js +++ b/commands/image-edit/distort.js @@ -40,7 +40,9 @@ module.exports = class DistortCommand extends Command { const ctx = canvas.getContext('2d'); ctx.drawImage(data, 0, 0); distort(ctx, level, 0, 0, data.width, data.height); - return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'distort.png' }] }); + const attachment = canvas.toBuffer(); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'distort.png' }] }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/image-edit/glitch.js b/commands/image-edit/glitch.js index cd621665..4a862260 100644 --- a/commands/image-edit/glitch.js +++ b/commands/image-edit/glitch.js @@ -34,7 +34,9 @@ module.exports = class GlitchCommand extends Command { const ctx = canvas.getContext('2d'); ctx.drawImage(data, 0, 0); distort(ctx, 20, 0, 0, data.width, data.height, 5); - return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'glitch.png' }] }); + const attachment = canvas.toBuffer(); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'glitch.png' }] }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/image-edit/greyscale.js b/commands/image-edit/greyscale.js index caa72402..e1a2e4f0 100644 --- a/commands/image-edit/greyscale.js +++ b/commands/image-edit/greyscale.js @@ -35,7 +35,9 @@ module.exports = class GreyscaleCommand extends Command { const ctx = canvas.getContext('2d'); ctx.drawImage(data, 0, 0); greyscale(ctx, 0, 0, data.width, data.height); - return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'greyscale.png' }] }); + const attachment = canvas.toBuffer(); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'greyscale.png' }] }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/image-edit/ifunny.js b/commands/image-edit/ifunny.js index 24931734..6d3a5cbe 100644 --- a/commands/image-edit/ifunny.js +++ b/commands/image-edit/ifunny.js @@ -37,7 +37,9 @@ module.exports = class IfunnyCommand extends Command { ctx.fillStyle = '#181619'; ctx.fillRect(0, canvas.height - base.height, canvas.width, base.height); ctx.drawImage(base, canvas.width - base.width, canvas.height - base.height); - return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'ifunny.png' }] }); + const attachment = canvas.toBuffer(); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'ifunny.png' }] }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/image-edit/invert.js b/commands/image-edit/invert.js index 77ab745e..84352cb9 100644 --- a/commands/image-edit/invert.js +++ b/commands/image-edit/invert.js @@ -34,7 +34,9 @@ module.exports = class InvertCommand extends Command { const ctx = canvas.getContext('2d'); ctx.drawImage(data, 0, 0); invert(ctx, 0, 0, data.width, data.height); - return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'invert.png' }] }); + const attachment = canvas.toBuffer(); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'invert.png' }] }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/image-edit/sepia.js b/commands/image-edit/sepia.js index 98c74805..873aa3e3 100644 --- a/commands/image-edit/sepia.js +++ b/commands/image-edit/sepia.js @@ -34,7 +34,9 @@ module.exports = class SepiaCommand extends Command { const ctx = canvas.getContext('2d'); ctx.drawImage(data, 0, 0); sepia(ctx, 0, 0, data.width, data.height); - return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'sepia.png' }] }); + const attachment = canvas.toBuffer(); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'sepia.png' }] }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/image-edit/silhouette.js b/commands/image-edit/silhouette.js index 2e9dd863..80c95300 100644 --- a/commands/image-edit/silhouette.js +++ b/commands/image-edit/silhouette.js @@ -34,7 +34,9 @@ module.exports = class SilhouetteCommand extends Command { const ctx = canvas.getContext('2d'); ctx.drawImage(data, 0, 0); silhouette(ctx, 0, 0, data.width, data.height); - return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'silhouette.png' }] }); + const attachment = canvas.toBuffer(); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'silhouette.png' }] }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/image-edit/tint.js b/commands/image-edit/tint.js index d1f0275e..ec0042e7 100644 --- a/commands/image-edit/tint.js +++ b/commands/image-edit/tint.js @@ -39,7 +39,9 @@ module.exports = class TintCommand extends Command { const canvas = createCanvas(data.width, data.height); const ctx = canvas.getContext('2d'); drawImageWithTint(ctx, data, color, 0, 0, data.width, data.height); - return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'tint.png' }] }); + const attachment = canvas.toBuffer(); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'tint.png' }] }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/package.json b/package.json index f0d9d28a..5cfaa45b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiao", - "version": "67.0.1", + "version": "67.1.0", "description": "Your personal server companion.", "main": "Xiao.js", "scripts": { diff --git a/types/image.js b/types/image.js index a65b4fdc..edfa07be 100644 --- a/types/image.js +++ b/types/image.js @@ -12,7 +12,7 @@ class ImageArgumentType extends ArgumentType { return valid; } if (!attachment.height || !attachment.width) return false; - if (attachment.size > 1000000) return false; + if (attachment.size > 8e+6) return 'Please provide an image under 8 MB.'; return true; }