Enhanced logging
This commit is contained in:
@@ -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")
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
Reference in New Issue
Block a user