"""Lazy source registry to avoid importing every source at module import time.""" from __future__ import annotations import importlib from ..utils import BaseModuleBuilder from .base import BaseMusicClient CLIENT_IMPORT_PATHS = { # Platforms in Greater China "QQMusicClient": ("musicdl.modules.sources.qq", "QQMusicClient"), "KugouMusicClient": ("musicdl.modules.sources.kugou", "KugouMusicClient"), "StreetVoiceMusicClient": ("musicdl.modules.sources.streetvoice", "StreetVoiceMusicClient"), "SodaMusicClient": ("musicdl.modules.sources.soda", "SodaMusicClient"), "FiveSingMusicClient": ("musicdl.modules.sources.fivesing", "FiveSingMusicClient"), "NeteaseMusicClient": ("musicdl.modules.sources.netease", "NeteaseMusicClient"), "QianqianMusicClient": ("musicdl.modules.sources.qianqian", "QianqianMusicClient"), "MiguMusicClient": ("musicdl.modules.sources.migu", "MiguMusicClient"), "KuwoMusicClient": ("musicdl.modules.sources.kuwo", "KuwoMusicClient"), "BilibiliMusicClient": ("musicdl.modules.sources.bilibili", "BilibiliMusicClient"), # Global Streaming / Indie "YouTubeMusicClient": ("musicdl.modules.sources.youtube", "YouTubeMusicClient"), "JooxMusicClient": ("musicdl.modules.sources.joox", "JooxMusicClient"), "AppleMusicClient": ("musicdl.modules.sources.apple", "AppleMusicClient"), "JamendoMusicClient": ("musicdl.modules.sources.jamendo", "JamendoMusicClient"), "SoundCloudMusicClient": ("musicdl.modules.sources.soundcloud", "SoundCloudMusicClient"), "DeezerMusicClient": ("musicdl.modules.sources.deezer", "DeezerMusicClient"), "QobuzMusicClient": ("musicdl.modules.sources.qobuz", "QobuzMusicClient"), "SpotifyMusicClient": ("musicdl.modules.sources.spotify", "SpotifyMusicClient"), "TIDALMusicClient": ("musicdl.modules.sources.tidal", "TIDALMusicClient"), # Audio / Radio "XimalayaMusicClient": ("musicdl.modules.audiobooks.ximalaya", "XimalayaMusicClient"), "LizhiMusicClient": ("musicdl.modules.audiobooks.lizhi", "LizhiMusicClient"), "QingtingMusicClient": ("musicdl.modules.audiobooks.qingting", "QingtingMusicClient"), "LRTSMusicClient": ("musicdl.modules.audiobooks.lrts", "LRTSMusicClient"), # Aggregators / Multi-Source Gateways "MP3JuiceMusicClient": ("musicdl.modules.common.mp3juice", "MP3JuiceMusicClient"), "TuneHubMusicClient": ("musicdl.modules.common.tunehub", "TuneHubMusicClient"), "GDStudioMusicClient": ("musicdl.modules.common.gdstudio", "GDStudioMusicClient"), "MyFreeMP3MusicClient": ("musicdl.modules.common.myfreemp3", "MyFreeMP3MusicClient"), "JBSouMusicClient": ("musicdl.modules.common.jbsou", "JBSouMusicClient"), # Unofficial Download Sites / Scrapers "MituMusicClient": ("musicdl.modules.thirdpartysites.mitu", "MituMusicClient"), "BuguyyMusicClient": ("musicdl.modules.thirdpartysites.buguyy", "BuguyyMusicClient"), "GequbaoMusicClient": ("musicdl.modules.thirdpartysites.gequbao", "GequbaoMusicClient"), "YinyuedaoMusicClient": ("musicdl.modules.thirdpartysites.yinyuedao", "YinyuedaoMusicClient"), "FLMP3MusicClient": ("musicdl.modules.thirdpartysites.flmp3", "FLMP3MusicClient"), "FangpiMusicClient": ("musicdl.modules.thirdpartysites.fangpi", "FangpiMusicClient"), "FiveSongMusicClient": ("musicdl.modules.thirdpartysites.fivesong", "FiveSongMusicClient"), "KKWSMusicClient": ("musicdl.modules.thirdpartysites.kkws", "KKWSMusicClient"), "GequhaiMusicClient": ("musicdl.modules.thirdpartysites.gequhai", "GequhaiMusicClient"), "LivePOOMusicClient": ("musicdl.modules.thirdpartysites.livepoo", "LivePOOMusicClient"), "HTQYYMusicClient": ("musicdl.modules.thirdpartysites.htqyy", "HTQYYMusicClient"), "JCPOOMusicClient": ("musicdl.modules.thirdpartysites.jcpoo", "JCPOOMusicClient"), "TwoT58MusicClient": ("musicdl.modules.thirdpartysites.twot58", "TwoT58MusicClient"), "ZhuolinMusicClient": ("musicdl.modules.thirdpartysites.zhuolin", "ZhuolinMusicClient"), } def _load_client_class(client_name: str): module_path, attr_name = CLIENT_IMPORT_PATHS[client_name] module = importlib.import_module(module_path) return getattr(module, attr_name) def _build_client_factory(client_name: str): def factory(**kwargs): return _load_client_class(client_name)(**kwargs) factory.__name__ = client_name return factory class MusicClientBuilder(BaseModuleBuilder): REGISTERED_MODULES = { client_name: _build_client_factory(client_name) for client_name in CLIENT_IMPORT_PATHS } def __getattr__(name: str): if name in CLIENT_IMPORT_PATHS: return _load_client_class(name) raise AttributeError(name) BuildMusicClient = MusicClientBuilder().build __all__ = ["BaseMusicClient", "BuildMusicClient", "MusicClientBuilder", *CLIENT_IMPORT_PATHS.keys()]