diff --git a/.env.example b/.env.example index 44a7aeaf..895f30a1 100644 --- a/.env.example +++ b/.env.example @@ -24,10 +24,6 @@ SILVER_FISH_EMOJI_ID= SILVER_FISH_EMOJI_NAME= PORTAL_EMOJI_ID= PORTAL_EMOJI_NAME= -FLANKER_EMOJI_ID= -FRONT_LINE_EMOJI_ID= -SUPPORT_EMOJI_ID= -DAMAGE_EMOJI_ID= LOADING_EMOJI_ID= MEGA_EVOLVE_EMOJI_ID= MEGA_EVOLVE_EMOJI_NAME= @@ -37,36 +33,20 @@ NAME_RATER_EMOJI_ID= ALPHA_VANTAGE_KEY= ANILIST_USERNAME= BITLY_KEY= -CLEARBIT_KEY= CLEVERBOT_KEY= DEVIANTART_ID= DEVIANTART_SECRET= -FACEPLUSPLUS_KEY= -FACEPLUSPLUS_SECRET= -FLICKR_KEY= GIPHY_KEY= GITHUB_ACCESS_TOKEN= -GODADDY_KEY= -GODADDY_SECRET= -GOOGLE_KEY= GOV_KEY= IMGUR_KEY= OPENWEATHERMAP_KEY= OSU_KEY= -PERSONAL_GOOGLE_CALENDAR_ID= SPOTIFY_KEY= SPOTIFY_SECRET= -STACKOVERFLOW_KEY= -TENOR_KEY= TMDB_KEY= -TUMBLR_KEY= -TWITCH_ID= -TWITCH_SECRET= -TWITTER_KEY= -TWITTER_SECRET= UNSPLASH_KEY= USPS_USERID= -WATTPAD_KEY= WEBSTER_KEY= XIAO_GITHUB_REPO_NAME= XIAO_GITHUB_REPO_USERNAME= diff --git a/.gitignore b/.gitignore index 69d6b2b5..cbd08ab6 100644 --- a/.gitignore +++ b/.gitignore @@ -20,9 +20,6 @@ blacklist.json # Tensorflow Models tf_models/ -# Tesseract Trained Data -*.traineddata - # Mac Files .DS_Store diff --git a/assets/images/spam.png b/assets/images/spam.png deleted file mode 100644 index 6f515fd6..00000000 Binary files a/assets/images/spam.png and /dev/null differ diff --git a/assets/images/wynaut.png b/assets/images/wynaut.png deleted file mode 100644 index 0e01f76b..00000000 Binary files a/assets/images/wynaut.png and /dev/null differ diff --git a/assets/json/apple-engraving.json b/assets/json/apple-engraving.json deleted file mode 100644 index 35d4e63c..00000000 --- a/assets/json/apple-engraving.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "airpods": "PRXJ2AM", - "airpods-pro": "PWP22AM", - "pencil": "PU8F2AM", - "ipod": "PVHV2LL", - "ipad-pro": "PTEM2LL", - "ipad": "PW752LL", - "ipad-mini": "PUQX2LL", - "ipad-air": "PUUK2LL" -} diff --git a/assets/json/hentai.json b/assets/json/hentai.json deleted file mode 100644 index b4fa1721..00000000 --- a/assets/json/hentai.json +++ /dev/null @@ -1,21 +0,0 @@ -[ - "hentai", - "ecchi", - "pantsu", - "hentai_gif", - "ahegao", - "rule34", - "hentaipetgirls", - "uncensoredhentai", - "masturbationhentai", - "animehandbras", - "hentaicleavage", - "sukebei", - "yurigif", - "collarhentai", - "oppai_gif", - "cumhentai", - "hentaimini", - "maidhentai", - "yuri" -] diff --git a/assets/json/paladins.json b/assets/json/paladins.json deleted file mode 100644 index 5334f231..00000000 --- a/assets/json/paladins.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "Damage": { - "id": "damage", - "display": "Damage" - }, - "Flanker": { - "id": "kills", - "display": "Kills" - }, - "Front Line": { - "id": "objective_time", - "display": "Objective Time" - }, - "Support": { - "id": "healing", - "display": "Healing" - } -} diff --git a/assets/json/porn.json b/assets/json/porn.json deleted file mode 100644 index 0df965fc..00000000 --- a/assets/json/porn.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - "nsfw_gifs", - "pussy", - "boobs", - "tits", - "ass", - "asstastic", - "lesbians", - "porn", - "nsfw", - "asiansgonewild", - "adorableporn", - "realgirls", - "holdthemoan", - "tinytits", - "blowjobs", - "pawg", - "gonewild", - "nsfw_plowcam", - "legalteens", - "pornstarlethq", - "biggerthanyouthought", - "onoff", - "shorthairchicks", - "petitegonewild", - "plastt", - "bustypetite", - "cumsluts", - "amateur", - "bbw", - "bbwgw" -] diff --git a/assets/json/soundboard.json b/assets/json/soundboard.json deleted file mode 100644 index f410d1c9..00000000 --- a/assets/json/soundboard.json +++ /dev/null @@ -1,19 +0,0 @@ -[ - ["soundboard", "alarm.mp3"], - ["soundboard", "car-crash.mp3"], - ["soundboard", "cat.mp3"], - ["soundboard", "cow.mp3"], - ["soundboard", "dun-dun-dun.mp3"], - ["explosion.mp3"], - ["soundboard", "hello-there.mp3"], - ["soundboard", "here-we-go-again.mp3"], - ["jeopardy.mp3"], - ["soundboard", "laugh-track.mp3"], - ["soundboard", "nipah.mp3"], - ["soundboard", "rooster.mp3"], - ["soundboard", "sad-violin.mp3"], - ["soundboard", "slow-clap.mp3"], - ["whos-that-pokemon.mp3"], - ["soundboard", "windows-error.mp3"], - ["soundboard", "windows-start-up.mp3"] -] diff --git a/assets/json/vocodes.json b/assets/json/vocodes.json deleted file mode 100644 index 9ebbd3fa..00000000 --- a/assets/json/vocodes.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "sonic": "sonic", - "homer": "homer-simpson", - "spongebob": "spongebob-squarepants", - "schwarzenegger": "arnold-schwarzenegger", - "christopher-lee": "christopher-lee", - "leonard-nimoy": "leonard-nimoy", - "squidward": "squidward", - "obama": "barack-obama", - "bart": "bart-simpson", - "lisa": "lisa-simpson", - "devito": "danny-devito", - "clinton": "bill-clinton", - "bush": "george-w-bush", - "reagan": "ronald-reagan", - "carter": "jimmy-carter", - "nixon": "richard-nixon", - "bill-gates": "bill-gates", - "krabs": "mr-krabs", - "scout": "scout", - "bob-barker": "bob-barker", - "boss": "the-boss", - "craig-ferguson": "craig-ferguson", - "gilbert-gottfried": "gilbert-gottfried", - "jim-cramer": "jim-cramer", - "mitch-mcconnell": "mitch-mcconnell", - "paula-deen": "paula-deen", - "david-attenborough": "david-attenborough", - "tucker-carlson": "tucker-carlson", - "alan-rickman": "alan-rickman", - "ben-shapiro": "ben-shapiro", - "betty-white": "betty-white", - "bill-nye": "bill-nye", - "bryan-cranston": "bryan-cranston", - "crypt-keeper": "crypt-keeper", - "dr-phil": "dr-phil-mcgraw", - "jk-simmons": "j-k-simmons", - "judi-dench": "judi-dench", - "michael-rosen": "michael-rosen", - "neil-degrasse-tyson": "neil-degrasse-tyson", - "palmer-luckey": "palmer-luckey", - "peter-thiel": "peter-thiel", - "richard-ayoade": "richard-ayoade", - "sam-altman": "sam-altman", - "saruman": "christopher-lee", - "snape": "alan-rickman", - "shohreh-aghdashloo": "shohreh-aghdashloo", - "wilford-brimley": "wilford-brimley", - "yugi": "yami-yugi", - "anderson-cooper": "anderson-cooper", - "ben-stein": "ben-stein", - "boomstick": "boomstick", - "james-earl-jones": "james-earl-jones", - "vader": "james-earl-jones", - "david-cross": "david-cross", - "hillary": "hillary-clinton", - "john-oliver": "john-oliver", - "zuckerberg": "mark-zuckerberg", - "moistcr1tikal": "moistcr1tikal", - "mr-rogers": "fred-rogers", - "trump": "donald-trump", - "sarah-palin": "sarah-palin", - "snake": "solid-snake", - "tommy-wiseau": "tommy-wiseau", - "trevor-philips": "trevor-philips", - "tupac-shakur": "tupac-shakur", - "vegeta": "vegeta", - "wizard": "wizard", - "george-takei": "george-takei", - "paul-graham": "paul-graham", - "yoda": "yoda", - "goku": "goku", - "peter-griffin": "peter-griffin", - "obi-wan": "obi-wan-kenobi", - "cartman": "eric-cartman", - "anakin": "anakin-skywalker" -} diff --git a/commands/analyze/domain-available.js b/commands/analyze/domain-available.js deleted file mode 100644 index 1c3665f4..00000000 --- a/commands/analyze/domain-available.js +++ /dev/null @@ -1,51 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { GODADDY_KEY, GODADDY_SECRET } = process.env; - -module.exports = class DomainAvailableCommand extends Command { - constructor(client) { - super(client, { - name: 'domain-available', - aliases: ['domain', 'buy-domain'], - group: 'analyze', - memberName: 'domain-available', - description: 'Determines if a domain is available for purchase.', - credit: [ - { - name: 'GoDaddy', - url: 'https://www.godaddy.com/', - reason: 'API', - reasonURL: 'https://developer.godaddy.com/' - } - ], - args: [ - { - key: 'url', - prompt: 'What URL do you want to test?', - type: 'url' - } - ] - }); - } - - async run(msg, { url }) { - const { type, domain, topLevelDomains } = this.client.parseDomain(url.hostname); - if (type !== this.client.ParseResultType.Listed) return msg.reply('This domain is not supported.'); - try { - const { body } = await request - .get('https://api.godaddy.com/v1/domains/available') - .set({ Authorization: `sso-key ${GODADDY_KEY}:${GODADDY_SECRET}` }) - .query({ - domain: `${domain}.${topLevelDomains.join('.')}`, - checkType: 'FAST', - forTransfer: false - }); - if (!body.definitive) return msg.reply('❔ This domain might be available, but I\'m not sure.'); - if (body.available) return msg.reply('πŸ‘ This domain is available.'); - return msg.reply('πŸ‘Ž This domain is taken.'); - } catch (err) { - if (err.status === 422) return msg.reply('This domain is not supported.'); - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/analyze/has-transparency.js b/commands/analyze/has-transparency.js deleted file mode 100644 index 072363d2..00000000 --- a/commands/analyze/has-transparency.js +++ /dev/null @@ -1,37 +0,0 @@ -const Command = require('../../framework/Command'); -const { loadImage } = require('canvas'); -const request = require('node-superfetch'); -const { hasAlpha } = require('../../util/Canvas'); - -module.exports = class HasTransparencyCommand extends Command { - constructor(client) { - super(client, { - name: 'has-transparency', - aliases: ['has-alpha', 'transparency', 'transparent', 'alpha'], - group: 'analyze', - memberName: 'has-transparency', - description: 'Determines if an image has transparency in it.', - throttling: { - usages: 2, - duration: 10 - }, - args: [ - { - key: 'image', - prompt: 'What image would you like to test?', - type: 'image-or-avatar' - } - ] - }); - } - - async run(msg, { image }) { - try { - const { body } = await request.get(image); - const data = await loadImage(body); - return msg.reply(`This image **${hasAlpha(data) ? 'has' : 'does not have'}** transparency.`); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/analyze/nsfw-url.js b/commands/analyze/nsfw-url.js index 5bfbf58c..9e92b3f9 100644 --- a/commands/analyze/nsfw-url.js +++ b/commands/analyze/nsfw-url.js @@ -22,7 +22,7 @@ module.exports = class NsfwUrlCommand extends Command { async run(msg, { url }) { const nsfw = await isUrlNSFW(url, this.client.adultSiteList); if (nsfw === null) return msg.reply('❔ This site sent an error, or just didn\'t respond.'); - if (!nsfw) return msg.reply('πŸ‘ This site is safe!'); + if (!nsfw) return msg.reply('πŸ‘ This site is SFW!'); return msg.reply('πŸ‘Ž This site is NSFW.'); } }; diff --git a/commands/analyze/ocr.js b/commands/analyze/ocr.js deleted file mode 100644 index 2686209d..00000000 --- a/commands/analyze/ocr.js +++ /dev/null @@ -1,55 +0,0 @@ -const Command = require('../../framework/Command'); -const { createWorker } = require('tesseract.js'); -const { reactIfAble } = require('../../util/Util'); -const { LOADING_EMOJI_ID, SUCCESS_EMOJI_ID, FAILURE_EMOJI_ID } = process.env; - -module.exports = class OcrCommand extends Command { - constructor(client) { - super(client, { - name: 'ocr', - aliases: ['tesseract', 'optical-character-recognition'], - group: 'analyze', - memberName: 'ocr', - description: 'Performs Optical Character Recognition on an image.', - throttling: { - usages: 2, - duration: 60 - }, - args: [ - { - key: 'image', - prompt: 'What image would you like to perform OCR on?', - type: 'image-or-avatar' - } - ] - }); - } - - async run(msg, { image }) { - if (image.toLowerCase().endsWith('.gif')) return msg.reply('I cannot read text from GIF images.'); - await reactIfAble(msg, this.client.user, LOADING_EMOJI_ID, 'πŸ’¬'); - const worker = createWorker(); - await worker.load(); - await worker.loadLanguage('eng'); - await worker.initialize('eng'); - let timedOut = false; - const timeout = setTimeout(async () => { - timedOut = true; - await worker.terminate(); - await reactIfAble(msg, msg.author, FAILURE_EMOJI_ID, '❌'); - await msg.reply('Scanning took longer than 30 seconds, so I\'ve given up.'); - }, 30000); - const { data: { text } } = await worker.recognize(image); - if (timedOut) return null; - clearTimeout(timeout); - await worker.terminate(); - await reactIfAble(msg, this.client.user, SUCCESS_EMOJI_ID, 'βœ…'); - if (!text) return msg.reply('There is no text in this image.'); - if (text.length > 2000) { - return msg.reply('The result was over 2000 characters, so here\'s a TXT file.', { - files: [{ attachment: Buffer.from(text), name: 'ocr.txt' }] - }); - } - return msg.reply(text); - } -}; diff --git a/commands/analyze/repost.js b/commands/analyze/repost.js deleted file mode 100644 index 958279ff..00000000 --- a/commands/analyze/repost.js +++ /dev/null @@ -1,75 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const UserAgent = require('user-agents'); -const { stripIndents } = require('common-tags'); -const { reactIfAble } = require('../../util/Util'); -const { LOADING_EMOJI_ID, SUCCESS_EMOJI_ID, FAILURE_EMOJI_ID } = process.env; -const fileTypeRe = /\.(jpe?g|png|gif|jfif|bmp)(\?.+)?$/i; -const notAllowed = ['gif', 'jfif', 'bmp']; - -module.exports = class RepostCommand extends Command { - constructor(client) { - super(client, { - name: 'repost', - aliases: ['repost-sleuth'], - group: 'analyze', - memberName: 'repost', - description: 'Checks if an image is a repost.', - credit: [ - { - name: 'Reddit Repost Sleuth', - url: 'https://www.repostsleuth.com/', - reason: 'API' - } - ], - args: [ - { - key: 'image', - prompt: 'What image would you like to check?', - type: 'image-or-avatar' - } - ] - }); - } - - async run(msg, { image }) { - if (notAllowed.includes(image.toLowerCase().match(fileTypeRe)[1])) { - return msg.reply('I cannot analyze images in this format.'); - } - try { - await reactIfAble(msg, this.client.user, LOADING_EMOJI_ID, 'πŸ’¬'); - const { body } = await request.get(image); - const results = await this.checkImage(body, image); - await reactIfAble(msg, this.client.user, SUCCESS_EMOJI_ID, 'βœ…'); - if (results === false) return msg.reply('This image is clean.'); - return msg.reply(stripIndents` - This image may be a repost. I've seen it **${results.matches.length + 1}** times. - The closest match is at **${results.closest_match.hamming_match_percent}%** similarity. - ${results.closest_match.post.url} - `); - } catch (err) { - await reactIfAble(msg, msg.author, FAILURE_EMOJI_ID, '❌'); - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async checkImage(image, fileurl) { - const { body } = await request - .post('https://api.repostsleuth.com/image') - .query({ - filter: true, - same_sub: false, - filter_author: false, - only_older: false, - include_crossposts: false, - meme_filter: false, - target_match_percent: 90, - filter_dead_matches: false, - target_days_old: 0 - }) - .attach('image', image, `image.${fileurl.match(fileTypeRe)[1]}`) - .set({ 'user-agent': new UserAgent().toString() }); - if (!body.closest_match) return false; - return body; - } -}; diff --git a/commands/analyze/safe-url.js b/commands/analyze/safe-url.js deleted file mode 100644 index e59bc3c6..00000000 --- a/commands/analyze/safe-url.js +++ /dev/null @@ -1,55 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { version } = require('../../package'); -const { GOOGLE_KEY } = process.env; - -module.exports = class SafeUrlCommand extends Command { - constructor(client) { - super(client, { - name: 'safe-url', - aliases: ['check-url', 'safe-browsing', 'virus', 'safe-link', 'check-link', 'spoopy-link'], - group: 'analyze', - memberName: 'safe-url', - description: 'Determines if a URL is safe or not.', - credit: [ - { - name: 'Google', - url: 'https://www.google.com/', - reason: 'Safe Browsing API', - reasonURL: 'https://developers.google.com/safe-browsing/' - } - ], - args: [ - { - key: 'url', - prompt: 'What URL do you want to test?', - type: 'url' - } - ] - }); - } - - async run(msg, { url }) { - try { - const { body } = await request - .post('https://safebrowsing.googleapis.com/v4/threatMatches:find') - .query({ key: GOOGLE_KEY }) - .send({ - client: { - clientId: 'xiao-discord', - clientVersion: version - }, - threatInfo: { - threatTypes: ['MALWARE', 'SOCIAL_ENGINEERING'], - platformTypes: ['ANY_PLATFORM'], - threatEntryTypes: ['URL'], - threatEntries: [{ url }] - } - }); - if (!body.matches) return msg.reply(`πŸ‘ Good to go! This link is safe!`); - return msg.reply('⚠️ This link is unsafe! **Do not click it!** ⚠️'); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/analyze/toxicity.js b/commands/analyze/toxicity.js deleted file mode 100644 index 6e155188..00000000 --- a/commands/analyze/toxicity.js +++ /dev/null @@ -1,57 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { Message } = require('discord.js'); -const { GOOGLE_KEY } = process.env; - -module.exports = class ToxicityCommand extends Command { - constructor(client) { - super(client, { - name: 'toxicity', - aliases: ['perspective', 'comment-toxicity', 'toxic'], - group: 'analyze', - memberName: 'toxicity', - description: 'Determines the toxicity of text.', - flags: [ - { - key: 'severe', - description: 'Makes the check much less vulnerable to basic swearing.' - } - ], - credit: [ - { - name: 'Perspective API', - url: 'https://www.perspectiveapi.com/#/', - reason: 'API' - } - ], - args: [ - { - key: 'text', - prompt: 'What text do you want to test the toxicity of?', - type: 'message|string' - } - ] - }); - } - - async run(msg, { text, flags: { severe } }) { - if (text instanceof Message) text = text.content; - try { - const { body } = await request - .post('https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze') - .query({ key: GOOGLE_KEY }) - .send({ - comment: { text }, - languages: ['en'], - requestedAttributes: severe ? { SEVERE_TOXICITY: {} } : { TOXICITY: {} } - }); - const score = severe ? body.attributeScores.SEVERE_TOXICITY : body.attributeScores.TOXICITY; - const toxicity = Math.round(score.summaryScore.value * 100); - if (toxicity >= 70) return msg.reply(`Likely to be perceived as toxic. (${toxicity}%)`); - if (toxicity >= 40) return msg.reply(`Unsure if this will be perceived as toxic. (${toxicity}%)`); - return msg.reply(`Unlikely to be perceived as toxic. (${toxicity}%)`); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/analyze/what-anime.js b/commands/analyze/what-anime.js deleted file mode 100644 index 53ae7272..00000000 --- a/commands/analyze/what-anime.js +++ /dev/null @@ -1,116 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { createCanvas, loadImage } = require('canvas'); -const { stripIndents } = require('common-tags'); -const { base64, reactIfAble } = require('../../util/Util'); -const { LOADING_EMOJI_ID, SUCCESS_EMOJI_ID, FAILURE_EMOJI_ID } = process.env; - -module.exports = class WhatAnimeCommand extends Command { - constructor(client) { - super(client, { - name: 'what-anime', - aliases: ['anime-source', 'anime-src', 'trace-moe'], - group: 'analyze', - memberName: 'what-anime', - description: 'Determines what anime a screenshot is from.', - throttling: { - usages: 2, - duration: 30 - }, - credit: [ - { - name: 'WAIT: What Anime Is This?', - url: 'https://trace.moe/', - reason: 'API', - reasonURL: 'https://soruly.github.io/trace.moe/#/' - } - ], - args: [ - { - key: 'screenshot', - prompt: 'What screenshot do you want to scan?', - type: 'image' - } - ] - }); - } - - async run(msg, { screenshot }) { - try { - await reactIfAble(msg, this.client.user, LOADING_EMOJI_ID, 'πŸ’¬'); - const status = await this.fetchRateLimit(); - if (!status.status) { - await reactIfAble(msg, msg.author, FAILURE_EMOJI_ID, '❌'); - return msg.reply(`Oh no, I'm out of requests! Please wait ${status.refresh} seconds and try again.`); - } - let { body } = await request.get(screenshot); - if (screenshot.endsWith('.gif')) body = await this.convertGIF(body); - const result = await this.search(body, msg.channel.nsfw); - if (result === 'size') { - await reactIfAble(msg, msg.author, FAILURE_EMOJI_ID, '❌'); - return msg.reply('Please do not send an image larger than 10MB.'); - } - if (result.nsfw && !msg.channel.nsfw) { - await reactIfAble(msg, msg.author, FAILURE_EMOJI_ID, '❌'); - return msg.reply('This is from a hentai, and this isn\'t an NSFW channel, pervert.'); - } - await reactIfAble(msg, this.client.user, SUCCESS_EMOJI_ID, 'βœ…'); - const title = `${result.title}${result.episode ? ` episode ${result.episode}` : ''}`; - return msg.reply(stripIndents` - I'm ${result.prob}% sure this is from ${title}. - ${result.prob < 90 ? '_This probablity is rather low, try using a higher quality image._' : ''} - `, result.preview ? { files: [{ attachment: result.preview, name: 'preview.mp4' }] } : {}); - } catch (err) { - await reactIfAble(msg, msg.author, FAILURE_EMOJI_ID, '❌'); - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async fetchRateLimit() { - try { - const { body } = await request.get('https://trace.moe/api/me'); - return { status: body.user_limit > 0, refresh: body.user_limit_ttl }; - } catch { - return { status: false, refresh: Infinity }; - } - } - - async search(file) { - if (Buffer.byteLength(file) > 1e+7) return 'size'; - const { body } = await request - .post('https://trace.moe/api/search') - .attach('image', base64(file)); - const data = body.docs[0]; - return { - prob: Math.round(data.similarity * 100), - episode: data.episode, - title: data.title_english, - preview: await this.fetchPreview(data), - nsfw: data.is_adult - }; - } - - async fetchPreview(data) { - try { - const { body } = await request - .get(`https://media.trace.moe/video/${data.anilist_id}/${encodeURIComponent(data.filename)}`) - .query({ - t: data.at, - token: data.tokenthumb, - mute: true, - size: 'm' - }); - return body; - } catch { - return null; - } - } - - async convertGIF(image) { - const data = await loadImage(image); - const canvas = createCanvas(data.width, data.height); - const ctx = canvas.getContext('2d'); - ctx.drawImage(data, 0, 0); - return canvas.toBuffer(); - } -}; diff --git a/commands/code/mdn.js b/commands/code/mdn.js deleted file mode 100644 index 370f1561..00000000 --- a/commands/code/mdn.js +++ /dev/null @@ -1,53 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); - -module.exports = class MDNCommand extends Command { - constructor(client) { - super(client, { - name: 'mdn', - group: 'code', - memberName: 'mdn', - description: 'Searches MDN for your query.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'MDN Web Docs', - url: 'https://developer.mozilla.org/en-US/', - reason: 'API' - } - ], - args: [ - { - key: 'query', - prompt: 'What article would you like to search for?', - type: 'string', - parse: query => query.replaceAll('#', '.prototype.') - } - ] - }); - } - - async run(msg, { query }) { - try { - const { body } = await request - .get('https://developer.mozilla.org/api/v1/search') - .query({ - q: query, - locale: 'en-US', - highlight: false - }); - if (!body.documents.length) return msg.say('Could not find any results.'); - const data = body.documents[0]; - const embed = new MessageEmbed() - .setColor(0x066FAD) - .setAuthor('MDN', 'https://i.imgur.com/DFGXabG.png', 'https://developer.mozilla.org/') - .setURL(`https://developer.mozilla.org${data.mdn_url}`) - .setTitle(data.title) - .setDescription(data.summary); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/code/stack-overflow.js b/commands/code/stack-overflow.js deleted file mode 100644 index 7f73b9ce..00000000 --- a/commands/code/stack-overflow.js +++ /dev/null @@ -1,68 +0,0 @@ -const Command = require('../../framework/Command'); -const moment = require('moment'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const { decode: decodeHTML } = require('html-entities'); -const { formatNumber, embedURL } = require('../../util/Util'); -const { STACKOVERFLOW_KEY } = process.env; - -module.exports = class StackOverflowCommand extends Command { - constructor(client) { - super(client, { - name: 'stack-overflow', - group: 'code', - memberName: 'stack-overflow', - description: 'Searches Stack Overflow for your query.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Stack Exchange', - url: 'https://stackexchange.com/', - reason: 'API', - reasonURL: 'https://api.stackexchange.com/docs' - } - ], - args: [ - { - key: 'query', - prompt: 'What question would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const { body } = await request - .get('http://api.stackexchange.com/2.2/search/advanced') - .query({ - page: 1, - pagesize: 1, - order: 'asc', - sort: 'relevance', - answers: 1, - q: query, - site: 'stackoverflow', - key: STACKOVERFLOW_KEY - }); - if (!body.items.length) return msg.say('Could not find any results.'); - const data = body.items[0]; - const embed = new MessageEmbed() - .setColor(0xF48023) - .setAuthor('Stack Overflow', 'https://i.imgur.com/P2jAgE3.png', 'https://stackoverflow.com/') - .setURL(data.link) - .setTitle(decodeHTML(data.title)) - .addField('❯ ID', data.question_id, true) - .addField('❯ Asker', embedURL(data.owner.display_name, data.owner.link), true) - .addField('❯ Views', formatNumber(data.view_count), true) - .addField('❯ Score', formatNumber(data.score), true) - .addField('❯ Creation Date', moment.utc(data.creation_date * 1000).format('MM/DD/YYYY h:mm A'), true) - .addField('❯ Last Activity', - moment.utc(data.last_activity_date * 1000).format('MM/DD/YYYY h:mm A'), true); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/edit-image-text/apple-engraving.js b/commands/edit-image-text/apple-engraving.js deleted file mode 100644 index 74866fee..00000000 --- a/commands/edit-image-text/apple-engraving.js +++ /dev/null @@ -1,53 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { list } = require('../../util/Util'); -const products = require('../../assets/json/apple-engraving'); - -module.exports = class AppleEngravingCommand extends Command { - constructor(client) { - super(client, { - name: 'apple-engraving', - aliases: ['apple-engrave', 'apple-e', 'a-engrave', 'a-engraving'], - group: 'edit-image-text', - memberName: 'apple-engraving', - description: 'Engraves the text of your choice onto an Apple product.', - details: `**Products:** ${Object.keys(products).join(', ')}`, - credit: [ - { - name: 'Apple', - url: 'https://www.apple.com/', - reason: 'API' - } - ], - args: [ - { - key: 'product', - prompt: `What product do you want to engrave? Either ${list(Object.keys(products), 'or')}.`, - type: 'string', - oneOf: Object.keys(products), - parse: product => product.toLowerCase() - }, - { - key: 'text', - prompt: 'What text do you want to engrave?', - type: 'string' - } - ] - }); - } - - async run(msg, { product, text }) { - try { - const { body } = await request - .get(`https://www.apple.com/shop/preview/engrave/${products[product]}/A`) - .query({ - th: text, - s: 2, - f: 'font1' - }); - return msg.say({ files: [{ attachment: body, name: 'apple-engraving.jpg' }] }); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/events/calendar.js b/commands/events/calendar.js index bc43be3d..94db39ec 100644 --- a/commands/events/calendar.js +++ b/commands/events/calendar.js @@ -54,6 +54,6 @@ module.exports = class CalendarCommand extends Command { } } display += '|'; - return msg.code(null, display); + return msg.say(`\`\`\`\n${display}\n\`\`\``); } }; diff --git a/commands/events/covid-19.js b/commands/events/covid-19.js deleted file mode 100644 index 76c2eb50..00000000 --- a/commands/events/covid-19.js +++ /dev/null @@ -1,68 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { MessageEmbed } = require('discord.js'); -const { formatNumber } = require('../../util/Util'); - -module.exports = class Covid19Command extends Command { - constructor(client) { - super(client, { - name: 'covid-19', - aliases: ['coronavirus', 'corona', 'covid'], - group: 'events', - memberName: 'covid-19', - description: 'Responds with stats for COVID-19.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'disease.sh', - url: 'https://disease.sh/', - reason: 'COVID-19 API', - reasonURL: 'https://disease.sh/docs/#/' - } - ], - args: [ - { - key: 'country', - prompt: 'What country do you want to get the stats for? Type `all` to get world stats.', - type: 'string', - default: 'all', - parse: country => encodeURIComponent(country) - } - ] - }); - } - - async run(msg, { country }) { - try { - const data = await this.fetchStats(country); - const slug = country === 'all' ? null : data.country === 'USA' ? 'us' : data.country.toLowerCase(); - const embed = new MessageEmbed() - .setColor(0xA2D84E) - .setAuthor('Worldometers', 'https://i.imgur.com/IoaBMuK.jpg', 'https://www.worldometers.info/coronavirus/') - .setTitle(`Stats for ${country === 'all' ? 'The World' : data.country}`) - .setURL(country === 'all' - ? 'https://www.worldometers.info/coronavirus/' - : `https://www.worldometers.info/coronavirus/country/${encodeURIComponent(slug.replace(/ /g, '-'))}/`) - .setThumbnail(country === 'all' ? null : data.countryInfo.flag || null) - .setFooter('Last Updated') - .setTimestamp(data.updated) - .addField('❯ Total Cases', `${formatNumber(data.cases)} (${formatNumber(data.todayCases)} Today)`, true) - .addField('❯ Total Deaths', `${formatNumber(data.deaths)} (${formatNumber(data.todayDeaths)} Today)`, true) - .addField('❯ Total Recoveries', - `${formatNumber(data.recovered)} (${formatNumber(data.todayRecovered)} Today)`, true) - .addField('❯ Active Cases', formatNumber(data.active), true) - .addField('❯ Active Critical Cases', formatNumber(data.critical), true) - .addField('❯ Tests', formatNumber(data.tests), true); - return msg.embed(embed); - } catch (err) { - if (err.status === 404) return msg.say('Country not found or doesn\'t have any cases.'); - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async fetchStats(country) { - const { body } = await request - .get(`https://disease.sh/v3/covid-19/${country === 'all' ? 'all' : `countries/${country}`}`); - return body; - } -}; diff --git a/commands/events/doomsday-clock.js b/commands/events/doomsday-clock.js deleted file mode 100644 index 6fff068f..00000000 --- a/commands/events/doomsday-clock.js +++ /dev/null @@ -1,43 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { decode: decodeHTML } = require('html-entities'); -const { MessageEmbed } = require('discord.js'); -const { embedURL } = require('../../util/Util'); - -module.exports = class DoomsdayClockCommand extends Command { - constructor(client) { - super(client, { - name: 'doomsday-clock', - group: 'events', - memberName: 'doomsday-clock', - description: 'Responds with the current time of the Doomsday Clock.', - credit: [ - { - name: 'Bulletin of the Atomic Scientists', - url: 'https://thebulletin.org/', - reason: 'Doomsday Clock Data', - reasonURL: 'https://thebulletin.org/doomsday-clock/current-time/' - } - ] - }); - } - - async run(msg) { - try { - const { text } = await request.get('https://thebulletin.org/doomsday-clock/past-statements/'); - const time = text.match(/

