50 lines
1.6 KiB
Python
50 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
|
|
def load_frozen_ids(path: Path) -> set[str]:
|
|
if not path.is_file():
|
|
return set()
|
|
return {
|
|
line.strip()
|
|
for line in path.read_text(encoding="utf-8").splitlines()
|
|
if line.strip() and not line.lstrip().startswith("#")
|
|
}
|
|
|
|
|
|
def captured_ids(asset_dir: Path) -> set[str]:
|
|
found: set[str] = set()
|
|
media_path = asset_dir / "media.json"
|
|
if media_path.is_file():
|
|
media = json.loads(media_path.read_text(encoding="utf-8"))
|
|
root_id = str(media.get("root_post_id") or "")
|
|
if root_id:
|
|
found.add(root_id)
|
|
for item in media.get("items") or []:
|
|
post_id = str(item.get("post_id") or "")
|
|
if post_id:
|
|
found.add(post_id)
|
|
thread_path = asset_dir / "thread_data.json"
|
|
if thread_path.is_file():
|
|
thread = json.loads(thread_path.read_text(encoding="utf-8"))
|
|
root_id = str(thread.get("root_post_id") or "")
|
|
if root_id:
|
|
found.add(root_id)
|
|
for post in thread.get("posts") or []:
|
|
post_id = str(post.get("post_id") or "")
|
|
if post_id:
|
|
found.add(post_id)
|
|
return found
|
|
|
|
|
|
def frozen_match(asset_dir: Path, frozen_ids: set[str]) -> str | None:
|
|
matches = sorted(captured_ids(asset_dir) & frozen_ids)
|
|
return matches[0] if matches else None
|
|
|
|
|
|
def require_writable(asset_dir: Path, frozen_ids: set[str]) -> None:
|
|
match = frozen_match(asset_dir, frozen_ids)
|
|
if match is not None:
|
|
raise SystemExit(f"frozen: skipped ({match})") |