async def render(self): playlist = self.playlist # show playlist title self.meta_widget.show() self.meta_widget.title = playlist.name # show playlist song list songs = songs_g = None with suppress(ProviderIOError): if playlist.meta.allow_create_songs_g: songs_g = GeneratorProxy.wrap(playlist.create_songs_g()) else: songs = await async_run(lambda: playlist.songs) self.show_songs(songs=songs, songs_g=songs_g, show_count=True) # show playlist cover if playlist.cover: aio.create_task( self.show_cover(playlist.cover, reverse(playlist, '/cover'))) def remove_song(song): playlist.remove(song.identifier) self.songs_table.remove_song_func = remove_song self.tabbar.show_desc_needed.connect( lambda: aio.create_task(self._show_desc()))
def create_g(func, identifier, field='songs', schema=None): if schema is None: schema = NestedSongSchema data = func(identifier, page=1) # user_favorite_songs 接口返回的数据有 total 字段, # 但 playlist_detail_v2 接口返回的数据没有 total 字段, # 这里取 pagingVO 结构体中的 count 字段值作为 total total = int(data['pagingVO']['count']) def g(): nonlocal data if data is None: yield from () else: paging = data['pagingVO'] # pagingVO 结构体中字段是 string 类型 page = int(paging['page']) page_size = int(paging['pageSize']) pages = int(paging['pages']) while page <= pages: obj_data_list = data[field] for obj_data in obj_data_list: yield _deserialize(obj_data, schema) page += 1 data = func(identifier, page, page_size) # FIXME: use SequentialRandomReader instead of GeneratorProxy return GeneratorProxy(g(), total)
async def render(self): playlist = self.playlist loop = asyncio.get_event_loop() songs = songs_g = None if playlist.meta.allow_create_songs_g: songs_g = GeneratorProxy.wrap(playlist.create_songs_g()) else: songs = await async_run(lambda: playlist.songs, loop=loop) self.show_songs(songs=songs, songs_g=songs_g, show_count=True) self.meta_widget.title = playlist.name desc = await async_run(lambda: playlist.desc) self.meta_widget.desc = desc if playlist.cover: loop.create_task(self.show_cover(playlist.cover)) def remove_song(song): model = self.songs_table.model() row = model.songs.index(song) msg = 'remove {} from {}'.format(song, playlist) with self._app.create_action(msg) as action: rv = playlist.remove(song.identifier) if rv: model.removeRow(row) else: action.failed() self.songs_table.song_deleted.connect(lambda song: remove_song(song))
def __init__(self, albums_g, fetch_image, parent=None): """ :param albums_g: :class:`fuocore.models.GeneratorProxy: """ super().__init__(parent) self.albums_g = GeneratorProxy.wrap(albums_g) self.fetch_image = fetch_image # false: no more, true: maybe more self._maybe_has_more = True self.albums = [] self.colors = [] self.pixmaps = {} # {uri: QPixmap}
async def render(self): playlist = self.playlist # show playlist title self.meta_widget.title = playlist.name # show playlist song list loop = asyncio.get_event_loop() songs = songs_g = None try: if playlist.meta.allow_create_songs_g: songs_g = GeneratorProxy.wrap(playlist.create_songs_g()) else: songs = await async_run(lambda: playlist.songs, loop=loop) except ProviderIOError as e: self._app.show_msg('read playlist/songs failed:{}'.format(str(e))) logger.exception('read playlist/songs failed') else: self.show_songs(songs=songs, songs_g=songs_g, show_count=True) # show playlist description try: desc = await async_run(lambda: playlist.desc) except ProviderIOError as e: self._app.show_msg('read playlist/desc failed:{}'.format(str(e))) else: self.meta_widget.desc = desc # show playlist cover if playlist.cover: loop.create_task( self.show_cover(playlist.cover, reverse(playlist, '/cover'))) def remove_song(song): model = self.songs_table.model() row = model.songs.index(song) msg = 'remove {} from {}'.format(song, playlist) with self._app.create_action(msg) as action: rv = playlist.remove(song.identifier) if rv: model.removeRow(row) else: action.failed() self.songs_table.song_deleted.connect(lambda song: remove_song(song)) self.meta_widget.toolbar.pure_songs_mode()
def create_g(func, identifier, schema): data = func(identifier, page=1) total = int(data['total']) def g(): nonlocal data if data is None: yield from () else: page = 1 while data['list']: obj_data_list = data['list'] for obj_data in obj_data_list: obj = _deserialize(obj_data, schema, gotten=False) # FIXME: 由于 feeluown 展示歌手的 album 列表时, # 会依次同步的去获取 cover,所以我们这里必须先把 cover 初始化好, # 否则 feeluown 界面会卡住 if schema == _ArtistAlbumSchema: obj.cover = provider.api.get_cover(obj.mid, 2) yield obj page += 1 data = func(identifier, page) return GeneratorProxy(g(), total)