From 372746eba998d6af38b26cb2a4a9f66d2c277d4a Mon Sep 17 00:00:00 2001 From: artie Date: Sun, 16 Feb 2025 00:34:00 +0100 Subject: [PATCH] fix some dry code --- src/commands/ocr/ocr.ts | 8 ++-- src/commands/ocr/ocrMenu.ts | 12 +----- src/commands/ocr/ocrTranslate.ts | 7 +--- src/commands/ocr/ocrTranslateEnglishMenu.ts | 12 +----- src/commands/ocr/ocrTranslateMenu.ts | 12 +----- src/utils/functions.ts | 41 +++++++++++++-------- 6 files changed, 36 insertions(+), 56 deletions(-) diff --git a/src/commands/ocr/ocr.ts b/src/commands/ocr/ocr.ts index dd566fd..51eaab1 100644 --- a/src/commands/ocr/ocr.ts +++ b/src/commands/ocr/ocr.ts @@ -11,7 +11,7 @@ import { yandexOcr } from "../../utils/yandex"; import sharp from "sharp"; import { capitalize, - getImageFromAttachmentOrString, + getImageUrlFromChatInteraction, languageCodeToName, run, } from "../../utils/functions"; @@ -76,7 +76,7 @@ export async function ocrImpl(url: string) { if (!type?.mime.startsWith("image/")) { console.log(type, url); - abort("The file must be an image!"); + abort("Not a valid image!"); } const compressed = await sharp(data) @@ -107,9 +107,7 @@ export default defineCommand({ ), async execute(interaction) { - const attachment = interaction.options.getAttachment("image"); - const url = interaction.options.getString("url"); - const imageUrl = getImageFromAttachmentOrString(attachment, url); + const imageUrl = getImageUrlFromChatInteraction(interaction); await interaction.deferReply(); diff --git a/src/commands/ocr/ocrMenu.ts b/src/commands/ocr/ocrMenu.ts index 872f223..bcc924c 100644 --- a/src/commands/ocr/ocrMenu.ts +++ b/src/commands/ocr/ocrMenu.ts @@ -1,7 +1,7 @@ import { ApplicationCommandType, ContextMenuCommandBuilder } from "discord.js"; import { defineCommand } from ".."; import { buildOcrPayload, ocrImpl } from "./ocr"; -import { getImageFromAttachmentOrString } from "../../utils/functions"; +import { getImageUrlFromMessage } from "../../utils/functions"; export default defineCommand({ data: new ContextMenuCommandBuilder() @@ -11,15 +11,7 @@ export default defineCommand({ async execute(interaction) { if (!interaction.isMessageContextMenuCommand()) return; - const attachment = interaction.targetMessage.attachments.first(); - const embed = interaction.targetMessage.embeds[0]; - - const imageUrl = getImageFromAttachmentOrString( - attachment, - embed?.image?.url || - embed?.thumbnail?.url || - interaction.targetMessage.content - ); + const imageUrl = getImageUrlFromMessage(interaction.targetMessage); await interaction.deferReply(); diff --git a/src/commands/ocr/ocrTranslate.ts b/src/commands/ocr/ocrTranslate.ts index c8ba1fd..a9c4aac 100644 --- a/src/commands/ocr/ocrTranslate.ts +++ b/src/commands/ocr/ocrTranslate.ts @@ -7,7 +7,7 @@ import { translateImpl, } from "../language/translate"; import { ocrImpl } from "./ocr"; -import { getImageFromAttachmentOrString } from "../../utils/functions"; +import { getImageUrlFromChatInteraction } from "../../utils/functions"; export default defineCommand({ data: new SlashCommandBuilder() @@ -37,13 +37,10 @@ export default defineCommand({ autocomplete: translateAutocompleteImpl, async execute(interaction) { - const attachment = interaction.options.getAttachment("image"); - const url = interaction.options.getString("url"); - const source = interaction.options.getString("source") ?? null; const target = interaction.options.getString("target") ?? "en-US"; - const imageUrl = getImageFromAttachmentOrString(attachment, url); + const imageUrl = getImageUrlFromChatInteraction(interaction); await interaction.deferReply(); diff --git a/src/commands/ocr/ocrTranslateEnglishMenu.ts b/src/commands/ocr/ocrTranslateEnglishMenu.ts index db8188f..85079f6 100644 --- a/src/commands/ocr/ocrTranslateEnglishMenu.ts +++ b/src/commands/ocr/ocrTranslateEnglishMenu.ts @@ -2,7 +2,7 @@ import { ApplicationCommandType, ContextMenuCommandBuilder } from "discord.js"; import { defineCommand } from ".."; import { translateImpl } from "../language/translate"; import { ocrImpl } from "./ocr"; -import { getImageFromAttachmentOrString } from "../../utils/functions"; +import { getImageUrlFromMessage } from "../../utils/functions"; export default defineCommand({ data: new ContextMenuCommandBuilder() @@ -12,15 +12,7 @@ export default defineCommand({ async execute(interaction) { if (!interaction.isMessageContextMenuCommand()) return; - const attachment = interaction.targetMessage.attachments.first(); - const embed = interaction.targetMessage.embeds[0]; - - const imageUrl = getImageFromAttachmentOrString( - attachment, - embed?.image?.url || - embed?.thumbnail?.url || - interaction.targetMessage.content - ); + const imageUrl = getImageUrlFromMessage(interaction.targetMessage); await interaction.deferReply(); diff --git a/src/commands/ocr/ocrTranslateMenu.ts b/src/commands/ocr/ocrTranslateMenu.ts index 35efac6..ad5db70 100644 --- a/src/commands/ocr/ocrTranslateMenu.ts +++ b/src/commands/ocr/ocrTranslateMenu.ts @@ -2,10 +2,10 @@ import { ApplicationCommandType, ContextMenuCommandBuilder } from "discord.js"; import { defineCommand } from ".."; import { translateImpl } from "../language/translate"; import { ocrImpl } from "./ocr"; -import { getImageFromAttachmentOrString } from "../../utils/functions"; import { buildTranslateModal } from "../language/translateMenu"; import { abort } from "../../utils/error"; import { findFuzzyLanguage } from "../../utils/deepl"; +import { getImageUrlFromMessage } from "../../utils/functions"; export default defineCommand({ data: new ContextMenuCommandBuilder() @@ -15,15 +15,7 @@ export default defineCommand({ async execute(interaction) { if (!interaction.isMessageContextMenuCommand()) return; - const attachment = interaction.targetMessage.attachments.first(); - const embed = interaction.targetMessage.embeds[0]; - - const imageUrl = getImageFromAttachmentOrString( - attachment, - embed?.image?.url || - embed?.thumbnail?.url || - interaction.targetMessage.content - ); + const imageUrl = getImageUrlFromMessage(interaction.targetMessage); const modal = buildTranslateModal(); await interaction.showModal(modal); diff --git a/src/utils/functions.ts b/src/utils/functions.ts index f5b64e0..9dac1d2 100644 --- a/src/utils/functions.ts +++ b/src/utils/functions.ts @@ -2,7 +2,7 @@ import * as cheerio from "cheerio"; import { execa } from "execa"; import { customAlphabet } from "nanoid"; import { URL_REGEX } from "./constants"; -import type { Attachment } from "discord.js"; +import { Message, type ChatInputCommandInteraction } from "discord.js"; import { abort } from "./error"; export const nanoid = customAlphabet("1234567890abcdef"); @@ -80,22 +80,31 @@ export function capitalize(str: string) { return str.charAt(0).toUpperCase() + str.slice(1); } -export function getImageFromAttachmentOrString( - attachment?: Attachment | null, - str?: string | null +export function getImageUrlFromChatInteraction( + interaction: ChatInputCommandInteraction, + attachmentName = "image", + urlName = "url" ) { - if (attachment) { - if (!attachment.contentType?.startsWith("image/")) { - abort("The file must be an image!"); - } - return attachment.url; - } else if (str) { - const match = findFirstUrl(str); - if (!match) abort("The URL is invalid!"); - return match; - } else { - abort("You must provide an image or an image URL!"); - } + const attachment = interaction.options.getAttachment(attachmentName); + const url = interaction.options.getString(urlName); + + return ( + (attachment?.contentType?.startsWith("image/") && attachment.url) || + (url && findFirstUrl(url)) || + abort("You must provide a valid image or image URL!") + ); +} + +export function getImageUrlFromMessage(message: Message): string { + const attachment = message.attachments.first(); + + return ( + (attachment?.contentType?.startsWith("image/") && attachment.url) || + message.embeds[0]?.image?.url || + message.embeds[0]?.thumbnail?.url || + findFirstUrl(message.content) || + abort("No valid image found!") + ); } export function languageCodeToName(code: string) {