| 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 |
| |
| 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 |
|
|