emma-hermes/optional-skills/security/unbroker/scripts/vectors.py

54 lines
2.1 KiB
Python

"""Enumerate the search queries to run per broker, across ALL of a subject's identifiers.
People-search sites index a person under every name, phone, email, and address they
have. A subject with two names (maiden/married) and three past cities can have many
distinct listings on one broker, each found via a different search. `search_vectors`
expands the dossier into the concrete searches to run, filtered by what each broker
supports (`broker.search.by`, default ["name"]).
"""
from __future__ import annotations
import dossier as dossier_mod
# What a broker can be searched by; default if a record doesn't declare it.
DEFAULT_BY = ["name"]
def supported_by(broker: dict) -> list[str]:
return list((broker.get("search") or {}).get("by") or DEFAULT_BY)
def search_vectors(subject_dossier: dict, broker: dict) -> list[dict]:
"""List of {by, query} searches to run for this subject on this broker."""
by = set(supported_by(broker))
ident = subject_dossier.get("identity", {})
vectors: list[dict] = []
if "name" in by:
names = dossier_mod.all_names(subject_dossier)
locations = dossier_mod.all_locations(subject_dossier)
if locations:
for name in names:
for loc in locations:
vectors.append({"by": "name",
"query": {"full_name": name, "city": loc.get("city"), "state": loc.get("state")}})
else:
for name in names:
vectors.append({"by": "name", "query": {"full_name": name}})
if "phone" in by:
for phone in ident.get("phones") or []:
vectors.append({"by": "phone", "query": {"phone": phone}})
if "email" in by:
for email in ident.get("emails") or []:
vectors.append({"by": "email", "query": {"email": email}})
if "address" in by:
for a in dossier_mod.all_addresses(subject_dossier):
if a.get("line1"):
vectors.append({"by": "address",
"query": {k: a.get(k) for k in ("line1", "city", "state", "postal")}})
return vectors