Initial miaojingAI project with image resolution guard
This commit is contained in:
59
fix_persistence_data.js
Normal file
59
fix_persistence_data.js
Normal file
@@ -0,0 +1,59 @@
|
||||
const { Client } = require('pg');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
require('dotenv').config({ path: '/root/miaojingAI/.env.local' });
|
||||
const root = '/root/miaojingAI';
|
||||
const c = new Client({ connectionString: process.env.LOCAL_DB_URL });
|
||||
function keyFromUrl(url) {
|
||||
if (!url) return null;
|
||||
const marker = '/api/local-storage/';
|
||||
const idx = String(url).indexOf(marker);
|
||||
if (idx < 0) return null;
|
||||
try { return decodeURIComponent(String(url).slice(idx + marker.length).split('?')[0]); } catch { return null; }
|
||||
}
|
||||
function publicUrl(key) { return `/api/local-storage/${key}`; }
|
||||
function copyToGallery(url, type, id, field) {
|
||||
const key = keyFromUrl(url);
|
||||
if (!key) return url;
|
||||
if (key.startsWith('gallery/')) return url;
|
||||
const src = path.join(root, 'local-storage', key);
|
||||
if (!fs.existsSync(src)) return url;
|
||||
const ext = path.extname(key) || '.bin';
|
||||
const folder = field === 'thumbnail_url' ? 'gallery/thumbnails' : (type === 'text2video' || type === 'img2video' || type === 'video' ? 'gallery/videos' : 'gallery/images');
|
||||
const destDir = path.join(root, 'local-storage', folder);
|
||||
fs.mkdirSync(destDir, { recursive: true });
|
||||
const destKey = `${folder}/${id}-${field}${ext}`;
|
||||
const dest = path.join(root, 'local-storage', destKey);
|
||||
if (!fs.existsSync(dest)) fs.copyFileSync(src, dest);
|
||||
return publicUrl(destKey);
|
||||
}
|
||||
(async () => {
|
||||
await c.connect();
|
||||
await c.query('BEGIN');
|
||||
try {
|
||||
const adminRes = await c.query(`select id,email from profiles where role='admin' order by case when email='admin@example.com' then 0 else 1 end, created_at asc limit 1`);
|
||||
if (!adminRes.rows.length) throw new Error('No admin profile found');
|
||||
const admin = adminRes.rows[0];
|
||||
const password = process.env.ADMIN_DEFAULT_PASSWORD || 'admin123';
|
||||
await c.query(`update auth.users set password_hash = crypt($1, gen_salt('bf')) where id=$2`, [password, admin.id]);
|
||||
const worksFixed = await c.query(`update works set user_id=$1 where user_id is null or user_id not in (select id from profiles) returning id`, [admin.id]);
|
||||
const creditDeleted = await c.query(`delete from credit_transactions where user_id not in (select id from profiles) returning id`);
|
||||
const publicWorks = await c.query(`select id,type,result_url,thumbnail_url from works where is_public=true order by created_at asc`);
|
||||
let copied = 0;
|
||||
for (const w of publicWorks.rows) {
|
||||
const nextResult = copyToGallery(w.result_url, w.type, w.id, 'result_url');
|
||||
const nextThumb = w.thumbnail_url ? copyToGallery(w.thumbnail_url, w.type, w.id, 'thumbnail_url') : null;
|
||||
if (nextResult !== w.result_url || nextThumb !== w.thumbnail_url) {
|
||||
await c.query(`update works set result_url=$1, thumbnail_url=$2, updated_at=now() where id=$3`, [nextResult, nextThumb, w.id]);
|
||||
copied++;
|
||||
}
|
||||
}
|
||||
await c.query('COMMIT');
|
||||
console.log(JSON.stringify({ admin: admin.email, passwordHashSet: true, worksFixed: worksFixed.rowCount, orphanCreditsDeleted: creditDeleted.rowCount, publicWorksCopiedToGallery: copied }, null, 2));
|
||||
} catch (e) {
|
||||
await c.query('ROLLBACK');
|
||||
throw e;
|
||||
} finally {
|
||||
await c.end();
|
||||
}
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
Reference in New Issue
Block a user