103 lines
3.3 KiB
Python
103 lines
3.3 KiB
Python
"""Configuration and persistence for the Excommunicado bot."""
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Any, Dict, Optional
|
|
|
|
DATA_DIR = Path(__file__).parent.parent / "data"
|
|
CONFIG_FILE = DATA_DIR / "xcom_config.json"
|
|
|
|
|
|
def _ensure_data_dir() -> None:
|
|
DATA_DIR.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
def load_config() -> Dict[str, Any]:
|
|
"""Load the entire config dict."""
|
|
_ensure_data_dir()
|
|
if not CONFIG_FILE.exists():
|
|
save_config({})
|
|
return {}
|
|
with open(CONFIG_FILE, "r", encoding="utf-8") as f:
|
|
return json.load(f)
|
|
|
|
|
|
def save_config(data: Dict[str, Any]) -> None:
|
|
"""Save the config dict."""
|
|
_ensure_data_dir()
|
|
with open(CONFIG_FILE, "w", encoding="utf-8") as f:
|
|
json.dump(data, f, indent=2, ensure_ascii=False)
|
|
|
|
|
|
def get_guild_data(guild_id: int) -> Dict[str, Any]:
|
|
"""Get or initialize data for a specific guild."""
|
|
config = load_config()
|
|
gid = str(guild_id)
|
|
if gid not in config:
|
|
config[gid] = {
|
|
"xcom_role_id": None,
|
|
"xcom_channel_id": None,
|
|
"isolated_users": {} # user_id -> {"reason": str, "timestamp": str}
|
|
}
|
|
save_config(config)
|
|
return config[gid]
|
|
|
|
|
|
def update_guild_data(guild_id: int, key: str, value: Any) -> None:
|
|
"""Update a top-level key for the guild."""
|
|
config = load_config()
|
|
gid = str(guild_id)
|
|
if gid not in config:
|
|
config[gid] = {
|
|
"xcom_role_id": None,
|
|
"xcom_channel_id": None,
|
|
"isolated_users": {}
|
|
}
|
|
config[gid][key] = value
|
|
save_config(config)
|
|
|
|
|
|
def add_isolated_user(guild_id: int, user_id: int, reason: str, timestamp: str) -> None:
|
|
"""Record a newly isolated user (shared xcom-lounge channel)."""
|
|
config = load_config()
|
|
gid = str(guild_id)
|
|
if gid not in config:
|
|
config[gid] = {"xcom_role_id": None, "xcom_channel_id": None, "isolated_users": {}}
|
|
config[gid]["isolated_users"][str(user_id)] = {
|
|
"reason": reason,
|
|
"timestamp": timestamp,
|
|
"absolution_points": 0,
|
|
"marked": True
|
|
}
|
|
save_config(config)
|
|
|
|
|
|
def increment_absolution_points(guild_id: int, user_id: int, amount: int = 1) -> int:
|
|
"""Increase absolution points for a user and return the new total."""
|
|
config = load_config()
|
|
gid = str(guild_id)
|
|
uid = str(user_id)
|
|
if gid in config and uid in config[gid].get("isolated_users", {}):
|
|
current = config[gid]["isolated_users"][uid].get("absolution_points", 0)
|
|
new_total = current + amount
|
|
config[gid]["isolated_users"][uid]["absolution_points"] = new_total
|
|
save_config(config)
|
|
return new_total
|
|
return 0
|
|
|
|
|
|
def remove_isolated_user(guild_id: int, user_id: int) -> Optional[Dict]:
|
|
"""Remove user from isolation record and return previous data or None."""
|
|
config = load_config()
|
|
gid = str(guild_id)
|
|
if gid in config and str(user_id) in config[gid].get("isolated_users", {}):
|
|
data = config[gid]["isolated_users"].pop(str(user_id))
|
|
save_config(config)
|
|
return data
|
|
return None
|
|
|
|
|
|
def get_isolated_users(guild_id: int) -> Dict[str, Dict]:
|
|
"""Return all isolated users for guild."""
|
|
data = get_guild_data(guild_id)
|
|
return data.get("isolated_users", {})
|