import toml import glob from typing import Optional from httpx import AsyncClient import asyncio try: with open("modinfo.toml", "r") as fp: modinfo = toml.load(fp) except OSError: modinfo = { "mods": {}, "categories": {} } mods = {} name_list: list[str] = [] for filename in glob.glob("mods/*.pw.toml"): modname = filename.removesuffix(".pw.toml").split("/", 1)[1] with open(filename, "r") as fp: mod = mods[modname] = toml.load(fp) modinfo["mods"].setdefault(modname, {}) link: Optional[str] = None if "modrinth" in mod["update"]: link = f"https://modrinth.com/mod/{modname}" for k, v in { "name": mod["name"], "description": "XXX: update", "link": link, "side": mod.get("side", "unknown"), "optional": mod.get("option", {}).get("optional", False) }.items(): modinfo["mods"][modname].setdefault(k, v) if modinfo["mods"][modname]["description"] == "XXX: update" or modinfo["mods"][modname].get("icon") is None: name_list.append(modname) async def fetch_description(modname: str) -> tuple[str, dict]: async with AsyncClient(headers={ "User-Agent": "Packwiz-Description-Generator/1.0 (hatkidchan@gmail.com)" }) as c: print(f"[ + ] GET {modname}") try: d = await c.get(f"https://api.modrinth.com/v2/project/{modname}") data = d.json() except Exception: return modname, {} return modname, data async def update_descriptions(): result = await asyncio.gather(*[ fetch_description(modname) for modname in name_list ]) for modname, data in result: modinfo["mods"][modname]["description"] = data.get("description", "") modinfo["mods"][modname]["icon"] = data.get("icon_url", "") asyncio.run(update_descriptions()) categories: dict[str, list] = {} for modname in modinfo["mods"]: if modname not in mods: modinfo["mods"][modname]["removed"] = True info = modinfo["mods"][modname] if info.get("icon", "") == "": print(f"[W] No icon set for {modname}") category = info.get("category", "unset") categories.setdefault(category, []) categories[category].append(modname) modinfo.setdefault("categories", {}) for catname, category in categories.items(): modinfo["categories"].setdefault(catname, {}) for k, v in { "title": catname, "description": "" }.items(): modinfo["categories"][catname].setdefault(k, v) with open("modinfo.toml", "w") as fp: toml.dump(modinfo, fp) with open("README.md", "w") as fp: try: with open("README.pre", "r") as fp_in: for line in fp_in: fp.write(line) except Exception as e: pass fp.write("# Mods list\n") for catname, modlist in categories.items(): catinfo = modinfo["categories"][catname] fp.write(f"## {catinfo['title']}\n") fp.write(catinfo["description"] + "\n") for modname in sorted(modlist): info = modinfo["mods"][modname] if info.get("removed"): continue tags = [] if info.get("optional", False): tags.append(("O", "optional")) side = info.get("side", "unknown") if side == "client": tags.append(("CO", "side:client")) elif side == "server": tags.append(("SO", "side:server")) elif side == "both": tags.append(("CS", "side:both")) try: fp.write(" * ") fp.write(f'') fp.write(str.join("", [ f"[{tag[0]}]" for tag in tags ])) fp.write(f" **[{info['name']}]({info['link']})**") fp.write(f" - {info['description']}\n") except Exception as e: print(f"Err: {e!r} for {modname = }") raise