refactor: split api.py monolith into 19 route modules (Phase B)
Split 3,598-line api.py into thin orchestrator (128 lines) + 19 route
modules in bot/routes/:
core.py (7 routes), mood.py (10), language.py (3), evil_mode.py (6),
bipolar_mode.py (9), gpu.py (2), bot_actions.py (4), autonomous.py (13),
profile_picture.py (26), manual_send.py (3), servers.py (6),
figurines.py (5), dms.py (18), image_generation.py (4), chat.py (1),
config.py (7), logging_config.py (9), voice.py (3), memory.py (10)
All 146 routes verified present via test_route_split.py (149 tests).
21/21 regression tests (test_config_state.py) pass.
Monolith backup: bot/api_monolith_backup.py (revert: cp it to api.py).
2026-04-15 11:38:14 +03:00
|
|
|
"""Evil mode routes."""
|
|
|
|
|
|
|
|
|
|
from fastapi import APIRouter
|
2026-04-15 15:43:18 +03:00
|
|
|
from fastapi.responses import JSONResponse
|
refactor: split api.py monolith into 19 route modules (Phase B)
Split 3,598-line api.py into thin orchestrator (128 lines) + 19 route
modules in bot/routes/:
core.py (7 routes), mood.py (10), language.py (3), evil_mode.py (6),
bipolar_mode.py (9), gpu.py (2), bot_actions.py (4), autonomous.py (13),
profile_picture.py (26), manual_send.py (3), servers.py (6),
figurines.py (5), dms.py (18), image_generation.py (4), chat.py (1),
config.py (7), logging_config.py (9), voice.py (3), memory.py (10)
All 146 routes verified present via test_route_split.py (149 tests).
21/21 regression tests (test_config_state.py) pass.
Monolith backup: bot/api_monolith_backup.py (revert: cp it to api.py).
2026-04-15 11:38:14 +03:00
|
|
|
import globals
|
|
|
|
|
from routes.models import EvilMoodSetRequest
|
|
|
|
|
from utils.logger import get_logger
|
|
|
|
|
|
|
|
|
|
logger = get_logger('api')
|
|
|
|
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/evil-mode")
|
|
|
|
|
def get_evil_mode_status():
|
|
|
|
|
"""Get current evil mode status"""
|
|
|
|
|
from utils.evil_mode import is_evil_mode, get_current_evil_mood
|
|
|
|
|
evil_mode = is_evil_mode()
|
|
|
|
|
if evil_mode:
|
|
|
|
|
mood, mood_desc = get_current_evil_mood()
|
|
|
|
|
return {
|
|
|
|
|
"evil_mode": True,
|
|
|
|
|
"mood": mood,
|
|
|
|
|
"description": mood_desc,
|
|
|
|
|
"available_moods": globals.EVIL_AVAILABLE_MOODS
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
"evil_mode": False,
|
|
|
|
|
"mood": None,
|
|
|
|
|
"description": None,
|
|
|
|
|
"available_moods": globals.EVIL_AVAILABLE_MOODS
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/evil-mode/enable")
|
|
|
|
|
def enable_evil_mode():
|
|
|
|
|
"""Enable evil mode"""
|
|
|
|
|
from utils.evil_mode import apply_evil_mode_changes
|
|
|
|
|
|
|
|
|
|
if globals.EVIL_MODE:
|
|
|
|
|
return {"status": "ok", "message": "Evil mode is already enabled", "evil_mode": True}
|
|
|
|
|
|
|
|
|
|
if globals.client and globals.client.loop and globals.client.loop.is_running():
|
|
|
|
|
globals.client.loop.create_task(apply_evil_mode_changes(globals.client))
|
|
|
|
|
return {"status": "ok", "message": "Evil mode enabled", "evil_mode": True}
|
|
|
|
|
else:
|
2026-04-15 15:43:18 +03:00
|
|
|
return JSONResponse(status_code=503, content={"status": "error", "message": "Discord client not ready"})
|
refactor: split api.py monolith into 19 route modules (Phase B)
Split 3,598-line api.py into thin orchestrator (128 lines) + 19 route
modules in bot/routes/:
core.py (7 routes), mood.py (10), language.py (3), evil_mode.py (6),
bipolar_mode.py (9), gpu.py (2), bot_actions.py (4), autonomous.py (13),
profile_picture.py (26), manual_send.py (3), servers.py (6),
figurines.py (5), dms.py (18), image_generation.py (4), chat.py (1),
config.py (7), logging_config.py (9), voice.py (3), memory.py (10)
All 146 routes verified present via test_route_split.py (149 tests).
21/21 regression tests (test_config_state.py) pass.
Monolith backup: bot/api_monolith_backup.py (revert: cp it to api.py).
2026-04-15 11:38:14 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/evil-mode/disable")
|
|
|
|
|
def disable_evil_mode():
|
|
|
|
|
"""Disable evil mode"""
|
|
|
|
|
from utils.evil_mode import revert_evil_mode_changes
|
|
|
|
|
|
|
|
|
|
if not globals.EVIL_MODE:
|
|
|
|
|
return {"status": "ok", "message": "Evil mode is already disabled", "evil_mode": False}
|
|
|
|
|
|
|
|
|
|
if globals.client and globals.client.loop and globals.client.loop.is_running():
|
|
|
|
|
globals.client.loop.create_task(revert_evil_mode_changes(globals.client))
|
|
|
|
|
return {"status": "ok", "message": "Evil mode disabled", "evil_mode": False}
|
|
|
|
|
else:
|
2026-04-15 15:43:18 +03:00
|
|
|
return JSONResponse(status_code=503, content={"status": "error", "message": "Discord client not ready"})
|
refactor: split api.py monolith into 19 route modules (Phase B)
Split 3,598-line api.py into thin orchestrator (128 lines) + 19 route
modules in bot/routes/:
core.py (7 routes), mood.py (10), language.py (3), evil_mode.py (6),
bipolar_mode.py (9), gpu.py (2), bot_actions.py (4), autonomous.py (13),
profile_picture.py (26), manual_send.py (3), servers.py (6),
figurines.py (5), dms.py (18), image_generation.py (4), chat.py (1),
config.py (7), logging_config.py (9), voice.py (3), memory.py (10)
All 146 routes verified present via test_route_split.py (149 tests).
21/21 regression tests (test_config_state.py) pass.
Monolith backup: bot/api_monolith_backup.py (revert: cp it to api.py).
2026-04-15 11:38:14 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/evil-mode/toggle")
|
|
|
|
|
def toggle_evil_mode():
|
|
|
|
|
"""Toggle evil mode on/off"""
|
|
|
|
|
from utils.evil_mode import apply_evil_mode_changes, revert_evil_mode_changes
|
|
|
|
|
|
|
|
|
|
if not globals.client or not globals.client.loop or not globals.client.loop.is_running():
|
2026-04-15 15:43:18 +03:00
|
|
|
return JSONResponse(status_code=503, content={"status": "error", "message": "Discord client not ready"})
|
refactor: split api.py monolith into 19 route modules (Phase B)
Split 3,598-line api.py into thin orchestrator (128 lines) + 19 route
modules in bot/routes/:
core.py (7 routes), mood.py (10), language.py (3), evil_mode.py (6),
bipolar_mode.py (9), gpu.py (2), bot_actions.py (4), autonomous.py (13),
profile_picture.py (26), manual_send.py (3), servers.py (6),
figurines.py (5), dms.py (18), image_generation.py (4), chat.py (1),
config.py (7), logging_config.py (9), voice.py (3), memory.py (10)
All 146 routes verified present via test_route_split.py (149 tests).
21/21 regression tests (test_config_state.py) pass.
Monolith backup: bot/api_monolith_backup.py (revert: cp it to api.py).
2026-04-15 11:38:14 +03:00
|
|
|
|
|
|
|
|
if globals.EVIL_MODE:
|
|
|
|
|
globals.client.loop.create_task(revert_evil_mode_changes(globals.client))
|
|
|
|
|
return {"status": "ok", "message": "Evil mode disabled", "evil_mode": False}
|
|
|
|
|
else:
|
|
|
|
|
globals.client.loop.create_task(apply_evil_mode_changes(globals.client))
|
|
|
|
|
return {"status": "ok", "message": "Evil mode enabled", "evil_mode": True}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/evil-mode/mood")
|
|
|
|
|
def get_evil_mood():
|
|
|
|
|
"""Get current evil mood"""
|
|
|
|
|
from utils.evil_mode import get_current_evil_mood
|
|
|
|
|
mood, mood_desc = get_current_evil_mood()
|
|
|
|
|
return {
|
|
|
|
|
"mood": mood,
|
|
|
|
|
"description": mood_desc,
|
|
|
|
|
"available_moods": globals.EVIL_AVAILABLE_MOODS
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/evil-mode/mood")
|
|
|
|
|
def set_evil_mood_endpoint(data: EvilMoodSetRequest):
|
|
|
|
|
"""Set evil mood"""
|
|
|
|
|
from utils.evil_mode import set_evil_mood, is_valid_evil_mood, update_all_evil_nicknames
|
|
|
|
|
|
|
|
|
|
if not is_valid_evil_mood(data.mood):
|
2026-04-15 15:43:18 +03:00
|
|
|
return JSONResponse(status_code=400, content={
|
refactor: split api.py monolith into 19 route modules (Phase B)
Split 3,598-line api.py into thin orchestrator (128 lines) + 19 route
modules in bot/routes/:
core.py (7 routes), mood.py (10), language.py (3), evil_mode.py (6),
bipolar_mode.py (9), gpu.py (2), bot_actions.py (4), autonomous.py (13),
profile_picture.py (26), manual_send.py (3), servers.py (6),
figurines.py (5), dms.py (18), image_generation.py (4), chat.py (1),
config.py (7), logging_config.py (9), voice.py (3), memory.py (10)
All 146 routes verified present via test_route_split.py (149 tests).
21/21 regression tests (test_config_state.py) pass.
Monolith backup: bot/api_monolith_backup.py (revert: cp it to api.py).
2026-04-15 11:38:14 +03:00
|
|
|
"status": "error",
|
|
|
|
|
"message": f"Mood '{data.mood}' not recognized. Available evil moods: {', '.join(globals.EVIL_AVAILABLE_MOODS)}"
|
2026-04-15 15:43:18 +03:00
|
|
|
})
|
refactor: split api.py monolith into 19 route modules (Phase B)
Split 3,598-line api.py into thin orchestrator (128 lines) + 19 route
modules in bot/routes/:
core.py (7 routes), mood.py (10), language.py (3), evil_mode.py (6),
bipolar_mode.py (9), gpu.py (2), bot_actions.py (4), autonomous.py (13),
profile_picture.py (26), manual_send.py (3), servers.py (6),
figurines.py (5), dms.py (18), image_generation.py (4), chat.py (1),
config.py (7), logging_config.py (9), voice.py (3), memory.py (10)
All 146 routes verified present via test_route_split.py (149 tests).
21/21 regression tests (test_config_state.py) pass.
Monolith backup: bot/api_monolith_backup.py (revert: cp it to api.py).
2026-04-15 11:38:14 +03:00
|
|
|
|
|
|
|
|
success = set_evil_mood(data.mood)
|
|
|
|
|
if success:
|
|
|
|
|
# Update nicknames if evil mode is active
|
|
|
|
|
if globals.EVIL_MODE and globals.client and globals.client.loop and globals.client.loop.is_running():
|
|
|
|
|
globals.client.loop.create_task(update_all_evil_nicknames(globals.client))
|
|
|
|
|
return {"status": "ok", "new_mood": data.mood}
|
|
|
|
|
|
2026-04-15 15:43:18 +03:00
|
|
|
return JSONResponse(status_code=500, content={"status": "error", "message": "Failed to set evil mood"})
|