[gnome-music/wip/mschraal/core: 71/86] player: Minimal playing playlist



commit b3feeb6c4a734b830655a5613211dbe021452dc4
Author: Marinus Schraal <mschraal gnome org>
Date:   Sun Jun 2 18:31:20 2019 +0200

    player: Minimal playing playlist

 gnomemusic/coregrilo.py                      |  3 ++
 gnomemusic/coremodel.py                      | 34 ++++++++++++++++++++++-
 gnomemusic/coresong.py                       |  3 ++
 gnomemusic/grilowrappers/grltrackersource.py | 33 ++++++++++++++++++++++
 gnomemusic/player.py                         | 37 +++++++++++++++++++++----
 gnomemusic/widgets/albumwidget2.py           | 41 ++++++++++++++++++----------
 gnomemusic/widgets/disclistboxwidget.py      |  2 ++
 7 files changed, 131 insertions(+), 22 deletions(-)
---
diff --git a/gnomemusic/coregrilo.py b/gnomemusic/coregrilo.py
index b8d5be7e..78386165 100644
--- a/gnomemusic/coregrilo.py
+++ b/gnomemusic/coregrilo.py
@@ -60,3 +60,6 @@ class CoreGrilo(GObject.GObject):
     def populate_album_disc_songs(self, media, discnr, callback):
         self._tracker_source.populate_album_disc_songs(
             media, discnr, callback)
+
+    def populate_album_songs(self, media, callback):
+        self._tracker_source.populate_album_songs(media, callback)
diff --git a/gnomemusic/coremodel.py b/gnomemusic/coremodel.py
index 0f790e18..efa877b0 100644
--- a/gnomemusic/coremodel.py
+++ b/gnomemusic/coremodel.py
@@ -8,6 +8,7 @@ from gnomemusic.coreartist import CoreArtist
 from gnomemusic.coregrilo import CoreGrilo
 from gnomemusic.coresong import CoreSong
 from gnomemusic.grilo import grilo
+from gnomemusic.widgets.songwidget import SongWidget
 
 
 class CoreDisc(GObject.GObject):
@@ -17,6 +18,10 @@ class CoreDisc(GObject.GObject):
 
 class CoreModel(GObject.GObject):
 
+    __gsignals__ = {
+        "playlist-loaded": (GObject.SignalFlags.RUN_FIRST, None, ())
+    }
+
     @log
     def __init__(self):
         super().__init__()
@@ -25,10 +30,11 @@ class CoreModel(GObject.GObject):
         self._model = Gio.ListStore.new(CoreSong)
         self._album_model = Gio.ListStore()
         self._artist_model = Gio.ListStore.new(CoreArtist)
+        self._playlist_model = Dazzle.ListModelFilter.new(self._model)
         self._album_store = None
         self._hash = {}
         self._url_hash = {}
-
+        print("PLAYLIST_MODEL", self._playlist_model)
         self._grilo = CoreGrilo(
             self._model, self._hash, self._url_hash, self._album_model,
             self._artist_model)
@@ -82,6 +88,32 @@ class CoreModel(GObject.GObject):
 
         return disc_model_sort
 
+    def get_playlist_model(self):
+        return self._playlist_model
+
+    def set_playlist_model(self, type, album_media, coresong):
+        song_ids = []
+
+        print("NEW PLAYLIST MODEL", self._playlist_model)
+
+        def _filter_func(core_song):
+            return core_song.props.media.get_id() in song_ids
+
+        def _callback(source, dunno, media, something, something2):
+            if media is None:
+                self._playlist_model.set_filter_func(_filter_func)
+                for song in self._playlist_model:
+                    if song.props.media.get_id() == coresong.get_id():
+                        song.props.state = SongWidget.State.PLAYING
+                        break
+                self.emit("playlist-loaded")
+                return
+
+            song_ids.append(media.get_id())
+
+        self._grilo.populate_album_songs(album_media, _callback)
+
+
         # albums_ids = []
 
         # model_filter = Dazzle.ListModelFilter.new(self._model)
diff --git a/gnomemusic/coresong.py b/gnomemusic/coresong.py
index 4807f35a..efc5aa9b 100644
--- a/gnomemusic/coresong.py
+++ b/gnomemusic/coresong.py
@@ -4,6 +4,7 @@ from gi.repository import Grl, GObject
 
 from gnomemusic import log
 from gnomemusic.grilo import grilo
+from gnomemusic.widgets.songwidget import SongWidget
 import gnomemusic.utils as utils
 
 
