Compare commits

...

2 commits

2 changed files with 221 additions and 19 deletions

View file

@ -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);

View file

@ -40,6 +40,8 @@ const APP_ICON_BASE = CDN + "app-icons/";
const APP_ASSET_BASE = CDN + "app-assets/";
const DISCOVERY_SPLASH_BASE = CDN + "discovery-splashes/";
const AVATAR_DECORATION_BASE = CDN + "avatar-decoration-presets/";
const CLAN_BADGE_BASE = CDN + "clan-badges/";
const CLAN_BANNER_BASE = CDN + "clan-banner/";
const DEFAULT_GROUP_DM_AVATARS = [
"/assets/ee9275c5a437f7dc7f9430ba95f12ebd.png",
@ -349,6 +351,15 @@ const CHANNEL_TYPE_NAMES = {
16: "media",
};
const CLAN_PLAYSTYLE = {
0: "None",
1: "Very Casual",
2: "Casual",
3: "Competitive",
4: "Creative",
5: "Very Competitive",
};
const EMOJI_SETS = {
blobs: {
prefix:
@ -451,11 +462,21 @@ async function getGuild(id) {
false
);
if (widget) return {source: "widget", data: widget};
} catch {
try {
const verification = await hf.bot.requestHandler.request(
"GET",
`/guilds/${id}/member-verification?with_guild=true`,
true
);
if (verification?.guild)
return {source: "verification", data: verification.guild};
} catch {
return null;
}
}
}
}
return null;
}
@ -1870,7 +1891,7 @@ guildinfo.addAlias("server");
guildinfo.addAlias("sinfo");
guildinfo.addAlias("si");
guildinfo.callback = async function (msg, line) {
let _guild;
let _guild, clanEmbed;
if (!line || line == "") {
if (!msg.guildID) return "Not in a guild.";
_guild = {source: "local", data: msg.channel.guild};
@ -1878,6 +1899,88 @@ guildinfo.callback = async function (msg, line) {
if (!SNOWFLAKE_REGEX.test(line)) return "Not a snowflake.";
const snowflake = line.match(SNOWFLAKE_REGEX)[1];
_guild = await getGuild(snowflake);
try {
const clan = await hf.bot.requestHandler.request(
"GET",
`/discovery/${snowflake}/clan`,
true
);
if (clan) {
const images = [];
clanEmbed = {
name: _guild != null ? "Clan data" : clan.name,
description: clan.description ?? "*No description*",
fields: [
!_guild && {
name: "Member Count",
value: clan.member_count,
inline: true,
},
{
name: "Tag",
value: clan.tag,
inline: true,
},
{
name: "Playstyle",
value:
CLAN_PLAYSTYLE[clan.playstyle] ??
`<unknown value: ${clan.playstyle}>`,
},
{
name: "Descriptors",
value: clan.wildcard_descriptors.join(", "),
inline: true,
},
{
name: "Interests/Topics/Traits",
value: `\`${clan.search_terms.map((x) => `"${x}"`).join(", ")}\``,
inline: false,
},
{
name: "Associated Game IDs",
value: `\`${clan.game_ids.map((x) => `"${x}"`).join(", ")}\``,
inline: false,
},
{
name: "Badge Colors",
value: `${clan.badge_color_primary} | ${clan.badge_color_secondary}`,
inline: true,
},
{
name: "Banner/Brand Colors",
value: `${clan.brand_color_primary} | ${clan.brand_color_secondary}`,
inline: true,
},
].filter((x) => !!x),
footer: !_guild ? {text: "Fetched from clan"} : null,
};
if (clan.badge_hash) {
const url = `${CLAN_BADGE_BASE}${clan.id}/${clan.badge_hash}.png?size=4096`;
images.push(`[Badge](${url})`);
clanEmbed.thumbnail = {url};
}
if (clan.banner_hash) {
const url = `${CLAN_BANNER_BASE}${clan.id}/${clan.banner_hash}.png?size=4096`;
images.push(`[Banner](${url})`);
clanEmbed.image = {url};
}
if (images.length > 0) {
clanEmbed.fields.push({
name: "\u200b",
value: images.join(" | "),
inline: false,
});
}
}
} catch {
// noop
}
}
if (!_guild) return "Guild not found.";
@ -2124,9 +2227,14 @@ guildinfo.callback = async function (msg, line) {
});
}
if (clanEmbed) {
return {embeds: [embed, clanEmbed]};
} else {
return {embed};
}
case "preview": {
}
case "preview":
case "verification": {
const embed = {
title: guild.name,
description: guild.description ?? "*No description.*",
@ -2136,7 +2244,12 @@ guildinfo.callback = async function (msg, line) {
value: `<t:${Math.floor(snowflakeToTimestamp(guild.id) / 1000)}:R>`,
inline: true,
},
guild.emojis.length > 0 && {
guild.verification_level && {
name: "Verification Level",
value: GUILD_VERIFICATION_LEVELS[guild.verification_level],
inline: true,
},
(guild.emojis?.length ?? 0) > 0 && {
name: `Emotes (${guild.emojis.length})`,
value: `${
guild.emojis.filter((e) => e.animated).length
@ -2147,7 +2260,7 @@ guildinfo.callback = async function (msg, line) {
} unavailable`,
inline: true,
},
guild.stickers.length > 0 && {
(guild.stickers?.length ?? 0) > 0 && {
name: `Stickers (${guild.stickers.length})`,
value: `${
guild.stickers.filter((s) => s.format_type == 1).length
@ -2164,7 +2277,11 @@ guildinfo.callback = async function (msg, line) {
},
].filter((x) => !!x),
footer: {
text: "Fetched from guild preview",
text: `Fetched from ${
_guild.source === "verification"
? "membership screening"
: "guild preview"
}`,
},
};
@ -2235,8 +2352,12 @@ guildinfo.callback = async function (msg, line) {
});
}
if (clanEmbed) {
return {embeds: [embed, clanEmbed]};
} else {
return {embed};
}
}
case "discovery": {
if (!guild.store_page) {
return "Got discovery data but no store page.";
@ -2359,8 +2480,12 @@ guildinfo.callback = async function (msg, line) {
});
}
if (clanEmbed) {
return {embeds: [embed, clanEmbed]};
} else {
return {embed};
}
}
case "widget": {
let invite;
if (guild.instant_invite) {
@ -2391,7 +2516,7 @@ guildinfo.callback = async function (msg, line) {
if (invite) {
embed.fields.push({
name: "Invite",
value: "https://discord.gg/" + guild.instant_invite,
value: guild.instant_invite,
inline: true,
});
@ -2432,7 +2557,7 @@ guildinfo.callback = async function (msg, line) {
const images = [];
if (invite.guild.icon) {
images.push(
`[Icon](${ICON_BASE}${invite.guild.id}/${invite.guild.icon}.png?size=4096`
`[Icon](${ICON_BASE}${invite.guild.id}/${invite.guild.icon}.png?size=4096)`
);
}
if (invite.guild.splash) {
@ -2461,8 +2586,12 @@ guildinfo.callback = async function (msg, line) {
});
}
if (clanEmbed) {
return {embeds: [embed, clanEmbed]};
} else {
return {embed};
}
}
default:
return "Guild not found.";
}