Esempio n. 1
0
    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()))
Esempio n. 2
0
    def after_scan(self):
        """
        歌曲扫描完成后,对信息进行一些加工,比如
        1. 给专辑歌曲排序
        2. 给专辑和歌手加封面
        """
        def sort_album_func(album):
            if album.songs:
                return (album.songs[0].date is not None, album.songs[0].date)
            return (False, '0')

        for album in self._albums.values():
            try:
                album.songs.sort(key=lambda x: (int(x.disc.split('/')[0]), int(x.track.split('/')[0])))
                if album.name != 'Unknown':
                    cover_data, _ = read_audio_cover(album.songs[0].url)
                    if cover_data:
                        cover = Media(reverse(album.songs[0], '/cover/data'),
                                      type_=MediaType.image)
                    else:
                        cover = None
                    album.cover = cover
            except:  # noqa
                logger.exception('Sort album songs failed.')

        for artist in self._artists.values():
            if artist.albums:
                artist.albums.sort(key=sort_album_func, reverse=True)
                artist.cover = artist.albums[0].cover
            if artist.contributed_albums:
                artist.contributed_albums.sort(key=sort_album_func, reverse=True)
            if artist.songs:
                # sort artist songs
                artist.songs.sort(key=lambda x: x.title)
                # use song cover as artist cover
                # https://github.com/feeluown/feeluown-local/pull/3/files#r362126996
                songs_with_unknown_album = [song for song in artist.songs
                                            if song.album_name == 'Unknown']
                for song in sorted(songs_with_unknown_album,
                                   key=lambda x: (x.date is not None, x.date),
                                   reverse=True):
                    if read_audio_cover(song.url)[0]:
                        artist.cover = Media(reverse(song, '/cover/data'),
                                             type_=MediaType.image)
                        break
Esempio n. 3
0
    def dump_state(self):
        playlist = self.playlist
        player = self.player

        song = self.player.current_song
        if song is not None:
            song = reverse(song, as_line=True)
        # TODO: dump player.media
        state = {
            'playback_mode': playlist.playback_mode.value,
            'volume': player.volume,
            'state': player.state.value,
            'song': song,
            'position': player.position,
            'playlist': [reverse(song, as_line=True) for song in playlist.list()],
        }
        with open(STATE_FILE, 'w') as f:
            json.dump(state, f)
Esempio n. 4
0
    async def render(self):
        album = self.album

        loop = asyncio.get_event_loop()
        songs = await async_run(lambda: album.songs)
        self.show_songs(songs)
        desc = await async_run(lambda: album.desc)
        self.meta_widget.title = album.name
        self.meta_widget.desc = desc
        cover = await async_run(lambda: album.cover)
        if cover:
            loop.create_task(self.show_cover(cover, reverse(album, '/cover')))
Esempio n. 5
0
    async def render(self):
        artist = self.artist

        # bind signal first
        # we only show album that implements create_albums_g
        if artist.meta.allow_create_albums_g:
            self.toolbar.filter_albums_needed.connect(
                lambda types: self.albums_table.model().filter_by_types(types))
            self.tabbar.show_albums_needed.connect(
                lambda: self.show_albums(self.artist.create_albums_g()))
            self.albums_table.show_album_needed.connect(self.show_model)
        if hasattr(artist, 'contributed_albums') and artist.contributed_albums:
            # show contributed_album list
            self.tabbar.show_contributed_albums_needed.connect(
                lambda: self.show_albums(self.artist.
                                         create_contributed_albums_g()))

        # fetch and render basic metadata
        self.meta_widget.title = artist.name
        self.meta_widget.show()
        self.tabbar.show()
        self.tabbar.artist_mode()

        # fetch and render songs
        songs = songs_g = None
        if artist.meta.allow_create_songs_g:
            songs_g = wrap(artist.create_songs_g())
            self.tabbar.show_songs_needed.connect(
                lambda: self.show_songs(songs_g=wrap(artist.create_songs_g()),
                                        songs=songs,
                                        show_count=True))
        else:
            songs = await async_run(lambda: artist.songs)
            self.tabbar.show_songs_needed.connect(lambda: self.show_songs(
                songs_g=None, songs=songs, show_count=True))
        self.show_songs(songs_g=songs_g, songs=songs, show_count=True)

        # finally, we render cover and description
        cover = await async_run(lambda: artist.cover)
        if cover:

            aio.create_task(
                self.show_cover(cover,
                                reverse(artist, '/cover'),
                                as_background=True))

        self.tabbar.show_desc_needed.connect(
            lambda: aio.create_task(self._show_desc()))
Esempio n. 6
0
    async def popup(self, song):
        if song is None:
            return
        title = song.title_display
        artists_name = song.artists_name_display
        album = song.album

        data = await self._app.img_mgr.get(album.cover,
                                           reverse(album, '/cover'))
        loader = GdkPixbuf.PixbufLoader.new()
        loader.write(data)
        loader.close()
        gdk_image = loader.get_pixbuf()
        self._notification.update(title, artists_name)
        self._notification.set_image_from_pixbuf(gdk_image)
        self._notification.show()
Esempio n. 7
0
    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()
Esempio n. 8
0
    async def render(self):
        artist = self.artist

        self.songs_table.show()

        # bind signal first
        # we only show album that implements create_albums_g
        if artist.meta.allow_create_albums_g:
            # show album detail
            self.albums_table.show_album_needed.connect(self.show_model)

            # show album list
            self.meta_widget.toolbar.show_albums_needed.connect(
                lambda: self.show_albums(self.artist.create_albums_g()))
            # album list fitlers
            self.meta_widget.toolbar.filter_albums_contributed_needed.connect(
                self.filter_albums_contributed)
            self.meta_widget.toolbar.filter_albums_mini_needed.connect(
                self.filter_albums_mini)
            self.meta_widget.toolbar.filter_albums_all_needed.connect(
                self.filter_albums_all)
            self.meta_widget.toolbar.filter_albums_live_needed.connect(
                self.filter_albums_live)

        # fetch and render metadata
        desc = await async_run(lambda: artist.desc)
        self.meta_widget.title = artist.name
        self.meta_widget.desc = desc
        cover = await async_run(lambda: artist.cover)

        # fetch and render songs
        songs = songs_g = None
        if artist.meta.allow_create_songs_g:
            songs_g = artist.create_songs_g()
        else:
            songs = await async_run(lambda: artist.songs)
        self.show_songs(songs_g=songs_g, songs=songs, show_count=True)
        self.meta_widget.toolbar.show_songs_needed.connect(
            lambda: self.show_songs(
                songs_g=songs_g, songs=songs, show_count=True))

        # render cover
        if cover:
            aio.create_task(self.show_cover(cover, reverse(artist, '/cover')))

        self.meta_widget.toolbar.artist_mode()
Esempio n. 9
0
    async def render(self):
        album = self.album

        songs = await async_run(lambda: album.songs)
        self.show_songs(songs)

        self.meta_widget.title = album.name_display
        self.meta_widget.songs_count = len(songs)
        self.meta_widget.creator = album.artists_name_display
        self.meta_widget.show()

        # fetch cover and description
        cover = await async_run(lambda: album.cover)
        if cover:
            aio.create_task(self.show_cover(cover, reverse(album, '/cover')))

        self.tabbar.show()
        self.tabbar.album_mode()
        self.tabbar.show_desc_needed.connect(lambda: aio.create_task(self._show_desc()))
        self.tabbar.show_songs_needed.connect(lambda: self.show_songs(songs))