@@ -18,6 +19,8 @@ class CoreSong(GObject.GObject):
     media = GObject.Property(type=Grl.Media)
     play_count = GObject.Property(type=int)
     selected = GObject.Property(type=bool, default=False)
+    state = GObject.Property(
+        type=int, default=SongWidget.State.UNPLAYED)
     title = GObject.Property(type=str)
     track_number = GObject.Property(type=int)
     url = GObject.Property(type=str)
diff --git a/gnomemusic/grilowrappers/grltrackersource.py b/gnomemusic/grilowrappers/grltrackersource.py
index 61220b7c..3d54a1ad 100644
--- a/gnomemusic/grilowrappers/grltrackersource.py
+++ b/gnomemusic/grilowrappers/grltrackersource.py
@@ -313,3 +313,36 @@ class GrlTrackerSource(GObject.GObject):
         options = self._fast_options.copy()
 
         self._source.query(query, self.METADATA_KEYS, options, _callback)
+
+    def populate_album_songs(self, media, _callback):
+        album_id = media.get_id()
+
+        query = """
+        SELECT DISTINCT
+            rdf:type(?song)
+            ?song AS ?tracker_urn
+            tracker:id(?song) AS ?id
+            nie:url(?song) AS ?url
+            nie:title(?song) AS ?title
+            nmm:artistName(nmm:performer(?song)) AS ?artist
+            nie:title(nmm:musicAlbum(?song)) AS ?album
+            nfo:duration(?song) AS ?duration
+            nmm:trackNumber(?song) AS ?track_number
+            nmm:setNumber(nmm:musicAlbumDisc(?song)) AS ?album_disc_number
+            ?tag AS ?favourite
+            nie:usageCounter(?song) AS ?play_count
+        WHERE
+        {
+            ?song a nmm:MusicPiece ;
+                  nmm:musicAlbum ?album .
+            OPTIONAL { ?song nao:hasTag ?tag .
+                       FILTER (?tag = nao:predefined-tag-favorite) } .
+            FILTER ( tracker:id(?album) = %(album_id)s )
+        }
+        """.replace('\n', ' ').strip() % {
+            'album_id': album_id,
+        }
+
+        options = self._fast_options.copy()
+
+        self._source.query(query, self.METADATA_KEYS, options, _callback)
diff --git a/gnomemusic/player.py b/gnomemusic/player.py
index 3e42d2aa..789d78d8 100644
--- a/gnomemusic/player.py
+++ b/gnomemusic/player.py
@@ -41,6 +41,7 @@ from gnomemusic.gstplayer import GstPlayer, Playback
 from gnomemusic.grilo import grilo
 from gnomemusic.playlists import Playlists
 from gnomemusic.scrobbler import LastFmScrobbler
+from gnomemusic.widgets.songwidget import SongWidget
 
 
 logger = logging.getLogger(__name__)
@@ -96,11 +97,12 @@ class PlayerPlaylist(GObject.GObject):
         return '<PlayerPlayList>'
 
     @log
-    def __init__(self):
+    def __init__(self, application):
         super().__init__()
 
         GstPbutils.pb_utils_init()
 
+        self._app = application
         self._songs = []
         self._shuffle_indexes = []
         self._current_index = 0
@@ -113,6 +115,8 @@ class PlayerPlaylist(GObject.GObject):
         self._discoverer.connect('discovered', self._on_discovered)
         self._discoverer.start()
 
+        self._model = self._app._coremodel.get_playlist_model()
+
         self.connect("notify::repeat-mode", self._on_repeat_mode_changed)
 
     @log
@@ -443,10 +447,18 @@ class PlayerPlaylist(GObject.GObject):
         :returns: the song being played or None if there are no songs
         :rtype: Grl.Media
         """
-        if self._songs:
-            return self._songs[self._current_index][PlayerField.SONG]
+        for coresong in self._model:
+            print("CORESONG", coresong.props.state, SongWidget.State.PLAYING)
+            if coresong.props.state == SongWidget.State.PLAYING:
+                print("RETURN CURRENT SONG")
+                return coresong.props.media
+
         return None
 
+        # if self._songs:
+        #     return self._songs[self._current_index][PlayerField.SONG]
+        # return None
+
     def _current_song_is_valid(self):
         """Check if current song can be played.
 
