Skip to content

Commit

Permalink
server: support show/play a playlist model (#861)
Browse files Browse the repository at this point in the history
  • Loading branch information
cosven authored Aug 6, 2024
1 parent 6a1fec7 commit d3d95e5
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 45 deletions.
27 changes: 24 additions & 3 deletions feeluown/server/handlers/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
from difflib import SequenceMatcher
from typing import Any

from feeluown.library import resolve, reverse
from feeluown.library import (
resolve, reverse, BriefSongModel, BriefPlaylistModel,
SupportsPlaylistSongsReader,
)
from .base import AbstractHandler
from .excs import HandlerException


def score(src, tar):
Expand Down Expand Up @@ -47,12 +51,29 @@ def handle(self, cmd): # pylint: disable=inconsistent-return-statements
self.player.toggle()

def play(self, s): # pylint: disable=inconsistent-return-statements
# pylint: disable=no-else-return
# pylint: disable=no-else-return,too-many-branches
if s.startswith('fuo://'):
model = resolve(s)
if model is None:
return 'Invalid fuo uri.'
self._app.playlist.play_model(model)
elif isinstance(model, BriefSongModel):
self._app.playlist.play_model(model)
elif isinstance(model, BriefPlaylistModel):
provider = self._app.library.get(model.source)
if isinstance(provider, SupportsPlaylistSongsReader):
reader = provider.playlist_create_songs_rd(model)
songs = reader.readall()
self._app.playlist.set_models(songs, next_=True)
self._app.player.resume()
else:
raise HandlerException(
f"provider:{provider.identifier} does not support"
" SupportsPlaylistSongsReader"
)
else:
model_type = model.meta.model_type
raise HandlerException(f"can't play this model type: {model_type}")

return
elif s.startswith('http'):
return self.player.play(s, video=False)
Expand Down
12 changes: 7 additions & 5 deletions feeluown/server/handlers/playlist.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from feeluown.library import ModelType
from feeluown.library import ModelType, SupportsPlaylistSongsReader
from feeluown.library import resolve, reverse
from feeluown.utils.utils import to_readall_reader
from .base import AbstractHandler


Expand Down Expand Up @@ -32,9 +31,12 @@ def add(self, furi_list):
if obj_type == ModelType.song:
playlist.add(obj)
elif obj_type == ModelType.playlist:
songs = to_readall_reader(obj, "songs").readall()
for song in songs:
playlist.add(song)
provider = self.library.get(obj.source)
if isinstance(provider, SupportsPlaylistSongsReader):
reader = provider.playlist_create_songs_rd(obj)
for song in reader:
playlist.add(song)
# TODO: raise error if it does not support

def remove(self, song_uri):
# FIXME: a little bit tricky
Expand Down
20 changes: 14 additions & 6 deletions feeluown/server/handlers/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
from functools import wraps
from urllib.parse import urlparse

from feeluown.utils.utils import to_readall_reader
from feeluown.utils.router import Router, NotFound
from feeluown.library import ResourceNotFound
from feeluown.library import NS_TYPE_MAP
from feeluown.library import ModelType
from feeluown.library import (
ResourceNotFound, NS_TYPE_MAP, ModelType,
SupportsPlaylistSongsReader, SupportsArtistAlbumsReader,
)

from .base import AbstractHandler
from .excs import HandlerException
Expand Down Expand Up @@ -120,12 +120,20 @@ def lyric_(req, provider, sid):
@use_provider
def playlist_songs(req, provider, pid):
playlist = get_model_or_raise(req.ctx['library'], provider, ModelType.playlist, pid)
return to_readall_reader(playlist, 'songs').readall()
if isinstance(provider, SupportsPlaylistSongsReader):
reader = provider.playlist_create_songs_rd(playlist)
return reader.readall()
raise HandlerException(f"provider:{provider.identifier} does not support"
f" {SupportsPlaylistSongsReader}")


@route('/<provider>/artists/<aid>/albums')
@use_provider
def albums_of_artist(req, provider, aid):
"""show all albums of an artist identified by artist id"""
artist = get_model_or_raise(req.ctx['library'], provider, ModelType.artist, aid)
return to_readall_reader(artist, 'albums').readall()
if isinstance(provider, SupportsArtistAlbumsReader):
reader = provider.artist_create_albums_rd(artist)
return reader.readall()
raise HandlerException(f"provider:{provider.identifier} does not support"
f" {SupportsArtistAlbumsReader}")
31 changes: 0 additions & 31 deletions feeluown/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
from functools import wraps
from itertools import filterfalse

from feeluown.utils.reader import wrap as reader_wrap


logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -90,34 +87,6 @@ def get_osx_theme():
return 1 if theme == 'Dark' else -1


def to_reader(model, field):
flag_attr = 'allow_create_{}_g'.format(field)
method_attr = 'create_{}_g'.format(field)

flag_g = getattr(model.meta, flag_attr)

if flag_g:
return reader_wrap(getattr(model, method_attr)())

value = getattr(model, field, None)
if value is None:
return reader_wrap([])
if isinstance(value, (list, tuple)):
return reader_wrap(value)
return reader_wrap(iter(value)) # TypeError if not iterable


def to_readall_reader(*args, **kwargs):
"""
hack: set SequentialReader reader's count to 1000 if it is None
so that we can call readall method.
"""
reader = to_reader(*args, **kwargs)
if reader.count is None:
reader.count = 1000
return reader


class DedupList(list):
"""List that doesn't contain duplicate items
Expand Down

0 comments on commit d3d95e5

Please sign in to comment.