mirror of
https://github.com/captbaritone/webamp.git
synced 2026-08-03 15:34:25 +00:00
Clean up cache and add command to delete skin locally only
This commit is contained in:
parent
8997049e18
commit
87aa794312
4 changed files with 58 additions and 24 deletions
|
|
@ -31,32 +31,41 @@ export async function addSkinFromBuffer(
|
|||
const ctx = new UserContext();
|
||||
const md5 = md5Buffer(buffer);
|
||||
if (await SkinModel.exists(ctx, md5)) {
|
||||
console.log("Skin found.")
|
||||
return { md5, status: "FOUND" };
|
||||
}
|
||||
|
||||
// Note: This will thrown on invalid skins.
|
||||
console.log("Getting zip...")
|
||||
const zip = await JSZip.loadAsync(buffer);
|
||||
console.log("Getting skin type...")
|
||||
const skinType = await getSkinType(zip);
|
||||
|
||||
switch (skinType) {
|
||||
case "CLASSIC":
|
||||
console.log("Adding classic skin...")
|
||||
return addClassicSkinFromBuffer(ctx, buffer, md5, filePath, uploader);
|
||||
case "MODERN":
|
||||
return addModernSkinFromBuffer(buffer, md5, filePath, uploader);
|
||||
return addModernSkinFromBuffer(ctx, buffer, md5, filePath, uploader);
|
||||
}
|
||||
}
|
||||
|
||||
async function addModernSkinFromBuffer(
|
||||
ctx: UserContext,
|
||||
buffer: Buffer,
|
||||
md5: string,
|
||||
filePath: string,
|
||||
uploader: string
|
||||
): Promise<Result> {
|
||||
console.log("Write temporarty file.")
|
||||
const tempFile = temp.path({ suffix: ".wal" });
|
||||
fs.writeFileSync(tempFile, buffer);
|
||||
console.log("Put skin to S3.")
|
||||
await S3.putSkin(md5, buffer, "wal");
|
||||
|
||||
console.log("Add skin to DB")
|
||||
await Skins.addSkin({
|
||||
ctx,
|
||||
md5,
|
||||
filePath,
|
||||
uploader,
|
||||
|
|
@ -97,6 +106,7 @@ async function addClassicSkinFromBuffer(
|
|||
await S3.putSkin(md5, buffer, "wsz");
|
||||
|
||||
await Skins.addSkin({
|
||||
ctx,
|
||||
md5,
|
||||
filePath,
|
||||
uploader,
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ program
|
|||
.command("share")
|
||||
.description(
|
||||
"Share a skin on Twitter and Instagram. If no md5 is " +
|
||||
"given, random approved skins are shared."
|
||||
"given, random approved skins are shared."
|
||||
)
|
||||
.argument("[md5]", "md5 of the skin to share")
|
||||
.option("-t, --twitter", "Share on Twitter")
|
||||
|
|
@ -102,7 +102,12 @@ program
|
|||
.option(
|
||||
"--delete",
|
||||
"Delete a skin from the database, including its S3 files " +
|
||||
"CloudFlare cache and seach index entries."
|
||||
"CloudFlare cache and seach index entries."
|
||||
)
|
||||
.option(
|
||||
"--delete-local",
|
||||
"Delete a skin from the database only, NOT including its S3 files " +
|
||||
"CloudFlare cache and seach index entries."
|
||||
)
|
||||
.option("--index", "Update the seach index for a skin.")
|
||||
.option(
|
||||
|
|
@ -111,11 +116,14 @@ program
|
|||
)
|
||||
.option("--reject", 'Give a skin a "rejected" review.')
|
||||
.option("--metadata", "Push metadata to the archive.")
|
||||
.action(async (md5, { delete: del, index, refresh, reject, metadata }) => {
|
||||
.action(async (md5, { delete: del, deleteLocal, index, refresh, reject, metadata }) => {
|
||||
const ctx = new UserContext("CLI");
|
||||
if (del) {
|
||||
await Skins.deleteSkin(md5);
|
||||
}
|
||||
if (deleteLocal) {
|
||||
await Skins.deleteLocalSkin(md5);
|
||||
}
|
||||
if (index) {
|
||||
console.log(await Skins.updateSearchIndex(ctx, md5));
|
||||
}
|
||||
|
|
@ -170,18 +178,18 @@ program
|
|||
.option(
|
||||
"--fetch-metadata <count>",
|
||||
"Fetch missing metadata for <count> items from the Internet " +
|
||||
"Archive. Currently it only fetches missing metadata. In the " +
|
||||
"future it could refresh stale metadata."
|
||||
"Archive. Currently it only fetches missing metadata. In the " +
|
||||
"future it could refresh stale metadata."
|
||||
)
|
||||
.option(
|
||||
"--fetch-items",
|
||||
"Seach the Internet Archive for items that we don't know about" +
|
||||
"and add them to our database."
|
||||
"and add them to our database."
|
||||
)
|
||||
.option(
|
||||
"--update-metadata <count>",
|
||||
"Find <count> items in our database that have incorrect or incomplete " +
|
||||
"metadata, and update the Internet Archive"
|
||||
"metadata, and update the Internet Archive"
|
||||
)
|
||||
.option(
|
||||
"--upload-new",
|
||||
|
|
@ -215,7 +223,7 @@ program
|
|||
.command("stats")
|
||||
.description(
|
||||
"Report information about skins in the database. " +
|
||||
"Identical to `!stats` in Discord."
|
||||
"Identical to `!stats` in Discord."
|
||||
)
|
||||
.action(async () => {
|
||||
console.table([await Skins.getStats()]);
|
||||
|
|
@ -261,17 +269,17 @@ program
|
|||
.option(
|
||||
"--likes",
|
||||
"Scrape @winampskins tweets for like and retweet counts, " +
|
||||
"and update the database."
|
||||
"and update the database."
|
||||
)
|
||||
.option(
|
||||
"--milestones",
|
||||
"Check the most recent @winampskins tweets to see if they have " +
|
||||
"passed a milestone. If so, notify the Discord channel."
|
||||
"passed a milestone. If so, notify the Discord channel."
|
||||
)
|
||||
.option(
|
||||
"--followers",
|
||||
"Check if @winampskins has passed a follower count milestone. " +
|
||||
"If so, notify the Discord channel."
|
||||
"If so, notify the Discord channel."
|
||||
)
|
||||
.action(async ({ likes, milestones, followers }) => {
|
||||
if (likes) {
|
||||
|
|
@ -299,7 +307,7 @@ program
|
|||
.option(
|
||||
"--upload-ia-screenshot <md5>",
|
||||
"Upload a screenshot of a skin to the skin's Internet Archive itme. " +
|
||||
"[[Warning!]] This might result in multiple screenshots on the item."
|
||||
"[[Warning!]] This might result in multiple screenshots on the item."
|
||||
)
|
||||
.option(
|
||||
"--upload-missing-screenshots",
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export const IS_NOT_README =
|
|||
/(genex\.txt)|(genexinfo\.txt)|(gen_gslyrics\.txt)|(region\.txt)|(pledit\.txt)|(viscolor\.txt)|(winampmb\.txt)|("gen_ex help\.txt)|(mbinner\.txt)$/i;
|
||||
|
||||
export default class SkinModel {
|
||||
constructor(readonly ctx: UserContext, readonly row: SkinRow) {}
|
||||
constructor(readonly ctx: UserContext, readonly row: SkinRow) { }
|
||||
|
||||
static async fromMd5(
|
||||
ctx: UserContext,
|
||||
|
|
@ -37,6 +37,13 @@ export default class SkinModel {
|
|||
return row == null ? null : new SkinModel(ctx, row);
|
||||
}
|
||||
|
||||
static clearMd5(
|
||||
ctx: UserContext,
|
||||
md5: string
|
||||
): void {
|
||||
getSkinLoader(ctx).clear(md5);
|
||||
}
|
||||
|
||||
static async fromMd5Assert(
|
||||
ctx: UserContext,
|
||||
md5: string
|
||||
|
|
|
|||
|
|
@ -26,11 +26,13 @@ export function getScreenshotUrl(md5: string): string {
|
|||
}
|
||||
|
||||
export async function addSkin({
|
||||
ctx,
|
||||
md5,
|
||||
filePath,
|
||||
uploader,
|
||||
modern,
|
||||
}: {
|
||||
ctx: UserContext,
|
||||
md5: string;
|
||||
filePath: string;
|
||||
uploader: string;
|
||||
|
|
@ -51,6 +53,7 @@ export async function addSkin({
|
|||
},
|
||||
[]
|
||||
);
|
||||
SkinModel.clearMd5(ctx, md5);
|
||||
}
|
||||
|
||||
const CRUFT_FILENAME = /winampskins\.info\.(html)|(txt)$/;
|
||||
|
|
@ -210,7 +213,21 @@ export async function updateSearchIndex(
|
|||
|
||||
// Note: This might leave behind some files in file_info.
|
||||
export async function deleteSkin(md5: string): Promise<void> {
|
||||
console.log(`Deleting skin ${md5}...`);
|
||||
await deleteLocalSkin(md5);
|
||||
console.log(`Deleting skin ${md5} from external sources...`);
|
||||
console.log(`... removing from Algolia index`);
|
||||
await searchIndex.deleteObjects([md5]);
|
||||
console.log(`... removing skin from S3`);
|
||||
await S3.deleteSkin(md5);
|
||||
console.log(`... removing screenshot from S3`);
|
||||
await S3.deleteScreenshot(md5);
|
||||
console.log(`... purging screenshot and skin from CloudFlare`);
|
||||
await CloudFlare.purgeFiles([getScreenshotUrl(md5), getSkinUrl(md5)]);
|
||||
console.log(`Done deleting skin ${md5} from external sources.`);
|
||||
}
|
||||
|
||||
export async function deleteLocalSkin(md5: string): Promise<void> {
|
||||
console.log(`Deleting skin ${md5} locally...`);
|
||||
console.log(`... sqlite "skins"`);
|
||||
await knex("skins").where({ md5 }).limit(1).delete();
|
||||
console.log(`... sqlite "refreshes"`);
|
||||
|
|
@ -231,15 +248,7 @@ export async function deleteSkin(md5: string): Promise<void> {
|
|||
await knex("skin_uploads").where({ skin_md5: md5 }).delete();
|
||||
console.log(`... sqlite "screenshot_updates"`);
|
||||
await knex("screenshot_updates").where({ skin_md5: md5 }).delete();
|
||||
console.log(`... removing from Algolia index`);
|
||||
await searchIndex.deleteObjects([md5]);
|
||||
console.log(`... removing skin from S3`);
|
||||
await S3.deleteSkin(md5);
|
||||
console.log(`... removing screenshot from S3`);
|
||||
await S3.deleteScreenshot(md5);
|
||||
console.log(`... purging screenshot and skin from CloudFlare`);
|
||||
await CloudFlare.purgeFiles([getScreenshotUrl(md5), getSkinUrl(md5)]);
|
||||
console.log(`Done deleting skin ${md5}.`);
|
||||
console.log(`Done deleting skin ${md5} locally.`);
|
||||
}
|
||||
|
||||
export async function recordScreenshotUpdate(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue