def _create_playlist(context, name, tracks): """ Creates new playlist using backend appropriate for the given tracks """ uri_schemes = set([urllib.parse.urlparse(t.uri).scheme for t in tracks]) for scheme in uri_schemes: new_playlist = context.core.playlists.create(name, scheme).get() if new_playlist is None: logger.debug( "Backend for scheme %s can't create playlists", scheme) continue # Backend can't create playlists at all new_playlist = new_playlist.replace(tracks=tracks) saved_playlist = context.core.playlists.save(new_playlist).get() if saved_playlist is not None: return # Created and saved else: continue # Failed to save using this backend # Can't use backend appropriate for passed URI schemes, use default one default_scheme = context.dispatcher.config[ 'mpd']['default_playlist_scheme'] new_playlist = context.core.playlists.create(name, default_scheme).get() if new_playlist is None: # If even MPD's default backend can't save playlist, everything is lost logger.warning("MPD's default backend can't create playlists") raise exceptions.MpdFailedToSavePlaylist(default_scheme) new_playlist = new_playlist.replace(tracks=tracks) saved_playlist = context.core.playlists.save(new_playlist).get() if saved_playlist is None: uri_scheme = urllib.parse.urlparse(new_playlist.uri).scheme raise exceptions.MpdFailedToSavePlaylist(uri_scheme)
def rename(context, old_name, new_name): """ *musicpd.org, stored playlists section:* ``rename {NAME} {NEW_NAME}`` Renames the playlist ``NAME.m3u`` to ``NEW_NAME.m3u``. """ _check_playlist_name(old_name) _check_playlist_name(new_name) old_playlist = _get_playlist(context, old_name) if _get_playlist(context, new_name, must_exist=False): raise exceptions.MpdExistError('Playlist already exists') # TODO: should we purge the mapping in an else? # Create copy of the playlist and remove original uri_scheme = urllib.parse.urlparse(old_playlist.uri).scheme new_playlist = context.core.playlists.create(new_name, uri_scheme).get() new_playlist = new_playlist.replace(tracks=old_playlist.tracks) saved_playlist = context.core.playlists.save(new_playlist).get() if saved_playlist is None: raise exceptions.MpdFailedToSavePlaylist(uri_scheme) context.core.playlists.delete(old_playlist.uri).get()
def playlistdelete(context, name, songpos): """ *musicpd.org, stored playlists section:* ``playlistdelete {NAME} {SONGPOS}`` Deletes ``SONGPOS`` from the playlist ``NAME.m3u``. """ _check_playlist_name(name) uri = context.lookup_playlist_uri_from_name(name) playlist = uri is not None and context.core.playlists.lookup(uri).get() if not playlist: raise exceptions.MpdNoExistError('No such playlist') try: # Convert tracks to list and remove requested tracks = list(playlist.tracks) tracks.pop(songpos) except IndexError: raise exceptions.MpdArgError('Bad song index') # Replace tracks and save playlist playlist = playlist.replace(tracks=tracks) saved_playlist = context.core.playlists.save(playlist).get() if saved_playlist is None: raise exceptions.MpdFailedToSavePlaylist( urllib.parse.urlparse(uri).scheme)
def playlistclear(context, name): """ *musicpd.org, stored playlists section:* ``playlistclear {NAME}`` Clears the playlist ``NAME.m3u``. The playlist will be created if it does not exist. """ _check_playlist_name(name) playlist = _get_playlist(context, name, must_exist=False) if not playlist: playlist = context.core.playlists.create(name).get() # Just replace tracks with empty list and save playlist = playlist.replace(tracks=[]) if context.core.playlists.save(playlist).get() is None: raise exceptions.MpdFailedToSavePlaylist( urllib.parse.urlparse(playlist.uri).scheme)
def playlistmove(context, name, from_pos, to_pos): """ *musicpd.org, stored playlists section:* ``playlistmove {NAME} {SONGID} {SONGPOS}`` Moves ``SONGID`` in the playlist ``NAME.m3u`` to the position ``SONGPOS``. *Clarifications:* - The second argument is not a ``SONGID`` as used elsewhere in the protocol documentation, but just the ``SONGPOS`` to move *from*, i.e. ``playlistmove {NAME} {FROM_SONGPOS} {TO_SONGPOS}``. """ if from_pos == to_pos: return _check_playlist_name(name) uri = context.lookup_playlist_uri_from_name(name) playlist = uri is not None and context.core.playlists.lookup(uri).get() if not playlist: raise exceptions.MpdNoExistError('No such playlist') if from_pos == to_pos: return # Nothing to do try: # Convert tracks to list and perform move tracks = list(playlist.tracks) track = tracks.pop(from_pos) tracks.insert(to_pos, track) except IndexError: raise exceptions.MpdArgError('Bad song index') # Replace tracks and save playlist playlist = playlist.replace(tracks=tracks) saved_playlist = context.core.playlists.save(playlist).get() if saved_playlist is None: raise exceptions.MpdFailedToSavePlaylist( urllib.parse.urlparse(uri).scheme)
def save(context, name): """ *musicpd.org, stored playlists section:* ``save {NAME}`` Saves the current playlist to ``NAME.m3u`` in the playlist directory. """ _check_playlist_name(name) tracks = context.core.tracklist.get_tracks().get() playlist = _get_playlist(context, name, must_exist=False) if not playlist: # Create new playlist _create_playlist(context, name, tracks) else: # Overwrite existing playlist new_playlist = playlist.replace(tracks=tracks) saved_playlist = context.core.playlists.save(new_playlist).get() if saved_playlist is None: raise exceptions.MpdFailedToSavePlaylist( urllib.parse.urlparse(playlist.uri).scheme)