[WIP] API adaptations for music.mpd
This commit is contained in:
parent
4e8c6dd435
commit
c3015bc687
2 changed files with 116 additions and 21 deletions
|
@ -333,6 +333,15 @@ class MusicMopidyPlugin(RunnablePlugin):
|
||||||
|
|
||||||
:return: .. schema:: mopidy.MopidyStatusSchema
|
:return: .. schema:: mopidy.MopidyStatusSchema
|
||||||
"""
|
"""
|
||||||
|
# Note: stop could be interpreted both as "stop the playback" and "stop
|
||||||
|
# the plugin". If the stop event is set, we assume that the user wants
|
||||||
|
# to stop the plugin.
|
||||||
|
if self.should_stop():
|
||||||
|
if self._client:
|
||||||
|
self._client.stop()
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
return self._exec_with_status({'method': 'core.playback.stop'})
|
return self._exec_with_status({'method': 'core.playback.stop'})
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
|
|
@ -116,6 +116,33 @@ class MusicMpdPlugin(MusicPlugin, RunnablePlugin):
|
||||||
|
|
||||||
return None, error
|
return None, error
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _dump_directory(item: dict):
|
||||||
|
item['type'] = 'directory'
|
||||||
|
item['uri'] = item['name'] = item['directory']
|
||||||
|
return item
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _dump_playlist(item: dict):
|
||||||
|
item['type'] = 'playlist'
|
||||||
|
item['uri'] = item['name'] = item['playlist']
|
||||||
|
item['last_modified'] = item.pop('last-modified', None)
|
||||||
|
return item
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _dump_track(item: dict, pos: Optional[int] = None):
|
||||||
|
item['type'] = 'track'
|
||||||
|
item['uri'] = item['file']
|
||||||
|
for attr in ('time', 'track', 'disc'):
|
||||||
|
item[attr] = int(item[attr]) if item.get(attr) is not None else None
|
||||||
|
|
||||||
|
if 'pos' in item:
|
||||||
|
item['playlist_pos'] = int(item.pop('pos'))
|
||||||
|
elif pos is not None:
|
||||||
|
item['playlist_pos'] = pos
|
||||||
|
|
||||||
|
return item
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def play(self, resource: Optional[str] = None, **__):
|
def play(self, resource: Optional[str] = None, **__):
|
||||||
"""
|
"""
|
||||||
|
@ -169,6 +196,15 @@ class MusicMpdPlugin(MusicPlugin, RunnablePlugin):
|
||||||
@action
|
@action
|
||||||
def stop(self, *_, **__): # type: ignore
|
def stop(self, *_, **__): # type: ignore
|
||||||
"""Stop playback"""
|
"""Stop playback"""
|
||||||
|
# Note: stop could be interpreted both as "stop the playback" and "stop
|
||||||
|
# the plugin". If the stop event is set, we assume that the user wants
|
||||||
|
# to stop the plugin.
|
||||||
|
if self.should_stop():
|
||||||
|
if self.client:
|
||||||
|
self.client.disconnect()
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
return self._exec('stop')
|
return self._exec('stop')
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -344,17 +380,44 @@ class MusicMpdPlugin(MusicPlugin, RunnablePlugin):
|
||||||
self._exec('rm', p)
|
self._exec('rm', p)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def move(self, from_pos, to_pos):
|
def move(
|
||||||
|
self,
|
||||||
|
start: Optional[int] = None,
|
||||||
|
end: Optional[int] = None,
|
||||||
|
position: Optional[int] = None,
|
||||||
|
from_pos: Optional[int] = None,
|
||||||
|
to_pos: Optional[int] = None,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Move the playlist item in position <from_pos> to position <to_pos>
|
Move the playlist items from the positions ``start`` to ``end`` to the
|
||||||
|
new position ``position``.
|
||||||
|
|
||||||
:param from_pos: Track current position
|
You can pass either:
|
||||||
:type from_pos: int
|
|
||||||
|
|
||||||
:param to_pos: Track new position
|
- ``start``, ``end`` and ``position`` to move a slice of tracks
|
||||||
:type to_pos: int
|
from ``start`` to ``end`` to the new position ``position``.
|
||||||
|
- ``from_pos`` and ``to_pos`` to move a single track from
|
||||||
|
``from_pos`` to ``to_pos``.
|
||||||
|
|
||||||
|
.. note: Positions are 0-based (i.e. the first track has position 0).
|
||||||
|
|
||||||
|
:param start: Start position of the selection.
|
||||||
|
:param end: End position of the selection.
|
||||||
|
:param position: New position.
|
||||||
|
:param from_pos: Alias for ``start`` - it only works with one track at
|
||||||
|
the time.
|
||||||
|
:param to_pos: Alias for ``position`` - it only works with one track at
|
||||||
|
the time.
|
||||||
"""
|
"""
|
||||||
return self._exec('move', from_pos, to_pos)
|
assert (start is not None and end is not None and position is not None) or (
|
||||||
|
from_pos is not None and to_pos is not None
|
||||||
|
), 'Specify either (start, end, position) or (from_pos, to_pos)'
|
||||||
|
|
||||||
|
if from_pos is not None and to_pos is not None:
|
||||||
|
return self._exec('move', from_pos, to_pos)
|
||||||
|
|
||||||
|
chunk = start if start == end else f'{start}:{end}'
|
||||||
|
return self._exec('move', chunk, position)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _parse_resource(cls, resource):
|
def _parse_resource(cls, resource):
|
||||||
|
@ -546,7 +609,10 @@ class MusicMpdPlugin(MusicPlugin, RunnablePlugin):
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
return self._exec('playlistinfo', return_status=False)
|
return [
|
||||||
|
self._dump_track(track, pos=i) # type: ignore
|
||||||
|
for i, track in enumerate(self._exec('playlistinfo', return_status=False))
|
||||||
|
]
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def get_playlists(self, *_, **__):
|
def get_playlists(self, *_, **__):
|
||||||
|
@ -558,11 +624,11 @@ class MusicMpdPlugin(MusicPlugin, RunnablePlugin):
|
||||||
output = [
|
output = [
|
||||||
{
|
{
|
||||||
"playlist": "Rock",
|
"playlist": "Rock",
|
||||||
"last-modified": "2018-06-25T21:28:19Z"
|
"last_modified": "2018-06-25T21:28:19Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"playlist": "Jazz",
|
"playlist": "Jazz",
|
||||||
"last-modified": "2018-06-24T22:28:29Z"
|
"last_modified": "2018-06-24T22:28:29Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
# ...
|
# ...
|
||||||
|
@ -573,22 +639,27 @@ class MusicMpdPlugin(MusicPlugin, RunnablePlugin):
|
||||||
playlists: list = self._exec( # type: ignore
|
playlists: list = self._exec( # type: ignore
|
||||||
'listplaylists', return_status=False
|
'listplaylists', return_status=False
|
||||||
)
|
)
|
||||||
return sorted(playlists, key=lambda p: p['playlist'])
|
|
||||||
|
return sorted(
|
||||||
|
[self._dump_playlist(pl) for pl in playlists], key=lambda p: p['playlist']
|
||||||
|
)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def get_playlist(self, playlist: str, *_, with_tracks: bool = False, **__):
|
def get_playlist(self, playlist: str, *_, **__):
|
||||||
"""
|
"""
|
||||||
List the information (and, optionally, the items) for the specified playlist.
|
Get the tracks in a playlist.
|
||||||
|
|
||||||
:param playlist: Name of the playlist
|
:param playlist: Name of the playlist
|
||||||
:param with_tracks: If True then the list of tracks in the playlist will
|
|
||||||
be returned as well (default: False).
|
|
||||||
"""
|
"""
|
||||||
return self._exec(
|
return [
|
||||||
'listplaylistinfo' if with_tracks else 'listplaylist',
|
self._dump_track(track) # type: ignore
|
||||||
playlist,
|
for track in self._exec(
|
||||||
return_status=False,
|
'listplaylistinfo', # if with_tracks else 'listplaylist',
|
||||||
)
|
playlist,
|
||||||
|
return_status=False,
|
||||||
|
)
|
||||||
|
if track
|
||||||
|
]
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def add_to_playlist(
|
def add_to_playlist(
|
||||||
|
@ -663,12 +734,27 @@ class MusicMpdPlugin(MusicPlugin, RunnablePlugin):
|
||||||
|
|
||||||
:param uri: URI to browse (default: root directory).
|
:param uri: URI to browse (default: root directory).
|
||||||
"""
|
"""
|
||||||
return (
|
resp: dict = ( # type: ignore
|
||||||
self._exec('lsinfo', uri, return_status=False)
|
self._exec('lsinfo', uri, return_status=False)
|
||||||
if uri
|
if uri
|
||||||
else self._exec('lsinfo', return_status=False)
|
else self._exec('lsinfo', return_status=False)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ret = []
|
||||||
|
for item in resp:
|
||||||
|
if item.get('directory'):
|
||||||
|
item = self._dump_directory(item)
|
||||||
|
elif item.get('playlist'):
|
||||||
|
item = self._dump_playlist(item)
|
||||||
|
elif item.get('file'):
|
||||||
|
item = self._dump_track(item)
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
ret.append(item)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def plchanges(self, version: int):
|
def plchanges(self, version: int):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in a new issue