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

Lookup track metadata for MPD load and listplaylistinfo #1621

Merged
merged 3 commits into from Apr 19, 2018

Conversation

kingosticks
Copy link
Member

This is the fix for #1511 that I forgot to submit.

Tests currently fail due to #1619.

@@ -38,6 +37,17 @@ def listplaylist(context, name):
return ['file: %s' % t.uri for t in playlist.tracks]


def _lookup_playlist(context, name):
uri = context.lookup_playlist_uri_from_name(name)
playlist = uri is not None and context.core.playlists.lookup(uri).get()
Copy link
Member

Choose a reason for hiding this comment

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

Would it be cleaner to spread this across normal ifs statements instead of statement and ...?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think this is OK and the same line is used throughout the file.

raise exceptions.MpdNoExistError('No such playlist')
track_uris = [track.uri for track in playlist.tracks]
tracks_map = context.core.library.lookup(uris=track_uris).get()
tracks = [track for u in track_uris for track in tracks_map[u]]
Copy link
Member

Choose a reason for hiding this comment

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

Not a huge fan of these nested for loops like this, I tend to get confused about which one is the inner one.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed.

@kingosticks kingosticks force-pushed the fix/mpd-load-tracklist-metadata branch from a4a1c4f to e23c2e7 Compare June 16, 2017 00:39
@kingosticks
Copy link
Member Author

kingosticks commented Jun 16, 2017

I'm really glad you prompted to me to take another look at this. I'd managed to mess up load: it didn't need to lookup the tracks since I was already getting that for free with tracklist.add(uris=track_uris). And as part of refactoring everything to use my new _get_playlist helper I discovered a bug and lack of testing in the cases where core.playlists.save fails. I just hacked in a mechanism to force DummyPlaylistsProvider.save to fail (it's late), maybe some mocking is better? I'm all ears to a cleaner solution.

playlist = None
uri = context.lookup_playlist_uri_from_name(name)
if uri:
playlist = context.core.playlists.lookup(uri).get()
Copy link
Member

Choose a reason for hiding this comment

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

Should we be using mopidy.core.PlaylistsController.get_items to reduce how much we lookup?

Feel free to postpone this for this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not doing the full track lookups in here anymore, these are just refs since other than for listplaylistinfo that's all we ever want.

Copy link
Member

Choose a reason for hiding this comment

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

core.playlist.lookup() returns a Playlist object with full Track objects in its Playlist.tracks field. The core playlist API seems to be missing a way to get a playlist Ref with just the name of the playlist other than using core.playlist.as_list() and filtering the returned playlist Refs by URI yourself. We should consider making an equivalent of core.playlist.lookup() to get a playlist Ref.

I see nothing wrong in the implementation of _get_playlist() in this PR. It makes nothing worse and reduces a bunch of duplication. Improving the core playlists API can come later.

👍

Copy link
Member Author

Choose a reason for hiding this comment

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

I am completely confused regarding my original reply. I have no idea why I thought I was getting Refs from core.PlaylistsController.lookup(). @adamcik your suggestion of core.PlaylistsController.get_items() seems much better and I can only assume that's what I thought I was getting from lookup()! But then that doesn't fit with what I've done here since some of these routines do need the full Track objects and some don't. And this change makes listplaylistinfo lookup the Tracks twice which is a bit weird.


with warnings.catch_warnings():
warnings.filterwarnings('ignore', 'tracklist.add.*"tracks".*')
context.core.tracklist.add(playlist.tracks[playlist_slice]).get()
Copy link
Member

Choose a reason for hiding this comment

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

We might as well keep adding the track ignoring warnings if we are looking up the playlist in a way which gets full tracks. Unless we switch to just getting refs like the comment above mentions.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't understand. My track_uris here are Track Refs. Wasn't the intent here to catch deprecation warnings? Which are not longer being emitted since I'm using the uris parameter instead of tracks?

Copy link
Member

Choose a reason for hiding this comment

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

The track variable here is actually full Track objects, but I guess the point of this PR is to do a new lookup of the tracks on load and listplaylistinfo in case the backend doesn't provided complete information in the returned Track objects.

👍

uri = context.lookup_playlist_uri_from_name(name)
if uri:
playlist = context.core.playlists.lookup(uri).get()
if must_exist and not playlist:
Copy link
Member

@jodal jodal Jun 25, 2017

Choose a reason for hiding this comment

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

s/not playlist/playlist is None/, so you don't error on empty playlists (in a future where Playlist might implement a container ABC).

@jodal jodal added A-mpd C-enhancement Category: A PR with an enhancement or an issue with an enhancement proposal labels Mar 31, 2018
@jodal jodal added this to the v2.2 milestone Apr 9, 2018
@kingosticks
Copy link
Member Author

What can I do to finish this off?

@@ -340,6 +397,22 @@ def test_playlistmove(self):
"dummy:c",
self.backend.playlists.get_items('dummy:a1').get()[0].uri)

def test_playlistmove_save_falis(self):
Copy link
Member

Choose a reason for hiding this comment

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

s/falis/fails/

self.assertEqual(1, len(tracks))
self.assertEqual('dummy:a', tracks[0].uri)
self.assertEqual('Track A', tracks[0].name)
self.assertEqual(5000, tracks[0].length)
Copy link
Member

Choose a reason for hiding this comment

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

I'd flip the arguments on the previous four lines.

playlist = None
uri = context.lookup_playlist_uri_from_name(name)
if uri:
playlist = context.core.playlists.lookup(uri).get()
Copy link
Member

Choose a reason for hiding this comment

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

core.playlist.lookup() returns a Playlist object with full Track objects in its Playlist.tracks field. The core playlist API seems to be missing a way to get a playlist Ref with just the name of the playlist other than using core.playlist.as_list() and filtering the returned playlist Refs by URI yourself. We should consider making an equivalent of core.playlist.lookup() to get a playlist Ref.

I see nothing wrong in the implementation of _get_playlist() in this PR. It makes nothing worse and reduces a bunch of duplication. Improving the core playlists API can come later.

👍


with warnings.catch_warnings():
warnings.filterwarnings('ignore', 'tracklist.add.*"tracks".*')
context.core.tracklist.add(playlist.tracks[playlist_slice]).get()
Copy link
Member

Choose a reason for hiding this comment

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

The track variable here is actually full Track objects, but I guess the point of this PR is to do a new lookup of the tracks on load and listplaylistinfo in case the backend doesn't provided complete information in the returned Track objects.

👍

@jodal
Copy link
Member

jodal commented Apr 14, 2018

Also, please add a changelog entry.

@kingosticks kingosticks force-pushed the fix/mpd-load-tracklist-metadata branch from 08303bf to e87599a Compare April 15, 2018 20:22
@kingosticks
Copy link
Member Author

Addressed comments, except the warning thing, I'm not sure what makes sense there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category: A PR with an enhancement or an issue with an enhancement proposal
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants