Files
Medios-Macina/ProviderCore/registry.py

144 lines
4.4 KiB
Python
Raw Normal View History

2025-12-11 19:04:02 -08:00
"""Provider registry.
Concrete provider implementations live in the `Provider/` package.
This module is the single source of truth for provider discovery.
"""
from __future__ import annotations
from typing import Any, Dict, Optional, Type
import sys
from SYS.logger import log
2025-12-19 02:29:42 -08:00
from ProviderCore.base import Provider, SearchProvider, FileProvider, SearchResult
2025-12-16 01:45:01 -08:00
from Provider.alldebrid import AllDebrid
2025-12-11 19:04:02 -08:00
from Provider.bandcamp import Bandcamp
from Provider.libgen import Libgen
from Provider.matrix import Matrix
2025-12-12 21:55:38 -08:00
from Provider.openlibrary import OpenLibrary
2025-12-11 19:04:02 -08:00
from Provider.soulseek import Soulseek, download_soulseek_file
2025-12-19 02:29:42 -08:00
from Provider.telegram import Telegram
2025-12-11 19:04:02 -08:00
from Provider.youtube import YouTube
from Provider.zeroxzero import ZeroXZero
2025-12-19 02:29:42 -08:00
_PROVIDERS: Dict[str, Type[Provider]] = {
# Search-capable providers
2025-12-16 01:45:01 -08:00
"alldebrid": AllDebrid,
2025-12-11 19:04:02 -08:00
"libgen": Libgen,
2025-12-12 21:55:38 -08:00
"openlibrary": OpenLibrary,
2025-12-11 19:04:02 -08:00
"soulseek": Soulseek,
"bandcamp": Bandcamp,
"youtube": YouTube,
2025-12-19 02:29:42 -08:00
"telegram": Telegram,
# Upload-capable providers
"0x0": ZeroXZero,
"matrix": Matrix,
2025-12-11 19:04:02 -08:00
}
2025-12-19 02:29:42 -08:00
def _supports_search(provider: Provider) -> bool:
return provider.__class__.search is not Provider.search
def _supports_upload(provider: Provider) -> bool:
return provider.__class__.upload is not Provider.upload
2025-12-11 19:04:02 -08:00
2025-12-19 02:29:42 -08:00
def get_provider(name: str, config: Optional[Dict[str, Any]] = None) -> Optional[Provider]:
"""Get a provider by name (unified registry)."""
provider_class = _PROVIDERS.get((name or "").lower())
2025-12-11 19:04:02 -08:00
if provider_class is None:
2025-12-19 02:29:42 -08:00
log(f"[provider] Unknown provider: {name}", file=sys.stderr)
2025-12-11 19:04:02 -08:00
return None
try:
provider = provider_class(config)
if not provider.validate():
log(f"[provider] Provider '{name}' is not available", file=sys.stderr)
return None
return provider
except Exception as exc:
log(f"[provider] Error initializing '{name}': {exc}", file=sys.stderr)
return None
2025-12-19 02:29:42 -08:00
def list_providers(config: Optional[Dict[str, Any]] = None) -> Dict[str, bool]:
"""List all providers and their availability."""
2025-12-11 19:04:02 -08:00
availability: Dict[str, bool] = {}
2025-12-19 02:29:42 -08:00
for name, provider_class in _PROVIDERS.items():
2025-12-11 19:04:02 -08:00
try:
provider = provider_class(config)
availability[name] = provider.validate()
except Exception:
availability[name] = False
return availability
2025-12-19 02:29:42 -08:00
def get_search_provider(name: str, config: Optional[Dict[str, Any]] = None) -> Optional[SearchProvider]:
"""Get a search-capable provider by name (compat API)."""
provider = get_provider(name, config)
if provider is None:
return None
if not _supports_search(provider):
log(f"[provider] Provider '{name}' does not support search", file=sys.stderr)
return None
return provider # type: ignore[return-value]
def list_search_providers(config: Optional[Dict[str, Any]] = None) -> Dict[str, bool]:
"""List all search providers and their availability."""
availability: Dict[str, bool] = {}
for name, provider_class in _PROVIDERS.items():
try:
provider = provider_class(config)
availability[name] = bool(provider.validate() and _supports_search(provider))
except Exception:
availability[name] = False
return availability
2025-12-11 19:04:02 -08:00
def get_file_provider(name: str, config: Optional[Dict[str, Any]] = None) -> Optional[FileProvider]:
2025-12-19 02:29:42 -08:00
"""Get an upload-capable provider by name (compat API)."""
2025-12-11 19:04:02 -08:00
2025-12-19 02:29:42 -08:00
provider = get_provider(name, config)
if provider is None:
2025-12-11 19:04:02 -08:00
return None
2025-12-19 02:29:42 -08:00
if not _supports_upload(provider):
log(f"[provider] Provider '{name}' does not support upload", file=sys.stderr)
2025-12-11 19:04:02 -08:00
return None
2025-12-19 02:29:42 -08:00
return provider # type: ignore[return-value]
2025-12-11 19:04:02 -08:00
def list_file_providers(config: Optional[Dict[str, Any]] = None) -> Dict[str, bool]:
"""List all file providers and their availability."""
availability: Dict[str, bool] = {}
2025-12-19 02:29:42 -08:00
for name, provider_class in _PROVIDERS.items():
2025-12-11 19:04:02 -08:00
try:
provider = provider_class(config)
2025-12-19 02:29:42 -08:00
availability[name] = bool(provider.validate() and _supports_upload(provider))
2025-12-11 19:04:02 -08:00
except Exception:
availability[name] = False
return availability
__all__ = [
"SearchResult",
2025-12-19 02:29:42 -08:00
"Provider",
2025-12-11 19:04:02 -08:00
"SearchProvider",
"FileProvider",
2025-12-19 02:29:42 -08:00
"get_provider",
"list_providers",
2025-12-11 19:04:02 -08:00
"get_search_provider",
"list_search_providers",
"get_file_provider",
"list_file_providers",
"download_soulseek_file",
]