s3.1080p.hk 已永久停用且文件不可恢复。首页查询排除旧源并统一分页统计,历史图册、聊天和画布保留记录并显示失效说明;下载和代理返回 410,停止旧源上传与归档。使用本地黑白 Logo 适配主题。 提供保存原配置后停用旧存储、取消失效精选、替换 Logo 的整理脚本。七牛 10 月 14 日上传核查记录见 docs/retired-storage.md。 验证:7 项旧存储检查、41 项下载和归档回归测试、TypeScript 检查通过。
30 lines
2.4 KiB
JavaScript
30 lines
2.4 KiB
JavaScript
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
require('node:module').createRequire(require.resolve('next/package.json'))('@next/env').loadEnvConfig(process.cwd());
|
|
const sql = require('postgres')(process.env.POSTGRES_URL, { max: 1, prepare: false });
|
|
const pattern = '^https?://s3[.]1080p[.]hk([/:?#]|$)';
|
|
|
|
async function main() {
|
|
const apply = process.argv.includes('--apply');
|
|
const result = await sql.begin(async tx => {
|
|
const storage = await tx`select id,"isEnabled","isDefault" from "StorageConfig" where endpoint ~* ${pattern} or "publicUrl" ~* ${pattern}`;
|
|
const featured = await tx`select id,"isFeatured" from "GeneratedImage" where "isFeatured" and "originalUrl" ~* ${pattern}`;
|
|
const branding = await tx`select id,"siteLogo","siteLogoDark",favicon from "SiteSettings" where "siteLogo" ~* ${pattern} or "siteLogoDark" ~* ${pattern} or favicon ~* ${pattern}`;
|
|
if (!apply) return { apply, storage: storage.length, featured: featured.length, branding: branding.length };
|
|
const directory = process.env.STORAGE_RETIREMENT_BACKUP_DIR || '/var/lib/ai-chatbot/retired-storage-20261103';
|
|
fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
const backup = path.join(directory, `before-${Date.now()}.json`);
|
|
fs.writeFileSync(backup, JSON.stringify({ storage, featured, branding }, null, 2), { flag: 'wx', mode: 0o600 });
|
|
const disabled = await tx`update "StorageConfig" set "isEnabled"=false,"isDefault"=false,"updatedAt"=now() where (endpoint ~* ${pattern} or "publicUrl" ~* ${pattern}) and ("isEnabled" or "isDefault") returning id`;
|
|
const unfeatured = await tx`update "GeneratedImage" set "isFeatured"=false where "isFeatured" and "originalUrl" ~* ${pattern} returning id`;
|
|
const branded = await tx`update "SiteSettings" set
|
|
"siteLogo"=case when "siteLogo" ~* ${pattern} then '/brand/logo-black.png' else "siteLogo" end,
|
|
"siteLogoDark"=case when "siteLogoDark" ~* ${pattern} then '/brand/logo-white.svg' else "siteLogoDark" end,
|
|
favicon=case when favicon ~* ${pattern} then '/brand/logo-black.png' else favicon end
|
|
where "siteLogo" ~* ${pattern} or "siteLogoDark" ~* ${pattern} or favicon ~* ${pattern} returning id`;
|
|
return { apply, backup, disabled: disabled.length, unfeatured: unfeatured.length, branded: branded.length };
|
|
});
|
|
console.log(JSON.stringify(result));
|
|
}
|
|
main().catch(error => { console.error(error.message); process.exitCode = 1; }).finally(() => sql.end());
|