42
42
43
43
if TYPE_CHECKING :
44
44
from beets .importer import ImportTask
45
- from beets .library import Item
45
+ from beets .library import Item , Library
46
46
47
47
from ._typing import (
48
48
GeniusAPI ,
@@ -934,7 +934,6 @@ def translator(self) -> Translator | None:
934
934
935
935
def __init__ (self ):
936
936
super ().__init__ ()
937
- self .import_stages = [self .imported ]
938
937
self .config .add (
939
938
{
940
939
"auto" : True ,
@@ -953,6 +952,7 @@ def __init__(self):
953
952
"fallback" : None ,
954
953
"force" : False ,
955
954
"local" : False ,
955
+ "print" : False ,
956
956
"synced" : False ,
957
957
# Musixmatch is disabled by default as they are currently blocking
958
958
# requests with the beets user agent.
@@ -966,14 +966,16 @@ def __init__(self):
966
966
self .config ["google_engine_ID" ].redact = True
967
967
self .config ["genius_api_key" ].redact = True
968
968
969
+ if self .config ["auto" ]:
970
+ self .import_stages = [self .imported ]
971
+
969
972
def commands (self ):
970
973
cmd = ui .Subcommand ("lyrics" , help = "fetch song lyrics" )
971
974
cmd .parser .add_option (
972
975
"-p" ,
973
976
"--print" ,
974
- dest = "printlyr" ,
975
977
action = "store_true" ,
976
- default = False ,
978
+ default = self . config [ "print" ]. get () ,
977
979
help = "print lyrics to console" ,
978
980
)
979
981
cmd .parser .add_option (
@@ -988,34 +990,27 @@ def commands(self):
988
990
cmd .parser .add_option (
989
991
"-f" ,
990
992
"--force" ,
991
- dest = "force_refetch" ,
992
993
action = "store_true" ,
993
- default = False ,
994
+ default = self . config [ "force" ]. get () ,
994
995
help = "always re-download lyrics" ,
995
996
)
996
997
cmd .parser .add_option (
997
998
"-l" ,
998
999
"--local" ,
999
- dest = "local_only" ,
1000
1000
action = "store_true" ,
1001
- default = False ,
1001
+ default = self . config [ "local" ]. get () ,
1002
1002
help = "do not fetch missing lyrics" ,
1003
1003
)
1004
1004
1005
- def func (lib , opts , args ):
1005
+ def func (lib : Library , opts , args ) -> None :
1006
1006
# The "write to files" option corresponds to the
1007
1007
# import_write config value.
1008
- items = list (lib .items (ui .decargs (args )))
1008
+ self .config .set (vars (opts ))
1009
+ items = list (lib .items (args ))
1009
1010
for item in items :
1010
- if not opts .local_only and not self .config ["local" ]:
1011
- self .fetch_item_lyrics (
1012
- item ,
1013
- ui .should_write (),
1014
- opts .force_refetch or self .config ["force" ],
1015
- )
1016
- if item .lyrics :
1017
- if opts .printlyr :
1018
- ui .print_ (item .lyrics )
1011
+ self .add_item_lyrics (item , ui .should_write ())
1012
+ if item .lyrics and opts .print :
1013
+ ui .print_ (item .lyrics )
1019
1014
1020
1015
if opts .rest_directory and (
1021
1016
items := [i for i in items if i .lyrics ]
@@ -1027,32 +1022,34 @@ def func(lib, opts, args):
1027
1022
1028
1023
def imported (self , _ , task : ImportTask ) -> None :
1029
1024
"""Import hook for fetching lyrics automatically."""
1030
- if self .config ["auto" ]:
1031
- for item in task .imported_items ():
1032
- self .fetch_item_lyrics (item , False , self .config ["force" ])
1025
+ for item in task .imported_items ():
1026
+ self .add_item_lyrics (item , False )
1027
+
1028
+ def find_lyrics (self , item : Item ) -> str :
1029
+ album , length = item .album , round (item .length )
1030
+ matches = (
1031
+ [
1032
+ lyrics
1033
+ for t in titles
1034
+ if (lyrics := self .get_lyrics (a , t , album , length ))
1035
+ ]
1036
+ for a , titles in search_pairs (item )
1037
+ )
1033
1038
1034
- def fetch_item_lyrics (self , item : Item , write : bool , force : bool ) -> None :
1039
+ return "\n \n ---\n \n " .join (next (filter (None , matches ), []))
1040
+
1041
+ def add_item_lyrics (self , item : Item , write : bool ) -> None :
1035
1042
"""Fetch and store lyrics for a single item. If ``write``, then the
1036
1043
lyrics will also be written to the file itself.
1037
1044
"""
1038
- # Skip if the item already has lyrics.
1039
- if not force and item .lyrics :
1040
- self .info ("🔵 Lyrics already present: {}" , item )
1045
+ if self .config ["local" ]:
1041
1046
return
1042
1047
1043
- lyrics_matches = []
1044
- album , length = item .album , round (item .length )
1045
- for artist , titles in search_pairs (item ):
1046
- lyrics_matches = [
1047
- self .get_lyrics (artist , title , album , length )
1048
- for title in titles
1049
- ]
1050
- if any (lyrics_matches ):
1051
- break
1052
-
1053
- lyrics = "\n \n ---\n \n " .join (filter (None , lyrics_matches ))
1048
+ if not self .config ["force" ] and item .lyrics :
1049
+ self .info ("🔵 Lyrics already present: {}" , item )
1050
+ return
1054
1051
1055
- if lyrics :
1052
+ if lyrics := self . find_lyrics ( item ) :
1056
1053
self .info ("🟢 Found lyrics: {0}" , item )
1057
1054
if translator := self .translator :
1058
1055
initial_lyrics = lyrics
0 commit comments