mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-23 18:25:30 +00:00
204 lines
6 KiB
JavaScript
Executable file
204 lines
6 KiB
JavaScript
Executable file
#!/usr/bin/env node
|
|
import fs from "fs";
|
|
import { knex } from "./db";
|
|
import { argv } from "yargs";
|
|
import logger from "./logger";
|
|
import DiscordWinstonTransport from "./DiscordWinstonTransport";
|
|
import * as Skins from "./data/skins";
|
|
import Discord from "discord.js";
|
|
import { tweet } from "./tasks/tweet";
|
|
import { addSkinFromBuffer } from "./addSkin";
|
|
import { searchIndex } from "./algolia";
|
|
import { scrapeLikeData } from "./tasks/scrapeLikes";
|
|
import UserContext from "./data/UserContext";
|
|
import { integrityCheck } from "./tasks/integrityCheck";
|
|
import { ensureWebampLinks, syncWithArchive } from "./tasks/syncWithArchive";
|
|
import { syncFromArchive } from "./tasks/syncFromArchive";
|
|
import { getSkinsToRefresh, refreshSkins } from "./tasks/refresh";
|
|
import { processUserUploads } from "./api/processUserUploads";
|
|
import DiscordEventHandler from "./api/DiscordEventHandler";
|
|
import SkinModel from "./data/SkinModel";
|
|
import { chunk } from "./utils";
|
|
import rl from "readline";
|
|
|
|
async function main() {
|
|
const client = new Discord.Client();
|
|
// The Winston transport logs in the client.
|
|
await DiscordWinstonTransport.addToLogger(client, logger);
|
|
const ctx = new UserContext("CLI");
|
|
const handler = new DiscordEventHandler();
|
|
|
|
try {
|
|
switch (argv._[0]) {
|
|
case "ensure-webamp-links":
|
|
await ensureWebampLinks();
|
|
break;
|
|
case "sync-from-ia":
|
|
await syncFromArchive();
|
|
break;
|
|
case "sync-ia":
|
|
await syncWithArchive();
|
|
break;
|
|
case "integity-check":
|
|
await integrityCheck();
|
|
break;
|
|
case "reject": {
|
|
const md5 = argv._[1];
|
|
if (md5 == null) {
|
|
return;
|
|
}
|
|
await Skins.reject(new UserContext("CLI"), md5);
|
|
break;
|
|
}
|
|
case "refresh": {
|
|
const md5 = argv._[1];
|
|
if (md5 != null) {
|
|
const skin = await SkinModel.fromMd5(ctx, md5);
|
|
if (skin == null) {
|
|
throw new Error(`Could not find skin ${md5}`);
|
|
}
|
|
refreshSkins([skin]);
|
|
} else {
|
|
const toRefresh = await getSkinsToRefresh(ctx, 100);
|
|
|
|
const chunks = chunk(toRefresh, toRefresh.length / 3);
|
|
|
|
await Promise.all(chunks.map(refreshSkins));
|
|
}
|
|
break;
|
|
}
|
|
case "nested": {
|
|
const nested = await knex("archive_files")
|
|
.select("archive_files.skin_md5", "file_name")
|
|
.leftJoin("skins", "skins.md5", "=", "file_md5")
|
|
.where(function () {
|
|
//this.where("file_name", "like", "%.wsz");
|
|
this.orWhere("file_name", "like", "%.zip");
|
|
})
|
|
.where("skins.md5", "IS", null);
|
|
|
|
for (const row of nested) {
|
|
const url = `https://zip-worker.jordan1320.workers.dev/zip/${
|
|
row.skin_md5
|
|
}/${encodeURI(row.file_name)}`;
|
|
console.log(url);
|
|
}
|
|
/*
|
|
const query = `SELECT skin_md5, error
|
|
FROM refreshes
|
|
WHERE
|
|
error LIKE "Not a skin%";`;
|
|
const rows = await knex.raw(query);
|
|
for (const row of rows) {
|
|
const files = await knex("archive_files")
|
|
.where("skin_md5", row.skin_md5)
|
|
.select();
|
|
console.log("Download:", Skins.getSkinUrl(row.skin_md5));
|
|
// const url = `;
|
|
console.table(
|
|
files.map((f) => ({
|
|
file_name: f.file_name,
|
|
url: `https://zip-worker.jordan1320.workers.dev/zip/${
|
|
row.skin_md5
|
|
}/${encodeURI(f.file_name)}`,
|
|
})),
|
|
["file_name", "url"]
|
|
);
|
|
const answer = await ask("skip (s), delete (d)");
|
|
switch (answer) {
|
|
case "s":
|
|
break;
|
|
case "d":
|
|
await Skins.deleteSkin(row.skin_md5);
|
|
}
|
|
}
|
|
*/
|
|
break;
|
|
}
|
|
case "tweet": {
|
|
console.log("tweet");
|
|
await tweet(client, null);
|
|
break;
|
|
}
|
|
case "stats": {
|
|
console.log(await Skins.getStats());
|
|
break;
|
|
}
|
|
case "add": {
|
|
const filePath = argv._[1];
|
|
const buffer = fs.readFileSync(filePath);
|
|
console.log(await addSkinFromBuffer(buffer, filePath, "cli-user"));
|
|
break;
|
|
}
|
|
case "delete": {
|
|
const md5 = argv._[1];
|
|
await Skins.deleteSkin(md5);
|
|
break;
|
|
}
|
|
case "index": {
|
|
console.log(await Skins.updateSearchIndex(argv._[1]));
|
|
break;
|
|
}
|
|
case "process": {
|
|
const handler = new DiscordEventHandler();
|
|
await processUserUploads((event) => handler.handle(event));
|
|
handler.dispose();
|
|
break;
|
|
}
|
|
case "add-missing-indexes": {
|
|
// eslint-disable-next-line no-inner-declarations
|
|
async function indexPage(pageNumber: number): Promise<void> {
|
|
const page = await Skins.getMuseumPage({
|
|
offset: pageNumber * 500,
|
|
first: 500,
|
|
});
|
|
const toCheck = page.map(({ md5 }) => md5);
|
|
const found = await searchIndex.getObjects(toCheck, {
|
|
attributesToRetrieve: ["objectId"],
|
|
});
|
|
// console.log({ toCheck, found });
|
|
const missing = toCheck.filter((_md5, i) => {
|
|
return found.results[i] == null;
|
|
});
|
|
|
|
console.log(
|
|
`Found ${missing.length} missing skins on page ${pageNumber}`
|
|
);
|
|
console.log(await Skins.updateSearchIndexs(missing));
|
|
}
|
|
|
|
for (let i = 0; i < 140; i++) {
|
|
await indexPage(i);
|
|
}
|
|
break;
|
|
}
|
|
case "tweet-data": {
|
|
await scrapeLikeData();
|
|
break;
|
|
}
|
|
|
|
default:
|
|
console.log(`Unknown command ${argv._[0]}`);
|
|
}
|
|
} finally {
|
|
knex.destroy();
|
|
logger.close();
|
|
client.destroy();
|
|
await handler.dispose();
|
|
}
|
|
}
|
|
|
|
function ask(question): Promise<string> {
|
|
return new Promise((resolve) => {
|
|
const r = rl.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout,
|
|
});
|
|
r.question(question + "\n", function (answer) {
|
|
r.close();
|
|
resolve(answer);
|
|
});
|
|
});
|
|
}
|
|
|
|
main();
|