bkmdfg
This commit is contained in:
+71
-7
@@ -19,6 +19,10 @@ import queue from "../src/inc/queue.mjs";
|
||||
import cfg from "../src/inc/config.mjs";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const STATE_FILE = path.join(__dirname, '.regen_state.json');
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
@@ -31,6 +35,8 @@ if (args.length === 0) {
|
||||
console.log(' node regen.mjs --pdf - Regenerate all PDF items');
|
||||
console.log(' node regen.mjs --youtube - Regenerate all YouTube thumbnails');
|
||||
console.log(' node regen.mjs --blur - Regenerate ONLY the blurred thumbnails for all items');
|
||||
console.log(' --from <id> - Resume/start from a specific item ID (inclusive)');
|
||||
console.log(' --resume - Resume from last checkpoint saved in .regen_state.json');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
@@ -45,6 +51,33 @@ const THUMB_SIZE = 512;
|
||||
const blurOnly = args.includes('--blur');
|
||||
console.log(`[regen] Thumb size: ${THUMB_SIZE}px\n`);
|
||||
|
||||
let fromId = null;
|
||||
const fromIdx = args.indexOf('--from');
|
||||
if (fromIdx !== -1 && args[fromIdx + 1]) {
|
||||
fromId = parseInt(args[fromIdx + 1], 10);
|
||||
if (isNaN(fromId)) {
|
||||
console.error('Invalid ID provided for --from');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fromId && args.includes('--resume')) {
|
||||
try {
|
||||
const raw = await fs.readFile(STATE_FILE, 'utf8');
|
||||
const state = JSON.parse(raw);
|
||||
if (state.lastId) {
|
||||
fromId = state.lastId;
|
||||
console.log(`[regen] Resuming from checkpoint at item ID: ${fromId}\n`);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(`[regen] No previous state checkpoint found to resume from.\n`);
|
||||
}
|
||||
}
|
||||
|
||||
if (fromId) {
|
||||
console.log(`[regen] Starting from item ID >= ${fromId}\n`);
|
||||
}
|
||||
|
||||
const regen = async (item) => {
|
||||
const { id, dest, mime, src } = item;
|
||||
|
||||
@@ -89,46 +122,77 @@ const regen = async (item) => {
|
||||
|
||||
// Shared NOT IN clause for Flash exclusion
|
||||
const flashExclude = db`mime NOT IN ${db(FLASH_MIMES)}`;
|
||||
const fromClause = fromId ? db`AND id >= ${fromId}` : db``;
|
||||
|
||||
const saveState = async (id) => {
|
||||
try {
|
||||
await fs.writeFile(STATE_FILE, JSON.stringify({ lastId: id, timestamp: new Date().toISOString() }, null, 2));
|
||||
} catch (_) {}
|
||||
};
|
||||
|
||||
let currentItemId = null;
|
||||
process.on('SIGINT', async () => {
|
||||
if (currentItemId) {
|
||||
await saveState(currentItemId);
|
||||
console.log(`\n[regen] Interrupted! Saved state at item ID ${currentItemId}.`);
|
||||
console.log(`[regen] Resume anytime with: node scripts/regen.mjs --resume (or --from ${currentItemId})\n`);
|
||||
}
|
||||
process.exit(130);
|
||||
});
|
||||
|
||||
try {
|
||||
let items;
|
||||
|
||||
if (args.includes('--all')) {
|
||||
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND ${flashExclude} ORDER BY id`;
|
||||
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND ${flashExclude} ${fromClause} ORDER BY id`;
|
||||
console.log(`Regenerating ALL ${items.length} non-Flash items...\n`);
|
||||
} else if (args.includes('--audio')) {
|
||||
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND mime ILIKE 'audio/%' ORDER BY id`;
|
||||
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND mime ILIKE 'audio/%' ${fromClause} ORDER BY id`;
|
||||
console.log(`Regenerating ${items.length} audio items...\n`);
|
||||
} else if (args.includes('--pdf')) {
|
||||
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND mime = 'application/pdf' ORDER BY id`;
|
||||
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND mime = 'application/pdf' ${fromClause} ORDER BY id`;
|
||||
console.log(`Regenerating ${items.length} PDF items...\n`);
|
||||
} else if (args.includes('--youtube')) {
|
||||
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND mime = 'video/youtube' ORDER BY id`;
|
||||
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND mime = 'video/youtube' ${fromClause} ORDER BY id`;
|
||||
console.log(`Regenerating ${items.length} YouTube items...\n`);
|
||||
} else if (blurOnly) {
|
||||
items = await db`
|
||||
SELECT id, dest, mime, src
|
||||
FROM items
|
||||
WHERE active = true AND is_deleted = false AND ${flashExclude}
|
||||
WHERE active = true AND is_deleted = false AND ${flashExclude} ${fromClause}
|
||||
ORDER BY id
|
||||
`;
|
||||
console.log(`Regenerating ONLY blurred thumbnails for all ${items.length} non-Flash items...\n`);
|
||||
} else {
|
||||
const ids = args.map(Number).filter(n => !isNaN(n) && n > 0);
|
||||
const positionalArgs = [];
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i] === '--from') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (args[i].startsWith('--')) continue;
|
||||
positionalArgs.push(args[i]);
|
||||
}
|
||||
const ids = positionalArgs.map(Number).filter(n => !isNaN(n) && n > 0);
|
||||
if (ids.length === 0) {
|
||||
console.error('No valid item IDs provided.');
|
||||
process.exit(1);
|
||||
}
|
||||
items = await db`SELECT id, dest, mime, src FROM items WHERE id IN ${db(ids)} ORDER BY id`;
|
||||
items = await db`SELECT id, dest, mime, src FROM items WHERE id IN ${db(ids)} ${fromClause} ORDER BY id`;
|
||||
const found = items.map(i => i.id);
|
||||
const missing = ids.filter(id => !found.includes(id));
|
||||
if (missing.length) console.warn(`Items not found: ${missing.join(', ')}\n`);
|
||||
}
|
||||
|
||||
for (const item of items) {
|
||||
currentItemId = item.id;
|
||||
await regen(item);
|
||||
await saveState(item.id);
|
||||
}
|
||||
|
||||
// Clean up state file on normal completion
|
||||
await fs.unlink(STATE_FILE).catch(() => {});
|
||||
|
||||
console.log(`\nDone. ${items.length} items processed.`);
|
||||
process.exit(0);
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user