56 lines
1.8 KiB
Python
56 lines
1.8 KiB
Python
from commerce.models import SourceSystem
|
|
from commerce.services import IngestResult, ingest_source_record
|
|
|
|
from .base import SourceAdapter
|
|
|
|
|
|
class AdapterRegistry:
|
|
def __init__(self):
|
|
self._adapters: dict[str, SourceAdapter] = {}
|
|
|
|
def register(self, adapter: SourceAdapter):
|
|
code = adapter.source_code.strip().lower()
|
|
if not code:
|
|
raise ValueError("Adapter source_code must not be empty")
|
|
if code in self._adapters:
|
|
raise ValueError(f"Adapter '{code}' is already registered")
|
|
self._adapters[code] = adapter
|
|
return adapter
|
|
|
|
def get(self, source_code: str) -> SourceAdapter:
|
|
try:
|
|
return self._adapters[source_code.strip().lower()]
|
|
except KeyError as exc:
|
|
raise LookupError(f"Adapter '{source_code}' is not registered") from exc
|
|
|
|
def codes(self) -> tuple[str, ...]:
|
|
return tuple(sorted(self._adapters))
|
|
|
|
|
|
adapter_registry = AdapterRegistry()
|
|
|
|
|
|
def sync_registered_source(source_code: str, *, entity_type: str) -> list[IngestResult]:
|
|
adapter = adapter_registry.get(source_code)
|
|
if entity_type not in adapter.supported_entity_types():
|
|
raise ValueError(
|
|
f"Adapter '{source_code}' does not support entity type '{entity_type}'"
|
|
)
|
|
|
|
source, _ = SourceSystem.objects.get_or_create(
|
|
code=adapter.source_code,
|
|
defaults={"name": adapter.source_name},
|
|
)
|
|
results = []
|
|
for external in adapter.iter_records(entity_type=entity_type):
|
|
results.append(
|
|
ingest_source_record(
|
|
source=source,
|
|
entity_type=external.entity_type,
|
|
external_id=external.external_id,
|
|
payload=external.payload,
|
|
source_updated_at=external.source_updated_at,
|
|
)
|
|
)
|
|
return results
|