47 lines
1.6 KiB
Python
47 lines
1.6 KiB
Python
"""Ordered gear evidence extracted from source records without auto-mapping."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from .community_sources import EquipmentItem
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class GearComponentIdentity:
|
|
role: str
|
|
position: int
|
|
raw_value: str
|
|
source_external_id: str | None
|
|
|
|
|
|
def _role_from_kind(kind: str) -> str:
|
|
value = kind.casefold()
|
|
terms = {
|
|
"удилищ": "rod", "катуш": "reel", "леск": "line", "крюч": "hook",
|
|
"поплав": "float", "груз": "sinker", "монтаж": "rig", "rig": "rig",
|
|
"приманк": "lure", "нажив": "bait", "bait": "bait", "lure": "lure",
|
|
}
|
|
return next((role for term, role in terms.items() if term in value), "other")
|
|
|
|
|
|
def from_equipment(items: tuple[EquipmentItem, ...]) -> tuple[GearComponentIdentity, ...]:
|
|
"""Keep source order and raw text; canonical mapping happens only after review."""
|
|
return tuple(
|
|
GearComponentIdentity(
|
|
role=_role_from_kind(item.kind), position=index,
|
|
raw_value=item.name, source_external_id=item.external_id,
|
|
)
|
|
for index, item in enumerate(items)
|
|
if item.name.strip()
|
|
)
|
|
|
|
|
|
def from_catch_fields(*, bait: str | None, rig_type: str | None) -> tuple[GearComponentIdentity, ...]:
|
|
values: list[GearComponentIdentity] = []
|
|
if bait and bait.strip():
|
|
values.append(GearComponentIdentity("lure", len(values), bait.strip(), None))
|
|
if rig_type and rig_type.strip():
|
|
values.append(GearComponentIdentity("rig", len(values), rig_type.strip(), None))
|
|
return tuple(values)
|