mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-17 16:46:04 +00:00
Reverts the temporary diagnostic logging added in 86588f56,
which introduced prettier formatting violations that broke CI.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
225 lines
6.4 KiB
TypeScript
225 lines
6.4 KiB
TypeScript
import {
|
|
User,
|
|
MessageReaction,
|
|
TextChannel,
|
|
DMChannel,
|
|
MessageEmbed,
|
|
} from "discord.js";
|
|
import SkinModel from "../data/SkinModel";
|
|
import * as Skins from "../data/skins";
|
|
import UserContext from "../data/UserContext";
|
|
import logger from "../logger";
|
|
import { TweetStatus } from "../types";
|
|
|
|
function isEligableToApprove(user: User): boolean {
|
|
return !user.bot;
|
|
}
|
|
|
|
const filter = async (reaction: MessageReaction): Promise<boolean> => {
|
|
const users = await reaction.users.fetch();
|
|
const hasNonBot = users.some(isEligableToApprove);
|
|
|
|
return (
|
|
hasNonBot &&
|
|
["👍", "👎", "👏", "😔", "🔞"].some((name) => reaction.emoji.name === name)
|
|
);
|
|
};
|
|
|
|
export async function postSkin({
|
|
md5,
|
|
title: _title,
|
|
dest,
|
|
source = "unknown",
|
|
}: {
|
|
md5: string;
|
|
title?: (filename: string | null) => string;
|
|
dest: TextChannel | DMChannel;
|
|
source?: string;
|
|
}) {
|
|
const ctx = new UserContext();
|
|
|
|
const skin = await SkinModel.fromMd5(ctx, md5);
|
|
if (skin == null) {
|
|
console.warn("Could not find skin for md5", { md5, alert: true });
|
|
logger.warn("Could not find skin for md5", { md5, alert: true, source });
|
|
return;
|
|
}
|
|
const readmeText = await skin.getReadme();
|
|
const tweet = await skin.getTweet();
|
|
const tweetStatus = await skin.getTweetStatus();
|
|
const iaItem = await skin.getIaItem();
|
|
const internetArchiveUrl = iaItem?.getUrl();
|
|
const internetArchiveItemName = iaItem?.getIdentifier();
|
|
const emails = skin.getEmails();
|
|
const canonicalFilename = await skin.getFileName();
|
|
const nsfw = await skin.getIsNsfw();
|
|
const title = _title ? _title(canonicalFilename) : canonicalFilename;
|
|
|
|
const embed = new MessageEmbed()
|
|
.setTitle(title)
|
|
.addField("Try Online", `[skins.webamp.org](${skin.getMuseumUrl()})`, true)
|
|
.addField("Download", `[${canonicalFilename}](${skin.getSkinUrl()})`, true)
|
|
.addField("Md5", md5, true);
|
|
|
|
if (await skin.getIsNsfw()) {
|
|
embed.addField("NSFW", `🔞`, true);
|
|
}
|
|
|
|
// @ts-ignore
|
|
if (nsfw && !(dest.type === "text" && dest.nsfw)) {
|
|
embed.addField(
|
|
"Screenshot",
|
|
`[Screenshot](${skin.getScreenshotUrl()})`,
|
|
true
|
|
);
|
|
} else {
|
|
embed.setImage(skin.getScreenshotUrl());
|
|
}
|
|
|
|
if (readmeText) {
|
|
// Trim the readme since Discord will reject it otherwise.
|
|
embed.setDescription(`\`\`\`${readmeText.slice(0, 2000)}\`\`\``);
|
|
}
|
|
if (emails.length) {
|
|
embed.addField("Emails", emails.join(", "), true);
|
|
}
|
|
if (tweet != null) {
|
|
const likes = `${tweet.getLikes().toLocaleString()} likes `;
|
|
const retweets = `${tweet.getRetweets().toLocaleString()} retweets `;
|
|
embed.addField(
|
|
"Tweet Status",
|
|
`[Tweeted](${tweet.getUrl()}) (${likes} / ${retweets})🐦`,
|
|
true
|
|
);
|
|
} else {
|
|
if (tweetStatus === "UNREVIEWED") {
|
|
embed.setFooter(
|
|
"React with 👍 or 👎 to approve or deny or 🔞 to mark NSFW"
|
|
);
|
|
}
|
|
embed.addField("Tweet Status", getPrettyTwitterStatus(tweetStatus), true);
|
|
}
|
|
if (internetArchiveUrl) {
|
|
embed.addField(
|
|
"Internet Archive",
|
|
`[${internetArchiveItemName || "Permalink"}](${internetArchiveUrl})`,
|
|
true
|
|
);
|
|
}
|
|
|
|
// @ts-ignore WAT?
|
|
const msg = await dest.send(embed);
|
|
if (tweetStatus !== "UNREVIEWED") {
|
|
return;
|
|
}
|
|
const msgId = Array.isArray(msg) ? msg.map((m) => m.id).join(",") : msg.id;
|
|
logger.info("postSkin: posted review", { md5, source, msgId });
|
|
|
|
// Don't await
|
|
Promise.all([msg.react("👍"), msg.react("👎"), msg.react("🔞")]).catch(
|
|
(err) =>
|
|
logger.error("postSkin: bot reactions failed", {
|
|
md5,
|
|
source,
|
|
msgId,
|
|
err: err?.message,
|
|
stack: err?.stack,
|
|
})
|
|
);
|
|
// TODO: Timeout at some point
|
|
await msg.awaitReactions(filter, { max: 1 }).then(async (collected) => {
|
|
const vote = collected.first();
|
|
if (vote == null) {
|
|
throw new Error("Did not expect vote to be empty");
|
|
}
|
|
const users = await vote.users.fetch();
|
|
const user = users.find(isEligableToApprove);
|
|
if (user == null) {
|
|
throw new Error("Expected to find approver.");
|
|
}
|
|
switch (vote.emoji.name) {
|
|
case "👍":
|
|
case "👏":
|
|
await Skins.approve(ctx, md5);
|
|
logger.info(`${user.username} approved ${md5}`);
|
|
await msg.channel.send(
|
|
`${canonicalFilename} was approved by ${user.username}`
|
|
);
|
|
msg.react("✅");
|
|
break;
|
|
case "😔":
|
|
case "👎":
|
|
await Skins.reject(ctx, md5);
|
|
logger.info(`${user.username} rejected ${md5}`);
|
|
await msg.channel.send(
|
|
`${canonicalFilename} was rejected by ${user.username}`
|
|
);
|
|
msg.react("❌");
|
|
break;
|
|
case "🔞":
|
|
logger.info(`${user.username} marked ${md5} as NSFW`);
|
|
await Skins.markAsNSFW(ctx, md5);
|
|
await msg.channel.send(
|
|
`${canonicalFilename} was marked as NSFW by ${user.username}`
|
|
);
|
|
await Skins.reject(ctx, md5);
|
|
logger.info(`${user.username} rejected ${md5}`);
|
|
await msg.channel.send(
|
|
`${canonicalFilename} was rejected by ${user.username}`
|
|
);
|
|
msg.react("❌");
|
|
break;
|
|
default:
|
|
logger.alert(
|
|
`Unknown skin reaction by ${user.username} on ${md5}: ${vote.emoji.name}`
|
|
);
|
|
}
|
|
});
|
|
}
|
|
|
|
function getPrettyTwitterStatus(status: TweetStatus): string {
|
|
switch (status) {
|
|
case "APPROVED":
|
|
return "Approved ✅";
|
|
case "NSFW":
|
|
return "Rejected (NSFW) ❌";
|
|
case "REJECTED":
|
|
return "Rejected ❌";
|
|
case "UNREVIEWED":
|
|
return "Unreviewed ❔";
|
|
case "TWEETED":
|
|
return "Tweeted 🐦";
|
|
}
|
|
}
|
|
|
|
export async function sendAlreadyReviewed({
|
|
md5,
|
|
dest,
|
|
}: {
|
|
md5: string;
|
|
dest: TextChannel | DMChannel;
|
|
}) {
|
|
const ctx = new UserContext();
|
|
const skin = await SkinModel.fromMd5(ctx, md5);
|
|
if (skin == null) {
|
|
console.warn("Could not find skin for md5", { md5, alert: true });
|
|
logger.warn("Could not find skin for md5", { md5, alert: true });
|
|
return;
|
|
}
|
|
const canonicalFilename = await skin.getFileName();
|
|
const tweetStatus = await skin.getTweetStatus();
|
|
const nsfw = await skin.getIsNsfw();
|
|
|
|
const embed = new MessageEmbed()
|
|
.setTitle(
|
|
`Someone flagged "${canonicalFilename}", but it's already been reviwed.`
|
|
)
|
|
.addField("Status", getPrettyTwitterStatus(tweetStatus), true)
|
|
.addField("Museum", `[${canonicalFilename}](${skin.getMuseumUrl()})`, true);
|
|
|
|
if (nsfw) {
|
|
embed.addField("NSFW", `🔞`, true);
|
|
}
|
|
|
|
dest.send(embed);
|
|
}
|