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