Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support import of ListenBrainz recommendations playlists #1

Merged
merged 15 commits into from
May 16, 2024

Conversation

orontee
Copy link
Contributor

@orontee orontee commented Mar 23, 2024

Proposal

The proposed branch adds support for playlists returned by the playlists created for endpoint (recommendations playlists) from ListenBrainz API.

AFAICT the returned playlists are made of suggestions taken from previously listened tracks.

Implementation

The playlist descriptions are fetched by the existing Mopidy frontend during setup. Mopidy-Local database is then searched for matching tracks and Mopidy playlists are created using a trivial Mopidy backend dedicated to those playlists management.

The playlist import must be enabled using a new configuration key import_playlists (default to false).

Playlists are periodically updated (each week, on monday).

Possible improvements

  • Import all user playlists, not only recommendations
  • Make user playlists editable and synchronized with Listenbrainz
  • Import playlists from other users, but doesn't make much sense if one doesn't have a huge local library... What do you think?

Test

python -m pip install --upgrade --break-system-packages git+https://github.com/orontee/mopidy-listenbrainz.git@feature/playlists

Tried with both Argos and Iris.

image

image

@orontee
Copy link
Contributor Author

orontee commented Mar 23, 2024

Something is wrong with current implementation because .m3u8 files are created; It looks like the created playlists are handled by Mopidy-M3U and not the introduced backend...

UPDATE: Fixed an import exception with Mopidy 3.4.2, also missing name while creating playlists, and finally missing tracks.

@orontee orontee force-pushed the feature/playlists branch from 9fd3925 to b487711 Compare March 23, 2024 20:57
@orontee orontee force-pushed the feature/playlists branch from d23988f to 5e830db Compare March 23, 2024 22:27
@orontee orontee force-pushed the feature/playlists branch from 3c62f20 to 294de17 Compare March 27, 2024 22:43
@orontee orontee changed the title Support import of ListenBrainz playlists Support import of ListenBrainz recommendations playlists Mar 29, 2024
@orontee orontee force-pushed the feature/playlists branch from ca2f78d to 96deeeb Compare March 29, 2024 06:15
@suaviloquence
Copy link
Owner

Thanks for the PR! Sorry for being so late, for some reason github did not notify me about it.

@orontee
Copy link
Contributor Author

orontee commented May 12, 2024

FYI, there's a regression in Iris, jaedb/Iris#953

Copy link
Owner

@suaviloquence suaviloquence left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good but I can't test it super well because I don't have the songs in my local backend. If you wanted to add configuration (here, in another PR) for that it would be awesome but I can still merge this one without it.

README.rst Outdated
@@ -45,7 +45,8 @@ The following configuration values are available:
Defaults to enabled.
- ``listenbrainz/token``: Your `Listenbrainz user token <https://listenbrainz.org/profile/>`_
- ``listenbrainz/url``: The URL of the API of the Listenbrainz instance to record listens to (default: api.listenbrainz.org)

- ``listenbrainz/import_playlists``: Whether to import Listenbrainz playlists (default: ``false``)
- ``listenbrainz/periodic_playlists_update``: Enable periodic import of Listenbrainz playlists (default: ``true``)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- ``listenbrainz/periodic_playlists_update``: Enable periodic import of Listenbrainz playlists (default: ``true``)
- ``listenbrainz/update_playlists``: Enable periodic import of Listenbrainz playlists (default: ``true``)

or something to keep the verb_noun order consistent. let me know if you think there's a better name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand and like the verb_noun paradigm.

May I suggest update_playlists_periodically, or monitor_playlists?

Copy link
Contributor Author

@orontee orontee May 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking for a meaning full name, I realized that this configuration key is useless. Listenbrainz generates new recommendation playlists on each Monday, why would a user import playlists once and refuse to update when new recommendations are published? If Mopidy is restarted for whatever reason, the new recommendations are imported! Non-sense.

I thus propose to remove this configuration key.

mopidy_listenbrainz/ext.conf Show resolved Hide resolved
mopidy_listenbrainz/backend.py Outdated Show resolved Hide resolved
mopidy_listenbrainz/frontend.py Outdated Show resolved Hide resolved
# finally be deleted

logger.debug(f"Already known playlist {playlist_uri}")
# maybe there're new tracks in Mopidy's database...
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean that the playlist has been updated since import? Do the playlists change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my experience, the playlists don't change from Listenbrainz backend point of view (but can't find the information in their documentation). From mopidy's point of view, they may change due to new tracks being imported in the library. The comment is related to that part.

mopidy_listenbrainz/frontend.py Outdated Show resolved Hide resolved
)
# search only in local database since other backends can
# be quite long to answer, should we offer choice through
# config?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be useful. For me no playlists are showing up because I use the mopidy-subidy extension exclusively

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@suaviloquence The track search is not limited to Mopidy-Local anymore. The default is to search through all backends. The search_schemes configuration key allows to specify a list of schemes to limit the results to URIs with the given schemes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arggg... I just tried with my living room instance of Mopidy, a "production instance" with multiple backends. And
some backends seems to not support search by musicbrainz_trackid and not respect the API...

No idea how to fix this...

mai 14 22:18:07 argos mopidy[1925]: INFO     [ListenbrainzFrontend-15 (_actor_loop)] mopidy_listenbrainz.frontend Importing ListenBrainz playlists
mai 14 22:18:08 argos mopidy[1925]: INFO     [InternetArchiveBackend-6 (_actor_loop)] mopidy_internetarchive.library Not searching Mopidy-InternetArchive: Keyword "musicbrainz_trackid" not supported
mai 14 22:18:08 argos mopidy[1925]: ERROR    [Core-11 (_actor_loop)] mopidy.core.library FileBackend backend returned bad data: Expected a SearchResult instance, not []
mai 14 22:18:08 argos mopidy[1925]: ERROR    [Core-11 (_actor_loop)] mopidy.core.library StreamBackend backend returned bad data: Expected a SearchResult instance, not []

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to have local: as default scheme for track searches and keep the documentation for users to be able to adapt to their favorite backend but warn them about many backends not supporting searches by musicbrainz id... Simple and acceptable to start with I guess.

@orontee
Copy link
Contributor Author

orontee commented May 13, 2024

It looks good but I can't test it super well because I don't have the songs in my local backend. If you wanted to add configuration (here, in another PR) for that it would be awesome but I can still merge this one without it.

Good point. I'll do it here, next week seems reasonable.

Copy link
Owner

@suaviloquence suaviloquence left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, awesome! ❤️ There are a few bugs about default config, but I think these suggestions should take care of that, let me know if they don't. Thanks for your work on this!

mopidy_listenbrainz/ext.conf Outdated Show resolved Hide resolved
mopidy_listenbrainz/frontend.py Outdated Show resolved Hide resolved
mopidy_listenbrainz/frontend.py Outdated Show resolved Hide resolved

for track_mbid in playlist_data.track_mbids:
query = self.library.search(
{"musicbrainz_trackid": [track_mbid]}, uris=search_schemes
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For an enhancement later (doesn't need to be in this PR), does LB expose the artist/track name in the playlist response? Might help with finding tracks without tagged MBIDs (or maybe from a different album) if so.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I received recommendations on this topic in the Listenbrainz channel on Discourse: See https://community.metabrainz.org/t/support-for-recommendations-in-mopidy-listenbrainz/688258/6

@suaviloquence
Copy link
Owner

Also feel free to take credit and link yourself in the credits section of README.rst for your awesome work!

@suaviloquence suaviloquence merged commit f334052 into suaviloquence:master May 16, 2024
@suaviloquence
Copy link
Owner

🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants