Compare commits

...

2 commits

Author SHA1 Message Date
a7ca9fd347 fedimbed: cohost support 2024-01-07 13:10:10 -07:00
9b86bbcabe utils: misc cleanup and fixes 2024-01-07 13:06:02 -07:00
2 changed files with 47 additions and 14 deletions

View file

@ -70,7 +70,9 @@ function readableTime(number) {
} }
async function isGif(url) { async function isGif(url) {
const type = await fetch(url).then((res) => res.headers.get("Content-Type")); const type = await fetch(url, {method: "HEAD"}).then((res) =>
res.headers.get("Content-Type")
);
return type == "image/gif"; return type == "image/gif";
} }
@ -115,11 +117,11 @@ async function getImage(msg, str) {
const attachments = [...refMsg.attachments.values()]; const attachments = [...refMsg.attachments.values()];
if (attachments[0]?.url) { if (attachments[0]?.url) {
return attachments[0].url; return attachments[0].url;
} else if (/<a?:[a-zA-Z0-9_]*:([0-9]*)>/.test(refMsg.content)) { } else if (/<a?:[a-zA-Z0-9_]+:([0-9]+)>/.test(refMsg.content)) {
const id = refMsg.content.match(/<a?:[a-zA-Z0-9_]*:([0-9]*)>/)[1]; const id = refMsg.content.match(/<a?:[a-zA-Z0-9_]+:([0-9]+)>/)[1];
return `https://cdn.discordapp.com/emojis/${id}.png?v=1`; return `https://cdn.discordapp.com/emojis/${id}.png?v=1`;
} else if (/<@!?([0-9]*)>/.test(refMsg.content)) { } else if (/<@!?([0-9]+)>/.test(refMsg.content)) {
const id = refMsg.content.match(/<@!?([0-9]*)>/)[1]; const id = refMsg.content.match(/<@!?([0-9]+)>/)[1];
const user = await hf.bot.requestHandler.request( const user = await hf.bot.requestHandler.request(
"GET", "GET",
"/users/" + id, "/users/" + id,
@ -140,11 +142,11 @@ async function getImage(msg, str) {
return attachments[0]?.url; return attachments[0]?.url;
} else if (urlRegex.test(str)) { } else if (urlRegex.test(str)) {
return str; return str;
} else if (/<a?:[a-zA-Z0-9_]*:([0-9]*)>/.test(str)) { } else if (/<a?:[a-zA-Z0-9_]+:([0-9]+)>/.test(str)) {
const id = str.match(/<a?:[a-zA-Z0-9_]*:([0-9]*)>/)[1]; const id = str.match(/<a?:[a-zA-Z0-9_]+:([0-9]+)>/)[1];
return `https://cdn.discordapp.com/emojis/${id}.png?v=1`; return `https://cdn.discordapp.com/emojis/${id}.png?v=1`;
} else if (/<@!?([0-9]*)>/.test(str)) { } else if (/<@!?([0-9]+)>/.test(str)) {
const id = str.match(/<@!?([0-9]*)>/)[1]; const id = str.match(/<@!?([0-9]+)>/)[1];
const user = await hf.bot.requestHandler.request( const user = await hf.bot.requestHandler.request(
"GET", "GET",
"/users/" + id, "/users/" + id,
@ -325,12 +327,20 @@ async function lookupUser(msg, str, filter) {
return user; return user;
} else if ( } else if (
user.username.toLowerCase().indexOf(str.toLowerCase()) > -1 || user.username.toLowerCase().indexOf(str.toLowerCase()) > -1 ||
(user.nick && user.nick.indexOf(str.toLowerCase()) > -1) (user.nick && user.nick.toLowerCase().indexOf(str.toLowerCase()) > -1) ||
(user.globalName &&
user.globalName.toLowerCase().indexOf(str.toLowerCase()) > -1)
) { ) {
selection.push({ selection.push({
value: user, value: user,
key: user.id, key: user.id,
display: `${formatUsername(user)}${user.nick ? ` (${user.nick})` : ""}`, display: `${formatUsername(user)}${
user.nick
? ` (${user.nick})`
: user.globalName
? ` (${user.globalName})`
: ""
}`,
}); });
} }
} }

View file

@ -24,7 +24,8 @@ const PATH_REGEX = {
misskey: /^\/notes\/[a-z0-9]+\/?/, misskey: /^\/notes\/[a-z0-9]+\/?/,
gotosocial: /^\/@(.+?)\/statuses\/[0-9A-Z]+\/?/, gotosocial: /^\/@(.+?)\/statuses\/[0-9A-Z]+\/?/,
lemmy: /^\/post\/\d+\/?/, lemmy: /^\/post\/\d+\/?/,
honk: /^\/u\/(.+?)\/h\/(.+?)\/?$/, honk: /^\/u\/(.+?)\/h\/(.+?)\/?/,
cohost: /^\/[A-Za-z0-9]+\/post\/\d+-[A-Za-z0-9-]+\/?/,
}; };
const PLATFORM_COLORS = { const PLATFORM_COLORS = {
@ -38,9 +39,12 @@ const PLATFORM_COLORS = {
lemmy: 0x14854f, lemmy: 0x14854f,
birdsitelive: 0x1da1f2, birdsitelive: 0x1da1f2,
iceshrimp: 0x8e82f9, // YCbCr interpolated as the accent color is a gradient iceshrimp: 0x8e82f9, // YCbCr interpolated as the accent color is a gradient
cohost: 0x83254f,
}; };
const domainCache = new Map(); const domainCache = new Map();
domainCache.set("cohost.org", "cohost"); // no nodeinfo
async function resolvePlatform(url) { async function resolvePlatform(url) {
const urlObj = new URL(url); const urlObj = new URL(url);
if (domainCache.has(urlObj.hostname)) return domainCache.get(urlObj.hostname); if (domainCache.has(urlObj.hostname)) return domainCache.get(urlObj.hostname);
@ -137,7 +141,8 @@ async function processUrl(msg, url, spoiler = false) {
let platformName = platform let platformName = platform
.replace("gotosocial", "GoToSocial") .replace("gotosocial", "GoToSocial")
.replace("birdsitelive", '"Twitter" (BirdsiteLive)') .replace("birdsitelive", '"Twitter" (BirdsiteLive)')
.replace(/^(.)/, (_, c) => c.toUpperCase()); .replace(/^(.)/, (_, c) => c.toUpperCase())
.replace("Cohost", "cohost");
const images = []; const images = [];
const videos = []; const videos = [];
@ -475,6 +480,8 @@ async function processUrl(msg, url, spoiler = false) {
) )
.then((res) => res.json()) .then((res) => res.json())
.catch((err) => { .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}`); logger.error("fedimbed", `Failed to get author for "${url}": ${err}`);
}); });
@ -486,6 +493,18 @@ async function processUrl(msg, url, spoiler = false) {
url: authorData.url, url: authorData.url,
avatar: authorData.icon?.url, avatar: authorData.icon?.url,
}; };
} else {
// 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
);
author = {
name,
handle: `${name}@${authorUrlObj.hostname}`,
url: authorUrl,
};
} }
if (postData.endTime && postData.oneOf && postData.votersCount) { if (postData.endTime && postData.oneOf && postData.votersCount) {
@ -515,6 +534,10 @@ async function processUrl(msg, url, spoiler = false) {
// FIXME: stop being lazy and use an html parser // FIXME: stop being lazy and use an html parser
content = content.replace(/<a .*?href="([^"]+?)".*?>(.+?)<\/a>/g, "[$2]($1)"); content = content.replace(/<a .*?href="([^"]+?)".*?>(.+?)<\/a>/g, "[$2]($1)");
content = content.replace(
/<img .*?src="([^"]+?)".*?alt="([^"]+?)".*?\/>/g,
"[$2]($1)"
);
content = content.replace(/<\/?\s*br\s*\/?>/g, "\n"); content = content.replace(/<\/?\s*br\s*\/?>/g, "\n");
content = content.replace(/<\/p><p>/g, "\n\n"); content = content.replace(/<\/p><p>/g, "\n\n");
content = content.replace(/<ol>/g, "\n"); content = content.replace(/<ol>/g, "\n");