feat: update character assets and registry for multiple packs
- Added new character images in .webp format for Dragon Ball FighterZ, Rivals of Aether II, and Skullgirls: 2nd Encore. - Removed outdated .png images for characters in Dragon Ball FighterZ and Rivals of Aether II. - Updated registry.json to reflect changes in character counts and total sizes for packs. - Introduced new packs for BlazBlue Centralfiction and Rivals of Aether II with their respective assets and manifest files. - Added scripts for updating image sizes and renaming images to match character slugs.
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
# update_pack_sizes.py
|
||||
#
|
||||
# Updates the selected pack by:
|
||||
# - recalculating each character's sizeBytes from its image file
|
||||
# - updating registry.json totalSizeBytes
|
||||
# - updating registry.json characterCount
|
||||
# - updating registry.json updatedAt
|
||||
#
|
||||
# Notes:
|
||||
# - Missing images are skipped and assigned sizeBytes = 0
|
||||
# - Missing images are NOT counted in characterCount
|
||||
# - Character objects are written on a single line for readability
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
REGISTRY_FILENAME = "registry.json"
|
||||
IMAGE_EXTENSIONS = (".png", ".jpg", ".jpeg", ".webp", ".avif")
|
||||
|
||||
|
||||
def format_bytes(size: int) -> str:
|
||||
return f"{size / 1024:.1f} KB"
|
||||
|
||||
|
||||
def load_json(path: Path) -> dict:
|
||||
return json.loads(path.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def save_json(path: Path, data: dict) -> None:
|
||||
path.write_text(
|
||||
json.dumps(data, indent=2, ensure_ascii=False) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
||||
def find_character_image(characters_dir: Path, slug: str) -> Optional[Path]:
|
||||
for ext in IMAGE_EXTENSIONS:
|
||||
candidate = characters_dir / f"{slug}{ext}"
|
||||
if candidate.exists():
|
||||
return candidate
|
||||
return None
|
||||
|
||||
|
||||
def ordered_character_payload(character: dict) -> dict:
|
||||
ordered: dict = {}
|
||||
for key in ("name", "slug", "dlc", "sizeBytes"):
|
||||
if key in character:
|
||||
ordered[key] = character[key]
|
||||
|
||||
for key, value in character.items():
|
||||
if key not in ordered:
|
||||
ordered[key] = value
|
||||
|
||||
return ordered
|
||||
|
||||
|
||||
def write_manifest(manifest_path: Path, manifest: dict) -> None:
|
||||
manifest_copy = dict(manifest)
|
||||
characters = manifest_copy.pop("characters", [])
|
||||
|
||||
base_json = json.dumps(manifest_copy, indent=2, ensure_ascii=False)
|
||||
if base_json.endswith("\n}"):
|
||||
base_json = base_json[:-2]
|
||||
elif base_json.endswith("}"):
|
||||
base_json = base_json[:-1]
|
||||
else:
|
||||
raise ValueError("Unexpected JSON format while writing manifest.")
|
||||
|
||||
if characters:
|
||||
character_lines = [
|
||||
" " + json.dumps(ordered_character_payload(character), ensure_ascii=False)
|
||||
for character in characters
|
||||
]
|
||||
characters_json = (
|
||||
' "characters": [\n'
|
||||
+ ",\n".join(character_lines)
|
||||
+ "\n ]\n"
|
||||
+ "}"
|
||||
)
|
||||
else:
|
||||
characters_json = ' "characters": []\n}'
|
||||
|
||||
manifest_path.write_text(
|
||||
base_json + ",\n" + characters_json + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
||||
def select_pack(packs: list[dict]) -> Optional[dict]:
|
||||
print("\nAvailable packs:\n")
|
||||
for index, pack in enumerate(packs, start=1):
|
||||
print(f"{index}. {pack['name']} ({pack['id']})")
|
||||
|
||||
raw = input("\nSelect pack number: ").strip()
|
||||
try:
|
||||
selected_index = int(raw) - 1
|
||||
except ValueError:
|
||||
print("\n❌ Invalid number")
|
||||
return None
|
||||
|
||||
if selected_index < 0 or selected_index >= len(packs):
|
||||
print("\n❌ Invalid selection")
|
||||
return None
|
||||
|
||||
return packs[selected_index]
|
||||
|
||||
|
||||
def update_pack(root: Path, registry: dict, selected_pack: dict) -> None:
|
||||
pack_dir = root / selected_pack["id"]
|
||||
manifest_path = pack_dir / "manifest.json"
|
||||
characters_dir = pack_dir / "characters"
|
||||
|
||||
if not manifest_path.exists():
|
||||
print("\n❌ manifest.json not found")
|
||||
return
|
||||
|
||||
if not characters_dir.exists():
|
||||
print("\n❌ characters folder not found")
|
||||
return
|
||||
|
||||
manifest = load_json(manifest_path)
|
||||
characters = manifest.get("characters", [])
|
||||
|
||||
print(f'\nUpdating "{manifest["name"]}"...\n')
|
||||
|
||||
total_size_bytes = 0
|
||||
valid_character_count = 0
|
||||
|
||||
for character in characters:
|
||||
slug = character["slug"]
|
||||
image_path = find_character_image(characters_dir, slug)
|
||||
|
||||
if image_path is None:
|
||||
character["sizeBytes"] = 0
|
||||
print(f"⚠ Missing image for {slug}")
|
||||
continue
|
||||
|
||||
size = image_path.stat().st_size
|
||||
character["sizeBytes"] = size
|
||||
total_size_bytes += size
|
||||
valid_character_count += 1
|
||||
|
||||
print(f"✓ {slug} -> {format_bytes(size)}")
|
||||
|
||||
registry_pack = next(
|
||||
(pack for pack in registry.get("packs", []) if pack["id"] == manifest["id"]),
|
||||
None,
|
||||
)
|
||||
|
||||
if registry_pack is None:
|
||||
print("\n❌ Pack not found in registry")
|
||||
return
|
||||
|
||||
registry_pack["totalSizeBytes"] = total_size_bytes
|
||||
registry_pack["characterCount"] = valid_character_count
|
||||
registry["updatedAt"] = datetime.now().strftime("%Y-%m-%d")
|
||||
|
||||
write_manifest(manifest_path, manifest)
|
||||
save_json(root / REGISTRY_FILENAME, registry)
|
||||
|
||||
print("\n✅ Done!\n")
|
||||
print(f"Characters: {valid_character_count}")
|
||||
print(f"Total size: {format_bytes(total_size_bytes)} ({total_size_bytes} bytes)")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
root = Path(__file__).parent.resolve()
|
||||
registry_path = root / REGISTRY_FILENAME
|
||||
|
||||
if not registry_path.exists():
|
||||
print("❌ registry.json not found")
|
||||
return
|
||||
|
||||
registry = load_json(registry_path)
|
||||
packs = registry.get("packs", [])
|
||||
|
||||
if not packs:
|
||||
print("❌ No packs found in registry")
|
||||
return
|
||||
|
||||
selected_pack = select_pack(packs)
|
||||
if selected_pack is None:
|
||||
return
|
||||
|
||||
update_pack(root, registry, selected_pack)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user