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).
81 lines
3.0 KiB
Python
81 lines
3.0 KiB
Python
"""Figurine subscriber and send routes."""
|
|
|
|
from fastapi import APIRouter, Form
|
|
import globals
|
|
from utils.figurine_notifier import (
|
|
load_subscribers as figurine_load_subscribers,
|
|
add_subscriber as figurine_add_subscriber,
|
|
remove_subscriber as figurine_remove_subscriber,
|
|
send_figurine_dm_to_all_subscribers,
|
|
send_figurine_dm_to_single_user,
|
|
)
|
|
from utils.logger import get_logger
|
|
|
|
logger = get_logger('api')
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/figurines/subscribers")
|
|
async def get_figurine_subscribers():
|
|
subs = figurine_load_subscribers()
|
|
return {"subscribers": [str(uid) for uid in subs]}
|
|
|
|
|
|
@router.post("/figurines/subscribers")
|
|
async def add_figurine_subscriber(user_id: str = Form(...)):
|
|
try:
|
|
uid = int(user_id)
|
|
ok = figurine_add_subscriber(uid)
|
|
return {"status": "ok", "added": ok}
|
|
except Exception as e:
|
|
return {"status": "error", "message": str(e)}
|
|
|
|
|
|
@router.delete("/figurines/subscribers/{user_id}")
|
|
async def delete_figurine_subscriber(user_id: str):
|
|
try:
|
|
uid = int(user_id)
|
|
ok = figurine_remove_subscriber(uid)
|
|
return {"status": "ok", "removed": ok}
|
|
except Exception as e:
|
|
return {"status": "error", "message": str(e)}
|
|
|
|
|
|
@router.post("/figurines/send_now")
|
|
async def figurines_send_now(tweet_url: str = Form(None)):
|
|
"""Trigger immediate figurine DM send to all subscribers, optionally with specific tweet URL"""
|
|
if globals.client and globals.client.loop and globals.client.loop.is_running():
|
|
logger.info(f"Sending figurine DMs to all subscribers, tweet_url: {tweet_url}")
|
|
globals.client.loop.create_task(send_figurine_dm_to_all_subscribers(globals.client, tweet_url=tweet_url))
|
|
return {"status": "ok", "message": "Figurine DMs queued"}
|
|
return {"status": "error", "message": "Bot not ready"}
|
|
|
|
|
|
@router.post("/figurines/send_to_user")
|
|
async def figurines_send_to_user(user_id: str = Form(...), tweet_url: str = Form(None)):
|
|
"""Send figurine DM to a specific user, optionally with specific tweet URL"""
|
|
logger.debug(f"Received figurine send request - user_id: '{user_id}', tweet_url: '{tweet_url}'")
|
|
|
|
if not globals.client or not globals.client.loop or not globals.client.loop.is_running():
|
|
logger.error("Bot not ready")
|
|
return {"status": "error", "message": "Bot not ready"}
|
|
|
|
try:
|
|
user_id_int = int(user_id)
|
|
logger.debug(f"Parsed user_id as {user_id_int}")
|
|
except ValueError:
|
|
logger.error(f"Invalid user ID: '{user_id}'")
|
|
return {"status": "error", "message": "Invalid user ID"}
|
|
|
|
# Clean up tweet URL if it's empty string
|
|
if tweet_url == "":
|
|
tweet_url = None
|
|
|
|
logger.info(f"Sending figurine DM to user {user_id_int}, tweet_url: {tweet_url}")
|
|
|
|
# Queue the DM send task in the bot's event loop
|
|
globals.client.loop.create_task(send_figurine_dm_to_single_user(globals.client, user_id_int, tweet_url=tweet_url))
|
|
|
|
return {"status": "ok", "message": f"Figurine DM to user {user_id} queued"}
|