Exemplo n.º 1
0
    def __init__(self,
                 songs=None,
                 playback_mode=PlaybackMode.loop,
                 audio_select_policy='hq<>'):
        """
        :param songs: list of :class:`feeluown.models.SongModel`
        :param playback_mode: :class:`feeluown.player.PlaybackMode`
        """
        #: store value for ``current_song`` property
        self._current_song = None

        #: songs whose url is invalid
        self._bad_songs = DedupList()

        #: store value for ``songs`` property
        self._songs = DedupList(songs or [])

        self.audio_select_policy = audio_select_policy

        #: store value for ``playback_mode`` property
        self._playback_mode = playback_mode

        #: playback mode changed signal
        self.playback_mode_changed = Signal()
        self.song_changed = Signal()
        """current song changed signal

        The player will play the song after it receive the signal,
        when song is None, the player will stop playback.
        """
        self.song_changed_v2 = Signal()
        """current song chagned signal, v2
Exemplo n.º 2
0
    def __init__(self,
                 app,
                 songs=None,
                 playback_mode=PlaybackMode.loop,
                 audio_select_policy='hq<>'):
        """
        :param songs: list of :class:`feeluown.models.SongModel`
        :param playback_mode: :class:`feeluown.player.PlaybackMode`
        """
        self._app = app

        #: init playlist mode normal
        self._mode = PlaylistMode.normal

        #: playlist eof signal
        # playlist have no enough songs
        self.eof_reached = Signal()

        #: playlist mode changed signal
        self.mode_changed = Signal()

        #: store value for ``current_song`` property
        self._current_song = None

        #: songs whose url is invalid
        self._bad_songs = DedupList()

        #: store value for ``songs`` property
        self._songs = DedupList(songs or [])

        self.audio_select_policy = audio_select_policy

        #: store value for ``playback_mode`` property
        self._playback_mode = playback_mode

        #: playback mode changed signal
        self.playback_mode_changed = Signal()
        self.song_changed = Signal()
        """current song changed signal

        The player will play the song after it receive the signal,
        when song is None, the player will stop playback.
        """
        self.song_changed_v2 = Signal()
        """current song chagned signal, v2

        emit(song, media)
        """

        #: When watch mode is on, playlist try to play the mv/video of the song
        self.watch_mode = False

        self._t_scm = self._app.task_mgr.get_or_create('set-current-model')

        # .. versionadded:: 3.7.11
        #    The *songs_removed* and *songs_added* signal.
        self.songs_removed = Signal()  # (index, count)
        self.songs_added = Signal()  # (index, count)

        self._app.player.media_finished.connect(self._on_media_finished)
Exemplo n.º 3
0
    def __init__(self,
                 app,
                 songs=None,
                 playback_mode=PlaybackMode.loop,
                 audio_select_policy='hq<>'):
        """
        :param songs: list of :class:`feeluown.models.SongModel`
        :param playback_mode: :class:`feeluown.player.PlaybackMode`
        """
        self._app = app

        #: mainthread asyncio loop ref
        # We know that feeluown is a asyncio-app, and we can assume
        # that the playlist is inited in main thread.
        self._loop = asyncio.get_event_loop()

        #: init playlist mode normal
        self._mode = PlaylistMode.normal

        #: playlist eof signal
        # playlist have no enough songs
        self.eof_reached = Signal()

        #: playlist mode changed signal
        self.mode_changed = Signal()

        #: store value for ``current_song`` property
        self._current_song = None

        #: songs whose url is invalid
        self._bad_songs = DedupList()

        #: store value for ``songs`` property
        self._songs = DedupList(songs or [])

        self.audio_select_policy = audio_select_policy

        #: store value for ``playback_mode`` property
        self._playback_mode = playback_mode

        #: playback mode changed signal
        self.playback_mode_changed = Signal()
        self.song_changed = Signal()
        """current song changed signal

        The player will play the song after it receive the signal,
        when song is None, the player will stop playback.
        """
        self.song_changed_v2 = Signal()
        """current song chagned signal, v2

        emit(song, media)
        """

        #: When watch mode is on, playlist try to play the mv/video of the song
        self.watch_mode = False
Exemplo n.º 4
0
 def addremove():
     song_list = DedupList()
     num = 1000
     for i in range(0, num):
         song = BriefSongModel(source='xxxx', identifier=str(i))
         if song not in song_list:
             song_list.append(song)
     for i in range(num // 10):
         song_list.pop(0)
Exemplo n.º 5
0
    def init_from(self, songs):
        """
        THINKING: maybe we should rename this method or maybe we should
        change mode on application level

        We change playlistmode here because the `player.play_all` call this
        method. We should check if we need to exit fm mode in `play_xxx`.
        Currently, we have two play_xxx API: play_all and play_song.
        1. play_all -> init_from
        2. play_song -> current_song.setter

        (alpha) temporarily, should only called by player.play_songs
        """

        if self.mode is PlaylistMode.fm:
            self.mode = PlaylistMode.normal
        self.clear()
        # since we will call songs.clear method during playlist clearing,
        # we need to deepcopy songs object here.
        self._songs = DedupList(copy.deepcopy(songs))
Exemplo n.º 6
0
 def init_from(self, songs):
     """(alpha) temporarily, should only called by player.play_songs"""
     self.clear()
     # since we will call songs.clear method during playlist clearing,
     # we need to deepcopy songs object here.
     self._songs = DedupList(copy.deepcopy(songs))
Exemplo n.º 7
0
def test_dedup_list():
    # init
    assert DedupList([1, 2, 3]) == [1, 2, 3]
    dlist = DedupList([3, 2, 3, 4, 2, 3, 1])
    assert dlist == [3, 2, 4, 1]

    # add
    dlist = dlist + [5, 1, 6]
    assert isinstance(dlist, DedupList)
    assert dlist == [3, 2, 4, 1, 5, 6]

    # radd
    dlist = [1, 2, 3, 7] + dlist
    assert isinstance(dlist, DedupList)
    assert dlist == [1, 2, 3, 7, 4, 5, 6]

    # setitem
    dlist[0] = 8
    assert dlist == [8, 2, 3, 7, 4, 5, 6]
    with pytest.raises(ValueError):
        dlist[2] = 5

    # append
    dlist.append(8)
    assert dlist == [8, 2, 3, 7, 4, 5, 6]
    dlist.append(9)
    assert dlist == [8, 2, 3, 7, 4, 5, 6, 9]

    # extend
    dlist.extend([8, 1, 10, 11, 3])
    assert dlist == [8, 2, 3, 7, 4, 5, 6, 9, 1, 10, 11]

    # insert
    dlist.insert(0, 5)
    assert dlist == [8, 2, 3, 7, 4, 5, 6, 9, 1, 10, 11]
    dlist.insert(0, 12)
    assert dlist == [12, 8, 2, 3, 7, 4, 5, 6, 9, 1, 10, 11]
    dlist.insert(-1, 13)
    assert dlist == [12, 8, 2, 3, 7, 4, 5, 6, 9, 1, 10, 13, 11]
    dlist.insert(-12, 14)
    assert dlist == [12, 14, 8, 2, 3, 7, 4, 5, 6, 9, 1, 10, 13, 11]
    dlist.insert(-14, 15)
    assert dlist == [15, 12, 14, 8, 2, 3, 7, 4, 5, 6, 9, 1, 10, 13, 11]
    dlist.insert(-99, 16)
    assert dlist == [16, 15, 12, 14, 8, 2, 3, 7, 4, 5, 6, 9, 1, 10, 13, 11]
    dlist.insert(99, 17)
    assert dlist == [16, 15, 12, 14, 8, 2, 3, 7, 4, 5, 6, 9, 1, 10, 13, 11, 17]

    # pop
    assert dlist.pop() == 17
    assert dlist == [16, 15, 12, 14, 8, 2, 3, 7, 4, 5, 6, 9, 1, 10, 13, 11]
    assert dlist.pop(0) == 16
    assert dlist == [15, 12, 14, 8, 2, 3, 7, 4, 5, 6, 9, 1, 10, 13, 11]
    assert dlist.pop(-2) == 13
    assert dlist == [15, 12, 14, 8, 2, 3, 7, 4, 5, 6, 9, 1, 10, 11]
    with pytest.raises(IndexError):
        dlist.pop(20)

    # copy
    dlist_orig = [Obj(i) for i in range(5)]
    dlist_copy = copy(dlist_orig)
    assert dlist_copy == dlist_orig
    assert id(dlist_copy) != id(dlist_orig)
    assert id(dlist_copy[0]) == id(dlist_orig[0])

    # deepcopy
    dlist_orig = [Obj(i) for i in range(5)]
    dlist_copy = deepcopy(dlist_orig)
    assert dlist_copy == dlist_orig
    assert id(dlist_copy) != id(dlist_orig)
    assert id(dlist_copy[0]) != id(dlist_orig[0])

    # getitem
    assert [dlist[i] for i in range(14)] == \
           [15, 12, 14, 8, 2, 3, 7, 4, 5, 6, 9, 1, 10, 11]

    # swap
    dlist.swap(7, 9)
    assert dlist == [15, 12, 14, 8, 2, 3, 7, 6, 5, 4, 9, 1, 10, 11]

    # index
    for idx, item in zip(range(len(dlist)), dlist):
        assert dlist.index(item) == idx
    with pytest.raises(ValueError):
        dlist.index(8, 4)
    with pytest.raises(ValueError):
        dlist.index(8, 1, 3)

    # sort
    dlist.sort()
    assert dlist == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15]
    for idx, item in zip(range(len(dlist)), dlist):
        assert dlist.index(item) == idx

    # remove
    dlist.remove(3)
    assert dlist == [1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15]
    with pytest.raises(ValueError):
        dlist.remove(16)
    # index should be correct after item is removed
    assert dlist.index(1) == 0
    assert dlist.index(4) == 2

    # clear
    dlist.clear()
    assert dlist == []