(.+)<\/h3>/)[1]; - const year = text.match(/

(.+)<\/h5>/)[1]; - const description = text.match(/
(.|\n)+

(.+)<\/p>/)[2] - .replace(/(.+)<\/a>/, embedURL('$2', '$1')); - const embed = new MessageEmbed() - .setTitle(`${year}: ${time}`) - .setColor(0x000000) - .setURL('https://thebulletin.org/doomsday-clock/current-time/') - .setAuthor('Bulletin of the Atomic Scientists', undefined, 'https://thebulletin.org/') - .setDescription(decodeHTML(description)); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/events/friday-the-13th.js b/commands/events/friday-the-13th.js deleted file mode 100644 index 33d63ec2..00000000 --- a/commands/events/friday-the-13th.js +++ /dev/null @@ -1,26 +0,0 @@ -const Command = require('../../framework/Command'); - -module.exports = class FridayThe13thCommand extends Command { - constructor(client) { - super(client, { - name: 'friday-the-13th', - aliases: ['friday-13th', 'friday-13', 'friday-the-13', 'friday-the-thirteenth', 'friday-thirteenth'], - group: 'events', - memberName: 'friday-the-13th', - description: 'Determines if today is Friday the 13th.', - credit: [ - { - name: 'r/IsTodayFridayThe13th', - url: 'https://www.reddit.com/r/IsTodayFridayThe13th/', - reason: 'Concept' - } - ] - }); - } - - run(msg) { - const today = new Date(); - const isFridaythe13th = today.getDay() === 5 && today.getDate() === 13; - return msg.say(`Today **is${isFridaythe13th ? '' : ' not'}** Friday the 13th.`); - } -}; diff --git a/commands/events/holidays.js b/commands/events/holidays.js deleted file mode 100644 index 5560aa6f..00000000 --- a/commands/events/holidays.js +++ /dev/null @@ -1,74 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { list, today, tomorrow } = require('../../util/Util'); -const { GOOGLE_KEY, PERSONAL_GOOGLE_CALENDAR_ID } = process.env; -const holidayCals = { - USA: 'en.usa#holiday@group.v.calendar.google.com', - Japan: 'en.japanese#holiday@group.v.calendar.google.com', - UK: 'en.uk#holiday@group.v.calendar.google.com', - Australia: 'en.australian#holiday@group.v.calendar.google.com', - Canada: 'en.canadian#holiday@group.v.calendar.google.com' -}; - -module.exports = class HolidaysCommand extends Command { - constructor(client) { - super(client, { - name: 'holidays', - aliases: ['events', 'google-calendar'], - group: 'events', - memberName: 'holidays', - description: 'Responds with today\'s holidays.', - credit: [ - { - name: 'Google', - url: 'https://www.google.com/', - reason: 'Calendar API', - reasonURL: 'https://developers.google.com/calendar/' - } - ] - }); - } - - async run(msg) { - try { - const events = []; - for (const [country, calID] of Object.entries(holidayCals)) { - const standardEvents = await this.fetchHolidays(calID); - if (standardEvents) { - const mapped = standardEvents.map(event => `${event} (${country})`); - events.push(...mapped); - } - } - if (PERSONAL_GOOGLE_CALENDAR_ID) { - const personalEvents = await this.fetchHolidays(PERSONAL_GOOGLE_CALENDAR_ID); - if (personalEvents) events.push(...personalEvents); - } - if (!events.length) return msg.say('There are no holidays today...'); - const holidays = list(events.map(event => `**${event}**`)); - return msg.say(`Today${events.length === 1 ? ' is' : `'s holidays are`} ${holidays}!`); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async fetchHolidays(id) { - try { - const { body } = await request - .get(`https://www.googleapis.com/calendar/v3/calendars/${encodeURIComponent(id)}/events`) - .query({ - maxResults: 20, - orderBy: 'startTime', - singleEvents: true, - timeMax: tomorrow().toISOString(), - timeMin: today().toISOString(), - timeZone: 'UTC', - key: GOOGLE_KEY - }); - if (!body.items.length) return null; - return body.items.map(holiday => holiday.summary); - } catch (err) { - if (err.status === 404) return null; - throw err; - } - } -}; diff --git a/commands/events/humble-bundle.js b/commands/events/humble-bundle.js deleted file mode 100644 index 1e16e962..00000000 --- a/commands/events/humble-bundle.js +++ /dev/null @@ -1,44 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { stripIndents } = require('common-tags'); - -module.exports = class HumbleBundleCommand extends Command { - constructor(client) { - super(client, { - name: 'humble-bundle', - aliases: ['humble'], - group: 'events', - memberName: 'humble-bundle', - description: 'Responds with the current Humble Bundle.', - credit: [ - { - name: 'Humble Bundle', - url: 'https://www.humblebundle.com/', - reason: 'API', - reasonURL: 'https://www.humblebundle.com/developer' - } - ] - }); - } - - async run(msg) { - try { - const { text } = await request.get('https://www.humblebundle.com/androidapp/v2/service_check'); - const body = JSON.parse(text); - if (!body.length) return msg.say('There is no bundle right now...'); - if (body.length > 1) { - return msg.say(stripIndents` - There are **${body.length}** bundles on right now! - ${body.map(bundle => `**${bundle.bundle_name}:** <${bundle.url}>`).join('\n')} - `); - } - const data = body[0]; - return msg.say(stripIndents` - The current bundle is **${data.bundle_name}**! - ${data.url} - `); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/events/iss.js b/commands/events/iss.js deleted file mode 100644 index db980c54..00000000 --- a/commands/events/iss.js +++ /dev/null @@ -1,32 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); - -module.exports = class IssCommand extends Command { - constructor(client) { - super(client, { - name: 'iss', - aliases: ['international-space-station'], - group: 'events', - memberName: 'iss', - description: 'Responds with where the Internation Space Station currently is.', - credit: [ - { - name: 'Open Notify', - url: 'http://open-notify.org/', - reason: 'ISS Current Location API', - reasonURL: 'http://open-notify.org/Open-Notify-API/ISS-Location-Now/' - } - ] - }); - } - - async run(msg) { - try { - const { body } = await request.get('http://api.open-notify.org/iss-now.json'); - const position = body.iss_position; - return msg.say(`The ISS is currently at **${position.latitude}, ${position.longitude}**.`); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/events/people-in-space.js b/commands/events/people-in-space.js deleted file mode 100644 index 01eda9b1..00000000 --- a/commands/events/people-in-space.js +++ /dev/null @@ -1,44 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { MessageEmbed } = require('discord.js'); - -module.exports = class PeopleInSpaceCommand extends Command { - constructor(client) { - super(client, { - name: 'people-in-space', - aliases: ['space', 'spacemen', 'astronauts', 'spacewomen'], - group: 'events', - memberName: 'people-in-space', - description: 'Responds with the people currently in space.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Open Notify', - url: 'http://open-notify.org/', - reason: 'People in Space API', - reasonURL: 'http://open-notify.org/Open-Notify-API/People-In-Space/' - } - ] - }); - } - - async run(msg) { - try { - const { body } = await request.get('http://api.open-notify.org/astros.json'); - const crafts = {}; - for (const person of body.people) { - if (crafts[person.craft]) crafts[person.craft].push(person.name); - else crafts[person.craft] = [person.name]; - } - const embed = new MessageEmbed() - .setColor(0x2E528E) - .setImage('https://i.imgur.com/m3ooNfl.jpg'); - for (const [craft, people] of Object.entries(crafts)) { - embed.addField(`❯ ${craft} (${people.length})`, people.join('\n'), true); - } - return msg.say(`There are currently **${body.number}** people in space!`, embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/info/bot.js b/commands/info/bot.js deleted file mode 100644 index 3c819e03..00000000 --- a/commands/info/bot.js +++ /dev/null @@ -1,60 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const moment = require('moment'); -const { embedURL, formatNumber } = require('../../util/Util'); - -module.exports = class BotCommand extends Command { - constructor(client) { - super(client, { - name: 'bot', - aliases: ['discord-bot', 'bot-info', 'discord-bot-info'], - group: 'info', - memberName: 'bot', - description: 'Responds with information on a Discord bot.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Discord Bots', - url: 'https://discord.bots.gg/', - reason: 'API' - } - ], - args: [ - { - key: 'user', - prompt: 'What bot would you like to get information on?', - type: 'user' - } - ] - }); - } - - async run(msg, { user }) { - if (!user.bot) return msg.say('This user is not a bot.'); - try { - const { body } = await request.get(`https://discord.bots.gg/api/v1/bots/${user.id}`); - const avatar = body.avatarURL === '/img/bot_icon_placeholder.png' - ? 'https://discord.bots.gg/img/bot_icon_placeholder.png' - : body.avatarURL; - const embed = new MessageEmbed() - .setColor(0x000001) - .setTitle(`${body.username} by ${body.owner.username}#${body.owner.discriminator}`) - .setDescription(body.shortDescription) - .setAuthor('Discord Bots', 'https://i.imgur.com/OhZCqVd.jpg', 'https://discord.bots.gg/') - .setThumbnail(avatar) - .setURL(`https://discord.bots.gg/bots/${user.id}`) - .setFooter(user.id) - .addField('❯ Prefix', body.prefix || '???', true) - .addField('❯ Library', body.libraryName || '???', true) - .addField('❯ Servers', body.guildCount ? formatNumber(body.guildCount) : '???', true) - .addField('❯ Invite', body.botInvite ? embedURL('Here', body.botInvite) : '???', true) - .addField('❯ Server', body.supportInvite ? embedURL('Here', body.supportInvite) : '???', true) - .addField('❯ Public List Date', moment.utc(body.addedDate).format('MM/DD/YYYY h:mm A'), true); - return msg.embed(embed); - } catch (err) { - if (err.status === 404) return msg.say('This bot is not publicly listed.'); - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/info/channel.js b/commands/info/channel.js deleted file mode 100644 index 3a2fc716..00000000 --- a/commands/info/channel.js +++ /dev/null @@ -1,45 +0,0 @@ -const Command = require('../../framework/Command'); -const moment = require('moment'); -const { MessageEmbed } = require('discord.js'); -const types = { - dm: 'DM', - group: 'Group DM', - text: 'Text Channel', - voice: 'Voice Channel', - category: 'Category', - unknown: 'Unknown' -}; - -module.exports = class ChannelCommand extends Command { - constructor(client) { - super(client, { - name: 'channel', - aliases: ['channel-info'], - group: 'info', - memberName: 'channel', - description: 'Responds with detailed information on a channel.', - clientPermissions: ['EMBED_LINKS'], - args: [ - { - key: 'channel', - prompt: 'Which channel would you like to get information on?', - type: 'channel', - default: msg => msg.channel - } - ] - }); - } - - run(msg, { channel }) { - const embed = new MessageEmbed() - .setColor(0x00AE86) - .addField('❯ Name', channel.type === 'dm' ? `@${channel.recipient.username}` : channel.name, true) - .addField('❯ ID', channel.id, true) - .addField('❯ NSFW', channel.nsfw ? 'Yes' : 'No', true) - .addField('❯ Category', channel.parent ? channel.parent.name : 'None', true) - .addField('❯ Type', types[channel.type], true) - .addField('❯ Creation Date', moment.utc(channel.createdAt).format('MM/DD/YYYY h:mm A'), true) - .addField('❯ Topic', channel.topic || 'None'); - return msg.embed(embed); - } -}; diff --git a/commands/info/emoji-list.js b/commands/info/emoji-list.js deleted file mode 100644 index 0edb64f8..00000000 --- a/commands/info/emoji-list.js +++ /dev/null @@ -1,32 +0,0 @@ -const Command = require('../../framework/Command'); -const { list } = require('../../util/Util'); -const types = ['animated', 'regular']; - -module.exports = class EmojiListCommand extends Command { - constructor(client) { - super(client, { - name: 'emoji-list', - aliases: ['emojis', 'emotes', 'emote-list'], - group: 'info', - memberName: 'emoji-list', - description: 'Responds with a list of the server\'s custom emoji.', - guildOnly: true, - args: [ - { - key: 'type', - prompt: `What type of emoji would you like to view? Either ${list(types, 'or')}.`, - type: 'string', - default: 'regular', - oneOf: types, - parse: type => type.toLowerCase() - } - ] - }); - } - - run(msg, { type }) { - const emojis = msg.guild.emojis.cache.filter(emoji => type === 'animated' ? emoji.animated : !emoji.animated); - if (!emojis.size) return msg.say(`This server has no ${type} custom emoji.`); - return msg.say(emojis.map(emoji => emoji.toString()).sort().join(' '), { split: { char: ' ' } }); - } -}; diff --git a/commands/info/emoji.js b/commands/info/emoji.js deleted file mode 100644 index ba23c97b..00000000 --- a/commands/info/emoji.js +++ /dev/null @@ -1,38 +0,0 @@ -const Command = require('../../framework/Command'); -const moment = require('moment'); -const { MessageEmbed } = require('discord.js'); - -module.exports = class EmojiCommand extends Command { - constructor(client) { - super(client, { - name: 'emoji', - aliases: ['emoji-info', 'emote'], - group: 'info', - memberName: 'emoji', - description: 'Responds with detailed information on an emoji.', - guildOnly: true, - clientPermissions: ['EMBED_LINKS', 'MANAGE_EMOJIS'], - args: [ - { - key: 'emoji', - prompt: 'Which emoji would you like to get information on?', - type: 'custom-emoji' - } - ] - }); - } - - async run(msg, { emoji }) { - if (!emoji.author && !emoji.managed) await emoji.fetchAuthor(); - const embed = new MessageEmbed() - .setColor(0x00AE86) - .setThumbnail(emoji.url) - .addField('❯ Name', emoji.name, true) - .addField('❯ ID', emoji.id, true) - .addField('❯ Creation Date', moment.utc(emoji.createdAt).format('MM/DD/YYYY h:mm A'), true) - .addField('❯ Animated?', emoji.animated ? 'Yes' : 'No', true) - .addField('❯ External?', emoji.managed ? 'Yes' : 'No', true) - .addField('❯ Added By', emoji.author ? emoji.author.tag : '???', true); - return msg.embed(embed); - } -}; diff --git a/commands/info/id.js b/commands/info/id.js deleted file mode 100644 index 5c16756c..00000000 --- a/commands/info/id.js +++ /dev/null @@ -1,25 +0,0 @@ -const Command = require('../../framework/Command'); - -module.exports = class IDCommand extends Command { - constructor(client) { - super(client, { - name: 'id', - aliases: ['user-id', 'member-id'], - group: 'info', - memberName: 'id', - description: 'Responds with a user\'s ID.', - args: [ - { - key: 'user', - prompt: 'Which user do you want to get the ID of?', - type: 'user', - default: msg => msg.author - } - ] - }); - } - - run(msg, { user }) { - return msg.reply(`${user.id === msg.author.id ? 'Your' : `${user.username}'s`} ID is ${user.id}.`); - } -}; diff --git a/commands/info/message-source.js b/commands/info/message-source.js deleted file mode 100644 index 56543f59..00000000 --- a/commands/info/message-source.js +++ /dev/null @@ -1,26 +0,0 @@ -const Command = require('../../framework/Command'); -const { shorten } = require('../../util/Util'); - -module.exports = class MessageSourceCommand extends Command { - constructor(client) { - super(client, { - name: 'message-source', - aliases: ['msg-source', 'message-src', 'msg-src', 'source', 'src'], - group: 'info', - memberName: 'message-source', - description: 'Responds with a codeblock containing a message\'s contents.', - args: [ - { - key: 'message', - prompt: 'Which message do you want to get the source of?', - type: 'message' - } - ] - }); - } - - run(msg, { message }) { - if (!message.content) return msg.reply('That message has no content. Maybe it\'s an embed or image?'); - return msg.code(null, shorten(message.content, 1990)); - } -}; diff --git a/commands/info/message.js b/commands/info/message.js deleted file mode 100644 index 09b24c3f..00000000 --- a/commands/info/message.js +++ /dev/null @@ -1,36 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); - -module.exports = class MessageCommand extends Command { - constructor(client) { - super(client, { - name: 'message', - aliases: ['message-info', 'msg', 'msg-info'], - group: 'info', - memberName: 'message', - description: 'Responds with detailed information on a message.', - clientPermissions: ['EMBED_LINKS'], - args: [ - { - key: 'message', - prompt: 'Which message would you like to get information on?', - type: 'message' - } - ] - }); - } - - run(msg, { message }) { - const hasImage = message.attachments.size && message.attachments.first().width; - const embed = new MessageEmbed() - .setColor(message.member ? message.member.displayHexColor : 0x00AE86) - .setThumbnail(message.author.displayAvatarURL({ format: 'png', dynamic: true })) - .setImage(hasImage ? message.attachments.first().url : null) - .setAuthor(message.author.tag, message.author.displayAvatarURL({ format: 'png', dynamic: true })) - .setDescription(message.content) - .setTimestamp(message.createdAt) - .setFooter(`ID: ${message.id}`) - .addField('❯ Jump', `[Click Here to Jump](${message.url})`); - return msg.embed(embed); - } -}; diff --git a/commands/info/role.js b/commands/info/role.js deleted file mode 100644 index 3b9d1478..00000000 --- a/commands/info/role.js +++ /dev/null @@ -1,40 +0,0 @@ -const Command = require('../../framework/Command'); -const moment = require('moment'); -const { MessageEmbed } = require('discord.js'); -const permissions = require('../../assets/json/permission-names'); - -module.exports = class RoleCommand extends Command { - constructor(client) { - super(client, { - name: 'role', - aliases: ['role-info'], - group: 'info', - memberName: 'role', - description: 'Responds with detailed information on a role.', - guildOnly: true, - clientPermissions: ['EMBED_LINKS'], - args: [ - { - key: 'role', - prompt: 'Which role would you like to get information on?', - type: 'role' - } - ] - }); - } - - run(msg, { role }) { - const serialized = role.permissions.serialize(); - const perms = Object.keys(permissions).filter(perm => serialized[perm]); - const embed = new MessageEmbed() - .setColor(role.hexColor) - .addField('❯ Name', role.name, true) - .addField('❯ ID', role.id, true) - .addField('❯ Color', role.hexColor.toUpperCase(), true) - .addField('❯ Creation Date', moment.utc(role.createdAt).format('MM/DD/YYYY h:mm A'), true) - .addField('❯ Hoisted?', role.hoist ? 'Yes' : 'No', true) - .addField('❯ Mentionable?', role.mentionable ? 'Yes' : 'No', true) - .addField('❯ Permissions', perms.map(perm => permissions[perm]).join(', ') || 'None'); - return msg.embed(embed); - } -}; diff --git a/commands/info/server.js b/commands/info/server.js deleted file mode 100644 index ee0622c3..00000000 --- a/commands/info/server.js +++ /dev/null @@ -1,51 +0,0 @@ -const Command = require('../../framework/Command'); -const moment = require('moment'); -const { MessageEmbed } = require('discord.js'); -const { formatNumber } = require('../../util/Util'); -const filterLevels = { - DISABLED: 'Off', - MEMBERS_WITHOUT_ROLES: 'No Role', - ALL_MEMBERS: 'Everyone' -}; -const verificationLevels = { - NONE: 'None', - LOW: 'Low', - MEDIUM: 'Medium', - HIGH: 'High', - VERY_HIGH: 'Highest' -}; - -module.exports = class ServerCommand extends Command { - constructor(client) { - super(client, { - name: 'server', - aliases: ['guild', 'server-info', 'guild-info'], - group: 'info', - memberName: 'server', - description: 'Responds with detailed information on the server.', - guildOnly: true, - clientPermissions: ['EMBED_LINKS'] - }); - } - - async run(msg) { - const owner = await msg.guild.fetchOwner(); - const embed = new MessageEmbed() - .setColor(0x00AE86) - .setThumbnail(msg.guild.iconURL({ format: 'png' })) - .addField('❯ Name', msg.guild.name, true) - .addField('❯ ID', msg.guild.id, true) - .addField('❯ Creation Date', moment.utc(msg.guild.createdAt).format('MM/DD/YYYY h:mm A'), true) - .addField('❯ Owner', owner.user.tag, true) - .addField('❯ Boost Count', formatNumber(msg.guild.premiumSubscriptionCount || 0), true) - .addField('❯ Boost Tier', msg.guild.premiumTier ? `Tier ${msg.guild.premiumTier}` : 'None', true) - .addField('❯ Region', msg.guild.region.toUpperCase(), true) - .addField('❯ Explicit Filter', filterLevels[msg.guild.explicitContentFilter], true) - .addField('❯ Verification Level', verificationLevels[msg.guild.verificationLevel], true) - .addField('❯ Members', formatNumber(msg.guild.memberCount), true) - .addField('❯ Roles', formatNumber(msg.guild.roles.cache.size), true) - .addField('❯ Channels', - formatNumber(msg.guild.channels.cache.filter(channel => channel.type !== 'category').size), true); - return msg.embed(embed); - } -}; diff --git a/commands/info/user.js b/commands/info/user.js deleted file mode 100644 index 91e0b464..00000000 --- a/commands/info/user.js +++ /dev/null @@ -1,72 +0,0 @@ -const Command = require('../../framework/Command'); -const moment = require('moment'); -const { MessageEmbed } = require('discord.js'); -const { trimArray } = require('../../util/Util'); -const flags = { - DISCORD_EMPLOYEE: 'Discord Employee', - PARTNERED_SERVER_OWNER: 'Discord Partner', - BUGHUNTER_LEVEL_1: 'Bug Hunter (Level 1)', - BUGHUNTER_LEVEL_2: 'Bug Hunter (Level 2)', - HYPESQUAD_EVENTS: 'HypeSquad Events', - HOUSE_BRAVERY: 'House of Bravery', - HOUSE_BRILLIANCE: 'House of Brilliance', - HOUSE_BALANCE: 'House of Balance', - EARLY_SUPPORTER: 'Early Supporter', - TEAM_USER: 'Team User', - SYSTEM: 'System', - VERIFIED_BOT: 'Verified Bot', - EARLY_VERIFIED_BOT_DEVELOPER: 'Early Verified Bot Developer' -}; -const deprecated = ['DISCORD_PARTNER', 'VERIFIED_DEVELOPER']; - -module.exports = class UserCommand extends Command { - constructor(client) { - super(client, { - name: 'user', - aliases: ['user-info', 'member', 'member-info', 'profile', 'who-is', 'who'], - group: 'info', - memberName: 'user', - description: 'Responds with detailed information on a user.', - clientPermissions: ['EMBED_LINKS'], - args: [ - { - key: 'user', - prompt: 'Which user would you like to get information on?', - type: 'user', - default: msg => msg.author - } - ] - }); - } - - async run(msg, { user }) { - const userFlags = user.flags ? user.flags.toArray().filter(flag => !deprecated.includes(flag)) : []; - const embed = new MessageEmbed() - .setThumbnail(user.displayAvatarURL({ format: 'png', dynamic: true })) - .setAuthor(user.tag) - .addField('❯ Discord Join Date', moment.utc(user.createdAt).format('MM/DD/YYYY h:mm A'), true) - .addField('❯ ID', user.id, true) - .addField('❯ Bot?', user.bot ? 'Yes' : 'No', true) - .addField('❯ Flags', userFlags.length ? userFlags.map(flag => flags[flag]).join(', ') : 'None'); - if (msg.guild) { - try { - const member = await msg.guild.members.fetch(user.id); - const defaultRole = msg.guild.roles.cache.get(msg.guild.id); - const roles = member.roles.cache - .filter(role => role.id !== defaultRole.id) - .sort((a, b) => b.position - a.position) - .map(role => role.name); - embed - .addField('❯ Server Join Date', moment.utc(member.joinedAt).format('MM/DD/YYYY h:mm A'), true) - .addField('❯ Highest Role', - member.roles.highest.id === defaultRole.id ? 'None' : member.roles.highest.name, true) - .addField('❯ Hoist Role', member.roles.hoist ? member.roles.hoist.name : 'None', true) - .addField(`❯ Roles (${roles.length})`, roles.length ? trimArray(roles, 6).join(', ') : 'None') - .setColor(member.displayHexColor); - } catch { - embed.setFooter('Failed to resolve member, showing basic user information instead.'); - } - } - return msg.embed(embed); - } -}; diff --git a/commands/search/anime-figure.js b/commands/search/anime-figure.js deleted file mode 100644 index 612952c5..00000000 --- a/commands/search/anime-figure.js +++ /dev/null @@ -1,49 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const cheerio = require('cheerio'); - -module.exports = class AnimeFigureCommand extends Command { - constructor(client) { - super(client, { - name: 'anime-figure', - aliases: ['my-figure-collection', 'mfc', 'figure'], - group: 'search', - memberName: 'anime-figure', - description: 'Searches MyFigureCollection for your query.', - credit: [ - { - name: 'MyFigureCollection.net', - url: 'https://myfigurecollection.net/', - reason: 'Figure Data' - } - ], - args: [ - { - key: 'query', - prompt: 'What figure would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const location = await this.search(query); - if (!location) return msg.say('Could not find any results.'); - return msg.say(location); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async search(query) { - const { text } = await request - .get('https://myfigurecollection.net/browse.v4.php') - .query({ keywords: query }); - const $ = cheerio.load(text); - const location = $('span[class="item-icon"]').first().children().first().attr('href'); - if (!location) return null; - return `https://myfigurecollection.net${location}`; - } -}; diff --git a/commands/search/book.js b/commands/search/book.js deleted file mode 100644 index 349cc6ab..00000000 --- a/commands/search/book.js +++ /dev/null @@ -1,61 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const { shorten, formatNumber } = require('../../util/Util'); -const { GOOGLE_KEY } = process.env; - -module.exports = class BookCommand extends Command { - constructor(client) { - super(client, { - name: 'book', - aliases: ['google-book', 'google-books'], - group: 'search', - memberName: 'book', - description: 'Searches Google Books for a book.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Google', - url: 'https://www.google.com/', - reason: 'Books API', - reasonURL: 'https://developers.google.com/books/' - } - ], - args: [ - { - key: 'query', - prompt: 'What book would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const { body } = await request - .get('https://www.googleapis.com/books/v1/volumes') - .query({ - apiKey: GOOGLE_KEY, - q: query, - maxResults: 1, - printType: 'books' - }); - if (!body.items) return msg.say('Could not find any results.'); - const data = body.items[0].volumeInfo; - const embed = new MessageEmbed() - .setColor(0x4285F4) - .setTitle(data.title) - .setURL(data.previewLink) - .setAuthor('Google Books', 'https://i.imgur.com/N3oHABo.png', 'https://books.google.com/') - .setDescription(data.description ? shorten(data.description) : 'No description available.') - .setThumbnail(data.imageLinks ? data.imageLinks.thumbnail : null) - .addField('❯ Authors', data.authors && data.authors.length ? data.authors.join(', ') : '???') - .addField('❯ Publish Date', data.publishedDate || '???', true) - .addField('❯ Page Count', data.pageCount ? formatNumber(data.pageCount) : '???', true); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/company.js b/commands/search/company.js deleted file mode 100644 index f4ef833e..00000000 --- a/commands/search/company.js +++ /dev/null @@ -1,68 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const { CLEARBIT_KEY } = process.env; -const dragonFireAliases = ['dragonfire535', 'dragon fire', 'dragonfire']; - -module.exports = class CompanyCommand extends Command { - constructor(client) { - super(client, { - name: 'company', - aliases: ['clearbit', 'logo', 'company-logo'], - group: 'search', - memberName: 'company', - description: 'Responds with the name and logo of a company.', - credit: [ - { - name: 'Clearbit', - url: 'https://clearbit.com/', - reason: 'Autocomplete API', - reasonURL: 'https://dashboard.clearbit.com/docs#autocomplete-api' - } - ], - args: [ - { - key: 'query', - prompt: 'What company would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const data = await this.fetchCompany(query); - if (!data) return msg.say('Could not find any results.'); - if (!msg.channel.nsfw && this.client.adultSiteList.includes(data.domain)) { - return msg.reply('This site is NSFW.'); - } - const embed = new MessageEmbed() - .setTitle(data.name) - .setImage(data.logo) - .setFooter(data.dragonFire ? 'Logo by MissPeahen' : 'Logos provided by Clearbit') - .setURL(data.domain ? `https://${data.domain}` : null) - .setColor(0x00AE86); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async fetchCompany(query) { - if (dragonFireAliases.includes(query.toLowerCase())) { - return { - name: 'Dragon Fire', - logo: 'https://i.imgur.com/tHxWaoA.png', - domain: null, - dragonFire: true - }; - } - const { body } = await request - .get(`https://autocomplete.clearbit.com/v1/companies/suggest`) - .query({ query }) - .set({ Authorization: `Bearer ${CLEARBIT_KEY}` }); - if (!body.length) return null; - return body[0]; - } -}; diff --git a/commands/search/country.js b/commands/search/country.js deleted file mode 100644 index ba0435e7..00000000 --- a/commands/search/country.js +++ /dev/null @@ -1,60 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const { formatNumber } = require('../../util/Util'); - -module.exports = class CountryCommand extends Command { - constructor(client) { - super(client, { - name: 'country', - group: 'search', - memberName: 'country', - description: 'Responds with information on a country.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Rest Countries', - url: 'https://restcountries.eu/', - reason: 'API' - } - ], - args: [ - { - key: 'query', - prompt: 'What country would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const { body } = await request.get(`https://restcountries.eu/rest/v2/name/${encodeURIComponent(query)}`); - const data = body.find(country => { - const search = query.toLowerCase(); - return country.name.toLowerCase() === search - || country.altSpellings.some(alt => alt.toLowerCase() === search) - || country.alpha2Code.toLowerCase() === search - || country.alpha3Code.toLowerCase() === search - || country.nativeName.toLowerCase() === search; - }) || body[0]; - const embed = new MessageEmbed() - .setColor(0x00AE86) - .setTitle(data.name) - .setThumbnail(`https://www.countryflags.io/${data.alpha2Code}/flat/64.png`) - .addField('❯ Population', formatNumber(data.population), true) - .addField('❯ Capital', data.capital || 'None', true) - .addField('❯ Currency', data.currencies[0].symbol, true) - .addField('❯ Location', data.subregion || data.region, true) - .addField('❯ Demonym', data.demonym || 'None', true) - .addField('❯ Native Name', data.nativeName, true) - .addField('❯ Area', `${formatNumber(data.area)}km`, true) - .addField('❯ Languages', data.languages.map(lang => lang.name).join('/')); - return msg.embed(embed); - } catch (err) { - if (err.status === 404) return msg.say('Could not find any results.'); - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/danbooru.js b/commands/search/danbooru.js deleted file mode 100644 index 0cb0c604..00000000 --- a/commands/search/danbooru.js +++ /dev/null @@ -1,49 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); - -module.exports = class DanbooruCommand extends Command { - constructor(client) { - super(client, { - name: 'danbooru', - aliases: ['booru'], - group: 'search', - memberName: 'danbooru', - description: 'Responds with an image from Danbooru, with optional query.', - nsfw: true, - credit: [ - { - name: 'Danbooru', - url: 'https://danbooru.donmai.us/', - reason: 'API' - } - ], - args: [ - { - key: 'query', - prompt: 'What image would you like to search for?', - type: 'string', - default: '', - validate: query => { - if (!query.includes(' ')) return true; - return 'Invalid query, please only search for one tag at a time.'; - } - } - ] - }); - } - - async run(msg, { query }) { - try { - const { body } = await request - .get('https://danbooru.donmai.us/posts.json') - .query({ - tags: `${query} order:random`, - limit: 1 - }); - if (!body.length || !body[0].file_url) return msg.say('Could not find any results.'); - return msg.say(body[0].file_url); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/derpibooru.js b/commands/search/derpibooru.js deleted file mode 100644 index 9010c118..00000000 --- a/commands/search/derpibooru.js +++ /dev/null @@ -1,61 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); - -module.exports = class DerpibooruCommand extends Command { - constructor(client) { - super(client, { - name: 'derpibooru', - aliases: ['derpi'], - group: 'search', - memberName: 'derpibooru', - description: 'Responds with an image from Derpibooru.', - credit: [ - { - name: 'Hasbro', - url: 'https://shop.hasbro.com/en-us', - reason: 'Original "My Little Pony: Friendship is Magic" Show', - reasonURL: 'https://mylittlepony.hasbro.com/en-us' - }, - { - name: 'Derpibooru', - url: 'https://derpibooru.org/', - reason: 'API', - reasonURL: 'https://www.derpibooru.org/pages/api' - } - ], - args: [ - { - key: 'query', - prompt: 'What image would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const url = await this.search(query, msg.channel.nsfw || false); - if (!url) return msg.say('Could not find any results.'); - if (url === 'nsfw') return msg.say('The image I found was NSFW, and this isn\'t the channel for that.'); - return msg.say(url); - } catch (err) { - if (err.status === 404) return msg.say('Could not find any results.'); - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async search(query, nsfw) { - const { body } = await request - .get('https://derpibooru.org/api/v1/json/search') - .query({ - q: query, - per_page: 1, - sf: 'random' - }); - if (!body || !body.images || !body.images.length) return null; - const image = body.images[0]; - if (!image.tags.includes('safe') && !nsfw) return 'nsfw'; - return image.representations.full; - } -}; diff --git a/commands/search/esrb.js b/commands/search/esrb.js deleted file mode 100644 index b8f3a817..00000000 --- a/commands/search/esrb.js +++ /dev/null @@ -1,68 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const path = require('path'); -const { decode: decodeHTML } = require('html-entities'); - -module.exports = class EsrbCommand extends Command { - constructor(client) { - super(client, { - name: 'esrb', - aliases: ['game-rating'], - group: 'search', - memberName: 'esrb', - description: 'Searches ESRB for your query.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'ESRB', - url: 'https://www.esrb.org/', - reason: 'API' - } - ], - args: [ - { - key: 'query', - prompt: 'What game would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const data = await this.search(query); - if (!data) return msg.say('Could not find any results.'); - const ratingFile = path.join(__dirname, '..', '..', 'assets', 'images', 'esrb', `${data.rating}.png`); - const embed = new MessageEmbed() - .attachFiles([{ attachment: ratingFile, name: 'rating.png' }]) - .setColor(0x1C8CDE) - .setTitle(`${decodeHTML(data.title)} by ${decodeHTML(data.company)}`) - .setDescription(data.descriptors || 'No Descriptors') - .setAuthor('ESRB', 'https://i.imgur.com/29U6Bax.jpg', 'https://www.esrb.org/') - .setThumbnail('attachment://rating.png') - .setURL(`https://www.esrb.org/ratings/${data.certificate}/`); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async search(query) { - const { text } = await request - .post('https://www.esrb.org/wp-admin/admin-ajax.php') - .attach({ - action: 'search_rating', - 'args[searchKeyword]': query, - 'args[searchType]': 'All', - 'args[pg]': 1, - 'args[platform][]': 'All Platforms', - 'args[rating][]': 'E,E10+,T,M,AO', - 'args[descriptor]': 'All Content' - }); - const body = JSON.parse(text); - if (!body.games.length) return null; - return body.games.find(game => game.title.toLowerCase() === query.toLowerCase()) || body.games[0]; - } -}; diff --git a/commands/search/flickr.js b/commands/search/flickr.js deleted file mode 100644 index 8091da69..00000000 --- a/commands/search/flickr.js +++ /dev/null @@ -1,59 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { isImageNSFW } = require('../../util/Util'); -const { FLICKR_KEY } = process.env; - -module.exports = class FlickrCommand extends Command { - constructor(client) { - super(client, { - name: 'flickr', - group: 'search', - memberName: 'flickr', - description: 'Searches Flickr for your query.', - throttling: { - usages: 2, - duration: 30 - }, - credit: [ - { - name: 'Flickr', - url: 'https://www.flickr.com/', - reason: 'API', - reasonURL: 'https://www.flickr.com/services/api/' - } - ], - args: [ - { - key: 'query', - prompt: 'What photo would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const { body } = await request - .get('https://api.flickr.com/services/rest/') - .query({ - api_key: FLICKR_KEY, - format: 'json', - method: 'flickr.photos.search', - text: query, - nojsoncallback: true - }); - if (!body.photos.photo.length) return msg.say('Could not find any results.'); - const data = body.photos.photo[Math.floor(Math.random() * body.photos.photo.length)]; - const url = `https://farm${data.farm}.staticflickr.com/${data.server}/${data.id}_${data.secret}.jpg`; - if (!msg.channel.nsfw) { - const { body: imageBody } = await request.get(url); - const aiDetect = await isImageNSFW(this.client.nsfwModel, imageBody); - if (aiDetect) return msg.reply('Found an NSFW image. Sorry, please try again.'); - } - return msg.say(url); - } catch (err) { - return msg.say(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/google.js b/commands/search/google.js deleted file mode 100644 index 7c8b4403..00000000 --- a/commands/search/google.js +++ /dev/null @@ -1,78 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const cheerio = require('cheerio'); -const { URLSearchParams, URL } = require('url'); - -module.exports = class GoogleCommand extends Command { - constructor(client) { - super(client, { - name: 'google', - aliases: ['search'], - group: 'search', - memberName: 'google', - description: 'Searches Google for your query.', - credit: [ - { - name: 'Google', - url: 'https://www.google.com/', - reason: 'Search' - }, - { - name: 'LMGTFY', - url: 'https://lmgtfy.com/', - reason: 'API' - } - ], - args: [ - { - key: 'query', - prompt: 'What would you like to search for?', - type: 'string', - validate: query => { - if (encodeURIComponent(query).length < 1950) return true; - return 'Invalid query, your query is too long.'; - } - } - ] - }); - } - - async run(msg, { query }) { - let hrefs; - try { - hrefs = await this.search(query, msg.channel.nsfw || false); - } catch { - hrefs = [{ href: `http://lmgtfy.com/?iie=1&q=${encodeURIComponent(query)}`, title: 'LMGTFY' }]; - } - if (!hrefs) return msg.say('Could not find any results.'); - return msg.say(hrefs.map(href => `${href.title}\n<${href.href}>`).join('\n\n')); - } - - async search(query, nsfw) { - const { text } = await request - .get('https://www.google.com/search') - .query({ - safe: nsfw ? 'images' : 'active', - pws: 0, - filter: 0, - q: query - }) - .set({ 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1' }); - const $ = cheerio.load(text); - const links = []; - $('body').find('h3').each((i, h3) => { - if ($(h3).parent()) { - const href = $(h3).parent().attr('href'); - if (href) { - const params = new URLSearchParams(href); - const url = new URL(params.get('url')); - if (nsfw || !this.client.adultSiteList.includes(url.host)) { - links.push({ href: url.href, title: $(h3).text() }); - } - } - } - }); - if (!links.length) return null; - return links.slice(0, 3); - } -}; diff --git a/commands/search/http-dog.js b/commands/search/http-dog.js deleted file mode 100644 index 36599baa..00000000 --- a/commands/search/http-dog.js +++ /dev/null @@ -1,38 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); - -module.exports = class HttpDogCommand extends Command { - constructor(client) { - super(client, { - name: 'http-dog', - group: 'search', - memberName: 'http-dog', - description: 'Responds with a dog for an HTTP status code.', - clientPermissions: ['ATTACH_FILES'], - credit: [ - { - name: 'HTTP Status Dogs', - url: 'https://httpstatusdogs.com/', - reason: 'API' - } - ], - args: [ - { - key: 'code', - prompt: 'What code do you want to get the dog of?', - type: 'integer' - } - ] - }); - } - - async run(msg, { code }) { - try { - const { body, headers } = await request.get(`https://httpstatusdogs.com/img/${code}.jpg`); - if (headers['content-type'].includes('text/html')) return msg.say('Could not find any results.'); - return msg.say({ files: [{ attachment: body, name: `${code}.jpg` }] }); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/http-duck.js b/commands/search/http-duck.js deleted file mode 100644 index 53b29d28..00000000 --- a/commands/search/http-duck.js +++ /dev/null @@ -1,39 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); - -module.exports = class HttpDuckCommand extends Command { - constructor(client) { - super(client, { - name: 'http-duck', - group: 'search', - memberName: 'http-duck', - description: 'Responds with a duck for an HTTP status code.', - clientPermissions: ['ATTACH_FILES'], - credit: [ - { - name: 'Random-d.uk', - url: 'https://random-d.uk/', - reason: 'API', - reasonURL: 'https://random-d.uk/http' - } - ], - args: [ - { - key: 'code', - prompt: 'What code do you want to get the duck of?', - type: 'integer' - } - ] - }); - } - - async run(msg, { code }) { - try { - const { body } = await request.get(`https://random-d.uk/api/http/${code}.jpg`); - return msg.say({ files: [{ attachment: body, name: `${code}.jpg` }] }); - } catch (err) { - if (err.status === 404) return msg.say('Could not find any results.'); - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/kickstarter.js b/commands/search/kickstarter.js deleted file mode 100644 index 2808d8ab..00000000 --- a/commands/search/kickstarter.js +++ /dev/null @@ -1,60 +0,0 @@ -const Command = require('../../framework/Command'); -const moment = require('moment'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const { shorten, formatNumber } = require('../../util/Util'); - -module.exports = class KickstarterCommand extends Command { - constructor(client) { - super(client, { - name: 'kickstarter', - group: 'search', - memberName: 'kickstarter', - description: 'Searches Kickstarter for your query.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Kickstarter', - url: 'https://www.kickstarter.com/', - reason: 'API' - } - ], - args: [ - { - key: 'query', - prompt: 'What project would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const { body } = await request - .get('https://www.kickstarter.com/projects/search.json') - .query({ - search: '', - term: query - }); - if (!body.projects.length) return msg.say('Could not find any results.'); - const data = body.projects[0]; - const embed = new MessageEmbed() - .setColor(0x14E06E) - .setTitle(data.name) - .setURL(data.urls.web.project) - .setAuthor('Kickstarter', 'https://i.imgur.com/EHDlH5t.png', 'https://www.kickstarter.com/') - .setDescription(shorten(data.blurb)) - .setThumbnail(data.photo ? data.photo.full : null) - .addField('❯ Goal', `$${formatNumber(data.goal)}`, true) - .addField('❯ Pledged', `$${formatNumber(data.pledged)}`, true) - .addField('❯ Backers', formatNumber(data.backers_count), true) - .addField('❯ Creator', data.creator.name, true) - .addField('❯ Creation Date', moment.utc(data.created_at * 1000).format('MM/DD/YYYY h:mm A'), true) - .addField('❯ Deadline', moment.utc(data.deadline * 1000).format('MM/DD/YYYY h:mm A'), true); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/league-of-legends.js b/commands/search/league-of-legends.js deleted file mode 100644 index 17ed68b8..00000000 --- a/commands/search/league-of-legends.js +++ /dev/null @@ -1,98 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const buttons = ['Q', 'W', 'E', 'R']; - -module.exports = class LeagueOfLegendsCommand extends Command { - constructor(client) { - super(client, { - name: 'league-of-legends', - aliases: ['league-of-legends-champion', 'league-of-legends-champ', 'league-champ', 'lol-champ'], - group: 'search', - memberName: 'league-of-legends', - description: 'Responds with information on a League of Legends champion.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Riot Games', - url: 'https://www.riotgames.com/en', - reason: 'API', - reasonURL: 'https://developer.riotgames.com/' - } - ], - args: [ - { - key: 'champion', - prompt: 'What champion would you like to get information on?', - type: 'string', - parse: champion => champion.toLowerCase() - } - ] - }); - - this.version = null; - this.champions = null; - } - - async run(msg, { champion }) { - if (champion === 'satan') champion = 'teemo'; - try { - if (!this.version) await this.fetchVersion(); - const data = await this.fetchChampion(champion); - if (!data) return msg.say('Could not find any results.'); - const tips = [].concat(data.allytips, data.enemytips); - const embed = new MessageEmbed() - .setColor(0x002366) - .setAuthor('League of Legends', 'https://i.imgur.com/2JL4Rko.png', 'https://leagueoflegends.com/') - .setTitle(`${data.name} ${data.title}`) - .setDescription(data.blurb) - .setThumbnail(`https://ddragon.leagueoflegends.com/cdn/${this.version}/img/champion/${data.image.full}`) - .addField('❯ Attack', data.info.attack, true) - .addField('❯ Defense', data.info.defense, true) - .addField('❯ Magic', data.info.magic, true) - .addField('❯ Difficulty', data.info.difficulty, true) - .addField('❯ HP', `${data.stats.hp} (${data.stats.hpperlevel}/level)`, true) - .addField('❯ HP Regen', `${data.stats.hpregen} (${data.stats.hpregenperlevel}/level)`, true) - .addField('❯ MP', `${data.stats.mp} (${data.stats.mpperlevel}/level)`, true) - .addField('❯ MP Regen', `${data.stats.mpregen} (${data.stats.mpregenperlevel}/level)`, true) - .addField('❯ Resource', data.partype, true) - .addField('❯ Armor', `${data.stats.armor} (${data.stats.armorperlevel}/level)`, true) - .addField('❯ Attack Damage', `${data.stats.attackdamage} (${data.stats.attackdamageperlevel}/level)`, true) - .addField('❯ Attack Range', data.stats.attackrange, true) - .addField('❯ Attack Speed', `${data.stats.attackspeed} (${data.stats.attackspeedperlevel}/level)`, true) - .addField('❯ Crit', `${data.stats.crit} (${data.stats.critperlevel}/level)`, true) - .addField('❯ Move Speed', data.stats.movespeed, true) - .addField('❯ Spell Block', `${data.stats.spellblock} (${data.stats.spellblockperlevel}/level)`, true) - .addField('❯ Passive', data.passive.name, true) - .addField('❯ Spells', data.spells.map((spell, i) => `${spell.name} (${buttons[i]})`).join('\n'), true); - return msg.say(`Tip: ${tips[Math.floor(Math.random() * tips.length)]}`, { embed }); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async fetchVersion() { - const { body } = await request.get('https://ddragon.leagueoflegends.com/api/versions.json'); - [this.version] = body; - setTimeout(() => { this.version = null; }, 3.6e+6); - return body; - } - - async fetchChampions() { - if (this.champions && this.champions.version === this.version) return this.champions; - const { body } = await request - .get(`https://ddragon.leagueoflegends.com/cdn/${this.version}/data/en_US/champion.json`); - this.champions = body; - return body; - } - - async fetchChampion(champion) { - const champions = await this.fetchChampions(); - const name = Object.keys(champions.data).find(key => key.toLowerCase() === champion); - if (!name) return null; - const { id } = champions.data[name]; - const { body } = await request - .get(`https://ddragon.leagueoflegends.com/cdn/${this.version}/data/en_US/champion/${id}.json`); - return body.data[id]; - } -}; diff --git a/commands/search/lyrics.js b/commands/search/lyrics.js deleted file mode 100644 index cae6d512..00000000 --- a/commands/search/lyrics.js +++ /dev/null @@ -1,62 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { shorten } = require('../../util/Util'); -// eslint-disable-next-line max-len -const top = ''; -const bottom = ''; -const lyricRegex = new RegExp(`${top}(.+)${bottom}`, 'si'); - -module.exports = class LyricsCommand extends Command { - constructor(client) { - super(client, { - name: 'lyrics', - aliases: ['az-lyrics'], - group: 'search', - memberName: 'lyrics', - description: 'Responds with lyrics to a song.', - credit: [ - { - name: 'AZLyrics', - url: 'https://www.azlyrics.com/', - reason: 'Lyrics Data' - } - ], - args: [ - { - key: 'artist', - prompt: 'What artist would you like to get the lyrics of?', - type: 'string', - parse: artist => artist.replace(/[^A-Za-z0-9]+|^(the )/gi, '').toLowerCase() - }, - { - key: 'song', - prompt: 'What song would you like to get the lyrics of?', - type: 'string', - parse: song => song.replace(/[^A-Za-z0-9]+/g, '').toLowerCase() - } - ] - }); - } - - async run(msg, { artist, song }) { - try { - const lyrics = await this.getLyrics(artist, song); - const url = `https://www.azlyrics.com/lyrics/${artist}/${song}.html`; - return msg.say(`${shorten(lyrics, 1750)}\n\n**Read the Rest:** ${url}`); - } catch (err) { - if (err.status === 404) return msg.say('Could not find any results.'); - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async getLyrics(artist, song) { - const { text } = await request.get(`https://www.azlyrics.com/lyrics/${artist}/${song}.html`); - const lyrics = text.match(lyricRegex)[1]; - return lyrics - .replaceAll('
', '') - .replace(/<\/?div>/g, '') - .replace(/<\/?i>/g, '*') - .replace(/<\/?b>/g, '**') - .trim(); - } -}; diff --git a/commands/search/mal-badges.js b/commands/search/mal-badges.js deleted file mode 100644 index 6488fadb..00000000 --- a/commands/search/mal-badges.js +++ /dev/null @@ -1,48 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); - -module.exports = class MalBadgesCommand extends Command { - constructor(client) { - super(client, { - name: 'mal-badges', - aliases: ['my-anime-list-badges', 'mal-badge', 'my-anime-list-badge'], - group: 'search', - memberName: 'mal-badges', - description: 'Responds with a MyAnimeList user\'s mal-badges badge.', - credit: [ - { - name: 'mal-badges', - url: 'http://www.mal-badges.net/', - reason: 'API' - } - ], - args: [ - { - key: 'user', - prompt: 'What user would you like to get the badge of?', - type: 'string', - parse: user => encodeURIComponent(user) - } - ] - }); - } - - async run(msg, { user }) { - try { - const { body } = await request.get(`http://www.mal-badges.net/users/${user}/badge`); - const embed = new MessageEmbed() - .attachFiles([{ attachment: body, name: 'badge.png' }]) - .setTitle(user) - .setImage('attachment://badge.png') - .setURL(`http://www.mal-badges.net/users/${user}`) - .setColor(0x00ADB5); - return msg.embed(embed); - } catch (err) { - if (err.status === 404 || err.status === 500) { - return msg.say(`Could not find any results. Try updating at .`); - } - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/map.js b/commands/search/map.js deleted file mode 100644 index 4d636611..00000000 --- a/commands/search/map.js +++ /dev/null @@ -1,60 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { GOOGLE_KEY } = process.env; - -module.exports = class MapCommand extends Command { - constructor(client) { - super(client, { - name: 'map', - aliases: ['google-maps', 'google-map'], - group: 'search', - memberName: 'map', - description: 'Responds with a map of a specific location.', - clientPermissions: ['ATTACH_FILES'], - credit: [ - { - name: 'Google', - url: 'https://www.google.com/', - reason: 'Maps Static API', - reasonURL: 'https://developers.google.com/maps/documentation/maps-static/intro' - } - ], - args: [ - { - key: 'zoom', - label: 'zoom level', - prompt: 'What would you like the zoom level to be? Must be a number from 1-20.', - type: 'integer', - min: 1, - max: 20 - }, - { - key: 'location', - prompt: 'What location would you like to get a map of?', - type: 'string', - validate: location => { - if (encodeURIComponent(location).length < 1950) return true; - return 'Invalid location, your location is too long.'; - } - } - ] - }); - } - - async run(msg, { zoom, location }) { - try { - const { body } = await request - .get('https://maps.googleapis.com/maps/api/staticmap') - .query({ - center: location, - zoom, - size: '500x500', - key: GOOGLE_KEY - }); - const url = `https://www.google.com/maps/search/${encodeURIComponent(location)}`; - return msg.say(`<${url}>`, { files: [{ attachment: body, name: 'map.png' }] }); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/mayo-clinic.js b/commands/search/mayo-clinic.js deleted file mode 100644 index 8ac75024..00000000 --- a/commands/search/mayo-clinic.js +++ /dev/null @@ -1,75 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const cheerio = require('cheerio'); -const { MessageEmbed } = require('discord.js'); -const { shorten } = require('../../util/Util'); - -module.exports = class MayoClinicCommand extends Command { - constructor(client) { - super(client, { - name: 'mayo-clinic', - aliases: ['disease'], - group: 'search', - memberName: 'mayo-clinic', - description: 'Searches Mayo Clinic for your query.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Mayo Clinic', - url: 'https://www.mayoclinic.org/', - reason: 'Disease Data' - } - ], - args: [ - { - key: 'query', - prompt: 'What disease would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const location = await this.search(query); - if (!location) return msg.say('Could not find any results.'); - const data = await this.fetchDisease(location); - if (typeof data === 'string') return msg.say(`I found a match, but it's not a disease: ${data}`); - const embed = new MessageEmbed() - .setColor(0x0044B3) - .setAuthor('Mayo Clinic', 'https://i.imgur.com/9zdulOS.jpg', 'https://www.mayoclinic.org/') - .setTitle(data.name) - .setDescription(shorten(data.description || 'No description available.')) - .setURL(data.url); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async search(query) { - const { text } = await request - .get('https://www.mayoclinic.org/search/search-results') - .query({ q: query }); - const $ = cheerio.load(text); - const location = $('ol.navlist').find('li.noimg').first().children().find('a').attr('href'); - if (!location) return null; - return location; - } - - async fetchDisease(location) { - const { text } = await request.get(location); - const $ = cheerio.load(text); - const header = $('h2').first(); - if (header.text() === 'Overview') { - const caption = $('p[class="caption"]').first().next().text().trim(); - return { - name: $('h1').first().text().trim(), - url: location, - description: caption || header.next().text().trim() - }; - } - return location; - } -}; diff --git a/commands/search/paladins.js b/commands/search/paladins.js deleted file mode 100644 index ad919258..00000000 --- a/commands/search/paladins.js +++ /dev/null @@ -1,107 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const moment = require('moment'); -const { formatNumber } = require('../../util/Util'); -const classStats = require('../../assets/json/paladins'); -const { FLANKER_EMOJI_ID, DAMAGE_EMOJI_ID, FRONT_LINE_EMOJI_ID, SUPPORT_EMOJI_ID } = process.env; - -module.exports = class PaladinsCommand extends Command { - constructor(client) { - super(client, { - name: 'paladins', - aliases: ['paladins-guru'], - group: 'search', - memberName: 'paladins', - description: 'Responds with information on a Paladins player.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Evil Mojo Games', - url: 'https://www.evilmojogames.com/', - reason: 'Original "Paladins" Game', - reasonURL: 'https://www.paladins.com/' - }, - { - name: 'PaladinsGuru', - url: 'https://paladins.guru/', - reason: 'API' - } - ], - args: [ - { - key: 'player', - prompt: 'What player would you like to get information on?', - type: 'string' - } - ] - }); - - this.champions = null; - } - - async run(msg, { player }) { - try { - const search = await this.search(player); - if (!search) return msg.say('Could not find any results.'); - const data = await this.fetchPlayer(search.id); - if (!this.champions) await this.fetchChampions(); - const champions = data.champions.map(champ => { - const champData = this.champions[champ.id]; - const classStat = classStats[champData.class]; - const emoji = this.classEmoji(champData.class); - return `${emoji} ${champData.name} (${formatNumber(champ[classStat.id] || 0)} ${classStat.display})`; - }); - const embed = new MessageEmbed() - .setColor(0x1E9BAD) - .setAuthor('Paladins Guru', 'https://i.imgur.com/iIAdriK.png', 'https://paladins.guru/') - .setTitle('View Profile on Paladins Guru') - .setURL(`https://paladins.guru/profile/${data.player.id}`) - .addField('❯ Name', data.player.name, true) - .addField('❯ ID', data.player.id, true) - .addField('❯ Level', data.player.level, true) - .addField('❯ Last Seen', moment.utc(data.player.seen).format('MM/DD/YYYY h:mm A'), true) - .addField('❯ Region', data.player.region, true) - .addField('❯ Team', data.player.team || 'Free Agent', true) - .addField('❯ Top 5 Champions', champions.slice(0, 5).join('\n')); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async search(query) { - const { body } = await request - .get('https://api.paladins.guru/v3/search') - .query({ - term: query, - type: 'Player' - }); - if (!body.length) return null; - return body[0]; - } - - async fetchPlayer(id) { - const { body } = await request.get(`https://api.paladins.guru/v3/profiles/${id}/summary`); - return body; - } - - async fetchChampions() { - if (this.champions) return this.champions; - const { body } = await request.get('https://api.paladins.guru/v3/champions/'); - this.champions = body; - setTimeout(() => { this.champions = null; }, 3.6e+6); - return body; - } - - classEmoji(className) { - let emojiID; - switch (className) { - case 'Flanker': emojiID = FLANKER_EMOJI_ID; break; - case 'Support': emojiID = SUPPORT_EMOJI_ID; break; - case 'Damage': emojiID = DAMAGE_EMOJI_ID; break; - case 'Front Line': emojiID = FRONT_LINE_EMOJI_ID; break; - } - return `<:${className.replaceAll(' ', '')}:${emojiID}>`; - } -}; diff --git a/commands/search/poem.js b/commands/search/poem.js deleted file mode 100644 index c08bc37d..00000000 --- a/commands/search/poem.js +++ /dev/null @@ -1,53 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { html } = require('common-tags'); -const { shorten } = require('../../util/Util'); - -module.exports = class PoemCommand extends Command { - constructor(client) { - super(client, { - name: 'poem', - aliases: ['poetry'], - group: 'search', - memberName: 'poem', - description: 'Searches for poems by a specific author.', - credit: [ - { - name: 'PoetryDB', - url: 'https://poetrydb.org/index.html', - reason: 'API', - reasonURL: 'https://github.com/thundercomb/poetrydb/blob/master/README.md' - } - ], - args: [ - { - key: 'author', - prompt: 'What author would you like to get a poem from?', - type: 'string', - parse: author => encodeURIComponent(author) - }, - { - key: 'title', - prompt: 'What is the title of the poem you want to get?', - type: 'string', - parse: title => encodeURIComponent(title) - } - ] - }); - } - - async run(msg, { author, title }) { - try { - const { body } = await request.get(`https://poetrydb.org/author,title/${author};${title}`); - if (body.status === 404) return msg.say('Could not find any results.'); - const data = body[0]; - return msg.say(html` - **${data.title}** by **${data.author}** - ${shorten(data.lines.join('\n'), 1750)} - `); - } catch (err) { - if (err.status === 404) return msg.say('Could not find any results.'); - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/pornhub.js b/commands/search/pornhub.js deleted file mode 100644 index 54cb0849..00000000 --- a/commands/search/pornhub.js +++ /dev/null @@ -1,49 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const cheerio = require('cheerio'); - -module.exports = class PornhubCommand extends Command { - constructor(client) { - super(client, { - name: 'pornhub', - group: 'search', - memberName: 'pornhub', - description: 'Searches Pornhub for your query.', - nsfw: true, - credit: [ - { - name: 'Pornhub', - url: 'https://www.pornhub.com/', - reason: 'Video Data' - } - ], - args: [ - { - key: 'query', - prompt: 'What video would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const url = await this.search(query); - if (!url) return msg.say('Could not find any results.'); - return msg.say(url); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async search(query) { - const { text } = await request - .get(`https://www.pornhub.com/video/search`) - .query({ search: query }); - if (text.includes('

')) return null; - const $ = cheerio.load(text); - const video = $('li[class="pcVideoListItem js-pop videoblock videoBox"]').eq(5); - return `https://www.pornhub.com/view_video.php?viewkey=${video.attr('data-video-vkey')}`; - } -}; diff --git a/commands/search/recipe.js b/commands/search/recipe.js deleted file mode 100644 index 21f4cfd3..00000000 --- a/commands/search/recipe.js +++ /dev/null @@ -1,60 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); - -module.exports = class RecipeCommand extends Command { - constructor(client) { - super(client, { - name: 'recipe', - aliases: ['recipe-puppy'], - group: 'search', - memberName: 'recipe', - description: 'Searches for recipes based on your query.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Recipe Puppy', - url: 'http://www.recipepuppy.com/', - reason: 'API', - reasonURL: 'http://www.recipepuppy.com/about/api/' - } - ], - args: [ - { - key: 'query', - prompt: 'What recipe would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const body = await this.fetchRecipe(query); - if (!body.results.length) return msg.say('Could not find any results.'); - const recipe = body.results[Math.floor(Math.random() * body.results.length)]; - const embed = new MessageEmbed() - .setAuthor('Recipe Puppy', 'https://i.imgur.com/lT94snh.png', 'http://www.recipepuppy.com/') - .setColor(0xC20000) - .setURL(recipe.href) - .setTitle(recipe.title) - .setDescription(`**Ingredients:** ${recipe.ingredients}`) - .setThumbnail(recipe.thumbnail); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async fetchRecipe(query) { - try { - const { text } = await request - .get('http://www.recipepuppy.com/api/') - .query({ q: query }); - return JSON.parse(text); - } catch (err) { - return JSON.parse(err.text.split(' m.name.toLowerCase() === query.toLowerCase()) || body.movies[0]; - return find.url.replace('/m/', ''); - } - - async fetchMovie(id) { - const { text } = await request - .get(`https://www.rottentomatoes.com/api/private/v1.0/movies/${id}`) - .set({ 'User-Agent': new UserAgent().toString() }); - return JSON.parse(text); - } -}; diff --git a/commands/search/safebooru.js b/commands/search/safebooru.js deleted file mode 100644 index abe6f044..00000000 --- a/commands/search/safebooru.js +++ /dev/null @@ -1,49 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); - -module.exports = class SafebooruCommand extends Command { - constructor(client) { - super(client, { - name: 'safebooru', - group: 'search', - memberName: 'safebooru', - description: 'Responds with an image from Safebooru, with optional query.', - credit: [ - { - name: 'Safebooru', - url: 'https://safebooru.org/', - reason: 'API' - } - ], - args: [ - { - key: 'query', - prompt: 'What image would you like to search for?', - type: 'string', - default: '' - } - ] - }); - } - - async run(msg, { query }) { - try { - const { text } = await request - .get('https://safebooru.org/index.php') - .query({ - page: 'dapi', - s: 'post', - q: 'index', - json: 1, - tags: query, - limit: 200 - }); - if (!text) return msg.say('Could not find any results.'); - const body = JSON.parse(text); - const data = body[Math.floor(Math.random() * body.length)]; - return msg.say(`https://safebooru.org/images/${data.directory}/${data.image}`); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/sakugabooru.js b/commands/search/sakugabooru.js deleted file mode 100644 index 54239bfc..00000000 --- a/commands/search/sakugabooru.js +++ /dev/null @@ -1,54 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { stripIndents } = require('common-tags'); - -module.exports = class SakugabooruCommand extends Command { - constructor(client) { - super(client, { - name: 'sakugabooru', - aliases: ['sakuga'], - group: 'search', - memberName: 'sakugabooru', - description: 'Responds with an image from Sakugabooru, with optional query.', - credit: [ - { - name: 'Sakugabooru', - url: 'https://www.sakugabooru.com/', - reason: 'API' - } - ], - args: [ - { - key: 'query', - prompt: 'What would you like to search for?', - type: 'string', - default: '' - } - ] - }); - } - - async run(msg, { query }) { - try { - const { body } = await request - .get('https://www.sakugabooru.com/post.json') - .query({ - tags: query, - limit: 100 - }); - if (!body.length) return msg.say('Could not find any results.'); - const posts = body.filter(post => { - if (!msg.channel.nsfw && (post.rating === 'e' || post.rating === 'q')) return false; - return post.file_url; - }); - if (!posts.length) return msg.say('Could not find any results.'); - const post = posts[Math.floor(Math.random() * posts.length)]; - return msg.say(stripIndents` - ${post.tags} - ${post.file_url} - `); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/stocks.js b/commands/search/stocks.js deleted file mode 100644 index d754ce4f..00000000 --- a/commands/search/stocks.js +++ /dev/null @@ -1,94 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const { formatNumber } = require('../../util/Util'); -const { ALPHA_VANTAGE_KEY } = process.env; - -module.exports = class StocksCommand extends Command { - constructor(client) { - super(client, { - name: 'stocks', - aliases: ['stock', 'alpha-vantage'], - group: 'search', - memberName: 'stocks', - description: 'Responds with the current stocks for a company.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Alpha Vantage', - url: 'https://www.alphavantage.co/', - reason: 'API' - }, - { - name: 'Yahoo', - url: 'https://www.yahoo.com/', - reason: 'Finance API' - } - ], - args: [ - { - key: 'query', - prompt: 'What company would you like to get the stocks of?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const company = await this.search(query); - if (!company) return msg.say('Could not find any results.'); - const stocks = await this.fetchStocks(company.symbol); - if (!stocks) return msg.say('Could not find any results.'); - const embed = new MessageEmbed() - .setTitle(`Stocks for ${company.name} (${stocks.symbol.toUpperCase()})`) - .setColor(0x9797FF) - .setFooter('Last Updated') - .setTimestamp(stocks.lastRefresh) - .addField('❯ Open', `$${formatNumber(stocks.open)}`, true) - .addField('❯ Close', `$${formatNumber(stocks.close)}`, true) - .addField('❯ Volume', formatNumber(stocks.volume), true) - .addField('❯ High', `$${formatNumber(stocks.high)}`, true) - .addField('❯ Low', `$${formatNumber(stocks.low)}`, true) - .addField('\u200B', '\u200B', true); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async search(query) { - const { body } = await request - .get('http://d.yimg.com/autoc.finance.yahoo.com/autoc') - .query({ - query, - region: 1, - lang: 'en' - }); - if (!body.ResultSet.Result.length) return null; - return body.ResultSet.Result[0]; - } - - async fetchStocks(symbol) { - const { body } = await request - .get('https://www.alphavantage.co/query') - .query({ - function: 'TIME_SERIES_INTRADAY', - symbol, - interval: '1min', - apikey: ALPHA_VANTAGE_KEY - }); - if (body['Error Message'] || !body['Time Series (1min)']) return null; - const data = Object.values(body['Time Series (1min)'])[0]; - return { - symbol, - open: data['1. open'], - high: data['2. high'], - low: data['3. low'], - close: data['4. close'], - volume: data['5. volume'], - lastRefresh: new Date(body['Meta Data']['3. Last Refreshed']) - }; - } -}; diff --git a/commands/search/strain.js b/commands/search/strain.js deleted file mode 100644 index 9954fc24..00000000 --- a/commands/search/strain.js +++ /dev/null @@ -1,73 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const cheerio = require('cheerio'); -const { formatNumber } = require('../../util/Util'); - -module.exports = class StrainCommand extends Command { - constructor(client) { - super(client, { - name: 'strain', - aliases: ['weed', 'marijuana', 'cannabis', 'leafly', 'marijuana-strain', 'weed-strain', 'cannabis-strain'], - group: 'search', - memberName: 'strain', - description: 'Responds with information on a cannabis strain.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Leafly', - url: 'https://www.leafly.com/', - reason: 'API' - } - ], - args: [ - { - key: 'query', - prompt: 'What strain would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const strain = await this.search(query); - if (!strain) return msg.say('Could not find any results.'); - const effects = Object.values(strain.effects).sort((a, b) => b.score - a.score).slice(0, 3); - const embed = new MessageEmbed() - .setColor(0x017C6A) - .setAuthor('Leafly', 'https://i.imgur.com/KQ0ABhI.png', 'https://www.leafly.com/') - .setTitle(strain.name) - .setThumbnail(strain.nugImage || null) - .setDescription(strain.shortDescriptionPlain || 'No description.') - .setURL(`https://www.leafly.com/strains/${strain.slug}`) - .setFooter(strain.subtitle || 'No alternative names.') - .addField('❯ Effects', effects.map(effect => effect.name).join(', ')) - .addField('❯ Phenotype', strain.phenotype, true) - .addField('❯ Rating', `${formatNumber(strain.averageRating)} ⭐`, true); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async search(query) { - const { text } = await request - .get('https://www.leafly.com/search') - .query({ - q: query, - searchCategory: 'strain' - }); - const $ = cheerio.load(text); - const data = JSON.parse($('script[id="__NEXT_DATA__"]')[0].children[0].data) - .props - .initialProps - .pageProps - .componentProps - .searchProps - .strain; - if (!data.length) return null; - return data[0]; - } -}; diff --git a/commands/search/tenor.js b/commands/search/tenor.js deleted file mode 100644 index 55ef3012..00000000 --- a/commands/search/tenor.js +++ /dev/null @@ -1,47 +0,0 @@ -const Command = require('../../framework/Command'); -const request = require('node-superfetch'); -const { TENOR_KEY } = process.env; - -module.exports = class TenorCommand extends Command { - constructor(client) { - super(client, { - name: 'tenor', - group: 'search', - memberName: 'tenor', - description: 'Searches Tenor for your query.', - credit: [ - { - name: 'Tenor', - url: 'https://tenor.com/', - reason: 'API', - reasonURL: 'https://tenor.com/gifapi/documentation' - } - ], - args: [ - { - key: 'query', - prompt: 'What GIF would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const { body } = await request - .get('https://api.tenor.com/v1/search') - .query({ - q: query, - key: TENOR_KEY, - limit: 50, - contentfilter: msg.channel.nsfw ? 'off' : 'high', - media_filter: 'minimal' - }); - if (!body.results.length) return msg.say('Could not find any results.'); - return msg.say(body.results[Math.floor(Math.random() * body.results.length)].media[0].gif.url); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/tumblr.js b/commands/search/tumblr.js deleted file mode 100644 index 9ffa65b2..00000000 --- a/commands/search/tumblr.js +++ /dev/null @@ -1,54 +0,0 @@ -const Command = require('../../framework/Command'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const { formatNumber } = require('../../util/Util'); -const { TUMBLR_KEY } = process.env; - -module.exports = class TumblrCommand extends Command { - constructor(client) { - super(client, { - name: 'tumblr', - group: 'search', - memberName: 'tumblr', - description: 'Responds with information on a Tumblr blog.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Tumblr', - url: 'https://www.tumblr.com/', - reason: 'API', - reasonURL: 'https://www.tumblr.com/docs/en/api/v2' - } - ], - args: [ - { - key: 'blog', - prompt: 'What blog would you like to get information on?', - type: 'string', - parse: blog => encodeURIComponent(blog) - } - ] - }); - } - - async run(msg, { blog }) { - try { - const { body } = await request - .get(`https://api.tumblr.com/v2/blog/${blog}/info`) - .query({ api_key: TUMBLR_KEY }); - const data = body.response.blog; - const embed = new MessageEmbed() - .setColor(0x395976) - .setAuthor('Tumblr', 'https://i.imgur.com/ouD9TUY.png', 'https://www.tumblr.com/') - .setThumbnail(`https://api.tumblr.com/v2/blog/${blog}/avatar/512`) - .setURL(data.url) - .setTitle(data.title) - .addField('❯ Posts', formatNumber(data.total_posts), true) - .addField('❯ A.M.A.?', data.ask ? 'Yes' : 'No', true); - return msg.embed(embed); - } catch (err) { - if (err.status === 404) return msg.say('Could not find any results.'); - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/twitch.js b/commands/search/twitch.js deleted file mode 100644 index 6d6adc63..00000000 --- a/commands/search/twitch.js +++ /dev/null @@ -1,83 +0,0 @@ -const Command = require('../../framework/Command'); -const moment = require('moment'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const { TWITCH_ID, TWITCH_SECRET } = process.env; - -module.exports = class TwitchCommand extends Command { - constructor(client) { - super(client, { - name: 'twitch', - group: 'search', - memberName: 'twitch', - description: 'Responds with information on a Twitch user.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Twitch', - url: 'https://www.twitch.tv/', - reason: 'API', - reasonURL: 'https://dev.twitch.tv/' - } - ], - args: [ - { - key: 'user', - prompt: 'What user would you like to get information on?', - type: 'string' - } - ] - }); - - this.token = null; - } - - async run(msg, { user }) { - try { - if (!this.token) await this.fetchToken(); - const { body } = await request - .get('https://api.twitch.tv/helix/search/channels') - .set({ - Authorization: `Bearer ${this.token}`, - 'client-id': TWITCH_ID - }) - .query({ - query: user, - first: 1 - }); - if (!body.data.length) return msg.say('Could not find any results.'); - const data = body.data[0]; - const embed = new MessageEmbed() - .setColor(0x9147FF) - .setAuthor('Twitch', 'https://i.imgur.com/6l1pPMI.jpg', 'https://www.twitch.tv/') - .setThumbnail(data.thumbnail_url || null) - .setURL(`https://twitch.tv/${data.broadcaster_login}`) - .setTitle(data.display_name) - .setDescription(data.is_live ? data.title : 'Not live') - .setFooter(data.id) - .addField('❯ Live?', data.is_live ? 'Yes' : 'No', true) - .addField('❯ Start Date', data.is_live - ? moment.utc(new Date(data.started_at)).format('MM/DD/YYYY h:mm A') - : '???', true) - .addField('❯ Game', data.is_live ? data.game_name : '???', true); - return msg.embed(embed); - } catch (err) { - if (err.status === 401) await this.fetchToken(); - if (err.status === 404) return msg.say('Could not find any results.'); - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async fetchToken() { - const { body } = await request - .post('https://id.twitch.tv/oauth2/token') - .query({ - client_id: TWITCH_ID, - client_secret: TWITCH_SECRET, - grant_type: 'client_credentials' - }); - this.token = body.access_token; - setTimeout(() => { this.token = null; }, body.expires_in); - return body; - } -}; diff --git a/commands/search/twitter.js b/commands/search/twitter.js deleted file mode 100644 index 3683eb87..00000000 --- a/commands/search/twitter.js +++ /dev/null @@ -1,86 +0,0 @@ -const Command = require('../../framework/Command'); -const moment = require('moment'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const { formatNumber, base64, embedURL } = require('../../util/Util'); -const { TWITTER_KEY, TWITTER_SECRET } = process.env; -const retweetRegex = /^RT @([a-zA-Z0-9_]{1,15}):/; - -module.exports = class TwitterCommand extends Command { - constructor(client) { - super(client, { - name: 'twitter', - group: 'search', - memberName: 'twitter', - description: 'Responds with information on a Twitter user.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Twitter', - url: 'https://twitter.com/', - reason: 'API', - reasonURL: 'https://developer.twitter.com/en/docs.html' - } - ], - args: [ - { - key: 'user', - prompt: 'What user would you like to get information on?', - type: 'string' - } - ] - }); - - this.token = null; - } - - async run(msg, { user }) { - try { - if (!this.token) await this.fetchToken(); - const { body } = await request - .get('https://api.twitter.com/1.1/users/show.json') - .set({ Authorization: `Bearer ${this.token}` }) - .query({ screen_name: user }); - let latest = body.status; - if (latest) { - const statusUser = body.status.retweeted_status ? body.status.text.match(retweetRegex)[1] : body.screen_name; - const statusID = body.status.retweeted_status ? body.status.retweeted_status.id_str : body.status.id_str; - latest = embedURL(body.status.text, `https://twitter.com/${statusUser}/status/${statusID}`); - } else { - latest = body.protected ? 'πŸ”’ Protected' : 'No tweets found.'; - } - const embed = new MessageEmbed() - .setColor(0x55ADEE) - .setAuthor('Twitter', 'https://i.imgur.com/QnfcO7y.png', 'https://twitter.com/') - .setThumbnail(body.profile_image_url_https.replace('_normal', '')) - .setURL(`https://twitter.com/${body.screen_name}`) - .setTitle(`${body.name} (@${body.screen_name})`) - .setDescription(body.description) - .addField('❯ Tweets', formatNumber(body.statuses_count), true) - .addField('❯ Followers', formatNumber(body.followers_count), true) - .addField('❯ Following', formatNumber(body.friends_count), true) - .addField('❯ Protected?', body.protected ? 'Yes' : 'No', true) - .addField('❯ Verified?', body.verified ? 'Yes' : 'No', true) - .addField('❯ Creation Date', moment.utc(new Date(body.created_at)).format('MM/DD/YYYY h:mm A'), true) - .addField('❯ Latest Tweet', latest); - return msg.embed(embed); - } catch (err) { - if (err.status === 401) await this.fetchToken(); - if (err.status === 403) return msg.say('This user is either private or suspended.'); - if (err.status === 404) return msg.say('Could not find any results.'); - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } - - async fetchToken() { - const { body } = await request - .post('https://api.twitter.com/oauth2/token') - .set({ - Authorization: `Basic ${base64(`${TWITTER_KEY}:${TWITTER_SECRET}`)}`, - 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' - }) - .send('grant_type=client_credentials'); - this.token = body.access_token; - return body; - } -}; diff --git a/commands/search/vocadb.js b/commands/search/vocadb.js deleted file mode 100644 index 977964e9..00000000 --- a/commands/search/vocadb.js +++ /dev/null @@ -1,62 +0,0 @@ -const Command = require('../../framework/Command'); -const moment = require('moment'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const { shorten } = require('../../util/Util'); - -module.exports = class VocadbCommand extends Command { - constructor(client) { - super(client, { - name: 'vocadb', - aliases: ['vocaloid'], - group: 'search', - memberName: 'vocadb', - description: 'Searches VocaDB for your query.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'VocaDB', - url: 'https://vocadb.net/', - reason: 'API', - reasonURL: 'https://vocadb.net/swagger/ui/index' - } - ], - args: [ - { - key: 'query', - prompt: 'What song would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const { body } = await request - .get('http://vocadb.net/api/songs') - .query({ - query, - maxResults: 1, - sort: 'FavoritedTimes', - preferAccurateMatches: true, - nameMatchMode: 'Words', - fields: 'ThumbUrl,Lyrics' - }); - if (!body.items.length) return msg.say('Could not find any results.'); - const data = body.items[0]; - const embed = new MessageEmbed() - .setColor(0x86D2D0) - .setAuthor('VocaDB', 'https://i.imgur.com/6QwraDT.jpg', 'http://vocadb.net/') - .setTitle(data.name) - .setURL(`http://vocadb.net/S/${data.id}`) - .setDescription(data.lyrics.length ? shorten(data.lyrics[0].value) : 'No lyrics available.') - .setThumbnail(data.thumbUrl) - .addField('❯ Artist', data.artistString) - .addField('❯ Publish Date', moment.utc(data.publishDate).format('MM/DD/YYYY'), true); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/wattpad.js b/commands/search/wattpad.js deleted file mode 100644 index fe233ee1..00000000 --- a/commands/search/wattpad.js +++ /dev/null @@ -1,63 +0,0 @@ -const Command = require('../../framework/Command'); -const moment = require('moment'); -const { MessageEmbed } = require('discord.js'); -const request = require('node-superfetch'); -const { shorten, formatNumber } = require('../../util/Util'); -const { WATTPAD_KEY } = process.env; - -module.exports = class WattpadCommand extends Command { - constructor(client) { - super(client, { - name: 'wattpad', - group: 'search', - memberName: 'wattpad', - description: 'Searches Wattpad for your query.', - clientPermissions: ['EMBED_LINKS'], - credit: [ - { - name: 'Wattpad', - url: 'https://www.wattpad.com/', - reason: 'API', - reasonURL: 'https://www.wattpad.com/developer/docs/api' - } - ], - args: [ - { - key: 'query', - prompt: 'What book would you like to search for?', - type: 'string' - } - ] - }); - } - - async run(msg, { query }) { - try { - const { body } = await request - .get('https://api.wattpad.com/v4/stories') - .query({ - query, - limit: 1 - }) - .set({ Authorization: `Basic ${WATTPAD_KEY}` }); - if (!body.stories.length) return msg.say('Could not find any results.'); - const data = body.stories[0]; - const embed = new MessageEmbed() - .setColor(0xF89C34) - .setAuthor('Wattpad', 'https://i.imgur.com/lFTXnlz.png', 'https://www.wattpad.com/') - .setURL(data.url) - .setTitle(data.title) - .setDescription(shorten(data.description)) - .setThumbnail(data.cover) - .addField('❯ Creation Date', moment.utc(data.createDate).format('MM/DD/YYYY h:mm A'), true) - .addField('❯ Author', data.user.name, true) - .addField('❯ Chapters', formatNumber(data.numParts), true) - .addField('❯ Reads', formatNumber(data.readCount), true) - .addField('❯ Votes', formatNumber(data.voteCount), true) - .addField('❯ Comments', formatNumber(data.commentCount), true); - return msg.embed(embed); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); - } - } -}; diff --git a/commands/search/yu-gi-oh.js b/commands/search/yu-gi-oh.js index 2fa0347a..ed5d84e1 100644 --- a/commands/search/yu-gi-oh.js +++ b/commands/search/yu-gi-oh.js @@ -52,7 +52,7 @@ module.exports = class YuGiOhCommand extends Command { .setDescription(data.type === 'Normal Monster' ? `_${shorten(data.desc)}_` : shorten(data.desc)) .setAuthor('Yu-Gi-Oh!', 'https://i.imgur.com/AJNBflD.png', 'http://www.yugioh-card.com/') .setThumbnail(data.card_images[0].image_url) - .setFooter(data.id) + .setFooter(data.id.toString()) .addField('❯ Type', data.type, true) .addField(data.type.includes('Monster') ? '❯ Race' : '❯ Spell Type', data.race, true); if (data.type.includes('Monster')) { diff --git a/commands/single/just-do-it.js b/commands/single/just-do-it.js deleted file mode 100644 index e7dd2635..00000000 --- a/commands/single/just-do-it.js +++ /dev/null @@ -1,25 +0,0 @@ -const Command = require('../../framework/Command'); - -module.exports = class JustDoItCommand extends Command { - constructor(client) { - super(client, { - name: 'just-do-it', - aliases: ['motivate'], - group: 'single', - memberName: 'just-do-it', - description: 'Sends a link to the "Just Do It!" motivational speech.', - credit: [ - { - name: 'MotivaShian', - url: 'https://www.youtube.com/channel/UC0yDCpC_UaXEdL6Zc4715rg', - reason: 'Original Motivational Speech', - reasonURL: 'https://www.youtube.com/watch?v=ZXsQAXx_ao0' - } - ] - }); - } - - run(msg) { - return msg.say('https://www.youtube.com/watch?v=ZXsQAXx_ao0'); - } -}; diff --git a/commands/single/lenny.js b/commands/single/lenny.js deleted file mode 100644 index 15554214..00000000 --- a/commands/single/lenny.js +++ /dev/null @@ -1,16 +0,0 @@ -const Command = require('../../framework/Command'); - -module.exports = class LennyCommand extends Command { - constructor(client) { - super(client, { - name: 'lenny', - group: 'single', - memberName: 'lenny', - description: 'Responds with the lenny face.' - }); - } - - run(msg) { - return msg.say('( Ν‘Β° ΝœΚ– Ν‘Β°)'); - } -}; diff --git a/commands/single/spam.js b/commands/single/spam.js deleted file mode 100644 index eefacd8d..00000000 --- a/commands/single/spam.js +++ /dev/null @@ -1,25 +0,0 @@ -const Command = require('../../framework/Command'); -const path = require('path'); - -module.exports = class SpamCommand extends Command { - constructor(client) { - super(client, { - name: 'spam', - group: 'single', - memberName: 'spam', - description: 'Responds with a picture of Spam.', - clientPermissions: ['ATTACH_FILES'], - credit: [ - { - name: 'SPAM Brand', - url: 'https://www.spam.com/', - reason: 'Image' - } - ] - }); - } - - run(msg) { - return msg.say({ files: [path.join(__dirname, '..', '..', 'assets', 'images', 'spam.png')] }); - } -}; diff --git a/commands/single/wynaut.js b/commands/single/wynaut.js deleted file mode 100644 index b34329cc..00000000 --- a/commands/single/wynaut.js +++ /dev/null @@ -1,26 +0,0 @@ -const Command = require('../../framework/Command'); -const path = require('path'); - -module.exports = class WynautCommand extends Command { - constructor(client) { - super(client, { - name: 'wynaut', - aliases: ['why-not'], - group: 'single', - memberName: 'wynaut', - description: 'Why not? Wynaut?', - clientPermissions: ['ATTACH_FILES'], - credit: [ - { - name: 'PokΓ©mon', - url: 'https://www.pokemon.com/us/', - reason: 'Image, Original Anime' - } - ] - }); - } - - run(msg) { - return msg.say({ files: [path.join(__dirname, '..', '..', 'assets', 'images', 'wynaut.png')] }); - } -}; diff --git a/framework/Extensions.js b/framework/Extensions.js index c9912549..eba55be9 100644 --- a/framework/Extensions.js +++ b/framework/Extensions.js @@ -11,7 +11,7 @@ Reflect.defineProperty(Message.prototype, 'embed', { value: function (embed, opt } }); Reflect.defineProperty(Message.prototype, 'code', { value: function (lang, content, options) { - return this.channel.send({ content, lang, ...options }); + return this.channel.send({ content, ...options }); } }); Reflect.defineProperty(Message.prototype, 'direct', { value: function (content, options) { diff --git a/package.json b/package.json index dd44e724..72b362b1 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,6 @@ "semver": "^7.6.0", "sherlockjs": "^1.4.2", "stackblur-canvas": "^2.7.0", - "tesseract.js": "^5.0.5", "text-diff": "^1.0.1", "tictactoe-minimax-ai": "github:marianoheller/tic-tac-toe-minimax", "twemoji-parser": "^14.0.0",