initial
This commit is contained in:
+207
@@ -0,0 +1,207 @@
|
||||
"""
|
||||
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
|
||||
|
||||
# Cache TTL in seconds (refresh wiki config every 30 minutes)
|
||||
WIKI_CACHE_TTL = 1800
|
||||
WIKI_PAGE_NAME = "minecraft_update_bot"
|
||||
|
||||
|
||||
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)
|
||||
wiki_page = subreddit.wiki[WIKI_PAGE_NAME]
|
||||
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:
|
||||
print(f"[WIKI_CONFIG] ✗ Error fetching wiki: {e}")
|
||||
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
|
||||
Reference in New Issue
Block a user