add encar scraper
This commit is contained in:
97
encar_scraper/core/runtime_config.py
Normal file
97
encar_scraper/core/runtime_config.py
Normal file
@@ -0,0 +1,97 @@
|
||||
"""Загрузчик runtime_config.json для управления фильтрами синхронизации."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
logger = logging.getLogger("encar_scraper.runtime_config")
|
||||
|
||||
DEFAULT_CONFIG_PATH = Path(__file__).resolve().parent.parent.parent / "runtime_config.json"
|
||||
|
||||
|
||||
@dataclass
|
||||
class SyncConfig:
|
||||
name: str | None = None
|
||||
lane: str = "encar_cars"
|
||||
only_new: bool = False
|
||||
limit: int | None = None
|
||||
probe_all_photos: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class FiltersConfig:
|
||||
price_min: int | None = None
|
||||
price_max: int | None = None
|
||||
mileage_min: int | None = None
|
||||
mileage_max: int | None = None
|
||||
brands: list[str] = field(default_factory=list)
|
||||
models: list[str] = field(default_factory=list)
|
||||
years: list[int] = field(default_factory=list)
|
||||
body_types: list[str] = field(default_factory=list)
|
||||
colors: list[str] = field(default_factory=list)
|
||||
drives: list[str] = field(default_factory=list)
|
||||
gearboxes: list[str] = field(default_factory=list)
|
||||
exclude_brands: list[str] = field(default_factory=list)
|
||||
exclude_models: list[str] = field(default_factory=list)
|
||||
exclude_years: list[int] = field(default_factory=list)
|
||||
exclude_body_types: list[str] = field(default_factory=list)
|
||||
|
||||
|
||||
@dataclass
|
||||
class RuntimeConfig:
|
||||
sync: SyncConfig = field(default_factory=SyncConfig)
|
||||
filters: FiltersConfig = field(default_factory=FiltersConfig)
|
||||
|
||||
|
||||
def load_runtime_config(path: str | Path | None = None) -> RuntimeConfig:
|
||||
"""Загружает runtime_config.json. Если файл не найден — возвращает дефолт."""
|
||||
config_path = Path(path) if path else DEFAULT_CONFIG_PATH
|
||||
if not config_path.exists():
|
||||
logger.info("runtime_config.json not found at %s, using defaults", config_path)
|
||||
return RuntimeConfig()
|
||||
|
||||
try:
|
||||
raw: dict[str, Any] = json.loads(config_path.read_text(encoding="utf-8"))
|
||||
except Exception as exc:
|
||||
logger.warning("Failed to parse runtime_config.json: %s, using defaults", exc)
|
||||
return RuntimeConfig()
|
||||
|
||||
sync_raw = raw.get("sync") or {}
|
||||
filters_raw = raw.get("filters") or {}
|
||||
price_raw = filters_raw.get("price") or {}
|
||||
mileage_raw = filters_raw.get("mileage") or {}
|
||||
|
||||
sync = SyncConfig(
|
||||
name=sync_raw.get("name"),
|
||||
lane=sync_raw.get("lane", "encar_cars"),
|
||||
only_new=bool(sync_raw.get("only_new", False)),
|
||||
limit=sync_raw.get("limit"),
|
||||
probe_all_photos=bool(sync_raw.get("probe_all_photos", False)),
|
||||
)
|
||||
|
||||
filters = FiltersConfig(
|
||||
price_min=price_raw.get("min"),
|
||||
price_max=price_raw.get("max"),
|
||||
mileage_min=mileage_raw.get("min"),
|
||||
mileage_max=mileage_raw.get("max"),
|
||||
brands=[b.lower() for b in (filters_raw.get("brands") or [])],
|
||||
models=[m.lower() for m in (filters_raw.get("models") or [])],
|
||||
years=filters_raw.get("years") or [],
|
||||
body_types=[b.lower() for b in (filters_raw.get("body_types") or [])],
|
||||
colors=[c.lower() for c in (filters_raw.get("colors") or [])],
|
||||
drives=[d.lower() for d in (filters_raw.get("drives") or [])],
|
||||
gearboxes=[g.lower() for g in (filters_raw.get("gearboxes") or [])],
|
||||
exclude_brands=[b.lower() for b in (filters_raw.get("exclude_brands") or [])],
|
||||
exclude_models=[m.lower() for m in (filters_raw.get("exclude_models") or [])],
|
||||
exclude_years=filters_raw.get("exclude_years") or [],
|
||||
exclude_body_types=[b.lower() for b in (filters_raw.get("exclude_body_types") or [])],
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"runtime_config loaded: lane=%s, limit=%s, brands=%d, exclude_brands=%d",
|
||||
sync.lane, sync.limit, len(filters.brands), len(filters.exclude_brands),
|
||||
)
|
||||
return RuntimeConfig(sync=sync, filters=filters)
|
||||
Reference in New Issue
Block a user