From 00725e8efb19d50feb4c1daef7c8d625836e164c Mon Sep 17 00:00:00 2001 From: bignutty <3515180-bignutty@users.noreply.gitlab.com> Date: Thu, 25 Jul 2024 19:47:18 +0200 Subject: [PATCH] expose ocr and reverseimage via regular slash --- commands/interaction/slash/utils/ocr.js | 63 ++++++++++++++ .../interaction/slash/utils/reverse-image.js | 82 +++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 commands/interaction/slash/utils/ocr.js create mode 100644 commands/interaction/slash/utils/reverse-image.js diff --git a/commands/interaction/slash/utils/ocr.js b/commands/interaction/slash/utils/ocr.js new file mode 100644 index 0000000..3e89fae --- /dev/null +++ b/commands/interaction/slash/utils/ocr.js @@ -0,0 +1,63 @@ +const { googleVisionOcr } = require("#api"); + +const { validateAttachment } = require("#utils/attachment"); +const { createEmbed } = require("#utils/embed"); +const { acknowledge } = require("#utils/interactions"); +const { codeblock, stringwrap } = require("#utils/markdown"); +const { editOrReply } = require("#utils/message"); +const { STATICS } = require("#utils/statics"); + +const { ApplicationCommandOptionTypes } = require('detritus-client/lib/constants'); + +module.exports = { + name: 'ocr', + description: 'Reads text contents from an image.', + contexts: [ + 0, + 1, + 2 + ], + integrationTypes: [ + 1 + ], + options: [ + { + name: 'image', + description: 'Image to scan', + type: ApplicationCommandOptionTypes.ATTACHMENT, + required: true + }, + { + name: 'incognito', + description: 'Makes the response only visible to you.', + type: ApplicationCommandOptionTypes.BOOLEAN, + required: false, + default: false + } + ], + run: async (context, args) => { + await acknowledge(context, args.incognito); + + if(!validateAttachment(args.image, "image")) return await editOrReply(context, createEmbed("warning", context, "Unsupported attachment type.")) + + try{ + let ocr = await googleVisionOcr(context, args.image.url); + + if(ocr.response.body.status == 1) return context.editOrRespond({ embeds: [createEmbed("warning", context, ocr.response.body.text)] }) + + return await editOrReply(context, createEmbed("default", context, { + thumbnail: { + url: args.image.url + }, + description: codeblock("ansi", ["​" + stringwrap(ocr.response.body.text, 2000)]), + footer: { + iconUrl: STATICS.google, + text: `Google Cloud Vision • ${context.application.name} • Took ${ocr.timings}s` + } + })) + }catch(e){ + console.log(e) + return editOrReply(context, createEmbed("error", context, "Unable to perform OCR.")) + } + } +} \ No newline at end of file diff --git a/commands/interaction/slash/utils/reverse-image.js b/commands/interaction/slash/utils/reverse-image.js new file mode 100644 index 0000000..6a45a32 --- /dev/null +++ b/commands/interaction/slash/utils/reverse-image.js @@ -0,0 +1,82 @@ +const { reverseImageSearch } = require("#api"); +const { paginator } = require("#client"); + +const { validateAttachment } = require("#utils/attachment"); +const { createEmbed, formatPaginationEmbeds, page } = require("#utils/embed"); +const { acknowledge } = require("#utils/interactions"); +const { editOrReply } = require("#utils/message"); + +const { ApplicationCommandOptionTypes } = require('detritus-client/lib/constants'); + +// TODO: create a favicon() util +function createReverseImageSearchResultPage(context, result, source) { + let res = page( + createEmbed("default", context, { + author: { + iconUrl: `https://www.google.com/s2/favicons?domain=${encodeURIComponent(result.url)}&sz=256`, + name: result.name, + url: result.url + }, + image: { + url: result.image + }, + thumbnail: { + url: source + } + })) + if (result.thumbnail) res.embeds[0].thumbnail = { url: result.thumbnail }; + return res; +} + +module.exports = { + name: 'reverse-image-search', + description: 'Searches for image matches on the internet.', + contexts: [ + 0, + 1, + 2 + ], + integrationTypes: [ + 1 + ], + options: [ + { + name: 'image', + description: 'Image to search for', + type: ApplicationCommandOptionTypes.ATTACHMENT, + required: true + }, + { + name: 'incognito', + description: 'Makes the response only visible to you.', + type: ApplicationCommandOptionTypes.BOOLEAN, + required: false, + default: false + } + ], + run: async (context, args) => { + await acknowledge(context, args.incognito); + + if(!validateAttachment(args.image, "image")) return await editOrReply(context, createEmbed("warning", context, "Unsupported attachment type.")) + + try{ + let search = await reverseImageSearch(context, args.image.url); + search = search.response + + if (search.body.status == 2) return editOrReply(context, createEmbed("error", context, search.body.message)) + + let pages = [] + for (const res of search.body.results) { + pages.push(createReverseImageSearchResultPage(context, res, args.image.url)) + } + + await paginator.createPaginator({ + context, + pages: formatPaginationEmbeds(pages) + }); + }catch(e){ + console.log(e) + return editOrReply(context, createEmbed("error", context, "Unable to perform reverse image search.")) + } + } +} \ No newline at end of file