[gnome-music/wip/jfelder/flatpak-submodule-lua: 6/7] Restart remote cover lookup on source availability
- From: Marinus Schraal <mschraal src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/wip/jfelder/flatpak-submodule-lua: 6/7] Restart remote cover lookup on source availability
- Date: Sun, 30 Sep 2018 09:56:50 +0000 (UTC)
commit c05bb1f626ae3dab0d24dd0db62740e5d95d9772
Author: Marinus Schraal <mschraal gnome org>
Date: Thu Sep 27 22:39:59 2018 +0200
Restart remote cover lookup on source availability
Grilo might not have a network available on startup, so the cover art
lookup does not check the remote sources. Music only checks for new art on
first start, so the remote lookup may never happen.
Add logic so Grilo triggers a remote art lookup if new Grilo cover art
sources become available.
Side effects from this change:
* No loading state for remote-art, as there is no check for network
connectivity by Music.
* All remote update checks are triggered in close proximity, this might
turn out to be problematic on large collections.
gnomemusic/albumartcache.py | 24 ++++++++++++++++++++----
gnomemusic/grilo.py | 20 ++++++++++++++++++++
gnomemusic/widgets/coverstack.py | 37 +++++++++++++++++++++++++++++++------
3 files changed, 71 insertions(+), 10 deletions(-)
---
diff --git a/gnomemusic/albumartcache.py b/gnomemusic/albumartcache.py
index 0365f89b..3ad64fcf 100644
--- a/gnomemusic/albumartcache.py
+++ b/gnomemusic/albumartcache.py
@@ -235,6 +235,7 @@ class Art(GObject.GObject):
remote_art = RemoteArt()
remote_art.connect('retrieved', self._remote_art_retrieved)
remote_art.connect('unavailable', self._remote_art_unavailable)
+ remote_art.connect('no-remote-sources', self._remote_art_no_sources)
remote_art.query(self._media)
@log
@@ -249,6 +250,10 @@ class Art(GObject.GObject):
self._add_to_blacklist()
self._no_art_available()
+ @log
+ def _remote_art_no_sources(self, klass):
+ self._no_art_available()
+
@log
def _no_art_available(self):
self._surface = DefaultIcon().get(
@@ -541,7 +546,8 @@ class RemoteArt(GObject.GObject):
__gsignals__ = {
'retrieved': (GObject.SignalFlags.RUN_FIRST, None, ()),
- 'unavailable': (GObject.SignalFlags.RUN_FIRST, None, ())
+ 'unavailable': (GObject.SignalFlags.RUN_FIRST, None, ()),
+ 'no-remote-sources': (GObject.SignalFlags.RUN_FIRST, None, ())
}
def __repr__(self):
@@ -562,10 +568,20 @@ class RemoteArt(GObject.GObject):
"""
self._album = utils.get_album_title(media)
self._artist = utils.get_artist_name(media)
+ self._media = media
- # FIXME: It seems this Grilo query does not always return,
- # especially on queries with little info.
- grilo.get_album_art_for_item(media, self._remote_album_art)
+ if not grilo.props.cover_sources:
+ self.emit('no-remote-sources')
+ grilo.connect(
+ 'notify::cover-sources', self._on_grilo_cover_sources_changed)
+ else:
+ # FIXME: It seems this Grilo query does not always return,
+ # especially on queries with little info.
+ grilo.get_album_art_for_item(media, self._remote_album_art)
+
+ def _on_grilo_cover_sources_changed(self, klass, data):
+ if grilo.props.cover_sources:
+ grilo.get_album_art_for_item(self._media, self._remote_album_art)
@log
def _delete_callback(self, src, result, data):
diff --git a/gnomemusic/grilo.py b/gnomemusic/grilo.py
index 890918be..65d0373f 100644
--- a/gnomemusic/grilo.py
+++ b/gnomemusic/grilo.py
@@ -80,6 +80,7 @@ class Grilo(GObject.GObject):
_theaudiodb_api_key = "195003"
sources = GObject.Property()
+ cover_sources = GObject.Property(type=bool, default=False)
def __repr__(self):
return '<Grilo>'
@@ -117,6 +118,9 @@ class Grilo(GObject.GObject):
self.changes_pending = {'Albums': False, 'Artists': False, 'Songs': False}
self.pending_changed_medias = []
+ self._thumbnail_sources = []
+ self._thumbnail_sources_timeout = None
+
self.registry = Grl.Registry.get_default()
self.sparqltracker = TrackerWrapper().tracker
@@ -201,6 +205,14 @@ class Grilo(GObject.GObject):
self.emit('changes-pending')
return False
+ @log
+ def _trigger_art_update(self):
+ self._thumbnail_sources_timeout = None
+ if len(self._thumbnail_sources) > 0:
+ self.props.cover_sources = True
+
+ return GLib.SOURCE_REMOVE
+
@log
def _on_source_added(self, pluginRegistry, mediaSource):
if ("net:plaintext" in mediaSource.get_tags()
@@ -212,6 +224,14 @@ class Grilo(GObject.GObject):
"Failed to unregister {}".format(mediaSource.get_id()))
return
+ if Grl.METADATA_KEY_THUMBNAIL in mediaSource.supported_keys():
+ self._thumbnail_sources.append(mediaSource)
+ if not self._thumbnail_sources_timeout:
+ # Aggregate sources being added, for example when the
+ # network comes online.
+ self._thumbnail_sources_timeout = GLib.timeout_add_seconds(
+ 5, self._trigger_art_update)
+
id = mediaSource.get_id()
logger.debug("new grilo source %s was added", id)
try:
diff --git a/gnomemusic/widgets/coverstack.py b/gnomemusic/widgets/coverstack.py
index 6950908c..afcff249 100644
--- a/gnomemusic/widgets/coverstack.py
+++ b/gnomemusic/widgets/coverstack.py
@@ -22,7 +22,7 @@
# code, but you are not obligated to do so. If you do not wish to do so,
# delete this exception statement from your version.
-from gi.repository import GObject, Gtk
+from gi.repository import GLib, GObject, Gtk
from gnomemusic import log
from gnomemusic.albumartcache import Art, DefaultIcon
@@ -55,8 +55,10 @@ class CoverStack(Gtk.Stack):
"""
super().__init__()
- self._size = None
+ self._art = None
self._handler_id = None
+ self._size = None
+ self._timeout = None
self._loading_cover = Gtk.Image()
self._cover_a = Gtk.Image()
@@ -68,6 +70,7 @@ class CoverStack(Gtk.Stack):
self.props.size = size
self.props.transition_type = Gtk.StackTransitionType.CROSSFADE
+ self.props.transition_duration = 1000
self.props.visible_child_name = "loading"
self.show_all()
@@ -100,15 +103,34 @@ class CoverStack(Gtk.Stack):
Update the stack with the art retrieved from the given media.
:param Grl.Media media: The media object
"""
+ if self._handler_id and self._art:
+ # Remove a possible dangling 'finished' callback if update
+ # is called again, but it is still looking for the previous
+ # art.
+ self._art.disconnect(self._handler_id)
+ # Set the loading state only after a delay to make between
+ # song transitions smooth if loading time is negligible.
+ self._timeout = GLib.timeout_add(100, self._set_loading_child)
+
self._active_child = self.props.visible_child_name
- art = Art(self.props.size, media, self.props.scale_factor)
- self._handler_id = art.connect('finished', self._art_retrieved)
- art.lookup()
+ self._art = Art(self.props.size, media, self.props.scale_factor)
+ self._handler_id = self._art.connect('finished', self._art_retrieved)
+ self._art.lookup()
+
+ @log
+ def _set_loading_child(self):
+ self.props.visible_child_name = "loading"
+ self._active_child = self.props.visible_child_name
+
+ return GLib.SOURCE_REMOVE
@log
def _art_retrieved(self, klass):
- klass.disconnect(self._handler_id)
+ if self._timeout:
+ GLib.source_remove(self._timeout)
+ self._timeout = None
+
if self._active_child == "B":
self._cover_a.props.surface = klass.surface
self.props.visible_child_name = "A"
@@ -116,4 +138,7 @@ class CoverStack(Gtk.Stack):
self._cover_b.props.surface = klass.surface
self.props.visible_child_name = "B"
+ self._active_child = self.props.visible_child_name
+ self._art = None
+
self.emit('updated')
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]