2323from beets .plugins import BeetsPlugin
2424from beets .util import displayable_path , normpath , syspath
2525
26+ # Mapping from beets field names to URL templates.
27+ FIELD_LINK_TEMPLATES : dict [str , str ] = {
28+ "mb_trackid" : "https://musicbrainz.org/recording/{value}" ,
29+ "mb_albumid" : "https://musicbrainz.org/release/{value}" ,
30+ "mb_artistid" : "https://musicbrainz.org/artist/{value}" ,
31+ "mb_albumartistid" : "https://musicbrainz.org/artist/{value}" ,
32+ "mb_releasetrackid" : "https://musicbrainz.org/track/{value}" ,
33+ "mb_releasegroupid" : "https://musicbrainz.org/release-group/{value}" ,
34+ "mb_workid" : "https://musicbrainz.org/work/{value}" ,
35+ "discogs_albumid" : "https://www.discogs.com/release/{value}" ,
36+ "discogs_artistid" : "https://www.discogs.com/artist/{value}" ,
37+ "discogs_labelid" : "https://www.discogs.com/label/{value}" ,
38+ }
39+
2640
2741def tag_data (lib , args , album = False ):
2842 query = []
@@ -92,13 +106,16 @@ def update_summary(summary, tags):
92106 return summary
93107
94108
95- def print_data (data , item = None , fmt = None ):
109+ def print_data (data , item = None , fmt = None , links = False ):
96110 """Print, with optional formatting, the fields of a single element.
97111
98112 If no format string `fmt` is passed, the entries on `data` are printed one
99113 in each line, with the format 'field: value'. If `fmt` is not `None`, the
100114 `item` is printed according to `fmt`, using the `Item.__format__`
101115 machinery.
116+
117+ When `links == True`, external ID fields will be rendered as clickable
118+ terminal hyperlinks using OSC 8 escape sequences.
102119 """
103120 if fmt :
104121 # use fmt specified by the user
@@ -110,7 +127,10 @@ def print_data(data, item=None, fmt=None):
110127 for key , value in data .items ():
111128 if isinstance (value , list ):
112129 formatted [key ] = "; " .join (value )
113- if value is not None :
130+ elif value is not None :
131+ if links and key in FIELD_LINK_TEMPLATES :
132+ url = FIELD_LINK_TEMPLATES [key ].format (value = value )
133+ value = ui .terminal_link (url , value )
114134 formatted [key ] = value
115135
116136 if len (formatted ) == 0 :
@@ -181,6 +201,11 @@ def commands(self):
181201 action = "store_true" ,
182202 help = "show only the keys" ,
183203 )
204+ cmd .parser .add_option (
205+ "--links" ,
206+ action = "store_true" ,
207+ help = "make ID fields (MusicBrainz, Discogs) clickable terminal hyperlinks" ,
208+ )
184209 cmd .parser .add_format_option (target = "item" )
185210 return [cmd ]
186211
@@ -231,8 +256,8 @@ def run(self, lib, opts, args):
231256 print_data_keys (data , item )
232257 else :
233258 fmt = [opts .format ][0 ] if opts .format else None
234- print_data (data , item , fmt )
259+ print_data (data , item , fmt , links = opts . links )
235260 first = False
236261
237262 if opts .summarize :
238- print_data (summary )
263+ print_data (summary , links = opts . links )
0 commit comments