Spaces:
Sleeping
Sleeping
| """Blueprint that returns location information for faculty, staff, or students.""" | |
| from __future__ import annotations | |
| from typing import Any, Dict, List, Optional | |
| from .base import AnalysisContext, Blueprint, BlueprintResult, Fact | |
| from .faculty_profile import _lookup_record | |
| from ..data.utils import canonicalize_name | |
| class LocationBlueprint(Blueprint): | |
| """Return where a person (faculty, staff, or student) can be found on campus. | |
| Automatically detects whether the name matches a faculty member, staff member, | |
| or student and returns the appropriate location information. | |
| """ | |
| name = "location" | |
| def run(self, context: AnalysisContext, **kwargs: Any) -> BlueprintResult: | |
| target_name = (kwargs.get("name") or kwargs.get("person") or "").strip() | |
| if not target_name: | |
| return BlueprintResult(self.name, kwargs, facts=[], notes=["No name provided."]) | |
| facts: List[Fact] = [] | |
| notes: List[str] = [] | |
| found_faculty = False | |
| found_staff = False | |
| found_student = False | |
| # Try faculty lookup first | |
| faculty_facts, faculty_notes, found_faculty = self._lookup_faculty_location(context, target_name) | |
| facts.extend(faculty_facts) | |
| notes.extend(faculty_notes) | |
| # Try staff lookup | |
| staff_facts, staff_notes, found_staff = self._lookup_staff_location(context, target_name) | |
| facts.extend(staff_facts) | |
| notes.extend(staff_notes) | |
| # Try student lookup | |
| student_facts, student_notes, found_student = self._lookup_student_seating(context, target_name) | |
| facts.extend(student_facts) | |
| notes.extend(student_notes) | |
| # If none found, report not found | |
| if not found_faculty and not found_staff and not found_student: | |
| return BlueprintResult( | |
| self.name, | |
| kwargs, | |
| facts=[], | |
| notes=[f"'{target_name}' not found in faculty, staff, or student records."], | |
| ) | |
| return BlueprintResult(self.name, kwargs, facts=facts, notes=notes) | |
| def _lookup_faculty_location( | |
| self, context: AnalysisContext, target_name: str | |
| ) -> tuple[List[Fact], List[str], bool]: | |
| """Look up faculty office location. Returns (facts, notes, found).""" | |
| record, lookup_notes, office_row = _lookup_record(context, target_name) | |
| if record is None and office_row is None: | |
| return [], [], False | |
| facts: List[Fact] = [] | |
| notes = list(lookup_notes) | |
| # Try to resolve office through relationship | |
| office_matches = [] | |
| if record is not None: | |
| office_matches = context.catalog.resolve_relationship("faculty_to_office", record) | |
| if office_matches: | |
| office_row = office_matches[0] | |
| office_entity = context.catalog.try_get("faculty_offices") | |
| office_source = office_entity.origin if office_entity else None | |
| building = (office_row.get("Building") or "").strip() | |
| room = (office_row.get("Room") or office_row.get("Room Location") or "").strip() | |
| location = " ".join(bit for bit in (building, room) if bit).strip() | |
| facts.append( | |
| Fact( | |
| subject=record["Name"], | |
| predicate="office", | |
| value=location or "Office location unavailable", | |
| source=office_source, | |
| ) | |
| ) | |
| elif office_row is not None: | |
| # Matched office assignment but no roster record | |
| office_entity = context.catalog.try_get("faculty_offices") | |
| office_source = office_entity.origin if office_entity else None | |
| building = (office_row.get("Building") or office_row.get("Location") or "").strip() | |
| room = (office_row.get("Room") or office_row.get("Room Location") or "").strip() | |
| location = " ".join(bit for bit in (building, room) if bit).strip() | |
| facts.append( | |
| Fact( | |
| subject=office_row.get("Assignee Name") or target_name, | |
| predicate="office", | |
| value=location or "Office location unavailable", | |
| source=office_source, | |
| ) | |
| ) | |
| elif record is not None: | |
| notes.append(f"No office assignment found for {record['Name']}.") | |
| return facts, notes, (record is not None or office_row is not None) | |
| def _lookup_staff_location( | |
| self, context: AnalysisContext, target_name: str | |
| ) -> tuple[List[Fact], List[str], bool]: | |
| """Look up staff office location. Returns (facts, notes, found).""" | |
| staff = context.catalog.try_get("staff") | |
| if not staff: | |
| return [], [], False | |
| record = None | |
| canonical_target = canonicalize_name(target_name) | |
| for row in staff.records: | |
| if canonicalize_name(row.get("Name", "")) == canonical_target: | |
| record = row | |
| break | |
| if record is None: | |
| return [], [], False | |
| facts: List[Fact] = [] | |
| notes: List[str] = [] | |
| location = (record.get("Room Location") or "").strip() | |
| if location and location.lower() not in {"not listed", "n/a", "none", ""}: | |
| facts.append( | |
| Fact( | |
| subject=record.get("Name", target_name), | |
| predicate="office", | |
| value=location, | |
| source=staff.origin, | |
| confidence=0.9, | |
| ) | |
| ) | |
| else: | |
| notes.append(f"No office location listed for {record.get('Name', target_name)}.") | |
| return facts, notes, True | |
| def _lookup_student_seating( | |
| self, context: AnalysisContext, target_name: str | |
| ) -> tuple[List[Fact], List[str], bool]: | |
| """Look up student seating location. Returns (facts, notes, found).""" | |
| students = context.catalog.try_get("students") | |
| if not students: | |
| return [], [], False | |
| record = None | |
| canonical_target = canonicalize_name(target_name) | |
| for row in students.records: | |
| if canonicalize_name(row.get("Name")) == canonical_target: | |
| record = row | |
| break | |
| if record is None: | |
| return [], [], False | |
| seating = context.catalog.resolve_relationship("student_to_mudd_seat", record) | |
| seating_entity = context.catalog.try_get("mudd_seating") | |
| seating_origin = seating_entity.origin if seating_entity else None | |
| facts: List[Fact] = [] | |
| for seat in seating: | |
| facts.append( | |
| Fact( | |
| subject=record.get("Name", target_name), | |
| predicate="seating", | |
| value={ | |
| "room": seat.get("Room Number"), | |
| "desk": seat.get("Desk Number"), | |
| "track": seat.get("Track"), | |
| "advisor": seat.get("Advocate/Advisor"), | |
| "email": seat.get("Email address"), | |
| }, | |
| source=seating_origin, | |
| confidence=0.8, | |
| ) | |
| ) | |
| notes: List[str] = [] | |
| if not facts: | |
| notes.append(f"No seating assignment listed for {record['Name']}.") | |
| return facts, notes, True | |