From f3f75fd6222068881aebf381bdb83d83267b73a9 Mon Sep 17 00:00:00 2001 From: Alexander01998 Date: Wed, 15 Jan 2025 16:35:52 +0100 Subject: [PATCH] Refactor python scripts --- scripts/add_mod_port.py | 15 ++++--- scripts/announce_mod_update.py | 61 ++-------------------------- scripts/util.py | 73 +++++++++++++++++++++++++++++++--- 3 files changed, 80 insertions(+), 69 deletions(-) diff --git a/scripts/add_mod_port.py b/scripts/add_mod_port.py index 12e3ce8..456b3bb 100644 --- a/scripts/add_mod_port.py +++ b/scripts/add_mod_port.py @@ -26,12 +26,15 @@ def update_mod_post(mod, modloader, mod_version, mc_version): key=lambda v: version_info[v]["releaseTime"], reverse=True, ) - elif mc_version not in front_matter["mcversions"]: - front_matter["mcversions"].append(mc_version) - front_matter["mcversions"].sort( - key=lambda v: version_info[v]["releaseTime"], - reverse=True, - ) + else: + if "mcversions" not in front_matter: + front_matter["mcversions"] = [] + if mc_version not in front_matter["mcversions"]: + front_matter["mcversions"].append(mc_version) + front_matter["mcversions"].sort( + key=lambda v: version_info[v]["releaseTime"], + reverse=True, + ) if modloader == "neoforge": if "neoforge" not in front_matter: diff --git a/scripts/announce_mod_update.py b/scripts/announce_mod_update.py index 7ebe73a..7e861ff 100644 --- a/scripts/announce_mod_update.py +++ b/scripts/announce_mod_update.py @@ -1,19 +1,7 @@ import argparse -import json -import os -import requests import util -from dataclasses import dataclass from pathlib import Path -from util import HugoPost - - -@dataclass -class WurstForumDiscussion: - title: str - tags: list[int] - content: str - +from util import HugoPost, WurstForumDiscussion announcement_template = """ @"Everyone"#g7 {mod_name} {mod_version} is now available. Download it here: <{update_url}> @@ -24,18 +12,6 @@ class WurstForumDiscussion: """.strip() -def parse_changelog(content: str) -> str: - """Parse the changelog from the content of a Wurst update post.""" - changelog_lines = [] - for line in content[content.find("## Changelog") :].splitlines(): - stripped = line.strip() - if not stripped or stripped.startswith("-") or stripped.startswith("## Changelog"): - changelog_lines.append(line) - continue - break - return "\n".join(changelog_lines).strip() - - def create_announcement(mod_update: HugoPost) -> WurstForumDiscussion: """Create an announcement from a mod update post.""" # Title @@ -56,43 +32,14 @@ def create_announcement(mod_update: HugoPost) -> WurstForumDiscussion: title=title, mod_name=mod_name, mod_version=mod_version, - update_url=f"https://www.wimods.net/{mod}/{mod}-{mod_version.replace('.', '-')}/", + update_url=mod_update.get_update_url(), image_url=mod_update.front_matter["image"], - changelog=parse_changelog(mod_update.content), + changelog=util.parse_changelog(mod_update.content), ) return WurstForumDiscussion(title, list(tags.values()), content) -def upload_discussion(discussion: WurstForumDiscussion) -> int: - """Upload a new discussion to WurstForum and return its ID.""" - url = "https://wurstforum.net/api/discussions" - headers = {"Authorization": f"Token {os.getenv('WURSTFORUM_TOKEN')}"} - data = { - "data": { - "type": "discussions", - "attributes": { - "title": discussion.title, - "content": discussion.content, - }, - "relationships": { - "tags": { - "data": [{"type": "tags", "id": tag_id} for tag_id in discussion.tags], - }, - }, - }, - } - - print(f"Request data: {json.dumps(data, indent=2)}") - response = requests.post(url, headers=headers, json=data) - if not response.ok: - raise requests.HTTPError(f"Request failed (code {response.status_code}): {response.text}") - discussion_id = response.json().get("data", {}).get("id") - if not discussion_id: - raise ValueError(f"No discussion ID in response: {response.text}") - return discussion_id - - def main(mod, mod_version): hugo_post = util.find_mod_update_post(mod, mod_version) @@ -100,7 +47,7 @@ def main(mod, mod_version): print(f"Title: {announcement.title}") print(f"Content: {announcement.content}") - discussion_id = upload_discussion(announcement) + discussion_id = util.upload_discussion(announcement) print(f"https://wurstforum.net/d/{discussion_id}") util.set_github_output("discussion_id", discussion_id) diff --git a/scripts/util.py b/scripts/util.py index 5488cbd..9055f04 100644 --- a/scripts/util.py +++ b/scripts/util.py @@ -1,11 +1,13 @@ import json import os +import requests import tomli from dataclasses import dataclass from io import StringIO from pathlib import Path from ruamel.yaml import YAML from ruamel.yaml.comments import CommentedMap, CommentedSeq +from typing import Iterator yaml = YAML() yaml.preserve_quotes = True @@ -17,6 +19,18 @@ class HugoPost: content: str path: Path + def get_update_url(self) -> str: + mod = self.front_matter["mod"] + version = self.front_matter["modversion"] + return f"https://www.wimods.net/{mod}/{mod}-{version.replace('.', '-')}/" + + +@dataclass +class WurstForumDiscussion: + title: str + tags: list[int] + content: str + def read_post(path: Path) -> HugoPost: """Read front matter and content from a Jekyll/Hugo post.""" @@ -41,14 +55,17 @@ def write_front_matter(path: Path, front_matter: CommentedMap): path.write_text(new_content, encoding="utf-8", newline="\n") -def find_mod_update_post(mod: str, version: str) -> HugoPost: - """Find the mod update post for a specific version.""" +def get_mod_update_posts(mod: str) -> Iterator[Path]: + """Get all update post paths for the given mod.""" posts_folder = Path("content") / mod - version_slug = version.replace(".", "-") - for post_path in posts_folder.rglob(f"*-{version_slug}.md"): - if not post_path.is_file(): - continue + for post_path in posts_folder.rglob("*.md"): + if post_path.is_file() and post_path.name.lower().startswith(mod): + yield post_path + +def find_mod_update_post(mod: str, version: str) -> HugoPost: + """Find and read the mod update post for a specific version.""" + for post_path in get_mod_update_posts(mod): post = read_post(post_path) if post.front_matter.get("modversion") == version: return post @@ -56,6 +73,50 @@ def find_mod_update_post(mod: str, version: str) -> HugoPost: raise ValueError(f"Could not find post for mod {mod} version {version}") +def parse_changelog(content: str) -> str: + """Parse the changelog from the content of a mod update post.""" + changelog_lines = [] + for line in content[content.find("## Changelog") :].splitlines(): + stripped = line.strip() + if not stripped or stripped.startswith("-") or stripped.startswith("## Changelog"): + changelog_lines.append(line) + continue + break + return "\n".join(changelog_lines).strip() + + +def upload_discussion(discussion: WurstForumDiscussion, dry_run: bool = False) -> int: + """Upload a new discussion to WurstForum and return its ID.""" + url = "https://wurstforum.net/api/discussions" + headers = {"Authorization": f"Token {os.getenv('WURSTFORUM_TOKEN')}"} + data = { + "data": { + "type": "discussions", + "attributes": { + "title": discussion.title, + "content": discussion.content, + }, + "relationships": { + "tags": { + "data": [{"type": "tags", "id": tag_id} for tag_id in discussion.tags], + }, + }, + }, + } + + print(f"Request data: {json.dumps(data, indent=2)}") + if dry_run: + return 123 + + response = requests.post(url, headers=headers, json=data) + if not response.ok: + raise requests.HTTPError(f"Request failed (code {response.status_code}): {response.text}") + discussion_id = response.json().get("data", {}).get("id") + if not discussion_id: + raise ValueError(f"No discussion ID in response: {response.text}") + return discussion_id + + def read_yaml_file(path: Path) -> CommentedMap | CommentedSeq: """Read a YAML data file.""" return yaml.load(path.read_text(encoding="utf-8"))