Adds list-import tooling, expands romhack-import for PC variants and patch batches, and syncs catalog with 2026-06-23 valhalla placements (Vanguard, Xenoverse, GBA patches, Infinity 3.3.1).
125 lines
5.5 KiB
Python
125 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Create vault notes for list-import hacks missing from catalog."""
|
|
import json, re, textwrap, unicodedata
|
|
from datetime import date
|
|
from pathlib import Path
|
|
|
|
VAULT = Path(r"C:\Users\MattC\Documents\Obsidian Vault\Pokémon ROM Hacks\Hacks")
|
|
CATALOG = Path(__file__).resolve().parents[1] / "wiki" / "catalog.json"
|
|
|
|
NEW = [
|
|
("Alchemist", "GBA", "FireRed", "Complete", "https://www.pokecommunity.com/threads/pokémon-alchemist.378280/"),
|
|
("Concealed", "PC", None, "Complete", "https://www.pokecommunity.com/threads/concealed.527325/"),
|
|
("Consonancia", "PC", None, "Complete", "https://www.pokecommunity.com/threads/pokémon-consonancia-full-game.537329/"),
|
|
("Crown", "PC", None, "Ongoing", "https://www.pokecommunity.com/threads/pokémon-crown.463821/"),
|
|
("Eon Guardians", "GBA", "Emerald", "Complete", "https://www.pokecommunity.com/threads/pokémon-eon-guardians.527913/"),
|
|
("Fire Ash", "GBA", "FireRed", "Complete", "https://www.pokecommunity.com/threads/pokémon-fire-ash.399096/"),
|
|
("Floral Tempus", "GBA", "Emerald", "Complete", "https://www.pokecommunity.com/threads/pokémon-floral-tempus-ex-1-9-4-released-12-gym-badges-elite-4-champion.409175/"),
|
|
("Hero Legacy", "PC", None, "Complete", "https://www.pokecommunity.com/threads/pokémon-hero-legacy-eng-de-now-with-new-game-mode.538518/"),
|
|
("HGSS Sevii", "NDS", "HeartGold", "Complete", "https://www.pokecommunity.com/threads/pokémon-hgss-sevii-islands-hoenn-postgame.434636/"),
|
|
("Itinerant", "GBA", "FireRed", "Ongoing", "https://www.pokecommunity.com/threads/pokemon-itinerant.528218/"),
|
|
("Jam Festival", "PC", None, "Complete", "https://www.pokecommunity.com/threads/pkmn-jam-festival.536702/"),
|
|
("Legends of the Arena", "GBA", "Emerald", "Complete", "https://www.pokecommunity.com/threads/pokémon-legends-of-the-arena.298738/"),
|
|
("Mega Adventures", "GBA", "Ruby", "Complete", "https://www.pokecommunity.com/threads/pokemon-mega-adventure.362058/"),
|
|
("Nightmare", "PC", None, "Complete", "https://www.pokecommunity.com/threads/pokémon-nightmare.504856/"),
|
|
("Poketale", "PC", None, "Complete", "https://www.mediafire.com/file/n6yzxnclf2uys7c/Poketale.zip/file"),
|
|
("Relict", "PC", None, "Complete", "https://phiongames.blogspot.com/2025/12/descarga-pokemon-relict.html"),
|
|
("Shattered Light", "PC", None, "Ongoing", "https://eeveeexpo.com/shattered-light/"),
|
|
("Sienna", "GBA", "Ruby", "Complete", "https://www.pokecommunity.com/threads/hack-of-the-year-2010-pokémon-sienna-complete-version-released.202372/"),
|
|
("Spades and Clubs", "GBA", "FireRed", "Beta", "https://senta-storage-system.neocities.org/patchrelease"),
|
|
("Tectonic", "PC", None, "Ongoing", "https://www.tectonic-game.com"),
|
|
("Vega Fairy EX", "GBA", "FireRed", "Complete", "https://www.pokecommunity.com/threads/pokemon-vega-fairy-edition-ex-minus-v1-4-balance-updates-and-skarmory-evo.475538/"),
|
|
]
|
|
|
|
UPDATES = {
|
|
"Coral": "roms/gbc/Hacks/Pokemon - Coral (Hack).gbc",
|
|
"Giratina Strikes Back": "roms/gba/Hacks/Pokemon - Giratina Strikes Back Full (Hack).gba",
|
|
}
|
|
|
|
|
|
def norm(s):
|
|
s = unicodedata.normalize("NFKD", s).encode("ascii", "ignore").decode().lower()
|
|
s = re.sub(r"^pokemon\s+", "", s)
|
|
return re.sub(r"[^a-z0-9]+", " ", s).strip()
|
|
|
|
|
|
def yaml_quote(s):
|
|
if s is None:
|
|
return '"—"'
|
|
if any(c in s for c in ':"\\#[]{}'):
|
|
return json.dumps(s)
|
|
return s
|
|
|
|
|
|
def note_body(title, source):
|
|
return textwrap.dedent(f"""\
|
|
# {title}
|
|
|
|
> [!info] From curated YouTube/pastebin list import (2026-06-23)
|
|
> Added to catalog from community recommendation lists. Download may be gated — see [[Wanted]].
|
|
|
|
## Summary
|
|
|
|
Surfaced from external recommendation lists (pastebin / Google Doc). Not yet in the RomM library unless noted in frontmatter.
|
|
|
|
## Links
|
|
|
|
- Info / thread: {source}
|
|
|
|
## In the library
|
|
|
|
> [!note] See `library_path` in frontmatter.
|
|
|
|
[[Index|← back to directory]]
|
|
""")
|
|
|
|
|
|
def patch_library_path(path: Path, lp: str):
|
|
text = path.read_text(encoding="utf-8")
|
|
text = re.sub(r"^library_path:.*$", f'library_path: "{lp}"', text, count=1, flags=re.M)
|
|
path.write_text(text, encoding="utf-8")
|
|
|
|
|
|
def main():
|
|
existing = {norm(p.stem) for p in VAULT.glob("*.md")}
|
|
today = date.today().isoformat()
|
|
created = []
|
|
for name, platform, base, status, source in NEW:
|
|
if norm(name) in existing:
|
|
continue
|
|
title = f"Pokémon {name}"
|
|
tags = ["hack", f"platform/{platform.lower()}", f"status/{status.lower().replace(' ', '-')}"]
|
|
if base:
|
|
tags.append(f"base/{base.lower().replace(' ', '-')}")
|
|
fm = [
|
|
"---",
|
|
f"title: {title}",
|
|
f'platform: {platform}',
|
|
f'base: {base or "—"}',
|
|
'version: "—"',
|
|
f"status: {status}",
|
|
"type: [New Experience]",
|
|
'generation: "—"',
|
|
'library_path: "—"',
|
|
f"source: {json.dumps(source)}",
|
|
f"added: {today}",
|
|
"play_status: Unplayed",
|
|
"tags:",
|
|
]
|
|
fm += [f" - {t}" for t in tags]
|
|
fm.append("---")
|
|
body = note_body(title, source)
|
|
out = VAULT / f"{name}.md"
|
|
out.write_text("\n".join(fm) + "\n" + body, encoding="utf-8")
|
|
created.append(name)
|
|
for stem, lp in UPDATES.items():
|
|
p = VAULT / f"{stem}.md"
|
|
if p.exists():
|
|
patch_library_path(p, lp)
|
|
print(f"Created {len(created)} notes: {', '.join(created)}")
|
|
print(f"Updated library_path: {', '.join(UPDATES)}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|