Implement complete MCP server for parsing Primavera P6 XER files and exposing schedule data through MCP tools. All 4 user stories complete. Tools implemented: - load_xer: Parse XER files into SQLite database - list_activities: Query activities with pagination and filtering - get_activity: Get activity details by ID - list_relationships: Query activity dependencies - get_predecessors/get_successors: Query activity relationships - get_project_summary: Project overview with counts - list_milestones: Query milestone activities - get_critical_path: Query driving path activities Features: - Tab-delimited XER format parsing with pluggable table handlers - In-memory SQLite database for fast queries - Pagination with 100-item default limit - Multi-project file support with project selection - ISO8601 date formatting - NO_FILE_LOADED error handling for all query tools Test coverage: 81 tests (contract, integration, unit)
33 lines
983 B
Python
33 lines
983 B
Python
"""CALENDAR table handler."""
|
|
|
|
from xer_mcp.parser.table_handlers.base import TableHandler
|
|
|
|
|
|
class CalendarHandler(TableHandler):
|
|
"""Handler for CALENDAR table in XER files."""
|
|
|
|
@property
|
|
def table_name(self) -> str:
|
|
return "CALENDAR"
|
|
|
|
def parse_row(self, fields: list[str], values: list[str]) -> dict | None:
|
|
"""Parse a CALENDAR row."""
|
|
if len(values) < len(fields):
|
|
values = values + [""] * (len(fields) - len(values))
|
|
|
|
data = dict(zip(fields, values, strict=False))
|
|
|
|
# Parse numeric fields
|
|
day_hr_str = data.get("day_hr_cnt", "")
|
|
day_hr = float(day_hr_str) if day_hr_str else None
|
|
|
|
week_hr_str = data.get("week_hr_cnt", "")
|
|
week_hr = float(week_hr_str) if week_hr_str else None
|
|
|
|
return {
|
|
"clndr_id": data.get("clndr_id", ""),
|
|
"clndr_name": data.get("clndr_name", ""),
|
|
"day_hr_cnt": day_hr,
|
|
"week_hr_cnt": week_hr,
|
|
}
|