Initial implementation of IRC LLM bot
Full implementation from spec: ZNC/IRC client with TLS, Ollama LLM backend, per-user SQLite conversation memory, and Flask web admin portal with 7 pages. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
68
portal/config_manager.py
Normal file
68
portal/config_manager.py
Normal file
@@ -0,0 +1,68 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import signal
|
||||
import socket
|
||||
import sys
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
CONFIG_PATH = "config/config.json"
|
||||
PID_PATH = "data/ircbot.pid"
|
||||
SOCK_PATH = "data/ircbot.sock"
|
||||
|
||||
|
||||
def load_config() -> dict:
|
||||
if not os.path.exists(CONFIG_PATH):
|
||||
return {}
|
||||
with open(CONFIG_PATH, "r") as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def save_config(cfg: dict) -> None:
|
||||
os.makedirs("config", exist_ok=True)
|
||||
with open(CONFIG_PATH, "w") as f:
|
||||
json.dump(cfg, f, indent=2)
|
||||
logger.info("[CONFIG] Saved config.json")
|
||||
|
||||
|
||||
def signal_bot_reload() -> bool:
|
||||
"""Signal bot to reload config. Returns True on success."""
|
||||
# Try Unix socket first (Docker mode)
|
||||
if sys.platform != "win32" and os.path.exists(SOCK_PATH):
|
||||
try:
|
||||
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
s.connect(SOCK_PATH)
|
||||
s.sendall(b"RELOAD")
|
||||
s.close()
|
||||
logger.info("[CONFIG] Sent RELOAD via Unix socket")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(f"[CONFIG] Socket reload failed: {e}")
|
||||
|
||||
# Fall back to SIGHUP
|
||||
if sys.platform != "win32" and os.path.exists(PID_PATH):
|
||||
try:
|
||||
with open(PID_PATH) as f:
|
||||
pid = int(f.read().strip())
|
||||
os.kill(pid, signal.SIGHUP)
|
||||
logger.info(f"[CONFIG] Sent SIGHUP to PID {pid}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(f"[CONFIG] SIGHUP failed: {e}")
|
||||
|
||||
logger.warning("[CONFIG] Could not signal bot (no socket or PID available)")
|
||||
return False
|
||||
|
||||
|
||||
def signal_bot_reconnect() -> bool:
|
||||
if sys.platform != "win32" and os.path.exists(SOCK_PATH):
|
||||
try:
|
||||
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
s.connect(SOCK_PATH)
|
||||
s.sendall(b"RECONNECT")
|
||||
s.close()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(f"[CONFIG] Reconnect signal failed: {e}")
|
||||
return False
|
||||
Reference in New Issue
Block a user