def splice_cb(src, result, data): tmp_file, iostream = data try: src.splice_finish(result) except Exception as err: logger.warn("Error: %s, %s", err.__class__, err) art_retrieved(False) return success, cache_path = MediaArt.get_path(artist, album, "album") try: # FIXME: I/O blocking MediaArt.file_to_jpeg(tmp_file.get_path(), cache_path) except Exception as err: logger.warn("Error: %s, %s", err.__class__, err) art_retrieved(False) return art_retrieved(True) tmp_file.delete_async(GLib.PRIORITY_LOW, None, delete_cb, None)
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: logger.warning("Error: {}, {}".format(error.domain, error.message)) self.emit('unavailable') return success, cache_path = MediaArt.get_path( self._artist, self._album, "album") if not success: self.emit('unavailable') return try: # FIXME: I/O blocking MediaArt.file_to_jpeg(tmp_file.get_path(), cache_path) except GLib.Error as error: logger.warning("Error: {}, {}".format(error.domain, error.message)) self.emit('unavailable') return self.emit('retrieved') tmp_file.delete_async( GLib.PRIORITY_LOW, None, self._delete_callback, None)
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: logger.warning("Error: {}, {}".format(error.domain, error.message)) self._coreartist.props.cached_thumbnail_uri = "" return success, cache_path = MediaArt.get_path(self._artist, None, "artist") if not success: self._coreartist.props.cached_thumbnail_uri = "" return try: # FIXME: I/O blocking MediaArt.file_to_jpeg(tmp_file.get_path(), cache_path) except GLib.Error as error: logger.warning("Error: {}, {}".format(error.domain, error.message)) self._coreartist.props.cached_thumbnail_uri = "" return self._in_cache() tmp_file.delete_async( GLib.PRIORITY_LOW, None, self._delete_callback, None)
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: logger.warning("Error: {}, {}".format(error.domain, error.message)) self.emit('unavailable') return success, cache_path = MediaArt.get_path(self._artist, self._album, "album") if not success: self.emit('unavailable') return try: # FIXME: I/O blocking MediaArt.file_to_jpeg(tmp_file.get_path(), cache_path) except GLib.Error as error: logger.warning("Error: {}, {}".format(error.domain, error.message)) self.emit('unavailable') return self.emit('retrieved') tmp_file.delete_async(GLib.PRIORITY_LOW, None, self._delete_callback, None)
def _lookup_local(self, item, callback, itr, art_size): """Checks if there is already a local art file, if not calls the remote lookup function""" album = utils.get_album_title(item) artist = utils.get_artist_name(item) def stream_open(thumb_file, result, arguments): try: stream = thumb_file.read_finish(result) except Exception as err: logger.warn("Error: %s, %s", err.__class__, err) do_callback(None) return GdkPixbuf.Pixbuf.new_from_stream_async(stream, None, pixbuf_loaded, None) def pixbuf_loaded(stream, result, data): try: pixbuf = GdkPixbuf.Pixbuf.new_from_stream_finish(result) except Exception as err: logger.warn("Error: %s, %s", err.__class__, err) do_callback(None) return do_callback(pixbuf) return def do_callback(pixbuf): if not pixbuf: surface = DefaultIcon(self._scale).get(DefaultIcon.Type.music, art_size) else: surface = _make_icon_frame(pixbuf, art_size, self._scale) # Sets the thumbnail location for MPRIS to use. item.set_thumbnail( GLib.filename_to_uri(thumb_file.get_path(), None)) GLib.idle_add(callback, surface, itr) return success, thumb_file = MediaArt.get_file(artist, album, "album") if (success and thumb_file.query_exists()): thumb_file.read_async(GLib.PRIORITY_LOW, None, stream_open, None) return stripped_album = MediaArt.strip_invalid_entities(album) if (artist in self.blacklist and stripped_album in self.blacklist[artist]): do_callback(None) return self._lookup_remote(item, callback, itr, art_size)
def _discovered(self, discoverer, info, error): tags = info.get_tags() index = 0 # FIXME: tags should not return as None, but it sometimes is. # So as a workaround until we figure out what is wrong check # for it. # https://bugzilla.gnome.org/show_bug.cgi?id=780980 if (error is not None or tags is None): if error: logger.warning("Discoverer error: {}, {}".format( Gst.CoreError(error.code), error.message)) discoverer.stop() self.emit('unavailable') return while True: success, sample = tags.get_sample_index(Gst.TAG_IMAGE, index) if not success: break index += 1 struct = sample.get_info() success, image_type = struct.get_enum( 'image-type', GstTag.TagImageType) if not success: continue if image_type != GstTag.TagImageType.FRONT_COVER: continue buf = sample.get_buffer() success, map_info = buf.map(Gst.MapFlags.READ) if not success: continue try: mime = sample.get_caps().get_structure(0).get_name() MediaArt.buffer_to_jpeg(map_info.data, mime, self._path) self.emit('found') discoverer.stop() return except GLib.Error as error: logger.warning("Error: {}, {}".format( MediaArt.Error(error.code), error.message)) discoverer.stop() self._lookup_cover_in_directory()
def _uri_async_cb(self, src, result, data): try: success = self._media_art.uri_finish(result) if success: self.emit('found') return except GLib.Error as error: if MediaArt.Error(error.code) == MediaArt.Error.SYMLINK_FAILED: # This error indicates that the coverart has already # been linked by another concurrent lookup. self.emit('found') else: logger.warning("Error: {}, {}".format( MediaArt.Error(error.code), error.message)) self.emit('unavailable')
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._coreobject.props.thumbnail = "generic" return if isinstance(self._coreobject, CoreArtist): success, cache_file = MediaArt.get_file( self._coreobject.props.artist, None, "artist") elif isinstance(self._coreobject, CoreAlbum): success, cache_file = MediaArt.get_file( self._coreobject.props.artist, self._coreobject.props.title, "album") elif isinstance(self._coreobject, CoreSong): success, cache_file = MediaArt.get_file( self._coreobject.props.artist, self._coreobject.props.album, "album") else: success = False if not success: self._coreobject.props.thumbnail = "generic" return try: # FIXME: I/O blocking MediaArt.file_to_jpeg(tmp_file.get_path(), cache_file.get_path()) except GLib.Error as error: self._log.warning("Error: {}, {}".format(error.domain, error.message)) self._coreobject.props.thumbnail = "generic" return self._coreobject.props.media.set_thumbnail(cache_file.get_uri()) self._coreobject.props.thumbnail = cache_file.get_uri() tmp_file.delete_async(GLib.PRIORITY_LOW, None, self._delete_callback, None)
def _in_cache(self): success, thumb_file = MediaArt.get_file(self._artist, None, "artist") if (not success or not thumb_file.query_exists()): return False self._coreartist.props.cached_thumbnail_uri = thumb_file.get_path() return True
def art_retrieved(result): if not result: if artist not in self.blacklist: self.blacklist[artist] = [] album_stripped = MediaArt.strip_invalid_entities(album) self.blacklist[artist].append(album_stripped) self.lookup(item, art_size, callback, itr)
def _in_cache(self): success, thumb_file = MediaArt.get_file(self._artist, None, "artist") if (not success or not thumb_file.query_exists()): self._coreartist.props.thumbnail = "loading" return False self._coreartist.props.thumbnail = thumb_file.get_uri() return True
def _add_to_blacklist(self): album = utils.get_album_title(self._media) artist = utils.get_artist_name(self._media) if artist not in self._blacklist: self._blacklist[artist] = [] album_stripped = MediaArt.strip_invalid_entities(album) self._blacklist[artist].append(album_stripped)
def _discovered(self, discoverer, info, error): tags = info.get_tags() index = 0 if (error is not None or tags is None): if error: logger.warning("Discoverer error: {}, {}".format( Gst.CoreError(error.code), error.message)) discoverer.stop() self.emit('unavailable') return while True: success, sample = tags.get_sample_index(Gst.TAG_IMAGE, index) if not success: break index += 1 struct = sample.get_info() success, image_type = struct.get_enum( 'image-type', GstTag.TagImageType) if not success: continue if image_type != GstTag.TagImageType.FRONT_COVER: continue buf = sample.get_buffer() success, map_info = buf.map(Gst.MapFlags.READ) if not success: continue try: mime = sample.get_caps().get_structure(0).get_name() MediaArt.buffer_to_jpeg(map_info.data, mime, self._path) self.emit('found') discoverer.stop() return except GLib.Error as error: logger.warning("Error: {}, {}".format( MediaArt.Error(error.code), error.message)) discoverer.stop() self._lookup_cover_in_directory()
def _discovered(self, discoverer, info, error): tags = info.get_tags() index = 0 if (error is not None or tags is None): if error: logger.warning("Discoverer error: {}, {}".format( Gst.CoreError(error.code), error.message)) discoverer.stop() self.emit('unavailable') return while True: success, sample = tags.get_sample_index(Gst.TAG_IMAGE, index) if not success: break index += 1 struct = sample.get_info() success, image_type = struct.get_enum('image-type', GstTag.TagImageType) if not success: continue if image_type != GstTag.TagImageType.FRONT_COVER: continue buf = sample.get_buffer() success, map_info = buf.map(Gst.MapFlags.READ) if not success: continue try: mime = sample.get_caps().get_structure(0).get_name() MediaArt.buffer_to_jpeg(map_info.data, mime, self._path) self.emit('found') discoverer.stop() return except GLib.Error as error: logger.warning("Error: {}, {}".format( MediaArt.Error(error.code), error.message)) discoverer.stop() self._lookup_cover_in_directory()
def lookup_worker(self, item, width, height, callback, itr, artist, album): try: width = width or -1 height = height or -1 path = MediaArt.get_path(artist, album, "album", None)[0] if not os.path.exists(path): self.cached_thumb_not_found(item, album, artist, path, callback, itr) self.read_cached_pixbuf(path, width, height, callback, itr) except Exception as e: logger.warn("Error: %s" % e)
def _in_blacklist(self): album = utils.get_album_title(self._media) artist = utils.get_artist_name(self._media) album_stripped = MediaArt.strip_invalid_entities(album) if artist in self._blacklist: if album_stripped in self._blacklist[artist]: return True return False
def _set_grilo_thumbnail_path(self): # TODO: This sets the thumbnail path for the Grilo Media object # to be used by MPRIS. However, calling this by default for # every cache hit is unnecessary. album = utils.get_album_title(self._media) artist = utils.get_artist_name(self._media) success, thumb_file = MediaArt.get_file(artist, album, "album") if success: self._media.set_thumbnail( GLib.filename_to_uri(thumb_file.get_path(), None))
def _add_to_blacklist(self): # FIXME: coresong can be a CoreAlbum try: album = self._coresong.props.album except AttributeError: album = self._coresong.props.title artist = self._coresong.props.artist if artist not in self._blacklist: self._blacklist[artist] = [] album_stripped = MediaArt.strip_invalid_entities(album) self._blacklist[artist].append(album_stripped)
def _in_blacklist(self): # FIXME: coresong can be a CoreAlbum try: album = self._coresong.props.album except AttributeError: album = self._coresong.props.title artist = self._coresong.props.artist album_stripped = MediaArt.strip_invalid_entities(album) if artist in self._blacklist: if album_stripped in self._blacklist[artist]: return True return False
def lookup_art_file_from_cache(media): """Lookup MediaArt cache art of an album or song. :param Grl.Media media: song or album :returns: a cache file :rtype: Gio.File """ album = utils.get_album_title(media) artist = utils.get_artist_name(media) success, thumb_file = MediaArt.get_file(artist, album, "album") if (not success or not thumb_file.query_exists()): return None return thumb_file
def query(self, media): """Start the cache query :param Grl.Media media: The media object to search art for """ album = utils.get_album_title(media) artist = utils.get_artist_name(media) success, thumb_file = MediaArt.get_file(artist, album, "album") if (success and thumb_file.query_exists()): thumb_file.read_async(GLib.PRIORITY_LOW, None, self._open_stream, None) return self.emit('miss')
def query(self, coresong): """Start the local query :param CoreSong coresong: The CoreSong object to search art for """ try: if coresong.props.url is None: self.emit('unavailable') return except AttributeError: self.emit('unavailable') return # FIXME: coresong can be a CoreAlbum try: self._album = coresong.props.album except AttributeError: self._album = coresong.props.title self._artist = coresong.props.artist self._coresong = coresong try: discoverer = GstPbutils.Discoverer.new(Gst.SECOND) except GLib.Error as error: logger.warning("Error: {}, {}".format(error.domain, error.message)) self._lookup_cover_in_directory() return discoverer.connect('discovered', self._discovered) discoverer.start() success, path = MediaArt.get_path(self._artist, self._album, "album") if not success: self.emit('unavailable') discoverer.stop() return self._path = path success = discoverer.discover_uri_async(self._coresong.props.url) if not success: logger.warning("Could not add url to discoverer.") self.emit('unavailable') discoverer.stop() return
def query(self, media): """Start the cache query :param Grl.Media media: The media object to search art for """ album = utils.get_album_title(media) artist = utils.get_artist_name(media) success, thumb_file = MediaArt.get_file(artist, album, "album") if (success and thumb_file.query_exists()): thumb_file.read_async( GLib.PRIORITY_LOW, None, self._open_stream, None) return self.emit('miss')
def _lookup_embedded(self, item, art_size, callback, itr): """Lookup embedded cover Lookup embedded art through Gst.Discoverer. If found copy locally and call _lookup_local to finish retrieving suitable art, otherwise follow up with _lookup_remote. """ album = utils.get_album_title(item) artist = utils.get_artist_name(item) success, cache_path = MediaArt.get_path(artist, album, "album") if not success: self._lookup_remote(item, art_size, callback, itr) self._discoverer_items[item.get_url()] = [ item, art_size, callback, itr, cache_path ] self._discoverer.discover_uri_async(item.get_url())
def lookup_art_file_from_cache(coresong): """Lookup MediaArt cache art of an album or song. :param CoreSong coresong: song or album :returns: a cache file :rtype: Gio.File """ try: album = coresong.props.album except AttributeError: album = coresong.props.title artist = coresong.props.artist success, thumb_file = MediaArt.get_file(artist, album, "album") if (not success or not thumb_file.query_exists()): return None return thumb_file
def lookup_worker(self, item, width, height, callback, itr, artist, album): try: if artist in self.blacklist and album in self.blacklist[artist]: self.finish(item, None, None, callback, itr) return path = MediaArt.get_path(artist, album, "album", None)[0] while path in self.queue: sleep(0.5) self.queue.append(path) if not os.path.exists(path): GLib.idle_add(self.cached_thumb_not_found, item, width, height, path, callback, itr, artist, album) return width = width or -1 height = height or -1 pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, width, height, True) self.finish(item, _make_icon_frame(pixbuf), path, callback, itr) except Exception as e: logger.warn("Error: %s" % e)
def query(self, media): """Start the local query :param Grl.Media media: The media object to search art for """ if media.get_url() is None: self.emit('unavailable') return self._album = utils.get_album_title(media) self._artist = utils.get_artist_name(media) self._media = media try: discoverer = GstPbutils.Discoverer.new(Gst.SECOND) except GLib.Error as error: logger.warning("Error: {}, {}".format(error.domain, error.message)) self._lookup_cover_in_directory() return discoverer.connect('discovered', self._discovered) discoverer.start() success, path = MediaArt.get_path(self._artist, self._album, "album") if not success: self.emit('unavailable') discoverer.stop() return self._path = path success = discoverer.discover_uri_async(self._media.get_url()) if not success: logger.warning("Could not add url to discoverer.") self.emit('unavailable') discoverer.stop() return
def lookup(self, item, width, height, callback, itr, artist, album, first=True): if artist in self.blacklist and album in self.blacklist[artist]: self.finish(item, None, None, callback, itr, width, height) return try: [success, thumb_file] = MediaArt.get_file(artist, album, "album") if success == False: self.finish(item, None, None, callback, itr, width, height) return if not thumb_file.query_exists(): if first: self.cached_thumb_not_found(item, width, height, thumb_file.get_path(), callback, itr, artist, album) else: self.finish(item, None, None, callback, itr, width, height) return stream = thumb_file.read_async(GLib.PRIORITY_LOW, None, self.stream_open, [item, width, height, thumb_file, callback, itr, artist, album]) except Exception as e: logger.warn("Error: %s, %s", e.__class__, e)
def lookup_worker(self, item, width, height, callback, itr, artist, album): try: if artist in self.blacklist and album in self.blacklist[artist]: self.finish(item, None, None, callback, itr, width, height) return path = None mediaart_tuple = MediaArt.get_path(artist, album, "album") for i in mediaart_tuple: if isinstance(i, str): path = i break if not os.path.exists(path): GLib.idle_add(self.cached_thumb_not_found, item, width, height, path, callback, itr, artist, album) return width = width or -1 height = height or -1 pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, width, height, True) self.finish(item, _make_icon_frame(pixbuf), path, callback, itr, width, height) except Exception as e: logger.warn("Error: %s", e)
def lookup_worker(self, item, width, height, callback, itr, artist, album): try: if artist in self.blacklist and album in self.blacklist[artist]: self.finish(item, None, None, callback, itr) return path = None mediaart_tuple = MediaArt.get_path(artist, album, "album") for i in mediaart_tuple: if isinstance(i, str): path = i break if not os.path.exists(path): GLib.idle_add(self.cached_thumb_not_found, item, width, height, path, callback, itr, artist, album) return width = width or -1 height = height or -1 pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, width, height, True) self.finish(item, _make_icon_frame(pixbuf), path, callback, itr) except Exception as e: logger.warn("Error: %s" % e)
def _discovered_cb(self, discoverer, info, error): item, art_size, callback, itr, cache_path = \ self._discoverer_items[info.get_uri()] album = utils.get_album_title(item) artist = utils.get_artist_name(item) tags = info.get_tags() index = 0 def art_retrieved(result): if not result: if artist not in self.blacklist: self.blacklist[artist] = [] album_stripped = MediaArt.strip_invalid_entities(album) self.blacklist[artist].append(album_stripped) self.lookup(item, art_size, callback, itr) # FIXME: tags should not return as None, but it sometimes is. # So as a workaround until we figure out what is wrong check # for it. # https://bugzilla.gnome.org/show_bug.cgi?id=780980 if (error is not None or tags is None): art_retrieved(False) return while True: success, sample = tags.get_sample_index(Gst.TAG_IMAGE, index) if not success: break index += 1 struct = sample.get_info() success, image_type = struct.get_enum('image-type', GstTag.TagImageType) if not success: continue if image_type != GstTag.TagImageType.FRONT_COVER: continue buf = sample.get_buffer() success, map_info = buf.map(Gst.MapFlags.READ) if not success: continue try: mime = sample.get_caps().get_structure(0).get_name() MediaArt.buffer_to_jpeg(map_info.data, mime, cache_path) art_retrieved(True) return except Exception as err: logger.warn("Error: %s, %s", err.__class__, err) try: self._media_art.uri(MediaArt.Type.ALBUM, MediaArt.ProcessFlags.NONE, item.get_url(), artist, album, None) if os.path.exists(cache_path): art_retrieved(True) return except Exception as err: logger.warn("Trying to process misc albumart: %s, %s", err.__class__, err) self._lookup_remote(item, art_size, callback, itr)
def _lookup_local(self, item, callback, itr, art_size): """Checks if there is already a local art file, if not calls the remote lookup function""" album = utils.get_album_title(item) artist = utils.get_artist_name(item) def stream_open(thumb_file, result, arguments): try: stream = thumb_file.read_finish(result) except Exception as err: logger.warn("Error: %s, %s", err.__class__, err) do_callback(None) return GdkPixbuf.Pixbuf.new_from_stream_async(stream, None, pixbuf_loaded, None) def pixbuf_loaded(stream, result, data): try: pixbuf = GdkPixbuf.Pixbuf.new_from_stream_finish(result) except Exception as err: logger.warn("Error: %s, %s", err.__class__, err) do_callback(None) return do_callback(pixbuf) return def do_callback(pixbuf): if not pixbuf: surface = DefaultIcon(self._scale).get(DefaultIcon.Type.music, art_size) else: surface = _make_icon_frame(pixbuf, art_size, self._scale) # Sets the thumbnail location for MPRIS to use. item.set_thumbnail(GLib.filename_to_uri(thumb_file.get_path(), None)) GLib.idle_add(callback, surface, itr) return success, thumb_file = MediaArt.get_file(artist, album, "album") if (success and thumb_file.query_exists()): thumb_file.read_async(GLib.PRIORITY_LOW, None, stream_open, None) return stripped_album = MediaArt.strip_invalid_entities(album) if (artist in self.blacklist and stripped_album in self.blacklist[artist]): do_callback(None) return self._lookup_remote(item, callback, itr, art_size)