68 lines
2.3 KiB
Python
68 lines
2.3 KiB
Python
"""
|
|
URI parsing and device classification utilities.
|
|
All functions are pure (no I/O, no DB).
|
|
"""
|
|
|
|
import re
|
|
from urllib.parse import urlparse
|
|
|
|
|
|
_SERIAL_SCHEMES = {"serial", "com"}
|
|
_SERVICE_HOSTS = {"localhost", "127.0.0.1"}
|
|
|
|
# Plugin name prefixes whose URIs point at the CAPS server itself, not separate devices.
|
|
_SKIP_PLUGIN_PREFIXES = ("mnemo", "processor", "recognition", "photo", "voice")
|
|
|
|
|
|
def extract_device_info(uri: str) -> tuple[str, str, str] | None:
|
|
"""Return (ip, username, password) from a URI, or None if not a network device.
|
|
|
|
Username and password are extracted from URI credentials (http://user:pass@ip).
|
|
They may be empty strings if not present in the URI.
|
|
"""
|
|
if not uri:
|
|
return None
|
|
try:
|
|
parsed = urlparse(uri)
|
|
scheme = (parsed.scheme or "").lower()
|
|
if scheme in _SERIAL_SCHEMES:
|
|
return None
|
|
hostname = parsed.hostname
|
|
if not hostname or hostname in _SERVICE_HOSTS:
|
|
return None
|
|
if re.match(r"^\d{1,3}(\.\d{1,3}){3}$", hostname):
|
|
return hostname, parsed.username or "", parsed.password or ""
|
|
except Exception:
|
|
pass
|
|
return None
|
|
|
|
|
|
def extract_ip(uri: str) -> str | None:
|
|
"""Return IP from a URI string, or None if not a network device."""
|
|
info = extract_device_info(uri)
|
|
return info[0] if info else None
|
|
|
|
|
|
def cls_to_category(cls: str) -> str:
|
|
cls_lower = cls.lower()
|
|
if "camera" in cls_lower or "facedetect" in cls_lower:
|
|
return "camera"
|
|
if "controller" in cls_lower or "ovenmk" in cls_lower or "rodos" in cls_lower:
|
|
return "io_board"
|
|
if "payment" in cls_lower or "sberpilot" in cls_lower or "payx" in cls_lower:
|
|
return "bank_terminal"
|
|
if "payonline" in cls_lower or "kkt" in cls_lower or "fiscal" in cls_lower:
|
|
return "cash_register"
|
|
return "other"
|
|
|
|
|
|
def cls_to_role(cls: str, plugin_name: str) -> str:
|
|
cls_lower = cls.lower()
|
|
name_lower = plugin_name.lower()
|
|
if "camera" in cls_lower or "camera" in name_lower:
|
|
if "grz" in name_lower or "plate" in name_lower or "lpr" in name_lower or "frame" in name_lower:
|
|
return "plate"
|
|
if "face" in name_lower or "lico" in name_lower:
|
|
return "face"
|
|
return "overview"
|
|
return "other"
|