[gnome-music/wip/mschraal/coresong-thumbnail-prop: 28/38] bit messy album art thumbnail retrieval
- From: Marinus Schraal <mschraal src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/wip/mschraal/coresong-thumbnail-prop: 28/38] bit messy album art thumbnail retrieval
- Date: Mon, 9 Mar 2020 23:22:36 +0000 (UTC)
commit 52e87c3c39c51a34242c09a3be1a5d9f0bd373af
Author: Marinus Schraal <mschraal gnome org>
Date: Thu Nov 28 17:47:26 2019 +0100
bit messy album art thumbnail retrieval
gnomemusic/albumart.py | 60 +++++++++++++++
gnomemusic/corealbum.py | 14 +---
gnomemusic/coregrilo.py | 8 ++
gnomemusic/grilowrappers/grltrackerwrapper.py | 24 ++++++
gnomemusic/storealbumart.py | 102 ++++++++++++++++++++++++++
5 files changed, 196 insertions(+), 12 deletions(-)
---
diff --git a/gnomemusic/albumart.py b/gnomemusic/albumart.py
new file mode 100644
index 00000000..d05999df
--- /dev/null
+++ b/gnomemusic/albumart.py
@@ -0,0 +1,60 @@
+# Copyright 2019 The GNOME Music developers
+#
+# GNOME Music is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GNOME Music is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The GNOME Music authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and GNOME Music. This permission is above and beyond the permissions
+# granted by the GPL license by which GNOME Music is covered. If you
+# modify this code, you may extend this exception to your version of the
+# code, but you are not obligated to do so. If you do not wish to do so,
+# delete this exception statement from your version.
+
+import gi
+gi.require_version("MediaArt", "2.0")
+from gi.repository import GObject, MediaArt
+
+
+class AlbumArt(GObject.GObject):
+
+ def __init__(self, corealbum, coremodel):
+ """Initialize the Album Art retrieval object
+
+ :param CoreAlbum corealbum: The CoreALbum to use
+ :param CoreModel coremodel: The CoreModel object
+ """
+ super().__init__()
+
+ self._corealbum = corealbum
+ self._artist = corealbum.props.artist
+ self._title = corealbum.props.title
+
+ if self._in_cache():
+ return
+
+ coremodel.props.grilo.get_album_art(corealbum)
+
+ def _in_cache(self):
+ success, thumb_file = MediaArt.get_file(
+ self._artist, self._title, "album")
+
+ # FIXME: Make async.
+ if (not success
+ or not thumb_file.query_exists()):
+ return False
+
+ self._corealbum.props.thumbnail = thumb_file.get_path()
+
+ return True
diff --git a/gnomemusic/corealbum.py b/gnomemusic/corealbum.py
index 058b3945..8ab3c62a 100644
--- a/gnomemusic/corealbum.py
+++ b/gnomemusic/corealbum.py
@@ -27,7 +27,7 @@ gi.require_versions({"Grl": "0.3", "MediaArt": "2.0"})
from gi.repository import Gio, Grl, GObject, MediaArt
import gnomemusic.utils as utils
-
+from gnomemusic.albumart import AlbumArt
class CoreAlbum(GObject.GObject):
"""Exposes a Grl.Media with relevant data as properties
@@ -119,7 +119,7 @@ class CoreAlbum(GObject.GObject):
if self._thumbnail == None:
self._thumbnail = "loading"
- self._in_cache()
+ AlbumArt(self, self._coremodel)
return self._thumbnail
@@ -129,13 +129,3 @@ class CoreAlbum(GObject.GObject):
return
self._thumbnail = value
-
- def _in_cache(self):
- success, thumb_file = MediaArt.get_file(
- self.props.artist, self.props.title, "album")
-
- if (not success
- or not thumb_file.query_exists()):
- return False
-
- self.props.thumbnail = thumb_file.get_path()
diff --git a/gnomemusic/coregrilo.py b/gnomemusic/coregrilo.py
index 4d408acf..29389707 100644
--- a/gnomemusic/coregrilo.py
+++ b/gnomemusic/coregrilo.py
@@ -202,6 +202,14 @@ class CoreGrilo(GObject.GObject):
self._wrappers["grl-tracker-source"].get_album_art_for_item(
coresong, callback)
+ def get_album_art(self, corealbum):
+ source = corealbum.props.media.get_source()
+
+ for wrapper_id in self._wrappers.keys():
+ if wrapper_id == source:
+ self._wrappers[wrapper_id].get_album_art(corealbum)
+ break
+
def get_artist_art(self, coreartist):
if "grl-tracker-source" in self._wrappers:
self._wrappers["grl-tracker-source"].get_artist_art(coreartist)
diff --git a/gnomemusic/grilowrappers/grltrackerwrapper.py b/gnomemusic/grilowrappers/grltrackerwrapper.py
index 285c4aa4..bdcb8e6a 100644
--- a/gnomemusic/grilowrappers/grltrackerwrapper.py
+++ b/gnomemusic/grilowrappers/grltrackerwrapper.py
@@ -31,6 +31,7 @@ from gnomemusic.coreartist import CoreArtist
from gnomemusic.coredisc import CoreDisc
from gnomemusic.coresong import CoreSong
from gnomemusic.grilowrappers.grltrackerplaylists import GrlTrackerPlaylists
+from gnomemusic.storealbumart import StoreAlbumArt
class GrlTrackerWrapper(GObject.GObject):
@@ -869,6 +870,29 @@ class GrlTrackerWrapper(GObject.GObject):
self.props.source.query(
query, self.METADATA_KEYS, options, songs_search_cb)
+ def get_album_art(self, corealbum):
+ def art_retrieved_cb(source, op_id, media, data, error):
+ if error:
+ print("ERROR", error)
+ corealbum.props.thumbnail = "generic"
+ return
+
+ StoreAlbumArt(corealbum, media)
+
+ album_id = corealbum.props.media.get_id()
+
+ query = self._get_album_for_album_id(album_id)
+
+ full_options = Grl.OperationOptions()
+ full_options.set_resolution_flags(
+ Grl.ResolutionFlags.FULL
+ | Grl.ResolutionFlags.IDLE_RELAY)
+ full_options.set_count(1)
+
+ self._source.query(
+ query, self.METADATA_THUMBNAIL_KEYS, full_options,
+ art_retrieved_cb)
+
def get_album_art_for_item(self, coresong, callback):
"""Placeholder until we got a better solution
"""
diff --git a/gnomemusic/storealbumart.py b/gnomemusic/storealbumart.py
new file mode 100644
index 00000000..2c634314
--- /dev/null
+++ b/gnomemusic/storealbumart.py
@@ -0,0 +1,102 @@
+import gi
+gi.require_version("MediaArt", "2.0")
+from gi.repository import Gio, GLib, GObject, MediaArt
+
+from gnomemusic.musiclogger import MusicLogger
+
+
+class StoreAlbumArt(GObject.GObject):
+
+ def __init__(self, corealbum, media):
+ """
+ """
+ super().__init__()
+
+ self._corealbum = corealbum
+ self._log = MusicLogger()
+ self._media = media
+
+ uri = media.get_thumbnail()
+ if (uri is None
+ or uri == ""):
+ self._corealbum.props.thumbnail = "generic"
+ return
+
+ src = Gio.File.new_for_uri(uri)
+ src.read_async(
+ GLib.PRIORITY_LOW, None, self._read_callback, None)
+
+ def _read_callback(self, src, result, data):
+ try:
+ istream = src.read_finish(result)
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+ self._corealbum.props.thumbnail = "generic"
+ return
+
+ try:
+ [tmp_file, iostream] = Gio.File.new_tmp()
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+ self._corealbum.props.thumbnail = "generic"
+ return
+
+ ostream = iostream.get_output_stream()
+ # FIXME: Passing the iostream here, otherwise it gets
+ # closed. PyGI specific issue?
+ ostream.splice_async(
+ istream, Gio.OutputStreamSpliceFlags.CLOSE_SOURCE
+ | Gio.OutputStreamSpliceFlags.CLOSE_TARGET, GLib.PRIORITY_LOW,
+ None, self._splice_callback, [tmp_file, iostream])
+
+ def _delete_callback(self, src, result, data):
+ try:
+ src.delete_finish(result)
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+
+ def _splice_callback(self, src, result, data):
+ tmp_file, iostream = data
+
+ iostream.close_async(
+ GLib.PRIORITY_LOW, None, self._close_iostream_callback, None)
+
+ try:
+ src.splice_finish(result)
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+ self._corealbum.props.thumbnail = "generic"
+ return
+
+ success, cache_path = MediaArt.get_path(
+ self._corealbum.props.artist, self._corealbum.props.title, "album")
+
+ if not success:
+ self._corealbum.props.thumbnail = "generic"
+ return
+
+ try:
+ # FIXME: I/O blocking
+ MediaArt.file_to_jpeg(tmp_file.get_path(), cache_path)
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+ self._corealbum.props.thumbnail = "generic"
+ return
+
+ # FIXME: Also set media.
+ self._corealbum.props.thumbnail = cache_path
+
+ tmp_file.delete_async(
+ GLib.PRIORITY_LOW, None, self._delete_callback, None)
+
+ def _close_iostream_callback(self, src, result, data):
+ try:
+ src.close_finish(result)
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]