Enhanced logging

This commit is contained in:
2026-01-28 13:00:15 -05:00
parent b5a4d84368
commit 1fbea7e701
2 changed files with 141 additions and 47 deletions

View File

@@ -1,7 +1,7 @@
#Faction data population and status management endpoints. #Faction data population and status management endpoints.
import json import json
from pathlib import Path from pathlib import Path
from fastapi import APIRouter from fastapi import APIRouter, Request, HTTPException
from models import FactionRequest from models import FactionRequest
from services.server_state import STATE from services.server_state import STATE
@@ -13,25 +13,101 @@ from services.torn_api import (
stop_friendly_status_loop, stop_friendly_status_loop,
stop_enemy_status_loop stop_enemy_status_loop
) )
from services.activity_log import activity_logger
from utils import load_json_list from utils import load_json_list
from utils.auth import get_current_user
router = APIRouter(prefix="/api", tags=["factions"]) router = APIRouter(prefix="/api", tags=["factions"])
@router.post("/populate_friendly") @router.post("/populate_friendly")
async def api_populate_friendly(data: FactionRequest): async def api_populate_friendly(request: Request, data: FactionRequest):
await populate_friendly(data.faction_id) # Get username for logging
# Return members list for frontend (already in STATE from populate_friendly) try:
members = [m.model_dump() for m in STATE.friendly.values()] user_info = get_current_user(request)
return {"status": "friendly populated", "id": data.faction_id, "members": members} username = user_info.get("username", "Unknown")
except:
username = "Unknown"
try:
await activity_logger.log_action(
username,
"Populate Friendly",
f"Starting population for faction {data.faction_id}"
)
result = await populate_friendly(data.faction_id)
if not result:
await activity_logger.log_action(
username,
"Populate Friendly Failed",
f"Failed to populate faction {data.faction_id} - API returned False (check API key, faction ID, or network)"
)
raise HTTPException(status_code=500, detail="Failed to populate friendly faction - check logs")
# Return members list for frontend (already in STATE from populate_friendly)
members = [m.model_dump() for m in STATE.friendly.values()]
await activity_logger.log_action(
username,
"Populate Friendly Success",
f"Populated {len(members)} members from faction {data.faction_id}"
)
return {"status": "friendly populated", "id": data.faction_id, "members": members}
except HTTPException:
raise
except Exception as e:
error_msg = f"Error populating friendly faction {data.faction_id}: {type(e).__name__}: {str(e)}"
await activity_logger.log_action(username, "Populate Friendly Error", error_msg)
raise HTTPException(status_code=500, detail=error_msg)
@router.post("/populate_enemy") @router.post("/populate_enemy")
async def api_populate_enemy(data: FactionRequest): async def api_populate_enemy(request: Request, data: FactionRequest):
await populate_enemy(data.faction_id) # Get username for logging
# Return members list for frontend (already in STATE from populate_enemy) try:
members = [m.model_dump() for m in STATE.enemy.values()] user_info = get_current_user(request)
return {"status": "enemy populated", "id": data.faction_id, "members": members} username = user_info.get("username", "Unknown")
except:
username = "Unknown"
try:
await activity_logger.log_action(
username,
"Populate Enemy",
f"Starting population for faction {data.faction_id}"
)
result = await populate_enemy(data.faction_id)
if not result:
await activity_logger.log_action(
username,
"Populate Enemy Failed",
f"Failed to populate faction {data.faction_id} - API returned False (check API key, faction ID, or network)"
)
raise HTTPException(status_code=500, detail="Failed to populate enemy faction - check logs")
# Return members list for frontend (already in STATE from populate_enemy)
members = [m.model_dump() for m in STATE.enemy.values()]
await activity_logger.log_action(
username,
"Populate Enemy Success",
f"Populated {len(members)} members from faction {data.faction_id}"
)
return {"status": "enemy populated", "id": data.faction_id, "members": members}
except HTTPException:
raise
except Exception as e:
error_msg = f"Error populating enemy faction {data.faction_id}: {type(e).__name__}: {str(e)}"
await activity_logger.log_action(username, "Populate Enemy Error", error_msg)
raise HTTPException(status_code=500, detail=error_msg)
@router.post("/start_friendly_status") @router.post("/start_friendly_status")

View File

@@ -23,45 +23,63 @@ async def populate_faction(faction_id: int, kind: str):
url = f"https://api.torn.com/v2/faction/{faction_id}?selections=members&key={TORN_API_KEY}" url = f"https://api.torn.com/v2/faction/{faction_id}?selections=members&key={TORN_API_KEY}"
async with aiohttp.ClientSession() as session: try:
async with session.get(url) as resp: async with aiohttp.ClientSession() as session:
if resp.status != 200: async with session.get(url) as resp:
print(f"Error fetching faction {faction_id}: {resp.status}") if resp.status != 200:
return False error_text = await resp.text()
data = await resp.json() print(f"[ERROR] Torn API returned {resp.status} for {kind} faction {faction_id}")
print(f"[ERROR] Response: {error_text[:200]}")
return False
data = await resp.json()
members_list = data.get("members", []) # Check for API error response
if not members_list: if "error" in data:
print(f"[ERROR] Torn API error for {kind} faction {faction_id}: {data['error']}")
return False
members_list = data.get("members", [])
if not members_list:
print(f"[ERROR] No members found in {kind} faction {faction_id}")
return False
member_ids = [m.get("id") for m in members_list if "id" in m]
if not member_ids:
print(f"[ERROR] No valid member IDs in {kind} faction {faction_id}")
return False
print(f"[INFO] Fetching FFScouter data for {len(member_ids)} members from {kind} faction {faction_id}")
# Fetch FFScouter estimates
ff_data = await fetch_batch_stats(member_ids)
received_ids = []
async with (friendly_lock if kind == "friendly" else enemy_lock):
for m in members_list:
pid = m["id"]
est = ff_data.get(str(pid), {}).get("bs_estimate_human", "?")
status = m.get("status", {}).get("state", "Unknown")
member_data = {
"id": pid,
"name": m.get("name", "Unknown"),
"level": m.get("level", 0),
"estimate": est,
"status": status
}
await STATE.upsert_member(member_data, kind)
received_ids.append(pid)
# Remove missing members from STATE
await STATE.remove_missing_members(received_ids, kind)
print(f"[SUCCESS] Populated {len(received_ids)} {kind} members from faction {faction_id}")
return True
except Exception as e:
print(f"[ERROR] Exception in populate_faction for {kind} faction {faction_id}: {type(e).__name__}: {str(e)}")
import traceback
traceback.print_exc()
return False return False
member_ids = [m.get("id") for m in members_list if "id" in m]
if not member_ids:
return False
# Fetch FFScouter estimates
ff_data = await fetch_batch_stats(member_ids)
received_ids = []
async with (friendly_lock if kind == "friendly" else enemy_lock):
for m in members_list:
pid = m["id"]
est = ff_data.get(str(pid), {}).get("bs_estimate_human", "?")
status = m.get("status", {}).get("state", "Unknown")
member_data = {
"id": pid,
"name": m.get("name", "Unknown"),
"level": m.get("level", 0),
"estimate": est,
"status": status
}
await STATE.upsert_member(member_data, kind)
received_ids.append(pid)
# Remove missing members from STATE
await STATE.remove_missing_members(received_ids, kind)
return True
# Status refresh loop # Status refresh loop
async def refresh_status_loop(faction_id: int, kind: str, lock: asyncio.Lock, interval: int): async def refresh_status_loop(faction_id: int, kind: str, lock: asyncio.Lock, interval: int):