diff --git a/src/modules/codePreviews.js b/src/modules/codePreviews.js index 276fa70..df7584d 100644 --- a/src/modules/codePreviews.js +++ b/src/modules/codePreviews.js @@ -1,4 +1,7 @@ -const {MessageFlags} = require("@projectdysnomia/dysnomia").Constants; +const {ApplicationCommandOptionTypes, MessageFlags} = + require("@projectdysnomia/dysnomia").Constants; +const InteractionCommand = require("../lib/interactionCommand.js"); +const {getOption} = require("../lib/interactionDispatcher.js"); const events = require("../lib/events.js"); const {hasFlag} = require("../lib/guildSettings.js"); @@ -20,7 +23,12 @@ function unindent(str) { return str.replace(new RegExp(`^ {${minIndent}}`, "gm"), ""); } -async function processFile(link, spoiler = false) { +async function processFile( + link, + originalLink, + spoiler = false, + linkFile = false +) { link = link.replaceAll("||", "").trim(); const res = await fetch(link); if (!res.ok) return ""; @@ -28,7 +36,7 @@ async function processFile(link, spoiler = false) { const file = await res.text(); const lines = file.replace(/\r/g, "").split("\n"); - const fileName = decodeURI(link).substring( + let fileName = decodeURIComponent(link).substring( link.lastIndexOf("/") + 1, link.indexOf("#") == -1 ? link.length : link.indexOf("#") ); @@ -37,6 +45,10 @@ async function processFile(link, spoiler = false) { ? "" : fileName.substring(fileName.lastIndexOf(".") + 1); + if (linkFile) { + fileName = `[${fileName}](<${originalLink}>)`; + } + if (fileType == "md") return ""; const lineStr = link.match(/#L\d+(-L?\d+)?/)?.[0]; @@ -79,7 +91,7 @@ async function processFile(link, spoiler = false) { warning = " - :warning: Zero width spaces present"; } - return `**${fileName}: **${whichLines}${warning}\n${ + return `**${fileName}:** ${whichLines}${warning}\n${ spoiler ? "||" : "" }\`\`\`${fileType}\n${unindent(targetLines)}\n\`\`\`${spoiler ? "||" : ""}`; } @@ -98,21 +110,27 @@ events.add("messageCreate", "codePreviews", async function (msg) { if (githubLinks?.length) { for (const link of githubLinks) { const spoiler = REGEX_SPOILER.test(link); - files.push(await processFile(link.replace("/blob/", "/raw/"), spoiler)); + files.push( + await processFile(link.replace("/blob/", "/raw/"), link, spoiler) + ); } } if (gitlabLinks?.length) { for (const link of gitlabLinks) { const spoiler = REGEX_SPOILER.test(link); - files.push(await processFile(link.replace("/blob/", "/raw/"), spoiler)); + files.push( + await processFile(link.replace("/blob/", "/raw/"), link, spoiler) + ); } } if (giteaLinks?.length) { for (const link of giteaLinks) { const spoiler = REGEX_SPOILER.test(link); - files.push(await processFile(link.replace("/src/", "/raw/"), spoiler)); + files.push( + await processFile(link.replace("/src/", "/raw/"), link, spoiler) + ); } } @@ -155,3 +173,58 @@ events.add("messageCreate", "codePreviews", async function (msg) { } } }); + +const codepreviewsCommand = new InteractionCommand("codepreview"); +codepreviewsCommand.helpText = + "Post snippets of codes from files on GitHub, Gitlab and Gitea instances."; +codepreviewsCommand.options.url = { + name: "url", + type: ApplicationCommandOptionTypes.STRING, + description: "URL to attempt to parse", + required: true, + default: "", +}; +codepreviewsCommand.options.spoiler = { + name: "spoiler", + type: ApplicationCommandOptionTypes.BOOLEAN, + description: "Send spoilered", + required: false, + default: false, +}; +codepreviewsCommand.callback = async function (interaction) { + const url = getOption(interaction, codepreviewsCommand, "url"); + const spoiler = getOption(interaction, codepreviewsCommand, "spoiler"); + + const githubOrGitlab = url.match(REGEX_GITHUB) ?? url.match(REGEX_GITLAB); + const gitea = url.match(REGEX_GITEA); + + let out = ""; + if (githubOrGitlab) { + out = await processFile(url.replace("/blob/", "/raw/"), url, spoiler, true); + } else if (gitea) { + out = await processFile(url.replace("/src/", "/raw/"), url, spoiler, true); + } else { + return { + content: "Provided link did not match any services.", + flags: MessageFlags.EPHEMERAL, + }; + } + + if (out == "") { + return { + content: + "No content was returned. Provided file is either too long, a markdown file, or not plaintext.", + flags: MessageFlags.EPHEMERAL, + }; + } + + if (out.length > 2000) { + return { + content: "Provided file is too long.", + flags: MessageFlags.EPHEMERAL, + }; + } + + return out; +}; +hf.registerCommand(codepreviewsCommand);