((.|\n)*?)<\/blockquote>/gi,
- (_, quote) => "> " + quote.split("\n").join("\n> ")
- );
- str = str.replace(/<\/p>/gi, "\n\n");
- str = str.replace(/
/gi, "\n");
- str = str.replace(/- /gi, "- ");
- str = str.replace(/<\/li>/gi, "\n");
- str = str.replace(/<\/?code>/gi, "`");
- str = str.replace(/<\/?em>/gi, "*");
- str = str.replace(/<\/?u>/gi, "__");
- str = str.replace(/<\/?s>/gi, "~~");
- str = str.replace(/(<([^>]+)>)/gi, "");
- str = parseHtmlEntities(str);
- // whyyyyyyyyyyyy
- str = str.replace(/\[https?:\/\/.+?\]\((https?:\/\/.+?)\)/gi, "$1");
-
- return str;
-}
-
async function processUrl(msg, url, spoiler = false) {
let invalidUrl = false;
let urlObj;
@@ -200,10 +162,7 @@ async function processUrl(msg, url, spoiler = false) {
},
}).then((res) => res.text());
} catch (err) {
- logger.error(
- "fedimbed",
- `Failed to signed fetch "${url}", retrying unsigned: ${err}`
- );
+ logger.error("fedimbed", `Failed to signed fetch "${url}", retrying unsigned: ${err}`);
}
if (!rawPostData) {
try {
@@ -223,10 +182,7 @@ async function processUrl(msg, url, spoiler = false) {
try {
postData = JSON.parse(rawPostData);
} catch (err) {
- logger.error(
- "fedimbed",
- `Failed to decode JSON for "${url}": ${err}\n "${rawPostData}"`
- );
+ logger.error("fedimbed", `Failed to decode JSON for "${url}": ${err}\n "${rawPostData}"`);
}
} else {
logger.warn("fedimbed", `Got non-JSON for "${url}": ${rawPostData}`);
@@ -280,18 +236,13 @@ async function processUrl(msg, url, spoiler = false) {
options.body = JSON.stringify({noteId});
headers["Content-Type"] = "application/json";
} else {
- logger.error(
- "fedimbed",
- `Missing MastoAPI replacement for "${platform}"`
- );
+ logger.error("fedimbed", `Missing MastoAPI replacement for "${platform}"`);
}
if (redirUrl) {
logger.verbose(
"fedimbed",
- `Redirecting "${url}" to "${redirUrl}": ${JSON.stringify(
- options
- )}, ${JSON.stringify(headers)}`
+ `Redirecting "${url}" to "${redirUrl}": ${JSON.stringify(options)}, ${JSON.stringify(headers)}`
);
let rawPostData2;
try {
@@ -304,10 +255,7 @@ async function processUrl(msg, url, spoiler = false) {
})
).then((res) => res.text());
} catch (err) {
- logger.error(
- "fedimbed",
- `Failed to signed fetch "${url}" via MastoAPI, retrying unsigned: ${err}`
- );
+ logger.error("fedimbed", `Failed to signed fetch "${url}" via MastoAPI, retrying unsigned: ${err}`);
}
if (!rawPostData2) {
try {
@@ -320,10 +268,7 @@ async function processUrl(msg, url, spoiler = false) {
})
).then((res) => res.text());
} catch (err) {
- logger.error(
- "fedimbed",
- `Failed to fetch "${url}" via MastoAPI: ${err}`
- );
+ logger.error("fedimbed", `Failed to fetch "${url}" via MastoAPI: ${err}`);
}
}
@@ -331,27 +276,18 @@ async function processUrl(msg, url, spoiler = false) {
if (rawPostData2?.startsWith("{")) {
postData2 = JSON.parse(rawPostData2);
} else {
- logger.warn(
- "fedimbed",
- `Got non-JSON for "${url}" via MastoAPI: ${rawPostData2}`
- );
+ logger.warn("fedimbed", `Got non-JSON for "${url}" via MastoAPI: ${rawPostData2}`);
}
if (!postData2) {
- logger.warn(
- "fedimbed",
- `Bailing trying to re-embed "${url}": Failed to get post from normal and MastoAPI.`
- );
+ logger.warn("fedimbed", `Bailing trying to re-embed "${url}": Failed to get post from normal and MastoAPI.`);
} else if (postData2.error) {
logger.error(
"fedimbed",
- `Bailing trying to re-embed "${url}", MastoAPI gave us error: ${JSON.stringify(
- postData2.error
- )}`
+ `Bailing trying to re-embed "${url}", MastoAPI gave us error: ${JSON.stringify(postData2.error)}`
);
} else {
- cw =
- postData2.spoiler_warning ?? postData2.spoiler_text ?? postData2.cw;
+ cw = postData2.spoiler_warning ?? postData2.spoiler_text ?? postData2.cw;
content =
postData2.akkoma?.source?.content ??
postData2.pleroma?.content?.["text/plain"] ??
@@ -364,21 +300,12 @@ async function processUrl(msg, url, spoiler = false) {
postData2.user?.name ??
postData2.user?.username,
handle:
- postData2.account?.fqn ??
- `${postData2.account?.username ?? postData2.user?.username}@${
- urlObj.hostname
- }`,
- url:
- postData2.account?.url ??
- `${urlObj.origin}/@${
- postData2.account?.username ?? postData2.user?.username
- }`,
+ postData2.account?.fqn ?? `${postData2.account?.username ?? postData2.user?.username}@${urlObj.hostname}`,
+ url: postData2.account?.url ?? `${urlObj.origin}/@${postData2.account?.username ?? postData2.user?.username}`,
avatar: postData2.account?.avatar ?? postData2.user?.avatarUrl,
};
timestamp = postData2.created_at ?? postData2.createdAt;
- emotes = postData2.emojis
- .filter((x) => !x.name.endsWith("@."))
- .map((x) => ({name: `:${x.name}:`, url: x.url}));
+ emotes = postData2.emojis.filter((x) => !x.name.endsWith("@.")).map((x) => ({name: `:${x.name}:`, url: x.url}));
sensitive = postData2.sensitive;
const attachments = postData2.media_attachments ?? postData2.files;
@@ -465,15 +392,12 @@ async function processUrl(msg, url, spoiler = false) {
if (realUrlObj.origin != urlObj.origin) {
platform = await resolvePlatform(postData.id);
color = PLATFORM_COLORS[platform];
- platformName = platform
- .replace("gotosocial", "GoToSocial")
- .replace(/^(.)/, (_, c) => c.toUpperCase());
+ platformName = platform.replace("gotosocial", "GoToSocial").replace(/^(.)/, (_, c) => c.toUpperCase());
url = postData.id;
}
}
- content =
- postData._misskey_content ?? postData.source?.content ?? postData.content;
+ content = postData._misskey_content ?? postData.source?.content ?? postData.content;
cw = postData.summary;
timestamp = postData.published;
sensitive = postData.sensitive;
@@ -482,36 +406,29 @@ async function processUrl(msg, url, spoiler = false) {
let tag = postData.tag;
// gts moment
if (!Array.isArray(tag)) tag = [tag];
- emotes = tag
- .filter((x) => !!x.icon)
- .map((x) => ({name: x.name, url: x.icon.url}));
+ emotes = tag.filter((x) => !!x.icon).map((x) => ({name: x.name, url: x.icon.url}));
}
// NB: gts doesnt send singular attachments as array
- const attachments = Array.isArray(postData.attachment)
- ? postData.attachment
- : [postData.attachment];
+ const attachments = Array.isArray(postData.attachment) ? postData.attachment : [postData.attachment];
for (const attachment of attachments) {
if (attachment.mediaType) {
if (attachment.mediaType.startsWith("video/")) {
videos.push({
url: attachment.url,
- desc:
- attachment.name ?? attachment.description ?? attachment.comment,
+ desc: attachment.name ?? attachment.description ?? attachment.comment,
type: attachment.mediaType,
});
} else if (attachment.mediaType.startsWith("image/")) {
images.push({
url: attachment.url,
- desc:
- attachment.name ?? attachment.description ?? attachment.comment,
+ desc: attachment.name ?? attachment.description ?? attachment.comment,
type: attachment.mediaType,
});
} else if (attachment.mediaType.startsWith("audio/")) {
audios.push({
url: attachment.url,
- desc:
- attachment.name ?? attachment.description ?? attachment.comment,
+ desc: attachment.name ?? attachment.description ?? attachment.comment,
type: attachment.mediaType,
});
}
@@ -524,22 +441,19 @@ async function processUrl(msg, url, spoiler = false) {
if (contentType.startsWith("image/")) {
images.push({
url: attachment.url,
- desc:
- attachment.name ?? attachment.description ?? attachment.comment,
+ desc: attachment.name ?? attachment.description ?? attachment.comment,
type: contentType,
});
} else if (contentType.startsWith("video/")) {
videos.push({
url: attachment.url,
- desc:
- attachment.name ?? attachment.description ?? attachment.comment,
+ desc: attachment.name ?? attachment.description ?? attachment.comment,
type: contentType,
});
} else if (contentType.startsWith("audio/")) {
audios.push({
url: attachment.url,
- desc:
- attachment.name ?? attachment.description ?? attachment.comment,
+ desc: attachment.name ?? attachment.description ?? attachment.comment,
type: contentType,
});
}
@@ -551,39 +465,29 @@ async function processUrl(msg, url, spoiler = false) {
? type
: type +
"/" +
- (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? type == "image"
- ? "png"
- : type == "video"
- ? "mp4"
- : "mpeg");
+ (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? type == "image" ? "png" : type == "video" ? "mp4" : "mpeg");
if (type.startsWith("image")) {
images.push({
url: attachment.url,
- desc:
- attachment.name ?? attachment.description ?? attachment.comment,
+ desc: attachment.name ?? attachment.description ?? attachment.comment,
type: fileType,
});
} else if (type.startsWith("video")) {
videos.push({
url: attachment.url,
- desc:
- attachment.name ?? attachment.description ?? attachment.comment,
+ desc: attachment.name ?? attachment.description ?? attachment.comment,
type: fileType,
});
} else if (type.startsWith("audio")) {
audios.push({
url: attachment.url,
- desc:
- attachment.name ?? attachment.description ?? attachment.comment,
+ desc: attachment.name ?? attachment.description ?? attachment.comment,
type: fileType,
});
}
}
} else {
- logger.warn(
- "fedimbed",
- `Unhandled attachment structure! ${JSON.stringify(attachment)}`
- );
+ logger.warn("fedimbed", `Unhandled attachment structure! ${JSON.stringify(attachment)}`);
}
}
@@ -599,30 +503,23 @@ async function processUrl(msg, url, spoiler = false) {
images.push({
url: postData.image.url,
desc: "",
- type:
- contentType ??
- "image/" +
- imageUrl.pathname.substring(imageUrl.pathname.lastIndexOf(".") + 1),
+ type: contentType ?? "image/" + imageUrl.pathname.substring(imageUrl.pathname.lastIndexOf(".") + 1),
});
}
if (postData.name) title = postData.name;
// Author data is not sent with the post with AS2
- const authorData = await signedFetch(
- postData.actor ?? postData.attributedTo,
- {
- headers: {
- "User-Agent": FRIENDLY_USERAGENT,
- Accept: "application/activity+json",
- },
- }
- )
+ const authorData = await signedFetch(postData.actor ?? postData.attributedTo, {
+ headers: {
+ "User-Agent": FRIENDLY_USERAGENT,
+ Accept: "application/activity+json",
+ },
+ })
.then((res) => res.json())
.catch((err) => {
// only posts can be activity+json right now, reduce log spam
- if (platform !== "cohost")
- logger.error("fedimbed", `Failed to get author for "${url}": ${err}`);
+ if (platform !== "cohost") logger.error("fedimbed", `Failed to get author for "${url}": ${err}`);
});
if (authorData) {
@@ -637,9 +534,7 @@ async function processUrl(msg, url, spoiler = false) {
// bootleg author, mainly for cohost
const authorUrl = postData.actor ?? postData.attributedTo;
const authorUrlObj = new URL(authorUrl);
- const name = authorUrlObj.pathname.substring(
- authorUrlObj.pathname.lastIndexOf("/") + 1
- );
+ const name = authorUrlObj.pathname.substring(authorUrlObj.pathname.lastIndexOf("/") + 1);
author = {
name,
handle: `${name}@${authorUrlObj.hostname}`,
@@ -661,10 +556,7 @@ async function processUrl(msg, url, spoiler = false) {
// We could just continue without author but it'd look ugly and be confusing.
if (!author) {
- logger.warn(
- "fedimbed",
- `Bailing trying to re-embed "${url}": Failed to get author.`
- );
+ logger.warn("fedimbed", `Bailing trying to re-embed "${url}": Failed to get author.`);
return {};
}
@@ -682,12 +574,7 @@ async function processUrl(msg, url, spoiler = false) {
let desc = "";
let MAX_LENGTH = 3999;
- if (
- (cw != "" || sensitive) &&
- images.length == 0 &&
- videos.length == 0 &&
- audios.length == 0
- ) {
+ if ((cw != "" || sensitive) && images.length == 0 && videos.length == 0 && audios.length == 0) {
desc += "||" + content + "||";
MAX_LENGTH -= 4;
@@ -708,9 +595,7 @@ async function processUrl(msg, url, spoiler = false) {
}
}
- const user = author.name
- ? `${author.name} (${author.handle})`
- : author.handle;
+ const user = author.name ? `${author.name} (${author.handle})` : author.handle;
const baseEmbed = {
color,
@@ -734,9 +619,7 @@ async function processUrl(msg, url, spoiler = false) {
};
if (images.length > 0) {
if (images.length > 1) {
- const links = images
- .map((attachment, index) => `[Image ${index + 1}](${attachment.url})`)
- .join(" | ");
+ const links = images.map((attachment, index) => `[Image ${index + 1}](${attachment.url})`).join(" | ");
if (links.length <= 1024)
baseEmbed.fields.push({
@@ -756,9 +639,7 @@ async function processUrl(msg, url, spoiler = false) {
if (videos.length > 1) {
baseEmbed.fields.push({
name: "Videos",
- value: videos
- .map((attachment, index) => `[Video ${index + 1}](${attachment.url})`)
- .join(" | "),
+ value: videos.map((attachment, index) => `[Video ${index + 1}](${attachment.url})`).join(" | "),
inline: true,
});
} else {
@@ -773,9 +654,7 @@ async function processUrl(msg, url, spoiler = false) {
if (audios.length > 1) {
baseEmbed.fields.push({
name: "Audios",
- value: audios
- .map((attachment, index) => `[Audio ${index + 1}](${attachment.url})`)
- .join(" | "),
+ value: audios.map((attachment, index) => `[Audio ${index + 1}](${attachment.url})`).join(" | "),
inline: true,
});
} else {
@@ -796,29 +675,24 @@ async function processUrl(msg, url, spoiler = false) {
const percent = o.count / poll.total;
const bar = Math.round(percent * 30);
- return `**${o.name}** (${o.count}, ${Math.round(
- percent * 100
- )}%)\n\`[${"=".repeat(bar)}${" ".repeat(30 - bar)}]\``;
+ return `**${o.name}** (${o.count}, ${Math.round(percent * 100)}%)\n\`[${"=".repeat(bar)}${" ".repeat(
+ 30 - bar
+ )}]\``;
})
- .join("\n\n") +
- `\n\n${poll.total} votes \u2022 Ends `,
+ .join("\n\n") + `\n\n${poll.total} votes \u2022 Ends `,
});
}
let sendWait = false;
if (videos.length > 0 || audios.length > 0 || images.length > 4) {
sendWait = true;
- if (msg instanceof Dysnomia.Message) await msg.addReaction("\uD83D\uDCE4");
+ if (msg instanceof Message) await msg.addReaction("\uD83D\uDCE4");
}
const embeds = [];
const files = [];
- const guild =
- msg.channel?.guild ??
- (msg.guildID ? hf.bot.guilds.get(msg.guildID) : false);
+ const guild = msg.channel?.guild ?? (msg.guildID ? hf.bot.guilds.get(msg.guildID) : false);
if (images.length > 0) {
if (images.length <= 4) {
@@ -852,9 +726,7 @@ async function processUrl(msg, url, spoiler = false) {
(cw != "" || spoiler ? "SPOILER_" : "") +
(attachment.type.indexOf("/") > -1
? attachment.type.replace("/", ".")
- : attachment.type +
- "." +
- (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? "png")),
+ : attachment.type + "." + (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? "png")),
file,
description: attachment.desc,
});
@@ -886,9 +758,7 @@ async function processUrl(msg, url, spoiler = false) {
(cw != "" || spoiler ? "SPOILER_" : "") +
(attachment.type.indexOf("/") > -1
? attachment.type.replace("/", ".")
- : attachment.type +
- "." +
- (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? "png")),
+ : attachment.type + "." + (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? "png")),
file,
description: attachment.desc,
});
@@ -959,9 +829,7 @@ async function processUrl(msg, url, spoiler = false) {
(cw != "" || spoiler ? "SPOILER_" : "") +
(attachment.type.indexOf("/") > -1
? attachment.type.replace("/", ".").replace("quicktime", "mov")
- : attachment.type +
- "." +
- (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? "mp4")),
+ : attachment.type + "." + (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? "mp4")),
file,
});
}
@@ -989,14 +857,8 @@ async function processUrl(msg, url, spoiler = false) {
filename:
(cw != "" || spoiler ? "SPOILER_" : "") +
(attachment.type.indexOf("/") > -1
- ? attachment.type
- .replace("/", ".")
- .replace("mpeg", "mp3")
- .replace("vnd.wave", "wav")
- .replace("x-", "")
- : attachment.type +
- "." +
- (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? "mp3")),
+ ? attachment.type.replace("/", ".").replace("mpeg", "mp3").replace("vnd.wave", "wav").replace("x-", "")
+ : attachment.type + "." + (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? "mp3")),
file,
});
}
@@ -1006,8 +868,7 @@ async function processUrl(msg, url, spoiler = false) {
return {
response: {
content:
- cw != "" &&
- (images.length > 0 || videos.length > 0 || audios.length > 0)
+ cw != "" && (images.length > 0 || videos.length > 0 || audios.length > 0)
? `:warning: ${cw} || ${url} ||`
: spoiler
? `|| ${url} ||`
@@ -1051,10 +912,7 @@ events.add("messageCreate", "fedimbed", async function (msg) {
for (const service of Object.keys(PATH_REGEX)) {
const regex = PATH_REGEX[service];
if (urlObj && regex.test(urlObj.pathname)) {
- logger.verbose(
- "fedimbed",
- `Hit "${service}" for "${url}", processing now.`
- );
+ logger.verbose("fedimbed", `Hit "${service}" for "${url}", processing now.`);
try {
const {response, sendWait} = await processUrl(msg, url, hasSpoiler);
await msg.channel.createMessage(response).then(() => {
@@ -1067,10 +925,7 @@ events.add("messageCreate", "fedimbed", async function (msg) {
}
});
} catch (err) {
- logger.error(
- "fedimbed",
- `Error processing "${url}":\n` + err.stack
- );
+ logger.error("fedimbed", `Error processing "${url}":\n` + err.stack);
}
break;
}
@@ -1080,8 +935,7 @@ events.add("messageCreate", "fedimbed", async function (msg) {
});
const fedimbedCommand = new InteractionCommand("fedimbed");
-fedimbedCommand.helpText =
- "Better embeds for fediverse (Mastodon, Pleroma, etc) posts";
+fedimbedCommand.helpText = "Better embeds for fediverse (Mastodon, Pleroma, etc) posts";
fedimbedCommand.options.url = {
name: "url",
type: ApplicationCommandOptionTypes.STRING,
@@ -1098,8 +952,8 @@ fedimbedCommand.options.spoiler = {
};
fedimbedCommand.permissions = Permissions.embedLinks | Permissions.attachFiles;
fedimbedCommand.callback = async function (interaction) {
- let url = getOption(interaction, fedimbedCommand, "url");
- const spoiler = getOption(interaction, fedimbedCommand, "spoiler");
+ let url = this.getOption(interaction, "url");
+ const spoiler = this.getOption(interaction, "spoiler");
url = url
.replace(/\|/g, "")
diff --git a/src/modules/foxwells.js b/src/modules/foxwells.js
index db0a512..fdeaff8 100644
--- a/src/modules/foxwells.js
+++ b/src/modules/foxwells.js
@@ -5,16 +5,15 @@ const CATEGORY = "misc";
const FOXWELLS_GUILD_ID = "300436792916836352";
const {tinycolor} = require("@ctrl/tinycolor");
-const {pastelize} = require("../lib/utils.js");
+const {pastelize} = require("../util/misc.js");
+const {createBoardMessage} = require("../util/starboard.js");
const logger = require("../lib/logger.js");
// taken from rot13.com
function rot(s, i) {
return s.replace(/[a-zA-Z]/g, function (c) {
- return String.fromCharCode(
- (c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + i) ? c : c - 26
- );
+ return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + i) ? c : c - 26);
});
}
@@ -42,9 +41,7 @@ utsuholights.callback = async function (msg, line, [hex, bri]) {
cachedLightsURL = Buffer.from(rot(LIGHTS_URL, 13), "base64").toString(); // Wow! It's That Easy!
}
- const response = await fetch(
- `${cachedLightsURL}?r=${r}&g=${g}&b=${b}${bri ? `&bri=${bri}` : ""}`
- );
+ const response = await fetch(`${cachedLightsURL}?r=${r}&g=${g}&b=${b}${bri ? `&bri=${bri}` : ""}`);
if (response.status == 200) {
return {reaction: "\uD83D\uDC4C"};
@@ -54,17 +51,11 @@ utsuholights.callback = async function (msg, line, [hex, bri]) {
};
//hf.registerCommand(utsuholights);
-const JPEG_HEADER = Buffer.from([
- 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46,
-]);
+const JPEG_HEADER = Buffer.from([0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46]);
async function fetchPlant() {
const res = await fetch("https://nuclear.utsuho.rocks/plant/");
- const boundary = res.headers
- .get("Content-Type")
- .split(";")[1]
- .trim()
- .replace("boundary=", "--");
+ const boundary = res.headers.get("Content-Type").split(";")[1].trim().replace("boundary=", "--");
let buffer = Buffer.alloc(0);
let searchForNextBoundary = false;
@@ -78,9 +69,7 @@ async function fetchPlant() {
} else if (searchForNextBoundary) {
if (data.toString().startsWith(boundary)) {
res.body.end();
- const length = Number(
- buffer.toString().match(/Content-Length:.*?(\d+)/)[1]
- );
+ const length = Number(buffer.toString().match(/Content-Length:.*?(\d+)/)[1]);
const headerOffset = buffer.indexOf(JPEG_HEADER);
const data = buffer.slice(headerOffset, headerOffset + length);
@@ -169,127 +158,6 @@ function deleteBoardEntry(id) {
});
}
-async function findSuitableImage(msg) {
- const out = {};
-
- const attachments = [...msg.attachments.values()];
- const attachment = attachments[0];
-
- if (attachment) {
- const url = attachment.url;
- const parsed = new URL(url);
- if (/(jpe?g|png|gif|webp)$/.test(parsed.pathname)) {
- out.url = url;
- } else if (/(mp4|webm|mov)$/.test(parsed.pathname)) {
- out.video = true;
- out.attachment = true;
- out.url = "attachment://thumb.jpg";
-
- let thumbUrl = attachment.proxyURL;
- if (thumbUrl.includes("media.discordapp.net") && thumbUrl.includes("?")) {
- if (thumbUrl.endsWith("&")) {
- thumbUrl = thumbUrl += "format=jpeg";
- } else {
- thumbUrl = thumbUrl += "&format=jpeg";
- }
- } else {
- thumbUrl = thumbUrl += "?format=jpeg";
- }
-
- out.file = await fetch(thumbUrl)
- .then((res) => res.arrayBuffer())
- .then((buf) => Buffer.from(buf));
- }
- } else {
- for (const embed of msg.embeds) {
- if (!embed.url) continue;
- const parsed = new URL(embed.url);
- if (embed.url && /(jpe?g|png|gif|webp)$/.test(parsed.pathname)) {
- out.url = embed.url;
- } else if (embed.image) {
- out.url = embed.image.url;
- break;
- } else if (embed.video) {
- out.video = true;
- out.url = "attachment://thumb.jpg";
-
- let thumbUrl =
- embed.video.proxyURL ??
- embed.video.url.replace("cdn.discordapp.com", "media.discordapp.net");
- if (
- thumbUrl.includes("media.discordapp.net") &&
- thumbUrl.includes("?")
- ) {
- if (thumbUrl.endsWith("&")) {
- thumbUrl = thumbUrl += "format=jpeg";
- } else {
- thumbUrl = thumbUrl += "&format=jpeg";
- }
- } else {
- thumbUrl = thumbUrl += "?format=jpeg";
- }
- if (embed.thumbnail?.url) thumbUrl = embed.thumbnail.url;
-
- let valid = await fetch(thumbUrl, {method: "HEAD"}).then(
- (res) => res.ok
- );
- if (!valid && thumbUrl.includes("media.discordapp.net")) {
- thumbUrl = await hf.bot.requestHandler
- .request("POST", "/attachments/refresh-urls", true, {
- attachment_urls: [thumbUrl],
- })
- .then((res) => res.refreshed_urls[0].refreshed);
- valid = true;
- }
-
- if (valid)
- out.file = await fetch(thumbUrl)
- .then((res) => res.arrayBuffer())
- .then((buf) => Buffer.from(buf));
- break;
- }
- }
- }
-
- return out;
-}
-
-async function createBoardMessage(msg, count, fetchAttachment = true) {
- const name = msg.member?.nick ?? msg.author.globalName ?? msg.author.username;
- const embed = {
- title: `${count} \u2b50 - ${msg.jumpLink}`,
- color: pastelize(name),
- description: msg.content,
- timestamp: new Date(msg.timestamp).toISOString(),
- };
-
- let image;
- if (fetchAttachment) {
- image = await findSuitableImage(msg);
- if (image.url) {
- if (image.video) {
- embed.description += `\n(contains video ${
- image.attachment ? "attachment" : "embed"
- })`;
- }
- embed.image = {
- url: image.url,
- };
- }
- }
-
- return {
- avatarURL: msg.member?.avatarURL ?? msg.author.avatarURL,
- username: name,
- threadID: VINBOARD_THREAD_ID,
- embeds: [embed],
- attachments: image?.file
- ? [{file: image.file, filename: "thumb.jpg"}]
- : null,
- wait: true,
- };
-}
-
let vinboard_webhook;
let vin_channel;
let board_channel;
@@ -300,9 +168,7 @@ async function processReaction(_msg, reaction, user) {
if (reaction.name != "\u2b50") return;
if (!vin_channel) {
- vin_channel = hf.bot.guilds
- .get(FOXWELLS_GUILD_ID)
- .channels.get(VINBOARD_CHANNEL_ID);
+ vin_channel = hf.bot.guilds.get(FOXWELLS_GUILD_ID).channels.get(VINBOARD_CHANNEL_ID);
}
if (!vin_channel) {
@@ -311,9 +177,7 @@ async function processReaction(_msg, reaction, user) {
}
if (!board_channel) {
- board_channel = hf.bot.guilds
- .get(FOXWELLS_GUILD_ID)
- .threads.get(VINBOARD_THREAD_ID);
+ board_channel = hf.bot.guilds.get(FOXWELLS_GUILD_ID).threads.get(VINBOARD_THREAD_ID);
}
if (!board_channel) {
@@ -321,15 +185,11 @@ async function processReaction(_msg, reaction, user) {
return;
}
- const msg =
- vin_channel.messages.get(_msg.id) ??
- (await vin_channel.getMessage(_msg.id));
+ const msg = vin_channel.messages.get(_msg.id) ?? (await vin_channel.getMessage(_msg.id));
if (!vinboard_webhook) {
const webhooks = await vin_channel.getWebhooks();
- vinboard_webhook = webhooks.find(
- (webhook) => webhook.id == VINBOARD_WEBHOOK_ID
- );
+ vinboard_webhook = webhooks.find((webhook) => webhook.id == VINBOARD_WEBHOOK_ID);
}
if (!vinboard_webhook) {
@@ -338,9 +198,7 @@ async function processReaction(_msg, reaction, user) {
}
const reacts = await msg.getReaction("\u2b50");
- const trueCount = reacts.filter(
- (reactor) => reactor.id != msg.author.id
- ).length;
+ const trueCount = reacts.filter((reactor) => reactor.id != msg.author.id).length;
const dbEntry = await getBoardEntry(msg.id);
if (dbEntry) {
@@ -360,12 +218,7 @@ async function processReaction(_msg, reaction, user) {
board_channel.messages.get(dbEntry.board_id) ??
(await board_channel.getMessage(dbEntry.board_id).catch(() => {}));
if (_boardMessage) {
- logger.verbose(
- "vinboard",
- `Updating count for "${msg.id}" (${
- dbEntry.count ?? 0
- } -> ${trueCount})`
- );
+ logger.verbose("vinboard", `Updating count for "${msg.id}" (${dbEntry.count ?? 0} -> ${trueCount})`);
const props = {
avatarURL: _boardMessage.author.avatarURL,
@@ -374,24 +227,17 @@ async function processReaction(_msg, reaction, user) {
embeds: _boardMessage.embeds,
wait: true,
};
- props.attachments = [..._boardMessage.attachments.values()].map(
- (attach) => ({id: attach.id})
- );
+ props.attachments = [..._boardMessage.attachments.values()].map((attach) => ({id: attach.id}));
props.embeds[0].title = `${trueCount} \u2b50`;
props.embeds[0].color = pastelize(msg.author.username);
- await hf.bot.editWebhookMessage(
- vinboard_webhook.id,
- vinboard_webhook.token,
- _boardMessage.id,
- props
- );
+ await hf.bot.editWebhookMessage(vinboard_webhook.id, vinboard_webhook.token, _boardMessage.id, props);
await setBoardEntry(msg.id, trueCount, _boardMessage.id);
} else {
logger.verbose("vinboard", `Creating entry for "${msg.id}"`);
const boardMessage = await hf.bot.executeWebhook(
vinboard_webhook.id,
vinboard_webhook.token,
- await createBoardMessage(msg, trueCount)
+ await createBoardMessage(msg, trueCount, VINBOARD_THREAD_ID)
);
await setBoardEntry(msg.id, trueCount, boardMessage.id);
}
@@ -400,7 +246,7 @@ async function processReaction(_msg, reaction, user) {
const boardMessage = await hf.bot.executeWebhook(
vinboard_webhook.id,
vinboard_webhook.token,
- await createBoardMessage(msg, trueCount)
+ await createBoardMessage(msg, trueCount, VINBOARD_THREAD_ID)
);
await setBoardEntry(msg.id, trueCount, boardMessage.id);
}
@@ -409,7 +255,7 @@ async function processReaction(_msg, reaction, user) {
const boardMessage = await hf.bot.executeWebhook(
vinboard_webhook.id,
vinboard_webhook.token,
- await createBoardMessage(msg, trueCount)
+ await createBoardMessage(msg, trueCount, VINBOARD_THREAD_ID)
);
await setBoardEntry(msg.id, trueCount, boardMessage.id);
}
diff --git a/src/modules/general.js b/src/modules/general.js
index 23feced..973d9a5 100644
--- a/src/modules/general.js
+++ b/src/modules/general.js
@@ -1,7 +1,7 @@
const Command = require("../lib/command.js");
const CATEGORY = "general";
-const {snowflakeToTimestamp} = require("../lib/utils.js");
+const {snowflakeToTimestamp} = require("../util/time.js");
const help = new Command("help");
help.category = CATEGORY;
@@ -27,9 +27,7 @@ help.callback = function (msg, line) {
for (const cat in sorted) {
embed.fields.push({
name: cat.toUpperCase().charAt(0) + cat.toLowerCase().substring(1),
- value: `${sorted[cat].length} Commands\n\`${
- hf.config.prefix
- }help --${cat.toLowerCase()}\``,
+ value: `${sorted[cat].length} Commands\n\`${hf.config.prefix}help --${cat.toLowerCase()}\``,
inline: true,
});
}
@@ -40,9 +38,7 @@ help.callback = function (msg, line) {
if (sorted[cat]) {
const embed = {
- title: `HiddenPhox Help: Category > ${
- cat.toUpperCase().charAt(0) + cat.toLowerCase().substring(1)
- }`,
+ title: `HiddenPhox Help: Category > ${cat.toUpperCase().charAt(0) + cat.toLowerCase().substring(1)}`,
fields: [],
};
@@ -78,9 +74,7 @@ help.callback = function (msg, line) {
fields: [
{
name: "Category",
- value:
- cmd.category.toUpperCase().charAt(0) +
- cmd.category.toLowerCase().substring(1),
+ value: cmd.category.toUpperCase().charAt(0) + cmd.category.toLowerCase().substring(1),
inline: true,
},
],
@@ -125,9 +119,7 @@ ping.callback = async function (msg) {
const msgTimestamp = snowflakeToTimestamp(msg.id);
const noncePing = Math.floor(msgTimestamp - nonceTimestamp);
- const gateway = hf.bot.shards.get(
- hf.bot.guildShardMap[hf.bot.channelGuildMap[msg.channel.id]] || 0
- ).latency;
+ const gateway = hf.bot.shards.get(hf.bot.guildShardMap[hf.bot.channelGuildMap[msg.channel.id]] || 0).latency;
const newMsg = await msg.channel.createMessage({
content: `Pong.\n**RTT:** \`...\`\n**Gateway:** \`${gateway}ms\`${
diff --git a/src/modules/image.js b/src/modules/image.js
index 0c517b2..4c73360 100644
--- a/src/modules/image.js
+++ b/src/modules/image.js
@@ -1,9 +1,9 @@
const Command = require("../lib/command.js");
const CATEGORY = "image";
-const {getImage} = require("../lib/utils.js");
+const {getImage} = require("../util/image.js");
-const dumpyConvert = require("dumpy").convert;
+//const dumpyConvert = require("dumpy").convert;
const Jimp = require("jimp");
async function createImageCallback(msg, url, callback, filename) {
@@ -29,7 +29,7 @@ async function createImageCallback(msg, url, callback, filename) {
}
}
-const dumpy = new Command("dumpy");
+/*const dumpy = new Command("dumpy");
dumpy.category = CATEGORY;
dumpy.helpText = "Among Us Dumpy GIF Creator";
dumpy.usage = " [url]";
@@ -37,14 +37,9 @@ dumpy.callback = async function (msg, line, [width, url]) {
if (isNaN(parseInt(width))) url = width;
width = Math.min(Math.max(isNaN(parseInt(width)) ? 10 : width, 2), 48);
- return await createImageCallback(
- msg,
- url,
- async (img) => await dumpyConvert(img, width),
- "dumpy.gif"
- );
+ return await createImageCallback(msg, url, async (img) => await dumpyConvert(img, width), "dumpy.gif");
};
-hf.registerCommand(dumpy);
+hf.registerCommand(dumpy);*/
const hooh = new Command("hooh");
hooh.category = CATEGORY;
@@ -56,14 +51,7 @@ hooh.callback = async function (msg, line) {
line,
async (url) => {
const img = await Jimp.read(url);
- const half1 = img
- .clone()
- .crop(
- 0,
- img.bitmap.height / 2,
- img.bitmap.width,
- img.bitmap.height / 2
- );
+ const half1 = img.clone().crop(0, img.bitmap.height / 2, img.bitmap.width, img.bitmap.height / 2);
const half2 = half1.clone().mirror(false, true);
return await img
@@ -86,9 +74,7 @@ woow.callback = async function (msg, line) {
line,
async (url) => {
const img = await Jimp.read(url);
- const half1 = img
- .clone()
- .crop(0, 0, img.bitmap.width, img.bitmap.height / 2);
+ const half1 = img.clone().crop(0, 0, img.bitmap.width, img.bitmap.height / 2);
const half2 = half1.clone().mirror(false, true);
return await img
@@ -111,9 +97,7 @@ haah.callback = async function (msg, line) {
line,
async (url) => {
const img = await Jimp.read(url);
- const half1 = img
- .clone()
- .crop(0, 0, img.bitmap.width / 2, img.bitmap.height);
+ const half1 = img.clone().crop(0, 0, img.bitmap.width / 2, img.bitmap.height);
const half2 = half1.clone().mirror(true, false);
return await img
@@ -136,9 +120,7 @@ waaw.callback = async function (msg, line) {
line,
async (url) => {
const img = await Jimp.read(url);
- const half1 = img
- .clone()
- .crop(img.bitmap.width / 2, 0, img.bitmap.width / 2, img.bitmap.height);
+ const half1 = img.clone().crop(img.bitmap.width / 2, 0, img.bitmap.width / 2, img.bitmap.height);
const half2 = half1.clone().mirror(true, false);
return await img
@@ -160,9 +142,7 @@ invert.callback = async function (msg, line) {
msg,
line,
async (img) => {
- return await Jimp.read(img).then((x) =>
- x.invert().getBufferAsync(Jimp.MIME_PNG)
- );
+ return await Jimp.read(img).then((x) => x.invert().getBufferAsync(Jimp.MIME_PNG));
},
"invert.png"
);
@@ -178,9 +158,7 @@ flip.callback = async function (msg, line) {
msg,
line,
async (img) => {
- return await Jimp.read(img).then((x) =>
- x.mirror(true, false).getBufferAsync(Jimp.MIME_PNG)
- );
+ return await Jimp.read(img).then((x) => x.mirror(true, false).getBufferAsync(Jimp.MIME_PNG));
},
"flip.png"
);
@@ -196,9 +174,7 @@ flop.callback = async function (msg, line) {
msg,
line,
async (img) => {
- return await Jimp.read(img).then((x) =>
- x.mirror(false, true).getBufferAsync(Jimp.MIME_PNG)
- );
+ return await Jimp.read(img).then((x) => x.mirror(false, true).getBufferAsync(Jimp.MIME_PNG));
},
"flop.png"
);
@@ -215,9 +191,7 @@ jpeg.callback = async function (msg, line) {
msg,
line,
async (img) => {
- return await Jimp.read(img).then((x) =>
- x.quality(1).getBufferAsync(Jimp.MIME_JPEG)
- );
+ return await Jimp.read(img).then((x) => x.quality(1).getBufferAsync(Jimp.MIME_JPEG));
},
"jpeg.jpg"
);
diff --git a/src/modules/misc.js b/src/modules/misc.js
index c4a536b..fbf5d9b 100644
--- a/src/modules/misc.js
+++ b/src/modules/misc.js
@@ -3,16 +3,12 @@ const InteractionCommand = require("../lib/interactionCommand.js");
const logger = require("../lib/logger.js");
const CATEGORY = "misc";
-const {ApplicationCommandOptionTypes} =
- require("@projectdysnomia/dysnomia").Constants;
-const {librex} = require("../../config.json");
-const {getOption} = require("../lib/interactionDispatcher.js");
-const {
- formatTime,
- parseHtmlEntities,
- formatUsername,
- safeString,
-} = require("../lib/utils.js");
+const {ApplicationCommandOptionTypes} = require("../util/dconstants.js");
+
+const {formatUsername, safeString} = require("../util/misc.js");
+const {formatTime} = require("../util/time.js");
+const {parseHtmlEntities} = require("../util/html.js");
+
const GoogleImages = require("google-images");
const {tinycolor, random: randomColor} = require("@ctrl/tinycolor");
const sharp = require("sharp");
@@ -28,15 +24,13 @@ yt.usage = "[search term]";
yt.callback = async function (msg, line) {
if (!line) return "Arguments are required.";
- const req = await fetch(
- `${hf.config.piped_api}/search?q=${encodeURIComponent(line)}&filter=videos`
- ).then((x) => x.json());
+ const req = await fetch(`${hf.config.piped_api}/search?q=${encodeURIComponent(line)}&filter=videos`).then((x) =>
+ x.json()
+ );
const topVid = req.items[0];
- let out = `**${safeString(
- parseHtmlEntities(topVid.title)
- )}** | \`${safeString(
+ let out = `**${safeString(parseHtmlEntities(topVid.title))}** | \`${safeString(
parseHtmlEntities(topVid.uploaderName)
)}\`\nhttps://youtube.com${topVid.url}\n\n**__See Also:__**\n`;
@@ -44,9 +38,7 @@ yt.callback = async function (msg, line) {
const vid = req.items[i];
if (!vid) continue;
- out += `- **${safeString(
- parseHtmlEntities(vid.title)
- )}** | By: \`${safeString(
+ out += `- **${safeString(parseHtmlEntities(vid.title))}** | By: \`${safeString(
parseHtmlEntities(vid.uploaderName)
)}\` | \n`;
}
@@ -65,7 +57,7 @@ ytInteraction.options.search = {
default: "",
};
ytInteraction.callback = async function (interaction) {
- const search = getOption(interaction, ytInteraction, "search");
+ const search = this.getOption(interaction, "search");
return yt.callback(interaction, search);
};
@@ -78,9 +70,9 @@ fyt.usage = "[search term]";
fyt.callback = async function (msg, line) {
if (!line) return "Arguments are required.";
- const req = await fetch(
- `${hf.config.piped_api}/search?q=${encodeURIComponent(line)}&filter=videos`
- ).then((x) => x.json());
+ const req = await fetch(`${hf.config.piped_api}/search?q=${encodeURIComponent(line)}&filter=videos`).then((x) =>
+ x.json()
+ );
const vid = req.items[0];
@@ -100,7 +92,7 @@ fytInteraction.options.search = {
default: "",
};
fytInteraction.callback = async function (interaction) {
- const search = getOption(interaction, fytInteraction, "search");
+ const search = this.getOption(interaction, "search");
return fyt.callback(interaction, search);
};
@@ -119,9 +111,7 @@ wolfram.callback = async function (msg, line, args, {verbose, v}) {
const query = args.join(" ");
const req = await fetch(
- `http://api.wolframalpha.com/v2/query?input=${encodeURIComponent(
- query
- )}&appid=LH2K8H-T3QKETAGT3&output=json`
+ `http://api.wolframalpha.com/v2/query?input=${encodeURIComponent(query)}&appid=LH2K8H-T3QKETAGT3&output=json`
).then((x) => x.json());
const data = req.queryresult.pods;
@@ -148,11 +138,9 @@ wolfram.callback = async function (msg, line, args, {verbose, v}) {
for (const x in extra) {
embed.fields.push({
name: extra[x].title,
- value: `[${
- extra[x].subpods[0].plaintext.length > 0
- ? extra[x].subpods[0].plaintext
- : ""
- }](${extra[x].subpods[0].img.src})`,
+ value: `[${extra[x].subpods[0].plaintext.length > 0 ? extra[x].subpods[0].plaintext : ""}](${
+ extra[x].subpods[0].img.src
+ })`,
inline: true,
});
}
@@ -173,8 +161,7 @@ wolfram.callback = async function (msg, line, args, {verbose, v}) {
}
let string = "";
- if (data[1].subpods[0].plaintext.length > 0)
- string = safeString(data[1].subpods[0].plaintext);
+ if (data[1].subpods[0].plaintext.length > 0) string = safeString(data[1].subpods[0].plaintext);
let text;
if (string.length > 2000 - (6 + safeString(query).length)) {
@@ -216,8 +203,8 @@ wolframInteraction.options.verbose = {
default: false,
};
wolframInteraction.callback = async function (interaction) {
- const query = getOption(interaction, wolframInteraction, "query");
- const verbose = getOption(interaction, wolframInteraction, "verbose");
+ const query = this.getOption(interaction, "query");
+ const verbose = this.getOption(interaction, "verbose");
return wolfram.callback(interaction, query, [query], {verbose});
};
@@ -232,10 +219,7 @@ gimg.callback = async function (msg, line) {
if (!line) return "No arguments given.";
const images = await imagesClient.search(line, {
- safe:
- msg.channel.nsfw && !msg.channel?.topic.includes("[no_nsfw]")
- ? "off"
- : "high",
+ safe: msg.channel.nsfw && !msg.channel?.topic.includes("[no_nsfw]") ? "off" : "high",
});
const index = Math.floor(Math.random() * images.length);
@@ -250,9 +234,7 @@ gimg.callback = async function (msg, line) {
url: image.url,
},
footer: {
- text: `Image ${Number(index) + 1}/${
- images.length
- }. Rerun to get a different image.`,
+ text: `Image ${Number(index) + 1}/${images.length}. Rerun to get a different image.`,
},
},
],
@@ -268,10 +250,7 @@ fimg.callback = async function (msg, line) {
if (!line) return "No arguments given.";
const images = await imagesClient.search(line, {
- safe:
- msg.channel.nsfw && !msg.channel?.topic.includes("[no_nsfw]")
- ? "off"
- : "high",
+ safe: msg.channel.nsfw && !msg.channel?.topic.includes("[no_nsfw]") ? "off" : "high",
});
const image = images[0];
@@ -295,22 +274,15 @@ poll.category = CATEGORY;
poll.helpText = "Start a poll";
poll.usage = "[topic] [option 1] [option 2] [...option 3-10]";
poll.callback = async function (msg, line, [topic, ...options]) {
- if (!line || !topic)
- return 'Usage: hf!poll "topic" "option 1" "option 2" "...options 3-10"';
+ if (!line || !topic) return 'Usage: hf!poll "topic" "option 1" "option 2" "...options 3-10"';
const arrOptions = [...options].slice(0, 10);
if (arrOptions.length < 2) return "A minimum of two options are required.";
const reactions = [];
- let displayString = `**${formatUsername(
- msg.author
- )}** has started a poll:\n## __${topic}__\n`;
+ let displayString = `**${formatUsername(msg.author)}** has started a poll:\n## __${topic}__\n`;
for (let i = 0; i < arrOptions.length; i++) {
- displayString +=
- (i === 9 ? "\ud83d\udd1f" : `${i + 1}\u20e3`) +
- ": " +
- arrOptions[i] +
- "\n";
+ displayString += (i === 9 ? "\ud83d\udd1f" : `${i + 1}\u20e3`) + ": " + arrOptions[i] + "\n";
reactions[i] = i === 9 ? "\ud83d\udd1f" : `${i + 1}\u20e3`;
}
@@ -353,28 +325,20 @@ anonradio.callback = async function () {
let playing;
try {
- playing = await fetch("https://anonradio.net/playing").then((res) =>
- res.text()
- );
+ playing = await fetch("https://anonradio.net/playing").then((res) => res.text());
} catch (err) {
try {
- playing = await fetch("http://anonradio.net/playing").then((res) =>
- res.text()
- );
+ playing = await fetch("http://anonradio.net/playing").then((res) => res.text());
} catch (err) {
//
}
}
let schedule;
try {
- schedule = await fetch("https://anonradio.net/schedule/").then((res) =>
- res.text()
- );
+ schedule = await fetch("https://anonradio.net/schedule/").then((res) => res.text());
} catch (err) {
try {
- schedule = await fetch("http://anonradio.net/schedule/").then((res) =>
- res.text()
- );
+ schedule = await fetch("http://anonradio.net/schedule/").then((res) => res.text());
} catch (err) {
//
}
@@ -384,9 +348,7 @@ anonradio.callback = async function () {
const icecast = await fetch("http://anonradio.net:8010/status-json.xsl")
.then((res) => res.text())
- .then((data) =>
- JSON.parse(data.replace(/"title": - ,/g, '"title":" - ",'))
- );
+ .then((data) => JSON.parse(data.replace(/"title": - ,/g, '"title":" - ",')));
let lines = schedule.split("\n");
lines = lines.slice(4, lines.length - 2);
@@ -418,17 +380,11 @@ anonradio.callback = async function () {
hour = hour.slice(0, 2) + ":" + hour.slice(-2);
const timestamp =
- Date.parse(
- `${DAYS[targetDay]}, ${currentYear}-${targetMonth}-${targetDateDay} ${hour} UTC`
- ) / 1000;
+ Date.parse(`${DAYS[targetDay]}, ${currentYear}-${targetMonth}-${targetDateDay} ${hour} UTC`) / 1000;
let nameOut = name;
- if (time == "Sat 0300")
- nameOut = name.replace(
- "Open Mic - Anyone can stream",
- "Synth Battle Royale"
- );
+ if (time == "Sat 0300") nameOut = name.replace("Open Mic - Anyone can stream", "Synth Battle Royale");
parsedLines.push({
timestamp,
@@ -451,14 +407,9 @@ anonradio.callback = async function () {
title = `${liveNow.name} (\`${liveNow.id}\`)`;
subtitle = playing;
} else {
- const [_, current, peakDay, peakMonth, dj, metadata] = playing.match(
- /\[(\d+)\/(\d+)\/(\d+)\] \((.+?)\): (.+)/
- );
+ const [_, current, peakDay, peakMonth, dj, metadata] = playing.match(/\[(\d+)\/(\d+)\/(\d+)\] \((.+?)\): (.+)/);
- if (
- metadata == "https://archives.anonradio.net" ||
- liveNow.name == "Synth Battle Royale"
- ) {
+ if (metadata == "https://archives.anonradio.net" || liveNow.name == "Synth Battle Royale") {
title = `${liveNow.name} (\`${dj}\`)`;
} else {
title = `${metadata} (\`${dj}\`)`;
@@ -468,14 +419,10 @@ anonradio.callback = async function () {
let openmicTime = "";
if (liveNow.id == "openmic") {
- const streamData = icecast.icestats.source.find(
- (src) => src.listenurl == "http://anonradio.net:8010/openmic"
- );
+ const streamData = icecast.icestats.source.find((src) => src.listenurl == "http://anonradio.net:8010/openmic");
if (streamData && streamData.stream_start_iso8601) {
const startTime = new Date(streamData.stream_start_iso8601).getTime();
- openmicTime = `-\\*- OpenMIC DJ has been streaming for ${formatTime(
- Date.now() - startTime
- )} -\\*-\n`;
+ openmicTime = `-\\*- OpenMIC DJ has been streaming for ${formatTime(Date.now() - startTime)} -\\*-\n`;
}
}
@@ -507,9 +454,7 @@ shodan.callback = async function (msg, line) {
if (!line || line == "") return "Arguments required.";
if (!REGEX_IPV4.test(line)) return "Invalid IP address.";
- const data = await fetch("https://internetdb.shodan.io/" + line).then((res) =>
- res.json()
- );
+ const data = await fetch("https://internetdb.shodan.io/" + line).then((res) => res.json());
if (data.detail) return data.detail;
@@ -519,10 +464,7 @@ shodan.callback = async function (msg, line) {
fields: [
{
name: "Hostnames",
- value:
- data.hostnames.length > 0
- ? data.hostnames.map((str) => `\`${str}\``).join(" ")
- : "None",
+ value: data.hostnames.length > 0 ? data.hostnames.map((str) => `\`${str}\``).join(" ") : "None",
inline: true,
},
{
@@ -532,26 +474,17 @@ shodan.callback = async function (msg, line) {
},
{
name: "Tags",
- value:
- data.tags.length > 0
- ? data.tags.map((str) => `\`${str}\``).join(", ")
- : "None",
+ value: data.tags.length > 0 ? data.tags.map((str) => `\`${str}\``).join(", ") : "None",
inline: true,
},
{
name: "CPEs",
- value:
- data.cpes.length > 0
- ? data.cpes.map((str) => `\`${str}\``).join(" ")
- : "None",
+ value: data.cpes.length > 0 ? data.cpes.map((str) => `\`${str}\``).join(" ") : "None",
inline: true,
},
{
name: "Vulnerabilities",
- value:
- data.vulns.length > 0
- ? data.vulns.map((str) => `\`${str}\``).join(" ")
- : "None",
+ value: data.vulns.length > 0 ? data.vulns.map((str) => `\`${str}\``).join(" ") : "None",
inline: true,
},
],
@@ -596,9 +529,7 @@ generate.callback = async function (msg, line) {
const title = `Responses for "${safeString(line)}"`;
const out = {
- content: `Generated in ${formatTime(Date.now() - start)}${
- retries > 0 ? " with " + retries + " retries" : ""
- }`,
+ content: `Generated in ${formatTime(Date.now() - start)}${retries > 0 ? " with " + retries + " retries" : ""}`,
embeds: [],
files: images,
};
@@ -627,7 +558,7 @@ search.addAlias("google");
search.addAlias("ddg");
search.callback = async function (msg, line, args, {results = 2}) {
const query = args.join(" ");
- if (!librex) return "LibreX instance not defined.";
+ if (!hf.config.librex) return "LibreX instance not defined.";
if (!query || query == "") return "Search query required.";
const encodedQuery = encodeURIComponent(query);
@@ -638,9 +569,7 @@ search.callback = async function (msg, line, args, {results = 2}) {
if (res.url != url) return res.url;
}
- const res = await fetch(`${librex}/api.php?q=${encodedQuery}&p=0&t=0`).then(
- (res) => res.json()
- );
+ const res = await fetch(`${hf.config.librex}/api.php?q=${encodedQuery}&p=0&t=0`).then((res) => res.json());
if (res.error?.message) {
if (res.error.message.indexOf("No results found.") > -1) {
return "Search returned no results.";
@@ -649,27 +578,17 @@ search.callback = async function (msg, line, args, {results = 2}) {
}
} else {
const searchResults = Object.values(res)
- .filter(
- (result) => result.did_you_mean == null && typeof result !== "string"
- )
+ .filter((result) => result.did_you_mean == null && typeof result !== "string")
.splice(0, Number(results));
if (searchResults.length > 0) {
let out = `__**Results for \`${safeString(query)}\`**__\n`;
for (const result of searchResults) {
if (result.special_response) {
- out +=
- "> " +
- safeString(
- parseHtmlEntities(
- result.special_response.response.split("\n").join("\n> ")
- )
- );
+ out += "> " + safeString(parseHtmlEntities(result.special_response.response.split("\n").join("\n> ")));
out += `\n<${encodeURI(result.special_response.source)}>`;
} else {
- out += `**${safeString(
- parseHtmlEntities(result.title)
- ).trim()}** - <${encodeURI(result.url)}>`;
+ out += `**${safeString(parseHtmlEntities(result.title)).trim()}** - <${encodeURI(result.url)}>`;
out += `\n> ${safeString(parseHtmlEntities(result.description))}`;
}
out += "\n\n";
@@ -702,8 +621,8 @@ searchInteraction.options.results = {
default: 2,
};
searchInteraction.callback = async function (interaction) {
- const query = getOption(interaction, searchInteraction, "query");
- const results = getOption(interaction, searchInteraction, "results");
+ const query = this.getOption(interaction, "query");
+ const results = this.getOption(interaction, "results");
return search.callback(interaction, query, [query], {results});
};
@@ -717,9 +636,7 @@ color.callback = async function (msg, line, args, {truerandom}) {
random = false;
if (!line || line == "" || args.length == 0) {
- color = truerandom
- ? tinycolor(Math.floor(Math.random() * 0xffffff))
- : randomColor();
+ color = truerandom ? tinycolor(Math.floor(Math.random() * 0xffffff)) : randomColor();
random = true;
}
@@ -806,14 +723,13 @@ colorInteraction.options.input = {
colorInteraction.options.truerandom = {
name: "truerandom",
type: ApplicationCommandOptionTypes.BOOLEAN,
- description:
- "Should the random color give a 'true random' color instead of an adjust color",
+ description: "Should the random color give a 'true random' color instead of an adjust color",
required: false,
default: false,
};
colorInteraction.callback = async function (interaction) {
- const input = getOption(interaction, colorInteraction, "input");
- const truerandom = getOption(interaction, colorInteraction, "truerandom");
+ const input = this.getOption(interaction, "input");
+ const truerandom = this.getOption(interaction, "truerandom");
return color.callback(interaction, input, [input], {truerandom});
};
@@ -849,10 +765,7 @@ const handshake = Buffer.concat([
identPort,
writeVarInt(1),
]);
-const handshakeWithLength = Buffer.concat([
- writeVarInt(handshake.length),
- handshake,
-]);
+const handshakeWithLength = Buffer.concat([writeVarInt(handshake.length), handshake]);
const status = Buffer.concat([writeVarInt(1), writeVarInt(0x0)]);
@@ -927,12 +840,7 @@ mcserver.callback = async function (msg, line) {
}
const dataAsString = totalData.toString().trim();
console.log(dataAsString);
- const json = JSON.parse(
- dataAsString.slice(
- dataAsString.indexOf("{"),
- dataAsString.lastIndexOf("}") + 1
- )
- );
+ const json = JSON.parse(dataAsString.slice(dataAsString.indexOf("{"), dataAsString.lastIndexOf("}") + 1));
logger.verbose("mcserver", "close", json);
clearTimeout(timeout);
return resolve(json);
@@ -946,22 +854,16 @@ mcserver.callback = async function (msg, line) {
} else {
await msg.removeReaction("\uD83C\uDFD3");
- const motd = data.description.text.replace(
- /\u00a7([a-f0-9k-or])/gi,
- (formatting) => {
- const ansi = formattingToAnsi[formatting];
- return ansi ? `\x1b[${ansi}m` : "";
- }
- );
+ const motd = data.description.text.replace(/\u00a7([a-f0-9k-or])/gi, (formatting) => {
+ const ansi = formattingToAnsi[formatting];
+ return ansi ? `\x1b[${ansi}m` : "";
+ });
const players = data.players?.sample?.map((player) => player.name) ?? [];
const totalPlayers = `(${data.players.online}/${data.players.max})`;
let image;
if (data.favicon) {
- image = Buffer.from(
- data.favicon.slice(data.favicon.indexOf(",")),
- "base64"
- );
+ image = Buffer.from(data.favicon.slice(data.favicon.indexOf(",")), "base64");
}
return {
diff --git a/src/modules/moderation.js b/src/modules/moderation.js
index 1bc3144..1c73272 100644
--- a/src/modules/moderation.js
+++ b/src/modules/moderation.js
@@ -1,7 +1,8 @@
const Command = require("../lib/command.js");
const CATEGORY = "moderation";
-const {lookupUser, formatUsername} = require("../lib/utils.js");
+const {formatUsername} = require("../util/misc.js");
+const {lookupUser} = require("../util/selection.js");
const tidy = new Command("tidy");
tidy.addAlias("prune");
@@ -14,16 +15,10 @@ tidy.callback = async function (msg, line, [subcommand, count, extra]) {
if (!showHelp && !msg.guildID) {
return "Can only be used in guilds.";
}
- if (
- !showHelp &&
- !msg.channel.permissionsOf(msg.author.id).has("manageMessages")
- ) {
+ if (!showHelp && !msg.channel.permissionsOf(msg.author.id).has("manageMessages")) {
return "You do not have `Manage Messages` permission.";
}
- if (
- !showHelp &&
- !msg.channel.permissionsOf(hf.bot.user.id).has("manageMessages")
- ) {
+ if (!showHelp && !msg.channel.permissionsOf(hf.bot.user.id).has("manageMessages")) {
return "I do not have `Manage Messages` permission.";
}
if (msg.author.bot) return "Zero-width space your say command.";
@@ -36,10 +31,7 @@ tidy.callback = async function (msg, line, [subcommand, count, extra]) {
limit: count && parseInt(count) > 0 ? parseInt(count) : 10,
})
.then((msgs) => msgs.map((m) => m.id));
- await msg.channel.deleteMessages(
- messages,
- `Message purge by ${formatUsername(msg.author)}`
- );
+ await msg.channel.deleteMessages(messages, `Message purge by ${formatUsername(msg.author)}`);
return `Deleted ${messages.length} message(s).`;
}
@@ -53,14 +45,10 @@ tidy.callback = async function (msg, line, [subcommand, count, extra]) {
before: msg.id,
limit: extra && parseInt(extra) > 0 ? parseInt(extra) : 10,
})
- .then((msgs) =>
- msgs.filter((m) => m.author.id == user.id).map((m) => m.id)
- );
+ .then((msgs) => msgs.filter((m) => m.author.id == user.id).map((m) => m.id));
await msg.channel.deleteMessages(
messages,
- `Message purge by ${formatUsername(
- msg.author
- )} targeting ${formatUsername(user)}`
+ `Message purge by ${formatUsername(msg.author)} targeting ${formatUsername(user)}`
);
return `Deleted ${messages.length} message(s).`;
@@ -73,29 +61,20 @@ tidy.callback = async function (msg, line, [subcommand, count, extra]) {
limit: count && parseInt(count) > 0 ? parseInt(count) : 50,
})
.then((msgs) => msgs.filter((m) => msg.author.bot).map((m) => m.id));
- await msg.channel.deleteMessages(
- messages,
- `Message purge by ${formatUsername(msg.author)} targeting bots`
- );
+ await msg.channel.deleteMessages(messages, `Message purge by ${formatUsername(msg.author)} targeting bots`);
return `Deleted ${messages.length} message(s).`;
}
case "filter": {
- if (count.length === 0)
- return "Filter must be at least 1 character long.";
+ if (count.length === 0) return "Filter must be at least 1 character long.";
const messages = await msg.channel
.getMessages({
before: msg.id,
limit: extra && parseInt(extra) > 0 ? parseInt(extra) : 10,
})
- .then((msgs) =>
- msgs.filter((m) => m.content.indexOf(count) > -1).map((m) => m.id)
- );
- await msg.channel.deleteMessages(
- messages,
- `Message purge by ${formatUsername(msg.author)} targeting "${count}"`
- );
+ .then((msgs) => msgs.filter((m) => m.content.indexOf(count) > -1).map((m) => m.id));
+ await msg.channel.deleteMessages(messages, `Message purge by ${formatUsername(msg.author)} targeting "${count}"`);
return `Deleted ${messages.length} message(s).`;
}
diff --git a/src/modules/music.js b/src/modules/music.js
index c45f8f3..efc8d36 100644
--- a/src/modules/music.js
+++ b/src/modules/music.js
@@ -4,23 +4,18 @@ const {Readable} = require("node:stream");
const ffprobe = require("node-ffprobe");
const Command = require("../lib/command.js");
-const {
- formatTime,
- parseHtmlEntities,
- formatUsername,
- selectionMessage,
-} = require("../lib/utils.js");
+
+const {formatUsername} = require("../util/misc.js");
+const {formatTime} = require("../util/time.js");
+const {parseHtmlEntities} = require("../util/html.js");
+const {selectionMessage} = require("../util/selection.js");
const REGEX_YOUTUBE = /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.?be)\/.+$/;
-const REGEX_YOUTUBE_PLAYLIST =
- /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.?be)\/playlist\?list=(.+)$/;
+const REGEX_YOUTUBE_PLAYLIST = /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.?be)\/playlist\?list=(.+)$/;
const REGEX_YOUTUBE_PLAYLIST_SHORT = /^PL[a-zA-Z0-9-_]{1,32}$/;
-const REGEX_SOUNDCLOUD =
- /^((https?:\/\/)?(www\.|m\.)?soundcloud\.com\/|sc:).+\/.+$/;
-const REGEX_SOUNDCLOUD_PLAYLIST =
- /^((https?:\/\/)?(www\.|m\.)?soundcloud\.com\/|sc:).+\/(sets\/.+|likes|tracks)$/;
-const REGEX_FILE =
- /^(https?:\/\/)?.*\..*\/.+\.(mp3|ogg|flac|wav|webm|mp4|mov|mkv|mod|s3m|it|xm)$/;
+const REGEX_SOUNDCLOUD = /^((https?:\/\/)?(www\.|m\.)?soundcloud\.com\/|sc:).+\/.+$/;
+const REGEX_SOUNDCLOUD_PLAYLIST = /^((https?:\/\/)?(www\.|m\.)?soundcloud\.com\/|sc:).+\/(sets\/.+|likes|tracks)$/;
+const REGEX_FILE = /^(https?:\/\/)?.*\..*\/.+\.(mp3|ogg|flac|wav|webm|mp4|mov|mkv|mod|s3m|it|xm)$/;
let SOUNDCLOUD_CLIENTID;
@@ -40,9 +35,7 @@ async function getSoundcloudClientID() {
return SOUNDCLOUD_CLIENTID;
}
const page = await fetch("https://soundcloud.com").then((res) => res.text());
- const scripts = page
- .match(/