Files

212 lines
7.1 KiB
Python
Raw Permalink Normal View History

2026-03-11 23:24:42 +00:00
"""
Wiki Configuration Manager - Fetches post templates and titles from subreddit wiki
"""
import time
import json
import re
import yaml
from typing import Dict, Optional, Tuple
2026-03-12 21:45:01 +00:00
import config
2026-03-11 23:24:42 +00:00
# Cache TTL in seconds (refresh wiki config every 30 minutes)
WIKI_CACHE_TTL = 1800
class WikiConfig:
"""Manages post configurations loaded from subreddit wiki."""
def __init__(self):
self.configs: Dict[str, Dict[str, str]] = {}
self.default_config: Dict[str, str] = {"title": "", "body": ""}
self.last_updated = 0
self.reddit = None
self.subreddit_name = None
def init(self, reddit, subreddit_name: str):
"""Initialize the wiki config manager."""
self.reddit = reddit
self.subreddit_name = subreddit_name
def should_refresh(self) -> bool:
"""Check if cache has expired."""
return (time.time() - self.last_updated) >= WIKI_CACHE_TTL
def fetch_from_wiki(self) -> bool:
"""
Fetch post configurations from subreddit wiki.
Wiki page format (YAML):
```yaml
release:
title: "Minecraft {version} Released!"
body: |
# Minecraft {version} Released
A new version of Minecraft is available!
**Version:** {version}
**Date:** {release_date}
Get it now at [minecraft.net](https://minecraft.net)
snapshot:
title: "Minecraft {version} Snapshot Available"
body: |
# Minecraft {version} Snapshot
A new snapshot is available for testing!
**Version:** {version}
**Date:** {release_date}
Try it in the launcher!
default:
title: "Minecraft {version} ({type})"
body: |
New {type}: {version}
Released: {release_date}
```
Returns:
True if successful, False otherwise
"""
try:
subreddit = self.reddit.subreddit(self.subreddit_name)
2026-03-12 21:45:01 +00:00
print(f"[WIKI_CONFIG] Attempting to fetch wiki page: {config.WIKI_PAGE_NAME}")
# Try the wiki page with the configured name
wiki_page = subreddit.wiki[config.WIKI_PAGE_NAME]
2026-03-11 23:24:42 +00:00
content = wiki_page.content_md
self.configs = self._parse_yaml_content(content)
self.last_updated = time.time()
if self.configs:
print(f"[WIKI_CONFIG] ✓ Loaded {len(self.configs)} configuration(s)")
for release_type in self.configs:
print(f" - {release_type}")
return True
else:
print("[WIKI_CONFIG] ⚠ No configurations found in wiki")
return False
except Exception as e:
2026-03-12 21:45:01 +00:00
print(f"[WIKI_CONFIG] ✗ Error fetching wiki page '{config.WIKI_PAGE_NAME}' from r/{self.subreddit_name}: {e}")
print(f"[WIKI_CONFIG] ⚠ Check that the page exists at reddit.com/r/{self.subreddit_name}/wiki/{config.WIKI_PAGE_NAME}")
2026-03-11 23:24:42 +00:00
return False
def _parse_yaml_content(self, content: str) -> Dict[str, Dict[str, str]]:
"""
Parse YAML content into configuration dict.
Expected format:
```yaml
release:
title: "Minecraft {version} Released!"
body: |
Multi-line post body
with {placeholders}
snapshot:
title: "Minecraft {version} Snapshot"
body: |
Snapshot post body
```
Returns:
Dict mapping release_type -> {"title": str, "body": str}
"""
try:
data = yaml.safe_load(content)
if not isinstance(data, dict):
print("[WIKI_CONFIG] ✗ Wiki content is not valid YAML dictionary")
return {}
configs = {}
for release_type, config in data.items():
if isinstance(config, dict):
if "title" in config and "body" in config:
configs[release_type.lower()] = {
"title": str(config["title"]),
"body": str(config["body"])
}
else:
print(f"[WIKI_CONFIG] ⚠ Missing 'title' or 'body' for {release_type}")
return configs
except yaml.YAMLError as e:
print(f"[WIKI_CONFIG] ✗ YAML parsing error: {e}")
return {}
def get_config(self, release_type: str, refresh: bool = False) -> Tuple[str, str]:
"""
Get title and body template for a release type.
Args:
release_type: Type like "release" or "snapshot"
refresh: Force refresh from wiki
Returns:
Tuple of (title_template, body_template)
"""
# Refresh if needed
if refresh or self.should_refresh() or not self.configs:
self.fetch_from_wiki()
# Get config for this type, fall back to any available config
if release_type in self.configs:
config = self.configs[release_type]
return config["title"], config["body"]
# Try generic "default" config
if "default" in self.configs:
config = self.configs["default"]
return config["title"], config["body"]
# Fall back to hardcoded defaults
default_title = "Minecraft {version} Released!"
default_body = """# Minecraft {version}
A new version is available!
**Version:** {version}
**Released:** {release_date}
Get it at [minecraft.net](https://minecraft.net)"""
return default_title, default_body
def format_post(self, release_type: str, version: str, release_date: str) -> Tuple[str, str]:
"""
Get formatted post title and body for a version.
Args:
release_type: Type like "release" or "snapshot"
version: Version string like "1.21"
release_date: Formatted date string
Returns:
Tuple of (formatted_title, formatted_body)
"""
title_template, body_template = self.get_config(release_type)
# Format with available placeholders
format_dict = {
"version": version,
"release_date": release_date,
"type": release_type
}
try:
formatted_title = title_template.format(**format_dict)
formatted_body = body_template.format(**format_dict)
return formatted_title, formatted_body
except KeyError as e:
print(f"[WIKI_CONFIG] ✗ Unknown placeholder in template: {e}")
# Fall back to defaults
formatted_title = f"Minecraft {version} ({release_type})"
formatted_body = f"New {release_type}: {version}\nReleased: {release_date}"
return formatted_title, formatted_body