From 5401359b1ad3bddcaff7a7b1c4f051f28ed0b720 Mon Sep 17 00:00:00 2001 From: carlos3g Date: Sun, 25 Jul 2021 12:51:39 -0300 Subject: [PATCH 1/8] [FIX] fix typo --- src/Alice.js | 2 +- src/utils/Parse.js | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Alice.js b/src/Alice.js index 4c4859f..30b8956 100644 --- a/src/Alice.js +++ b/src/Alice.js @@ -1,5 +1,5 @@ const auth = require('./auth'); -const { Parse } = require('./utils/Parse'); +const { Parse } = require('./utils'); const build = require('./build'); const session = new auth.Session(); diff --git a/src/utils/Parse.js b/src/utils/Parse.js index 848981d..fdf6747 100644 --- a/src/utils/Parse.js +++ b/src/utils/Parse.js @@ -76,6 +76,4 @@ class Parse { } } -module.exports = { - Parse, -}; +module.exports = Parse; From 23ab10c74a35d28cfe7a9e4a7e46079b208bc966 Mon Sep 17 00:00:00 2001 From: carlos3g Date: Tue, 27 Jul 2021 19:54:03 -0300 Subject: [PATCH 2/8] [REFACTOR] removes Path.js --- src/build/Path.js | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 src/build/Path.js diff --git a/src/build/Path.js b/src/build/Path.js deleted file mode 100644 index 6fd872f..0000000 --- a/src/build/Path.js +++ /dev/null @@ -1,21 +0,0 @@ -const path = require('path'); - -class Path { - constructor(BASE_PATH) { - this.BASE_PATH = BASE_PATH; - } - - create(RELATIVE_PATH, alias) { - const FILE_PATH = path.join(this.BASE_PATH, RELATIVE_PATH); - const { name } = path.parse(FILE_PATH); - const func = require(FILE_PATH); // eslint-disable-line global-require - - if (alias) { - return [alias, func]; - } - - return [name, func]; - } -} - -module.exports = Path; From 3c334087cc1da9f2a8e292c36aaa77fcc15da11e Mon Sep 17 00:00:00 2001 From: carlos3g Date: Tue, 27 Jul 2021 19:55:55 -0300 Subject: [PATCH 3/8] [REFACTOR][BREAKING] makes Commands.js compatible with Commands made with classes --- src/build/Commands.js | 26 +++++++++----------------- src/build/index.js | 1 - 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/build/Commands.js b/src/build/Commands.js index 821b173..9a7f401 100644 --- a/src/build/Commands.js +++ b/src/build/Commands.js @@ -1,7 +1,3 @@ -function isFunction(object) { - return typeof object === 'function'; -} - /** * Commands wrapper * @param {object} commands - Object that contains the commands. @@ -17,12 +13,8 @@ class Commands { * @param {string} name - Command's name. * @param {function} callback - Callback to command. */ - set(name, callback) { - if (!isFunction(callback)) { - throw new Error(`${callback} must be a function`); - } - - this.commands[name] = callback; + register(cmd) { + this.commands[cmd.name] = cmd; } /** @@ -48,15 +40,15 @@ class Commands { * @see https://docs.wwebjs.dev/Message.html * @see https://docs.wwebjs.dev/Client.html */ - async call(cmd, data, message, client) { - if (!this.has(cmd)) { - throw new Error(`${cmd} is not registered`); + async call(cmdName, data, message, client) { + if (!this.has(cmdName)) { + throw new Error(`${cmdName} is not registered.`); } - const response = await this.commands[cmd](data, message, client); - - if (response) { - message.reply(String(response)); + try { + await this.commands[cmdName].execute(data, message, client); + } catch (e) { + message.reply(`❗ ${e.message}`); } } } diff --git a/src/build/index.js b/src/build/index.js index 3084ace..952ce1e 100644 --- a/src/build/index.js +++ b/src/build/index.js @@ -2,5 +2,4 @@ module.exports = { Commands: require('./Commands'), - Path: require('./Path'), }; From 6d2be0ff9cd927aa7c6fb859d491e6bbc6dfcbad Mon Sep 17 00:00:00 2001 From: carlos3g Date: Tue, 27 Jul 2021 19:57:07 -0300 Subject: [PATCH 4/8] [REFACTOR][BREAKING][WIP] Re-do commands with classes --- index.js | 37 +++++++++++++---------- src/Alice.js | 2 +- src/commands/bot.js | 15 ++++++++-- src/commands/coin.js | 63 +++++++++++++++++++++++----------------- src/commands/commands.js | 20 +++++++++---- src/commands/cron.js | 13 ++++----- src/commands/dice.js | 27 ----------------- src/commands/doc.js | 26 ++++++++++------- src/commands/index.js | 15 ++++++++++ src/commands/links.js | 17 +++++++++-- src/commands/lyric.js | 39 ++++++++++++++----------- src/commands/report.js | 38 +++++++++++++++--------- src/commands/search.js | 47 ++++++++++++++++-------------- src/commands/suggest.js | 54 ++++++++++++++++++++-------------- src/commands/wiki.js | 44 ++++++++++++++++++---------- 15 files changed, 270 insertions(+), 187 deletions(-) delete mode 100644 src/commands/dice.js create mode 100644 src/commands/index.js diff --git a/index.js b/index.js index 5944ea4..a4848c8 100644 --- a/index.js +++ b/index.js @@ -1,22 +1,29 @@ require('dotenv').config(); const { Alice } = require('./src/Alice'); -const build = require('./src/build'); - -const path = new build.Path(__dirname); +const { + Bot, + Coin, + Commands, + Doc, + Links, + Lyric, + Report, + Search, + Suggest, + Wiki, +} = require('./src/commands'); const alice = new Alice([ - path.create('src/commands/bot', 'bot'), - path.create('src/commands/coin', 'coin'), - path.create('src/commands/commands', 'commands'), - path.create('src/commands/cron', 'cron'), - path.create('src/commands/dice', 'dice'), - path.create('src/commands/doc', 'doc'), - path.create('src/commands/links', 'links'), - path.create('src/commands/lyric', 'lyric'), - path.create('src/commands/report', 'report'), - path.create('src/commands/search', 'search'), - path.create('src/commands/suggest', 'suggest'), - path.create('src/commands/wiki', 'wiki'), + new Bot(), + new Coin(), + new Commands(), + new Doc(), + new Links(), + new Lyric(), + new Report(), + new Search(), + new Suggest(), + new Wiki(), ]); alice.initialize(); diff --git a/src/Alice.js b/src/Alice.js index 30b8956..8cbbdf6 100644 --- a/src/Alice.js +++ b/src/Alice.js @@ -12,7 +12,7 @@ class Alice { }; commandsArray.forEach((cmd) => { - commands.set(...cmd); + commands.register(cmd); }); } diff --git a/src/commands/bot.js b/src/commands/bot.js index 7f2047b..5036972 100644 --- a/src/commands/bot.js +++ b/src/commands/bot.js @@ -1,2 +1,13 @@ -module.exports = () => - `Olá, eu sou a Alice. Quer saber mais sobre mim? use o comando !doc`; +class Bot { + constructor() { + this.name = 'bot'; + this.defaultMessage = + 'Olá, eu sou a Alice. Quer saber mais sobre mim? use o comando !doc'; + } + + execute(_, message) { + message.reply(this.defaultMessage); + } +} + +module.exports = Bot; diff --git a/src/commands/coin.js b/src/commands/coin.js index 111a567..1f26a62 100644 --- a/src/commands/coin.js +++ b/src/commands/coin.js @@ -1,13 +1,6 @@ const axios = require('axios'); const cheerio = require('cheerio'); -const defaultMessage = ` -uso: *!coin* [--flag] name -_--all -> mostra todas as informações disponiveis_ - -a flag _all_ pode retornar dados em excesso, sua utilização repetida será considera spam -`; - async function loadCheerio(url) { try { const { data } = await axios.get(url); @@ -63,30 +56,46 @@ function getUrl(args, text) { return baseURL + path; } -module.exports = async (data) => { - const { args, text } = data; +class Coin { + constructor() { + this.name = 'coin'; + this.defaultMessage = ` +uso: *!coin* [--flag] name +_--all -> mostra todas as informações disponiveis_ - if (!text) { - return defaultMessage.trim(); +a flag _all_ pode retornar dados em excesso, sua utilização repetida será considera spam + `.trim(); } - const url = getUrl(args, text); - let coinStats = await getData(url); + async execute(data, message) { + const { args, text } = data; - if (!coinStats) { - return 'moeda não encontrada'; - } - if (!args.includes('all')) { - coinStats = coinStats.slice(0, 3); - } + if (!text) { + message.reply(this.defaultMessage.trim()); + return; + } - let output = ''; + const url = getUrl(args, text); + let coinStats = await getData(url); - coinStats.forEach((s) => { - const [key, value] = Object.entries(s)[0]; - const string = `*_${key}_*:\n - ${value}\n\n`; - output += string; - }); + if (!coinStats) { + message.reply('moeda não encontrada'); + return; + } + if (!args.includes('all')) { + coinStats = coinStats.slice(0, 3); + } + + let output = ''; + + coinStats.forEach((s) => { + const [key, value] = Object.entries(s)[0]; + const string = `*_${key}_*:\n - ${value}\n\n`; + output += string; + }); + + message.reply(output.trim()); + } +} - return output.trim(); -}; +module.exports = Coin; diff --git a/src/commands/commands.js b/src/commands/commands.js index 9ff9cf1..2b07e3c 100644 --- a/src/commands/commands.js +++ b/src/commands/commands.js @@ -1,15 +1,25 @@ -module.exports = () => - `Os seguintes comandos estão disponiveis: +class Commands { + constructor() { + this.name = 'commands'; + this.defaultMessage = ` +Os seguintes comandos estão disponiveis: - !bot - !coin - !commands - !cron -- !dice - !doc -- !github - !links - !lyric - !report - !search - !suggest -- !wiki`.trim(); +- !wiki + `.trim(); + } + + execute(_, message) { + message.reply(this.defaultMessage); + } +} + +module.exports = Commands; diff --git a/src/commands/cron.js b/src/commands/cron.js index 8cec8a1..e84ed92 100644 --- a/src/commands/cron.js +++ b/src/commands/cron.js @@ -34,6 +34,7 @@ function toPositiveNumber(value) { class Cron { constructor(data, message) { + this.name = 'cron'; this.data = data; this.text = data.text; this.message = message; @@ -46,15 +47,16 @@ class Cron { this.timer = time.timer(seconds, minutes, hours, days); } - async init() { + async execute(_, message) { const { args } = this.data; const isAdm = await chattools.isAdm(this.message); if (isAdm) { - return this.runsArg(args); + message.reply(this.runsArg(args)); + return; } - return 'staff only.'; + message.reply('staff only.'); } create() { @@ -166,7 +168,4 @@ _--d -> define um intervalor de dias_ } } -module.exports = async (data, message) => { - const cron = new Cron(data, message); - return cron.init(); -}; +module.exports = Cron; diff --git a/src/commands/dice.js b/src/commands/dice.js deleted file mode 100644 index a9371b1..0000000 --- a/src/commands/dice.js +++ /dev/null @@ -1,27 +0,0 @@ -const help = `Para chamar o dado você deve digitar !dice seguido do seu valor. - -Ele deve ser escrito na forma d+, sendo o valor adicional um atributo opcional. -Caso seja passado o valor adicional, ele deve ser escrito sem espaços, ou será considerado nulo. -Ex: - - !dice 1d10 + 4 // Joga um dado de dez lados mas *não* faz a soma. -`.trim(); - -module.exports = (data) => { - const { text } = data; - const regexp = /(\d+)d(\d+)([-|+]\d+)?/; - const match = text.match(regexp); - - if (text && match) { - const multiplier = Number(match[1]); - const value = Math.ceil(Math.random() * Number(match[2])); - const adder = Number(match[3]) || 0; - const total = multiplier * value + adder; - const result = `Resultado: ${value}\nMultiplicador: ${multiplier}\nAdicional: ${adder}\nTotal: ${total}\n`; - return result; - } - if (text) { - return 'Não foi possivel achar o valor, use !dice para mais informações.'; - } - - return help; -}; diff --git a/src/commands/doc.js b/src/commands/doc.js index df96bfb..2a07154 100644 --- a/src/commands/doc.js +++ b/src/commands/doc.js @@ -19,10 +19,6 @@ comando: *!cron* args: --create, --destroy, --start, --stop kwargs: --s, --m, --h, --d descrição: repete uma mensagem a cada determinado periodo de tempo -`, - dice: ` -comando: *!dice* -descrição: lanca um dado de rpg e retorna seu valor `, doc: ` comando: *!doc* @@ -56,12 +52,22 @@ descrição: retorna o primeiro resultado de uma pesquisa na wikipedia `, }; -module.exports = (data) => { - const { args } = data; +class Doc { + constructor() { + this.name = 'doc'; + this.strings = strings; + } + + execute(data, message) { + const { args } = data; - if (strings[args[0]]) { - return strings[args[0]].trim(); + if (strings[args[0]]) { + message.reply(strings[args[0]].trim()); + return; + } + + message.reply(this.strings.defaultMessage.trim()); } +} - return strings.defaultMessage.trim(); -}; +module.exports = Doc; diff --git a/src/commands/index.js b/src/commands/index.js new file mode 100644 index 0000000..4cef83b --- /dev/null +++ b/src/commands/index.js @@ -0,0 +1,15 @@ +/* eslint-disable global-require */ + +module.exports = { + Bot: require('./bot'), + Coin: require('./coin'), + Commands: require('./commands'), + Cron: require('./cron'), + Doc: require('./doc'), + Links: require('./links'), + Lyric: require('./lyric'), + Report: require('./report'), + Search: require('./search'), + Suggest: require('./suggest'), + Wiki: require('./wiki'), +}; diff --git a/src/commands/links.js b/src/commands/links.js index da4f919..9498a22 100644 --- a/src/commands/links.js +++ b/src/commands/links.js @@ -1,5 +1,8 @@ -module.exports = () => - `Coding in python: +class Links { + constructor() { + this.name = 'links'; + this.defaultMessage = ` +Coding in python: https://chat.whatsapp.com/I4IpHC0YFPQLUcGHJeqYdF Coding in C/C++: @@ -22,4 +25,12 @@ https://chat.whatsapp.com/GOXnIXSXEFH7wHvO9aTuFs Speaking in English: https://chat.whatsapp.com/EOirNapuFe3CVunBqbwj1Z -`.trim(); + `.trim(); + } + + execute(_, message) { + message.reply(this.defaultMessage); + } +} + +module.exports = Links; diff --git a/src/commands/lyric.js b/src/commands/lyric.js index ee60399..139a44b 100644 --- a/src/commands/lyric.js +++ b/src/commands/lyric.js @@ -17,25 +17,30 @@ function removeBr(raw) { return new JSSoup(html); } -module.exports = async (data, message) => { - const { text } = data; - - if (!text) { - message.reply('please tell me the song name'); +class Lyric { + constructor() { + this.name = 'lyric'; } - const results = await search.google(text, 'https://www.letras.mus.br'); - const { link } = results[0]; - const soup = await makeSoup(link); - const title = soup.find('div', { class: 'cnt-head_title' }).find('h1'); - const lyricsDiv = soup.find('div', { class: 'cnt-letra' }); - const pArray = lyricsDiv.findAll('p'); - const output = `\ -*${title.text}* + // eslint-disable-next-line + async execute(data, message) { + const { text } = data; + + if (!text) { + throw new Error('Nenhum nome foi passado'); + } -${pArray.map((p) => removeBr(p).text).join('')} + const results = await search.google(text, 'https://www.letras.mus.br'); + const { link } = results[0]; + const soup = await makeSoup(link); + const title = soup.find('div', { class: 'cnt-head_title' }).find('h1'); + const lyricsDiv = soup.find('div', { class: 'cnt-letra' }); + const pArray = lyricsDiv.findAll('p'); + const lyric = pArray.map((p) => removeBr(p).text).join(''); + const output = `*${title.text}*\n\n${lyric}\n\n_${link}_`; -_${link}_`; + message.reply(output); + } +} - message.reply(output); -}; +module.exports = Lyric; diff --git a/src/commands/report.js b/src/commands/report.js index 71034d1..36a7a77 100644 --- a/src/commands/report.js +++ b/src/commands/report.js @@ -14,22 +14,32 @@ argumentos: user: 'o usuário foi reportado a administração', }; -module.exports = (data, message, client) => { - const { args, text } = data; - - if (args.length === 0 && text) { - return 'nenhuma flag foi fornecida'; - } - if (args.length > 0 && !text) { - return 'nenhuma descrição foi fornecida'; +class Report { + constructor() { + this.name = 'report'; + this.strings = strings; } - const reportMsg = `⚠️ *${args[0]} report* ⚠️\n\n${text}`; + execute(data, message, client) { + const { args, text } = data; + + const reportMsg = `⚠️ *${args[0]} report* ⚠️\n\n${text}`; - if (args.includes('bug') || args.includes('user')) { - client.sendMessage(myID, reportMsg); - return strings[args[0]]; + if (args.length === 0 && text) { + throw new Error('Nenhuma flag foi fornecida.'); + } + if (args.length > 0 && !text) { + throw new Error('Nenhuma descrição foi fornecida.'); + } + + if (args.includes('bug') || args.includes('user')) { + client.sendMessage(myID, reportMsg); + message.reply(this.strings[args[0]]); + return; + } + + message.reply(this.strings.defaultMessage.trim()); } +} - return strings.defaultMessage.trim(); -}; +module.exports = Report; diff --git a/src/commands/search.js b/src/commands/search.js index 949704f..72f0175 100644 --- a/src/commands/search.js +++ b/src/commands/search.js @@ -1,32 +1,35 @@ const { search } = require('../utils'); -function callback(object) { - const { title, link, snippet } = object; - return ` -*${title}* +class Search { + constructor() { + this.name = 'search'; + } -${snippet} + // eslint-disable-next-line + async execute(data, message) { + const { text } = data; -_${link}_ -`; -} + if (!text) { + throw new Error('Nenhum texto para pesquisa foi especificado.'); + } -module.exports = async (data) => { - const { text } = data; + const results = await search.google(text, undefined, 1); - if (!text) { - return 'Nenhum texto para pesquisa foi especificado.'; - } + if (results.length > 0) { + const stringResult = results + .map((r) => Search.formatResult(r)) + .join('\n\n'); + message.reply(stringResult); + return; + } - const results = await search.google(text, undefined, 1); + message.reply(`Nenhum resultado foi encontrado para: _${text}_`); + } - if (results.length > 0) { - const stringResult = results - .map((r) => callback(r)) - .join('\n\n') - .trim(); - return stringResult; + static formatResult(object) { + const { title, link, snippet } = object; + return `*${title}*\n\n${snippet}\n\n_${link}_`; } +} - return `Nenhum resultado foi encontrado para: _${text}_`; -}; +module.exports = Search; diff --git a/src/commands/suggest.js b/src/commands/suggest.js index 33162d7..851a103 100644 --- a/src/commands/suggest.js +++ b/src/commands/suggest.js @@ -1,7 +1,11 @@ const { chattools } = require('../utils'); const myID = chattools.userID(process.env.REPORT_NUMBER); -const defaultMessage = ` + +class Suggest { + constructor() { + this.name = 'suggest'; + this.defaultMessage = ` uso: _!suggest [--flag] [sugestão]_ argumentos: @@ -9,28 +13,34 @@ argumentos: _--change para sugerir mudanças_ _--remove para sugerir remoções_ -⚠️ *o uso indevido dessa função resultará em ban de 3 dias* ⚠️`; - -module.exports = (data, msg, client) => { - const { args, text } = data; - - const reportMsg = `⚠️ *${args[0]} suggestion* ⚠️\n\n${text}`; - - if (args.length === 0 && text) { - return 'Nenhuma flag foi fornecida.'; - } - if (args.length > 0 && !text) { - return 'Nenhuma sugestão foi fornecida.'; +⚠️ *o uso indevido dessa função resultará em ban de 3 dias* ⚠️ + `.trim(); } - if ( - args.includes('feature') || - args.includes('remove') || - args.includes('change') - ) { - client.sendMessage(myID, reportMsg); - return 'obrigado pela colaboração'; + execute(data, message, client) { + const { args, text } = data; + + const reportMsg = `⚠️ *${args[0]} suggestion* ⚠️\n\n${text}`; + + if (args.length === 0 && text) { + throw new Error('Nenhuma flag foi fornecida.'); + } + if (args.length > 0 && !text) { + throw new Error('Nenhuma sugestão foi fornecida.'); + } + + if ( + args.includes('feature') || + args.includes('remove') || + args.includes('change') + ) { + client.sendMessage(myID, reportMsg); + message.reply('Obrigado pela colaboração!'); + return; + } + + message.reply(this.defaultMessage.trim()); } +} - return defaultMessage.trim(); -}; +module.exports = Suggest; diff --git a/src/commands/wiki.js b/src/commands/wiki.js index 1edf806..f7b0463 100644 --- a/src/commands/wiki.js +++ b/src/commands/wiki.js @@ -1,20 +1,34 @@ const wikijs = require('wikijs').default; -module.exports = async (data) => { - const { text, args } = data; - const wiki = wikijs({ apiUrl: 'https://pt.wikipedia.org/w/api.php' }); - let output; +class Wiki { + constructor() { + this.name = 'wiki'; + this.wikiOptions = { apiUrl: 'https://pt.wikipedia.org/w/api.php' }; + } + + async execute(data, message) { + const { text, args } = data; + const wiki = wikijs(this.wikiOptions); + let output; + + if (!text) { + throw new Error('Nenhum texto para pesquisa foi especificado.'); + } + + if (args.includes('search')) { + const { results } = await wiki.search(text, 10); + output = '*Resultados encontrados:*\n\n'; + output += results.join('\n'); + message.reply(output); + return; + } - if (args.includes('search')) { - const { results } = await wiki.search(text, 10); - output = '*Resultados encontrados:*\n\n'; - output += results.join('\n'); - return output; + const page = await wiki.page(text); + const { title, canonicalurl: url } = page.raw; + const summary = await page.summary(); + output = `*${title}*\n\n${summary}\n\n_${url}_`; + message.reply(output); } +} - const page = await wiki.page(text); - const { title, canonicalurl: url } = page.raw; - const summary = await page.summary(); - output = `*${title}*\n\n${summary}\n\n_${url}_`; - return output; -}; +module.exports = Wiki; From 9dd363218896ebb3a863113d4afc9545c98e5db9 Mon Sep 17 00:00:00 2001 From: carlos3g Date: Wed, 28 Jul 2021 00:30:27 -0300 Subject: [PATCH 5/8] [REFACTOR] Re-do Cron command --- index.js | 2 + src/commands/cron.js | 175 ++++++++++++++++++------------------------- src/utils/index.js | 2 +- 3 files changed, 76 insertions(+), 103 deletions(-) diff --git a/index.js b/index.js index a4848c8..eaa67a0 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,7 @@ const { Bot, Coin, Commands, + Cron, Doc, Links, Lyric, @@ -17,6 +18,7 @@ const alice = new Alice([ new Bot(), new Coin(), new Commands(), + new Cron(), new Doc(), new Links(), new Lyric(), diff --git a/src/commands/cron.js b/src/commands/cron.js index e84ed92..996d053 100644 --- a/src/commands/cron.js +++ b/src/commands/cron.js @@ -1,9 +1,7 @@ const events = require('events'); -const { chattools, time } = require('../utils'); +const { chattools, Time } = require('../utils'); const emitter = new events.EventEmitter(); -let threads = []; -let counter = 0; function Thread(id, text, message, timer) { this.id = id; @@ -19,152 +17,125 @@ function Thread(id, text, message, timer) { }); } -function toPositiveNumber(value) { - const number = Number.parseFloat(value); - - if (number >= 0) { - return number; - } - if (Number.isNaN(number)) { - return 0; - } - - return -number; -} - class Cron { - constructor(data, message) { + constructor() { this.name = 'cron'; - this.data = data; - this.text = data.text; - this.message = message; + this.threads = []; + this.counter = 0; + this.defaultMessage = ` +*criação*: _!cron --create --[time]=_ +*outros*: _!cron [--flag] []_ - const seconds = toPositiveNumber(data.kwargs.s); - const minutes = toPositiveNumber(data.kwargs.m); - const hours = toPositiveNumber(data.kwargs.h); - const days = toPositiveNumber(data.kwargs.d); +*argumentos*: +_--create -> cria uma nova thread_ +_--destroy -> apaga uma thread_ +_--start -> inicia uma thread_ +_--stop -> para uma thread_ +_--s -> define um intervalor de segundos_ +_--m -> define um intervalor de minutos_ +_--h -> define um intervalor de horas_ +_--d -> define um intervalor de dias_ - this.timer = time.timer(seconds, minutes, hours, days); +⚠️ *o uso indevido dessa função resultará em ban de 3 dias* ⚠️ + `.trim(); } - async execute(_, message) { - const { args } = this.data; - const isAdm = await chattools.isAdm(this.message); + async execute(data, message) { + const isAdm = await chattools.isAdm(message); if (isAdm) { - message.reply(this.runsArg(args)); + message.reply(this.runs(data, message)); return; } message.reply('staff only.'); } - create() { - if (!(this.timer > 0)) { - return 'you must add a valid time'; + create(data, message) { + const { kwargs, text } = data; + const timer = Time.timer( + Math.abs(kwargs.s || 0), + Math.abs(kwargs.m || 0), + Math.abs(kwargs.h || 0), + Math.abs(kwargs.d || 0) + ); + + if (timer <= 0) { + throw new Error('Time invalid.'); } - counter++; - const { message, text, timer } = this; - const thread = new Thread(counter, text, message, timer); - threads.push(thread); + this.counter += 1; + const thread = new Thread(this.counter, text, message, timer); + this.threads.push(thread); - return `thread created using id: ${thread.id}`; + return `Thread criada usando o id ${thread.id}`; } - destroy() { - if (!Cron.isIdValid(this.text)) { - return 'thread not found'; + destroy(id) { + if (!this.isIdValid(id)) { + return 'Thread não encontrada.'; } - const thread = threads.find((t) => t.id === Number(this.text)); - this.stop(); + const thread = this.threads.find((t) => t.id === Number(id)); + this.stop(id); - emitter.removeAllListeners(`start-cron${this.text}`, thread.start); - emitter.removeAllListeners(`stop-cron${this.text}`, thread.stop); + emitter.removeAllListeners(`start-cron${id}`, thread.start); + emitter.removeAllListeners(`stop-cron${id}`, thread.stop); - threads = threads.filter((t) => !(t.id === Number(this.text))); - return 'thread destroyed successfully'; + this.threads = this.threads.filter((t) => !(t.id === Number(id))); + return 'Thread destruida com sucesso.'; } - start() { - if (Cron.isIdValid(this.text)) { - emitter.emit(`start-cron${this.text}`); - return `starting thread ${this.text}`; + start(id) { + if (this.isIdValid(id)) { + emitter.emit(`start-cron${id}`); + return `starting thread ${id}`; } return 'thread not found'; } - stop() { - if (Cron.isIdValid(this.text)) { - emitter.emit(`stop-cron${this.text}`); - return `stopping thread ${this.text}`; + stop(id) { + if (this.isIdValid(id)) { + emitter.emit(`stop-cron${id}`); + return `Parando a thread de id ${id}...`; } - return 'thread not found'; + return 'Thread não encontrada.'; } - static log() { - let output = ''; - - if (threads.length === 0) { - output += 'thread not open'; - } else { - output += 'threads open:\n\n'; + log() { + if (this.threads.length === 0) { + return 'Nenhuma thread aberta.'; } - threads.forEach((thread) => { - const id = `id: ${thread.id}\n`; - const description = `desc: ${thread.description}\n`; - output += `${id}${description}\n`; + let output = 'Threads abertas:\n\n'; + + this.threads.forEach((t) => { + output += `id: ${t.id}\ndesc: ${t.description}\n\n`; }); return output.trim(); } - static killall() { - return null; - } - - runsArg(args) { - const seila = { - log: () => Cron.log(), - killall: () => 'sorry, this function is not done yet', - create: () => this.create(), - destroy: () => this.destroy(), - start: () => this.start(), - stop: () => this.stop(), + runs(data, message) { + const methods = { + log: () => this.log(), + create: () => this.create(data, message), + destroy: () => this.destroy(data.text), + start: () => this.start(data.text), + stop: () => this.stop(data.text), }; - if (seila[args[0]]) { - return seila[args[0]](); + if (methods[data.args[0]]) { + return methods[data.args[0]](); } - return Cron.default(); - } - - static isIdValid(id) { - return threads.some((t) => t.id === Number(id)); + return this.defaultMessage; } - static default() { - return ` -*criação*: _!cron --create --[time]=_ -*outros*: _!cron [--flag] []_ - -*argumentos*: -_--create -> cria uma nova thread_ -_--destroy -> apaga uma thread_ -_--start -> inicia uma thread_ -_--stop -> para uma thread_ -_--s -> define um intervalor de segundos_ -_--m -> define um intervalor de minutos_ -_--h -> define um intervalor de horas_ -_--d -> define um intervalor de dias_ - -⚠️ *o uso indevido dessa função resultará em ban de 3 dias* ⚠️ -`.trim(); + isIdValid(id) { + return this.threads.some((t) => t.id === Number(id)); } } diff --git a/src/utils/index.js b/src/utils/index.js index 804d5f2..4eda1e3 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -4,5 +4,5 @@ module.exports = { Parse: require('./Parse'), chattools: require('./chattools'), search: require('./search'), - time: require('./time'), + Time: require('./time'), }; From 1bb8587aaf8166ff8a35f55dca394d73333948c3 Mon Sep 17 00:00:00 2001 From: carlos3g Date: Wed, 28 Jul 2021 13:34:21 -0300 Subject: [PATCH 6/8] [REFACTOR] Makes some changes to commands uses classes correctly --- src/commands/coin.js | 34 +++++++++++++++------------------- src/commands/lyric.js | 10 ++++++---- src/commands/report.js | 5 ++--- src/commands/search.js | 4 ++-- src/commands/suggest.js | 6 ++---- 5 files changed, 27 insertions(+), 32 deletions(-) diff --git a/src/commands/coin.js b/src/commands/coin.js index 1f26a62..1574049 100644 --- a/src/commands/coin.js +++ b/src/commands/coin.js @@ -10,7 +10,7 @@ async function loadCheerio(url) { } } -async function getData(url) { +async function getCoinStats(url) { const $ = await loadCheerio(url); if (!(typeof $ === 'function')) { @@ -23,8 +23,8 @@ async function getData(url) { .find('tr'); const statsArray = []; - priceStatistics.each(function () { - const tr = $(this); + priceStatistics.each((_, pS) => { + const tr = $(pS); const key = tr.find('th').text(); let value = tr.find('td'); @@ -36,7 +36,7 @@ async function getData(url) { value = value.text(); } - if (value !== 'No Data' || value !== 'Sem Dados') { + if (value !== 'No Data') { const object = Object.fromEntries([[key, value]]); statsArray.push(object); } @@ -45,20 +45,10 @@ async function getData(url) { return statsArray; } -function getUrl(args, text) { - let baseURL = 'https://coinmarketcap.com/currencies/'; - const path = text.replace(/\s/g, '-').toLowerCase(); - - if (args.includes('brl')) { - baseURL = 'https://coinmarketcap.com/pt-br/currencies/'; - } - - return baseURL + path; -} - class Coin { constructor() { this.name = 'coin'; + this.BASE_URL = 'https://coinmarketcap.com/currencies/'; this.defaultMessage = ` uso: *!coin* [--flag] name _--all -> mostra todas as informações disponiveis_ @@ -71,17 +61,18 @@ a flag _all_ pode retornar dados em excesso, sua utilização repetida será con const { args, text } = data; if (!text) { - message.reply(this.defaultMessage.trim()); + message.reply(this.defaultMessage); return; } - const url = getUrl(args, text); - let coinStats = await getData(url); + const url = this.getUrl(text); + let coinStats = await getCoinStats(url); if (!coinStats) { - message.reply('moeda não encontrada'); + message.reply('Moeda não encontrada.'); return; } + if (!args.includes('all')) { coinStats = coinStats.slice(0, 3); } @@ -96,6 +87,11 @@ a flag _all_ pode retornar dados em excesso, sua utilização repetida será con message.reply(output.trim()); } + + getUrl(text) { + const path = text.replace(/\s/g, '-').toLowerCase(); + return this.BASE_URL + path; + } } module.exports = Coin; diff --git a/src/commands/lyric.js b/src/commands/lyric.js index 139a44b..00a3982 100644 --- a/src/commands/lyric.js +++ b/src/commands/lyric.js @@ -34,10 +34,12 @@ class Lyric { const { link } = results[0]; const soup = await makeSoup(link); const title = soup.find('div', { class: 'cnt-head_title' }).find('h1'); - const lyricsDiv = soup.find('div', { class: 'cnt-letra' }); - const pArray = lyricsDiv.findAll('p'); - const lyric = pArray.map((p) => removeBr(p).text).join(''); - const output = `*${title.text}*\n\n${lyric}\n\n_${link}_`; + const lyrics = soup + .find('div', { class: 'cnt-letra' }) + .findAll('p') + .map((p) => removeBr(p).text) + .join(''); + const output = `*${title.text}*\n\n${lyrics}\n\n_${link}_`; message.reply(output); } diff --git a/src/commands/report.js b/src/commands/report.js index 36a7a77..048476b 100644 --- a/src/commands/report.js +++ b/src/commands/report.js @@ -1,6 +1,5 @@ const { chattools } = require('../utils'); -const myID = chattools.userID(process.env.REPORT_NUMBER); const strings = { defaultMessage: ` uso: _!report [--flag] [descrição]_ @@ -17,12 +16,12 @@ argumentos: class Report { constructor() { this.name = 'report'; + this.reportID = chattools.userID(process.env.REPORT_NUMBER); this.strings = strings; } execute(data, message, client) { const { args, text } = data; - const reportMsg = `⚠️ *${args[0]} report* ⚠️\n\n${text}`; if (args.length === 0 && text) { @@ -33,7 +32,7 @@ class Report { } if (args.includes('bug') || args.includes('user')) { - client.sendMessage(myID, reportMsg); + client.sendMessage(this.reportID, reportMsg); message.reply(this.strings[args[0]]); return; } diff --git a/src/commands/search.js b/src/commands/search.js index 72f0175..5aacf5b 100644 --- a/src/commands/search.js +++ b/src/commands/search.js @@ -26,8 +26,8 @@ class Search { message.reply(`Nenhum resultado foi encontrado para: _${text}_`); } - static formatResult(object) { - const { title, link, snippet } = object; + static formatResult(result) { + const { title, link, snippet } = result; return `*${title}*\n\n${snippet}\n\n_${link}_`; } } diff --git a/src/commands/suggest.js b/src/commands/suggest.js index 851a103..d86f900 100644 --- a/src/commands/suggest.js +++ b/src/commands/suggest.js @@ -1,10 +1,9 @@ const { chattools } = require('../utils'); -const myID = chattools.userID(process.env.REPORT_NUMBER); - class Suggest { constructor() { this.name = 'suggest'; + this.reportID = chattools.userID(process.env.REPORT_NUMBER); this.defaultMessage = ` uso: _!suggest [--flag] [sugestão]_ @@ -19,7 +18,6 @@ argumentos: execute(data, message, client) { const { args, text } = data; - const reportMsg = `⚠️ *${args[0]} suggestion* ⚠️\n\n${text}`; if (args.length === 0 && text) { @@ -34,7 +32,7 @@ argumentos: args.includes('remove') || args.includes('change') ) { - client.sendMessage(myID, reportMsg); + client.sendMessage(this.reportID, reportMsg); message.reply('Obrigado pela colaboração!'); return; } From 8ad1c474467e55623cbc5bab66e2613c57b3ea61 Mon Sep 17 00:00:00 2001 From: carlos3g Date: Wed, 28 Jul 2021 16:43:23 -0300 Subject: [PATCH 7/8] [REFACTOR] re-do cron default message --- src/commands/cron.js | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/commands/cron.js b/src/commands/cron.js index 996d053..fcef835 100644 --- a/src/commands/cron.js +++ b/src/commands/cron.js @@ -23,21 +23,23 @@ class Cron { this.threads = []; this.counter = 0; this.defaultMessage = ` -*criação*: _!cron --create --[time]=_ -*outros*: _!cron [--flag] []_ - -*argumentos*: -_--create -> cria uma nova thread_ -_--destroy -> apaga uma thread_ -_--start -> inicia uma thread_ -_--stop -> para uma thread_ -_--s -> define um intervalor de segundos_ -_--m -> define um intervalor de minutos_ -_--h -> define um intervalor de horas_ -_--d -> define um intervalor de dias_ - -⚠️ *o uso indevido dessa função resultará em ban de 3 dias* ⚠️ - `.trim(); +Repete uma mensagem em um determinado período de tempo. Cada mensagem é representada por uma thread. + +*uso:* \`\`\`!command [--args] [--kwargs=] ...\`\`\` + +*args válidos:* + \`\`\`--create\`\`\` -> _cria uma nova thread._ + \`\`\`--destroy\`\`\` -> _para e apaga uma thread._ + \`\`\`--stop\`\`\` -> _para uma thread._ + \`\`\`--start\`\`\` -> _inicia uma thread._ + \`\`\`--log\`\`\` -> _mostra as threads existentes._ + +*kwargs válidos:* + \`\`\`--s=\`\`\` -> _define um periodo em segundos._ + \`\`\`--m=\`\`\` -> _define um periodo em minutos._ + \`\`\`--h=\`\`\` -> _define um periodo em horas._ + \`\`\`--d=\`\`\` -> _define um periodo em dias._ +`.trim(); } async execute(data, message) { From fbce136a132f5b5b3bba04e2d87d103d05b40b0c Mon Sep 17 00:00:00 2001 From: carlos3g Date: Wed, 28 Jul 2021 16:44:12 -0300 Subject: [PATCH 8/8] [FEAT] adds and uses Commands.isValid --- src/build/Commands.js | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/build/Commands.js b/src/build/Commands.js index 9a7f401..362c23a 100644 --- a/src/build/Commands.js +++ b/src/build/Commands.js @@ -14,22 +14,38 @@ class Commands { * @param {function} callback - Callback to command. */ register(cmd) { + if (!Commands.isValid(cmd)) { + throw new Error(`${cmd} isn't a valid Command!`); + } + this.commands[cmd.name] = cmd; } /** * Checks if a command is set in Commands instance. - * @param {string} cmd - The command's name. + * @param {string} cmdName - The command's name. * @returns {boolean} `True` if the command is set in Commands instance, `False` if not. */ - has(cmd) { + has(cmdName) { const availableCommands = Object.keys(this.commands); - return availableCommands.includes(cmd); + return availableCommands.includes(cmdName); + } + + /** + * Checks if a command is valid. + * @param {any} cmd - The command instance. + * @returns {boolean} `True` if the command is valid, `False` if not. + */ + static isValid(cmd) { + if (cmd.name && cmd.execute && typeof cmd.execute === 'function') { + return true; + } + return false; } /** * Calls (executes) a command. - * @param {string} cmd - The command's name to be called. + * @param {string} cmdName - The command's name to be called. * @param {object} data - The data extracted from the message that called the command. * @param {string} data.command - The command's name extracted from the message. * @param {string[]} data.args - The args extracted from the message.