@@ -562,7 +574,7 @@ class Player(GObject.GObject):
         """
         super().__init__()
 
-        self._playlist = PlayerPlaylist()
+        self._playlist = PlayerPlaylist(application)
         self._playlist.connect('song-validated', self._on_song_validated)
 
         self._settings = application.props.settings
@@ -633,8 +645,17 @@ class Player(GObject.GObject):
         else:
             self.stop()
 
+    def _load2(self, song):
+        self._gst_player.props.state = Playback.LOADING
+        self._time_stamp = int(time.time())
+
+        self._gst_player.props.url = song.get_url()
+        print(song.get_url())
+
+        # self.emit('song-changed')
+
     @log
-    def play(self, song_changed=True, song_offset=None):
+    def play(self, song_changed=True, song_offset=None, media=None):
         """Play a song.
 
         Load a new song or resume playback depending on song_changed
@@ -643,6 +664,10 @@ class Player(GObject.GObject):
         :param bool song_changed: indicate if a new song must be loaded
         :param int song_offset: position relative to current song
         """
+        self._load2(media)
+
+        self._gst_player.props.state = Playback.PLAYING
+        return
         if self.props.current_song is None:
             return
 
@@ -775,7 +800,7 @@ class Player(GObject.GObject):
             tick, self._gst_player.props.position))
 
         current_song = self._playlist.props.current_song
-
+        print("TICK", current_song)
         if tick == 0:
             self._new_clock = True
             self._lastfm.now_playing(current_song)
diff --git a/gnomemusic/widgets/albumwidget2.py b/gnomemusic/widgets/albumwidget2.py
index c5ee05e9..9f5f3542 100644
--- a/gnomemusic/widgets/albumwidget2.py
+++ b/gnomemusic/widgets/albumwidget2.py
@@ -55,8 +55,6 @@ class AlbumWidget2(Gtk.EventBox):
 
         self._album_name = None
 
-        self._listbox.connect("row-activated", self._on_row_activated)
-
     @log
     def update(self, album):
         """Update the album widget.
@@ -164,15 +162,19 @@ class AlbumWidget2(Gtk.EventBox):
             GObject.TYPE_INT
         )
 
-        for song in self._model[0]:
-            _iter = old_model.insert_with_valuesv(-1, [5], [song.props.media])
-            if song is self._model[0][listboxrow.get_index()]:
-                activated_iter = _iter
-                listboxrow.get_child().props.state = SongWidget.State.PLAYING
-
-        self._player.set_playlist(
-            PlayerPlaylist.Type.ALBUM, self._album_name, old_model,
-            activated_iter)
+        print(listboxrow.get_index())
+        # for song in self._model[0]:
+        #     _iter = old_model.insert_with_valuesv(-1, [5], [song.props.media])
+        #     if song is self._model[0][listboxrow.get_index()]:
+        #         activated_iter = _iter
+        #         listboxrow.get_child().props.state = SongWidget.State.PLAYING
+
+        coresong = listboxrow.get_child()
+        self._parent_view._window._app._coremodel.set_playlist_model(
+            PlayerPlaylist.Type.ALBUM, album, coresong)
+        # self._player.set_playlist(
+        #     PlayerPlaylist.Type.ALBUM, self._album_name, old_model,
+        #     activated_iter)
         self._player.play()
 
     @log
@@ -186,14 +188,23 @@ class AlbumWidget2(Gtk.EventBox):
 
     @log
     def _song_activated(self, widget, song_widget):
+        print("activated", song_widget)
         if self.props.selection_mode:
             song_widget.props.selected = not song_widget.props.selected
             return
 
-        self._player.set_playlist(
-            PlayerPlaylist.Type.ALBUM, self._album_name, song_widget.model,
-            song_widget.itr)
-        self._player.play()
+        signal_id = None
+
+        def _on_playlist_loaded(klass):
+            self._player.play(None, None, song_widget._media)
+            self._parent_view._window._app._coremodel.disconnect(signal_id)
+
+        # coresong = listboxrow.get_child()
+        signal_id = self._parent_view._window._app._coremodel.connect(
+            "playlist-loaded", _on_playlist_loaded)
+        self._parent_view._window._app._coremodel.set_playlist_model(
+            PlayerPlaylist.Type.ALBUM, self._album, song_widget._media)
+
         return True
 
     @log
diff --git a/gnomemusic/widgets/disclistboxwidget.py b/gnomemusic/widgets/disclistboxwidget.py
index 689ca08a..364d46f8 100644
--- a/gnomemusic/widgets/disclistboxwidget.py
+++ b/gnomemusic/widgets/disclistboxwidget.py
@@ -213,6 +213,8 @@ class DiscBox(Gtk.Box):
             GObject.BindingFlags.BIDIRECTIONAL
             | GObject.BindingFlags.SYNC_CREATE)
 
+        song_widget.connect('button-release-event', self._song_activated)
+
         song_widget.show_all()
 
         return song_widget


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]