from __future__ import annotations import re from typing import Any, Dict, Iterable, List def source_authority_tier(doc_name: str) -> int: doc = str(doc_name or "").strip().lower() if not doc: return 9 if "web-sourced" in doc or "not from our internal docs" in doc: return 4 if any(k in doc for k in ["airlink.com", "cradlepoint", "digi.com", "teltonika", "meraki", "cisco"]): return 2 # Internal doc paths, local filenames, and generated source blocks default to highest authority. return 1 def sort_sources_by_authority(sources: Iterable[Dict[str, Any]]) -> List[Dict[str, Any]]: rows = [dict(s or {}) for s in sources or []] rows.sort( key=lambda s: ( source_authority_tier(str(s.get("doc") or "")), str(s.get("doc") or "").lower(), str(s.get("location") or "").lower(), ) ) return rows def detect_lifecycle_year_conflicts(sources: Iterable[Dict[str, Any]]) -> Dict[str, List[str]]: eos_years = set() eol_years = set() for src in sources or []: text = f"{src.get('excerpt') or ''} {src.get('text') or ''}" low = str(text).lower() eos_years.update(re.findall(r"(?:eos|end[- ]of[- ]sale)[^0-9]{0,18}(20\d{2})", low)) eol_years.update(re.findall(r"(?:eol|end[- ]of[- ]life)[^0-9]{0,18}(20\d{2})", low)) out: Dict[str, List[str]] = {} if len(eos_years) > 1: out["eos"] = sorted(eos_years) if len(eol_years) > 1: out["eol"] = sorted(eol_years) return out