92 lines
2.6 KiB
Python
92 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
||
"""把 static/annotations 根目录下的图片按创建时间(天)归入 YYYY-MM-DD 子目录。
|
||
|
||
用法:
|
||
python3 scripts/organize_annotations_by_day.py # 实际移动
|
||
python3 scripts/organize_annotations_by_day.py --dry-run # 只预览
|
||
python3 scripts/organize_annotations_by_day.py --dir /path # 指定目录
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import argparse
|
||
import os
|
||
import shutil
|
||
import sys
|
||
from collections import Counter
|
||
from datetime import datetime
|
||
from pathlib import Path
|
||
|
||
IMAGE_EXTS = {".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp"}
|
||
|
||
|
||
def file_day(path: Path) -> str:
|
||
"""取文件创建日(优先 birth time,否则 mtime),本地时区 YYYY-MM-DD。"""
|
||
st = path.stat()
|
||
ts = getattr(st, "st_birthtime", None) or st.st_mtime
|
||
return datetime.fromtimestamp(ts).strftime("%Y-%m-%d")
|
||
|
||
|
||
def main() -> int:
|
||
repo = Path(__file__).resolve().parent.parent
|
||
parser = argparse.ArgumentParser(description="按天整理 annotations 图片")
|
||
parser.add_argument(
|
||
"--dir",
|
||
type=Path,
|
||
default=repo / "static" / "annotations",
|
||
help="annotations 目录(默认 static/annotations)",
|
||
)
|
||
parser.add_argument(
|
||
"--dry-run",
|
||
action="store_true",
|
||
help="只打印将要执行的操作,不实际移动",
|
||
)
|
||
args = parser.parse_args()
|
||
root: Path = args.dir.resolve()
|
||
|
||
if not root.is_dir():
|
||
print(f"目录不存在: {root}", file=sys.stderr)
|
||
return 1
|
||
|
||
files = [
|
||
p
|
||
for p in root.iterdir()
|
||
if p.is_file() and p.suffix.lower() in IMAGE_EXTS
|
||
]
|
||
if not files:
|
||
print(f"根目录没有待整理图片: {root}")
|
||
return 0
|
||
|
||
by_day: Counter[str] = Counter()
|
||
moved = 0
|
||
skipped = 0
|
||
|
||
for src in sorted(files):
|
||
day = file_day(src)
|
||
dest_dir = root / day
|
||
dest = dest_dir / src.name
|
||
by_day[day] += 1
|
||
|
||
if dest.exists():
|
||
print(f"SKIP 目标已存在: {dest.relative_to(root)}")
|
||
skipped += 1
|
||
continue
|
||
|
||
if args.dry_run:
|
||
print(f"MOVE {src.name} -> {day}/")
|
||
else:
|
||
dest_dir.mkdir(parents=True, exist_ok=True)
|
||
shutil.move(str(src), str(dest))
|
||
moved += 1
|
||
|
||
print("---")
|
||
print(f"目录: {root}")
|
||
print(f"{'预览' if args.dry_run else '完成'}: {moved} 个文件"
|
||
+ (f", 跳过 {skipped}" if skipped else ""))
|
||
for day in sorted(by_day):
|
||
print(f" {day}: {by_day[day]}")
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
raise SystemExit(main())
|