[Feature] Musicbrainz/Discogs terminal links#6453
[Feature] Musicbrainz/Discogs terminal links#6453Nukesor wants to merge 2 commits intobeetbox:masterfrom
Conversation
a52a4ad to
bd2b15f
Compare
There was a problem hiding this comment.
Pull request overview
grug see PR add small QoL for beet info: make MusicBrainz/Discogs ids show as clickable terminal link when user pass --links.
Changes:
- add
--linksflag toinfoplugin and wrap known external-id fields with OSC 8 hyperlink escape - add
ui.terminal_link()helper for building terminal hyperlinks - add docs + changelog entry + test for link output
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
beetsplug/info.py |
add --links option and map id fields to URL templates, then wrap values with ui.terminal_link() |
beets/ui/__init__.py |
add terminal_link() helper that emits OSC 8 escape sequences |
test/plugins/test_info.py |
add regression test asserting id fields become terminal links with --links |
docs/plugins/info.rst |
document new --links option |
docs/changelog.rst |
add unreleased changelog entry for new flag |
.gitignore |
ignore uv.lock |
|
I also considered adding a config for the info plugin, since I pretty much want those links to be there whenever I call info. Since the plugin didn't have a config yet, I wanted to wait for your feedback on this. |
aa2e263 to
3c61ef1
Compare
|
Had a quick glance - great direction! This has indeed been missing. On the other hand, I don't want this to be available through info only - I also want to be able to run I think you can generalize this by adding |
| FIELD_LINK_TEMPLATES: dict[str, str] = { | ||
| "mb_trackid": "https://musicbrainz.org/recording/{value}", | ||
| "mb_albumid": "https://musicbrainz.org/release/{value}", | ||
| "mb_artistid": "https://musicbrainz.org/artist/{value}", | ||
| "mb_albumartistid": "https://musicbrainz.org/artist/{value}", | ||
| "mb_releasetrackid": "https://musicbrainz.org/track/{value}", | ||
| "mb_releasegroupid": "https://musicbrainz.org/release-group/{value}", | ||
| "mb_workid": "https://musicbrainz.org/work/{value}", | ||
| "discogs_albumid": "https://www.discogs.com/release/{value}", | ||
| "discogs_artistid": "https://www.discogs.com/artist/{value}", | ||
| "discogs_labelid": "https://www.discogs.com/label/{value}", | ||
| } | ||
|
|
There was a problem hiding this comment.
We want to account for all possible data sources here, I think. See the logic I use in my CLI wrapper around beets database:
CASE
WHEN ${colmap[data_source]} == 'Discogs' THEN printf('https://discogs.com/release/%s',${colmap[release_id]})
WHEN ${colmap[data_source]} == 'Deezer' THEN printf('https://deezer.com/us/%s',iif(length(mb_albumid)>0,'album/'||mb_albumid,'track/'||mb_trackid))
WHEN ${colmap[data_source]} == 'Spotify' THEN printf('https://open.spotify.com/%s',iif(length(mb_albumid)>0,'album/'||mb_albumid,'track/'||mb_trackid))
WHEN ${colmap[data_source]} == 'MusicBrainz' THEN printf('https://musicbrainz.org/%s',iif(length(mb_albumid)>0,'release/'||mb_albumid,'recording/'||mb_trackid))
ELSE iif(instr(${colmap[release_id]}, '#'), substr(${colmap[release_id]}, 0, instr(${colmap[release_id]}, '#')), ${colmap[release_id]})
ENDThere was a problem hiding this comment.
^ This applies only to track and album URLs but you can see the idea
3c61ef1 to
a76ad95
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #6453 +/- ##
==========================================
+ Coverage 69.71% 69.74% +0.02%
==========================================
Files 145 145
Lines 18515 18524 +9
Branches 3015 3016 +1
==========================================
+ Hits 12908 12919 +11
+ Misses 4972 4971 -1
+ Partials 635 634 -1
🚀 New features to boost your workflow:
|
What exactly would $url be here? To be honest, I didn't fully get how
Which getters do you mean exactly? I just looked at the Album/Item models and they seem to have generic |
See @classmethod
def _getters(cls):
getters = plugins.item_field_getters()
getters["singleton"] = lambda i: i.album_id is None
getters["filesize"] = Item.try_filesize # In bytes.
return gettersand then $ beet list -f 'title: $title, size: $filesize' | head -10
title: Spadge, size: 411053212
title: The Hakke Show, size: 71675418
title: 01 SN MIX, size: 318295397
title: SN MIX 07, size: 445052073
title: Solar Hive, size: 6860941
title: Live, size: 42281264
title: DRILLCAST 67, size: 63227889
title: Hardcore 002, size: 43728569
title: Hardcore 081, size: 30001318
title: Hardcore 097, size: 27795958 |
|
I'll come back to this soon. I got super side-tracked with another project 😅 |
Description
This MR adds a neat little QoL feature that I was missing from beets.
When calling
beet info --links, external ids are now clickable terminal links, which directly open the respective website.I found myself needing this a lot when investigating why something got tagged wrong or when I was unsure whether I messed up a mapping.
Feel free to let me know if anything is missing.
Regarding the implementation, I considered using a library for the ANSI stuff, but since beets seems to roll its own escape handling, I decided to do the same :)
Oh, and I added the uv.lock to the gitignore. I regularily accidentally check it in and I need
uvto manage the python version. Let me know if this works out for you!Cheers!
To Do
docs/to describe it.)docs/changelog.rstto the bottom of one of the lists near the top of the document.)