from typing import Dict, Any from src.schema.state import WikiState, ShipData from src.clients.esi import ESIClient import logging logger = logging.getLogger("esi-collector") async def get_dogma_attribute(esi: ESIClient, type_id: int, attribute_id: int) -> float: """Helper to get a specific dogma attribute value for a type.""" type_details = await esi.get_type_details(type_id) for attr in type_details.get("dogma_attributes", []): if attr.get("attribute_id") == attribute_id: return float(attr.get("value", 0)) return 0.0 async def esi_collector_node(state: WikiState) -> Dict[str, Any]: """ LangGraph node to collect structured data from ESI. """ esi = ESIClient() # Common Attribute IDs (ESI Dogma) ATTR_HP_SHIELD = 263 ATTR_HP_ARMOR = 265 ATTR_HP_STRUCT = 9 ATTR_CPU_OUTPUT = 48 ATTR_PG_OUTPUT = 11 try: if state.current_page and state.current_page.metadata.page_type == "ship": type_id = state.current_page.frontmatter.get("type_id") if type_id: logger.info(f"Collecting ESI data for type_id {type_id}") type_details = await esi.get_type_details(type_id) # Fetch group for category verification group = await esi.get_group_details(type_details.get("group_id")) # Map attributes dogma = {a["attribute_id"]: a["value"] for a in type_details.get("dogma_attributes", [])} ship_data = ShipData( type_id=type_id, group=group.get("name", "Unknown"), race="Unknown", # Need race mapping hull_stats={ "hp_shield": int(dogma.get(ATTR_HP_SHIELD, 0)), "hp_armor": int(dogma.get(ATTR_HP_ARMOR, 0)), "hp_structure": int(dogma.get(ATTR_HP_STRUCT, 0)) }, fitting_stats={ "cpu_output": int(dogma.get(ATTR_CPU_OUTPUT, 0)), "powergrid_output": int(dogma.get(ATTR_PG_OUTPUT, 0)) }, velocity=int(dogma.get(37, 0)), # Base velocity attribute skill_requirements=[] ) logger.info(f"Successfully collected data for {type_details.get('name')}") # We update the state with the new data overlay return {"current_page": state.current_page} # State update logic needed return {} except Exception as e: logger.error(f"ESI Collection Failed: {str(e)}") return {"error": str(e)} finally: await esi.close()