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-12 21:55:38 -08:00
|
|
|
from ProviderCore.base import FileProvider, SearchProvider, SearchResult
|
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
|
|
|
|
|
from Provider.youtube import YouTube
|
|
|
|
|
from Provider.zeroxzero import ZeroXZero
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_SEARCH_PROVIDERS: Dict[str, Type[SearchProvider]] = {
|
|
|
|
|
"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,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_search_provider(name: str, config: Optional[Dict[str, Any]] = None) -> Optional[SearchProvider]:
|
|
|
|
|
"""Get a search provider by name."""
|
|
|
|
|
|
|
|
|
|
provider_class = _SEARCH_PROVIDERS.get((name or "").lower())
|
|
|
|
|
if provider_class is None:
|
|
|
|
|
log(f"[provider] Unknown search provider: {name}", file=sys.stderr)
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 _SEARCH_PROVIDERS.items():
|
|
|
|
|
try:
|
|
|
|
|
provider = provider_class(config)
|
|
|
|
|
availability[name] = provider.validate()
|
|
|
|
|
except Exception:
|
|
|
|
|
availability[name] = False
|
|
|
|
|
return availability
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_FILE_PROVIDERS: Dict[str, Type[FileProvider]] = {
|
|
|
|
|
"0x0": ZeroXZero,
|
|
|
|
|
"matrix": Matrix,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_file_provider(name: str, config: Optional[Dict[str, Any]] = None) -> Optional[FileProvider]:
|
|
|
|
|
"""Get a file provider by name."""
|
|
|
|
|
|
|
|
|
|
provider_class = _FILE_PROVIDERS.get((name or "").lower())
|
|
|
|
|
if provider_class is None:
|
|
|
|
|
log(f"[provider] Unknown file provider: {name}", file=sys.stderr)
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
provider = provider_class(config)
|
|
|
|
|
if not provider.validate():
|
|
|
|
|
log(f"[provider] File provider '{name}' is not available", file=sys.stderr)
|
|
|
|
|
return None
|
|
|
|
|
return provider
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
log(f"[provider] Error initializing file provider '{name}': {exc}", file=sys.stderr)
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def list_file_providers(config: Optional[Dict[str, Any]] = None) -> Dict[str, bool]:
|
|
|
|
|
"""List all file providers and their availability."""
|
|
|
|
|
|
|
|
|
|
availability: Dict[str, bool] = {}
|
|
|
|
|
for name, provider_class in _FILE_PROVIDERS.items():
|
|
|
|
|
try:
|
|
|
|
|
provider = provider_class(config)
|
|
|
|
|
availability[name] = provider.validate()
|
|
|
|
|
except Exception:
|
|
|
|
|
availability[name] = False
|
|
|
|
|
return availability
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__all__ = [
|
|
|
|
|
"SearchResult",
|
|
|
|
|
"SearchProvider",
|
|
|
|
|
"FileProvider",
|
|
|
|
|
"get_search_provider",
|
|
|
|
|
"list_search_providers",
|
|
|
|
|
"get_file_provider",
|
|
|
|
|
"list_file_providers",
|
|
|
|
|
"download_soulseek_file",
|
|
|
|
|
]
|