上传素材管控-历史素材success
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""项目 CLI 脚本包。"""
|
||||
@@ -0,0 +1,88 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import asyncio
|
||||
import json
|
||||
import sys
|
||||
|
||||
from app.models.base import async_session
|
||||
from app.enums.upload_resource import UploadResourceEventEnum
|
||||
from app.services.upload_resource.backfill_service import BackfillOptions, run_upload_resource_backfill
|
||||
from app.services.upload_resource.log_service import log_upload_resource_exception, safe_rollback_with_log
|
||||
|
||||
|
||||
VALID_MODULES = {"common", "hot_opening_replicate", "shot_replicate"}
|
||||
|
||||
|
||||
def build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(description="补录 storage/uploads 下的上传资源账本,并可重绑模块归属。")
|
||||
parser.add_argument("--root", default="storage/uploads", help="扫描根目录,默认 storage/uploads")
|
||||
parser.add_argument("--batch-size", type=int, default=500, help="每批处理数量,默认 500")
|
||||
parser.add_argument("--dry-run", action="store_true", help="试跑,不写数据库")
|
||||
parser.add_argument("--commit", action="store_true", help="真实执行写入")
|
||||
parser.add_argument("--include-legacy", action="store_true", help="补录 gen_{user_id}_* 等旧版散落文件")
|
||||
parser.add_argument("--rebind-modules", action="store_true", help="根据 hot/shot 业务表中保存的 URL 重新绑定模块归属")
|
||||
parser.add_argument("--rebuild-stats", action="store_true", help="补录完成后按资源账本重算容量统计")
|
||||
parser.add_argument("--only-user-id", default=None, help="只处理指定用户ID")
|
||||
parser.add_argument("--only-module", choices=sorted(VALID_MODULES), default=None, help="只处理指定模块")
|
||||
parser.add_argument("--cleanup-pending-files", action="store_true", help="清理已软删但真实文件待删除/删除失败的 UploadResource 文件")
|
||||
parser.add_argument("--cleanup-limit", type=int, default=500, help="每次最多清理待删除真实文件数量,默认 500")
|
||||
return parser
|
||||
|
||||
|
||||
async def amain(argv: list[str]) -> int:
|
||||
parser = build_parser()
|
||||
args = parser.parse_args(argv)
|
||||
if args.dry_run and args.commit:
|
||||
parser.error("--dry-run 和 --commit 不能同时使用")
|
||||
if not args.dry_run and not args.commit:
|
||||
args.dry_run = True
|
||||
if args.batch_size <= 0:
|
||||
parser.error("--batch-size 必须大于 0")
|
||||
|
||||
options = BackfillOptions(
|
||||
root=args.root,
|
||||
batch_size=args.batch_size,
|
||||
dry_run=not args.commit,
|
||||
include_legacy=args.include_legacy,
|
||||
rebind_modules=args.rebind_modules,
|
||||
rebuild_stats=args.rebuild_stats,
|
||||
only_user_id=args.only_user_id,
|
||||
only_module=args.only_module,
|
||||
cleanup_pending_files=args.cleanup_pending_files,
|
||||
cleanup_limit=args.cleanup_limit,
|
||||
)
|
||||
|
||||
async with async_session() as db:
|
||||
try:
|
||||
result = await run_upload_resource_backfill(db, options)
|
||||
if options.dry_run:
|
||||
await db.rollback()
|
||||
else:
|
||||
await db.commit()
|
||||
except Exception as exc: # noqa: BLE001
|
||||
await safe_rollback_with_log(
|
||||
db,
|
||||
event_type=UploadResourceEventEnum.UPLOAD_RESOURCE_BACKFILL_CLI_ROLLBACK_FAILED.value,
|
||||
message="UploadResource 补录/清理 CLI 回滚失败",
|
||||
detail={"argv": argv, "options": vars(args)},
|
||||
original_exc=exc,
|
||||
)
|
||||
log_upload_resource_exception(
|
||||
event_type=UploadResourceEventEnum.UPLOAD_RESOURCE_BACKFILL_CLI_FAILED.value,
|
||||
message=f"UploadResource 补录/清理 CLI 执行失败: {exc}",
|
||||
detail={"argv": argv, "options": vars(args)},
|
||||
exc=exc,
|
||||
)
|
||||
raise
|
||||
|
||||
print(json.dumps(result.to_dict(), ensure_ascii=False, indent=2, default=str))
|
||||
return 0
|
||||
|
||||
|
||||
def main() -> int:
|
||||
return asyncio.run(amain(sys.argv[1:]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user