Skip to content

Lookup track metadata for MPD load and listplaylistinfo#1621

Merged
jodal merged 3 commits intomopidy:developfrom
kingosticks:fix/mpd-load-tracklist-metadata
Apr 19, 2018
Merged

Lookup track metadata for MPD load and listplaylistinfo#1621
jodal merged 3 commits intomopidy:developfrom
kingosticks:fix/mpd-load-tracklist-metadata

Conversation

@kingosticks
Copy link
Copy Markdown
Member

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

Tests currently fail due to #1619.


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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
Member Author

@kingosticks kingosticks Jun 27, 2017

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
Copy Markdown
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
Copy Markdown
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).

@kingosticks
Copy link
Copy Markdown
Member Author

What can I do to finish this off?

"dummy:c",
self.backend.playlists.get_items('dummy:a1').get()[0].uri)

def test_playlistmove_save_falis(self):
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants