@@ -241,7 +241,14 @@ def handle_request(self) -> Iterator[None]:
241
241
self .warn ("Request error: {}" , exc )
242
242
243
243
244
- class Backend (RequestHandler ):
244
+ class BackendClass (type ):
245
+ @property
246
+ def name (cls ) -> str :
247
+ """Return lowercase name of the backend class."""
248
+ return cls .__name__ .lower ()
249
+
250
+
251
+ class Backend (RequestHandler , metaclass = BackendClass ):
245
252
def __init__ (self , config , log ):
246
253
self ._log = log
247
254
self .config = config
@@ -736,15 +743,21 @@ def scrape(cls, html: str) -> str | None:
736
743
737
744
738
745
class LyricsPlugin (RequestHandler , plugins .BeetsPlugin ):
739
- SOURCES = ["lrclib" , "google" , "musixmatch" , "genius" , "tekstowo" ]
740
- SOURCE_BACKENDS = {
741
- "google" : Google ,
742
- "musixmatch" : MusiXmatch ,
743
- "genius" : Genius ,
744
- "tekstowo" : Tekstowo ,
745
- "lrclib" : LRCLib ,
746
+ BACKEND_BY_NAME = {
747
+ b .name : b for b in [LRCLib , Google , Genius , Tekstowo , MusiXmatch ]
746
748
}
747
749
750
+ @cached_property
751
+ def backends (self ) -> list [Backend ]:
752
+ user_sources = self .config ["sources" ].get ()
753
+
754
+ chosen = plugins .sanitize_choices (user_sources , self .BACKEND_BY_NAME )
755
+ if "google" in chosen and not self .config ["google_API_key" ].get ():
756
+ self .warn ("Disabling Google source: no API key configured." )
757
+ chosen .remove ("google" )
758
+
759
+ return [self .BACKEND_BY_NAME [c ](self .config , self ._log ) for c in chosen ]
760
+
748
761
def __init__ (self ):
749
762
super ().__init__ ()
750
763
self .import_stages = [self .imported ]
@@ -767,7 +780,9 @@ def __init__(self):
767
780
"synced" : False ,
768
781
# Musixmatch is disabled by default as they are currently blocking
769
782
# requests with the beets user agent.
770
- "sources" : [s for s in self .SOURCES if s != "musixmatch" ],
783
+ "sources" : [
784
+ n for n in self .BACKEND_BY_NAME if n != "musixmatch"
785
+ ],
771
786
}
772
787
)
773
788
self .config ["bing_client_secret" ].redact = True
@@ -784,29 +799,10 @@ def __init__(self):
784
799
# open yet.
785
800
self .rest = None
786
801
787
- available_sources = list (self .SOURCES )
788
- sources = plugins .sanitize_choices (
789
- self .config ["sources" ].as_str_seq (), available_sources
790
- )
791
-
792
- if "google" in sources :
793
- if not self .config ["google_API_key" ].get ():
794
- # We log a *debug* message here because the default
795
- # configuration includes `google`. This way, the source
796
- # is silent by default but can be enabled just by
797
- # setting an API key.
798
- self .debug ("Disabling google source: " "no API key configured." )
799
- sources .remove ("google" )
800
-
801
802
self .config ["bing_lang_from" ] = [
802
803
x .lower () for x in self .config ["bing_lang_from" ].as_str_seq ()
803
804
]
804
805
805
- self .backends = [
806
- self .SOURCE_BACKENDS [s ](self .config , self ._log .getChild (s ))
807
- for s in sources
808
- ]
809
-
810
806
@cached_property
811
807
def bing_access_token (self ) -> str | None :
812
808
params = {
0 commit comments