You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This PR adds six typed flexible attributes to the Tidal plugin that are populated during album/track imports, and introduces a new beet tidalsync command to refresh popularity data post-import.
- Add item_types ClassVar with tidal_track_id, tidal_album_id,
tidal_artist_id, tidal_track_popularity, tidal_alb_popularity,
tidal_updated fields
- Populate flexattrs during album/track import via AlbumInfo/TrackInfo
kwargs
- Add beet tidalsync command to refresh popularity data post-import
- Add tidal fields to REIMPORT_FRESH_FIELDS_ITEM for reimport support
- Add tests for flexattr population and tidalsync behavior
- Update tidal plugin docs with attribute reference and tidalsync usage
❌ Patch coverage is 57.37705% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.50%. Comparing base (60047df) to head (ab2a9ce).
✅ All tests successful. No failed tests found.
The reason will be displayed to describe this comment to others. Learn more.
It looks like we're now storing the same track ID twice in the database: track_id and tidal_track_id.
Summoning @snejus ;) What's our preferred approach here? Should we consolidate these?
The reason will be displayed to describe this comment to others. Learn more.
I am not sure we can consolidate. All the other plugins (bandcamp, spotify, etc. store bandcamp_album_id, spotify_album_id as flexattrs). Until we can make musicbrainz completely optional, I feel we keep them for consistency with the plugin ecosystem pattern (other metadata plugins store their own *_id flexattrs), but we should get @snejus's input.
Also makes queries like tidal_track_id unambiguous without needing to know which standard field maps to which source.
The reason will be displayed to describe this comment to others. Learn more.
I see two separate topics here:
1. <source>_album_id set by musicbrainz
musicbrainz sets <source>_album_id flex attr - this is reliable information, and it's a good idea to record those. However, we aren't making any use of them currently.
A potential use case could be something like:
Extend autotagging candidates with a result for each of the URLs (using the corresponding plugin, if enabled).
2. Everything else
I only see problems with setting source-specific <source>_{artist,label,track,album}_id etc. fields:
They can stay around even after data_source changes. That makes the fields look authoritative when they may just be stale leftovers from a previous tag source.
Our current source of truth is already confusing: mb_albumid, mb_trackid, and mb_artistid are the fields that drive a lot of beets behavior, but in practice they can contain source-specific IDs, not only MusicBrainz IDs. Adding more provider-specific ID fields without clarifying that model risks making this ambiguity worse.
They become part of the user-visible data model, but without a clear contract around naming, ownership, or semantics.
They are easy to write and hard to make useful. If no code reads them, we are mostly creating permanent metadata surface area that has to be documented, migrated, tested, and kept consistent across plugins.
So I think recording a source ID is fine when it has a concrete consumer or when the plugin is preserving the exact source used for a match. But I would avoid adding more provider-specific ID fields as a general pattern until we have a shared abstraction and an actual feature that uses them.
The reason will be displayed to describe this comment to others. Learn more.
musicbrainz sets _album_id flex attr - this is reliable information, and it's a good idea to record those. However, we aren't making any use of them currently.
We use the same pattern here and it looks like we actually make use of it here: We can get the popularity values (from tidal) via these ids. Even for albums/tracks that are initially tagged via musicbrainz if they include the tidal_album_id.
Sorry about the iterative comments. Im coming back to this whenever I have time or thought about something ;)
I just noticed that albums on tidal also have popularity values. I would vote we make popularity work for both tracks and albums (currently it only works for tracks, right?). Maybe a general tidal_popularity flex attribute could work?
I'm also able to make some changes if you feel like it gets too much give me a headsup 😨
Sorry about the iterative comments. Im coming back to this whenever I have time or thought about something ;)
I just noticed that albums on tidal also have popularity values. I would vote we make popularity work for both tracks and albums (currently it only works for tracks, right?). Maybe a general tidal_popularity flex attribute could work?
I'm also able to make some changes if you feel like it gets too much give me a headsup 😨
We have tidal_album_popularity to be explicit and avoid any confusion. Updated the parsing based on your comments.
Please don't worry about it. Happy to work with you on this and get this merged. Thanks for all your guidance, and by all means, feel free to improve upon it.
Replace tidalsync() with sync_item_popularity() / sync_album_popularity()
backed by a shared _sync_popularity() helper.
Split the `tidal` command into `tidal` (auth-only) and `tidalsync`
(popularity sync with --item, --album, --force, --write flags). While
I liked the tidal [auth|sync] it is currently not well supported in beets
and e.g. help pages are lacking.
Accept int IDs throughout the search pipeline to avoid unnecessary
str conversions.
@arsaboo Just enhanced the sync logic a bit. Make sure to pull ;) Please have a look! Am mostly happy with the changes but ofcourse if you see something or have a better idea, lets discuss.
The reason will be displayed to describe this comment to others. Learn more.
I used mb_trackid intentionally. If we want to keep it as tidal_track_id, we'll need a way to migrate the existing mb_trackid values into the tidal_track_id flex field for users who were using the plugin before flex fields were introduced.
Is there a command that copies mb_trackid values into the tidal_track_id flex field? If so, we can mention it in the changelog, and I'm happy with that approach. 🙂
The reason will be displayed to describe this comment to others. Learn more.
mb_trackid is a MusicBrainz UUID, while tidal_track_id is an integer (type mismatch). The Tidal API cannot be called with a MusicBrainz ID. So using mb_trackid as the id_field would have other unintended consequences. I don't think that is the right path. Users can re-import or create a custom script.
One option is to try tidal_track_id first and, if missing, fall back to mb_trackid (I don't think this is a good idea, but I will defer to your judgment).
The reason will be displayed to describe this comment to others. Learn more.
That's not how it currently works, unfortunately. The mb_trackid field stores the ID corresponding to the data_source, this is what I was referring to as duplication in my other comment. For example, if data_source == "tidal", then mb_trackid will always contain the TIDAL track ID.
What I had in mind instead was a simple beets command that migrates all mb_*id values for models where data_source == "tidal" into the new flex fields. Otherwise, users who have previously used the TIDAL plugin won't be able to use sync after these changes unless they manually fix their libraries (me included :/)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds six typed flexible attributes to the Tidal plugin that are populated during album/track imports, and introduces a new
beet tidalsynccommand to refresh popularity data post-import.cc: @semohr
Flexible Attributes (
item_types)tidal_track_id,tidal_album_id,tidal_artist_id— INTEGER fields for Tidal entity IDs.tidal_track_popularity,tidal_alb_popularity— INTEGER (0–100) normalized popularity scores.tidal_updated— DATE timestamp of last sync.Import population
_get_album_info()and_get_track_info()pass the new fields through toAlbumInfo/TrackInfo, which store them as flexattrs on the item._popularity()helper normalizes float/int/None from the Tidal API.Reimport support
REIMPORT_FRESH_FIELDS_ITEMso they refresh on reimport.beet tidalsynccommandtidal_track_id, and updatestidal_track_popularity+tidal_updated.--force/-f— re-fetch even if data already exists.--write/-w— write updated tags to media files.beet tidalsync artist:Miles).Documentation & Tests
Attribute reference table and command usage examples in
docs/plugins/tidal.rst.Flexattr assertions in existing tests, new
TestPopularityandTestTidalsynctest classes.Documentation. (If you've added a new command-line flag, for example, find the appropriate page under
docs/to describe it.)Changelog. (Add an entry to
docs/changelog.rstto the bottom of one of the lists near the top of the document.)Tests. (Very much encouraged but not strictly required.)