コード例 #1
0
    def _add_search_item(self, source, param, item, remaining=0, data=None):
        if not item:
            if grilo._search_callback_counter == 0 and grilo.search_source:
                self.emit('no-music-found')
            return

        if data != self.model:
            return

        artist = utils.get_artist_name(item)
        album = utils.get_album_title(item)
        composer = item.get_composer()

        key = '%s-%s' % (artist, album)
        if key not in self._albums:
            self._albums[key] = Grl.Media()
            self._albums[key].set_title(album)
            self._albums[key].add_artist(artist)
            self._albums[key].set_composer(composer)
            self._albums[key].set_source(source.get_id())
            self._albums[key].tracks = []
            self._add_item(source, None, self._albums[key], 0, [self.model, 'album'])
            self._add_item(source, None, self._albums[key], 0, [self.model, 'artist'])

        self._albums[key].tracks.append(item)
        self._add_item(source, None, item, 0, [self.model, 'song'])
コード例 #2
0
    def _now_playing(self, media):
        """Internal method called by self.now_playing"""
        api_key = self._authentication.props.client_id
        sk = self._authentication.call_get_access_token_sync(None)[0]
        secret = self._authentication.props.client_secret

        artist = utils.get_artist_name(media)
        title = utils.get_media_title(media)

        sig = ("api_key{}artist{}methodtrack.updateNowPlayingsk{}track"
               "{}{}").format(api_key, artist, sk, title, secret)

        api_sig = md5(sig.encode()).hexdigest()
        request_dict = {
            "api_key": api_key,
            "method": "track.updateNowPlaying",
            "artist": artist,
            "track": title,
            "sk": sk,
            "api_sig": api_sig
        }

        try:
            r = requests.post("https://ws.audioscrobbler.com/2.0/",
                              request_dict)
            if r.status_code != 200:
                logger.warn("Failed to update currently played track: %s %s" %
                            (r.status_code, r.reason))
                logger.warn(r.text)
        except Exception as e:
            logger.warn(e)
コード例 #3
0
ファイル: player.py プロジェクト: pratik4/gnome-music
    def load(self, media):
        self.progressScale.set_value(0)
        self._set_duration(media.get_duration())
        self.songTotalTimeLabel.set_label(
            utils.seconds_to_string(media.get_duration()))
        self.progressScale.set_sensitive(True)

        self.playBtn.set_sensitive(True)
        self._sync_prev_next()

        artist = utils.get_artist_name(media)
        self.artistLabel.set_label(artist)
        self._currentArtist = artist

        self.coverImg.set_from_surface(self._loading_icon_surface)
        self.cache.lookup(media, ArtSize.xsmall, self._on_cache_lookup, None)

        self._currentTitle = utils.get_media_title(media)
        self.titleLabel.set_label(self._currentTitle)

        self._currentTimestamp = int(time.time())

        url = media.get_url()
        if url != self.player.get_value('current-uri', 0):
            self.player.set_property('uri', url)

        if self.currentTrack and self.currentTrack.valid():
            currentTrack = self.playlist.get_iter(self.currentTrack.get_path())
            self.emit('playlist-item-changed', self.playlist, currentTrack)
            self.emit('current-changed')

        self._validate_next_track()
コード例 #4
0
ファイル: searchview.py プロジェクト: pratik4/gnome-music
    def _add_search_item(self, source, param, item, remaining=0, data=None):
        if not item:
            if grilo._search_callback_counter == 0 and grilo.search_source:
                self.emit('no-music-found')
            return

        if data != self.model:
            return

        artist = utils.get_artist_name(item)
        album = utils.get_album_title(item)
        composer = item.get_composer()

        key = '%s-%s' % (artist, album)
        if key not in self._albums:
            self._albums[key] = Grl.Media()
            self._albums[key].set_title(album)
            self._albums[key].add_artist(artist)
            self._albums[key].set_composer(composer)
            self._albums[key].set_source(source.get_id())
            self._albums[key].tracks = []
            self._add_item(source, None, self._albums[key], 0,
                           [self.model, 'album'])
            self._add_item(source, None, self._albums[key], 0,
                           [self.model, 'artist'])

        self._albums[key].tracks.append(item)
        self._add_item(source, None, item, 0, [self.model, 'song'])
コード例 #5
0
ファイル: artistsview.py プロジェクト: GNOME/gnome-music
    def _add_item(self, source, param, item, remaining=0, data=None):
        if (not item and remaining == 0):
            self._window.notifications_popup.pop_loading()
            self._sidebar.show()
            return
        self._offset += 1
        artist = utils.get_artist_name(item)
        row = None
        if not artist.casefold() in self._artists:
            # populate sidebar
            row = SidebarRow()
            row.props.text = artist
            row.connect('notify::selected', self._on_selection_changed)
            self.bind_property('selection-mode', row, 'selection-mode')
            self._sidebar.add(row)

            self._artists[artist.casefold()] = {
                'albums': [],
                'widget': None
            }

        self._artists[artist.casefold()]['albums'].append(item)

        if (row is not None
                and len(self._sidebar) == 1):
            self._sidebar.select_row(row)
            self._sidebar.emit('row-activated', row)
コード例 #6
0
    def _add_item(self, source, param, item, remaining=0, data=None):
        if (not item and remaining == 0):
            self._window.notifications_popup.pop_loading()
            self._sidebar.show()
            return
        self._offset += 1
        artist = utils.get_artist_name(item)
        if not artist.casefold() in self._artists:
            # populate sidebar
            row = Gtk.ListBoxRow()
            row.artist = artist
            box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
            row.add(box)
            row.check = Gtk.CheckButton(margin_left=12)
            row.check.connect('toggled', self._on_selection_toggled)
            artist_label = Gtk.Label(label=artist,
                                     xalign=0,
                                     xpad=16,
                                     ypad=16,
                                     ellipsize=Pango.EllipsizeMode.END)
            box.pack_start(row.check, False, True, 0)
            box.pack_start(artist_label, True, True, 0)
            self._sidebar.add(row)
            row.show_all()
            row.check.hide()
            row.check.bind_property('visible', self, 'selection_mode',
                                    GObject.BindingFlags.BIDIRECTIONAL)

            self._artists[artist.casefold()] = {'albums': [], 'widget': None}
        self._artists[artist.casefold()]['albums'].append(item)
コード例 #7
0
    def load(self, media):
        self._progress_scale_zero()
        self._set_duration(media.get_duration())
        self.songTotalTimeLabel.set_label(
            utils.seconds_to_string(media.get_duration()))
        self.progressScale.set_sensitive(True)

        self.playBtn.set_sensitive(True)
        self._sync_prev_next()

        artist = utils.get_artist_name(media)
        self.artistLabel.set_label(artist)
        self._currentArtist = artist

        self.coverImg.set_from_surface(self._loading_icon_surface)
        self.cache.lookup(media, ArtSize.xsmall, self._on_cache_lookup, None)

        self._currentTitle = utils.get_media_title(media)
        self.titleLabel.set_label(self._currentTitle)

        self._currentTimestamp = int(time.time())

        url = media.get_url()
        if url != self.player.get_value('current-uri', 0):
            self.player.set_property('uri', url)

        if self.currentTrack and self.currentTrack.valid():
            currentTrack = self.playlist.get_iter(self.currentTrack.get_path())
            self.emit('playlist-item-changed', self.playlist, currentTrack)
            self.emit('current-changed')

        self._validate_next_track()
コード例 #8
0
    def _add_item(self, source, param, item, remaining=0, data=None):
        if not item:
            if remaining == 0:
                self.view.set_model(self.model)
                self.window.pop_loading_notification()
                self.view.show()
            return

        self._offset += 1
        artist = utils.get_artist_name(item)
        title = utils.get_media_title(item)

        _iter = self.model.append(None)

        loading_icon = Gdk.pixbuf_get_from_surface(
            self._loadin_icon_surface, 0, 0,
            self._loading_icon_surface.get_width(),
            self._loading_icon_surface.get_height())

        self.model[_iter][0, 1, 2, 3, 4, 5, 7, 9] = [
            str(item.get_id()),
            '',
            title,
            artist,
            loading_icon,
            item,
            0,
            False
        ]
        self.cache.lookup(item, self._iconWidth, self._iconHeight,
                          self._on_lookup_ready, _iter)
コード例 #9
0
ファイル: searchview.py プロジェクト: iqHpi/gnome-music
    def _add_search_item(self, source, param, item, remaining=0, data=None):
        if not item:
            if (grilo._search_callback_counter == 0
                    and grilo.search_source):
                self.props.search_state = Search.State.NO_RESULT
            return

        if data != self.model:
            return

        artist = utils.get_artist_name(item)
        album = utils.get_album_title(item)

        key = '%s-%s' % (artist, album)
        if key not in self._albums:
            self._albums[key] = Grl.Media()
            self._albums[key].set_title(album)
            self._albums[key].add_artist(artist)
            self._albums[key].set_source(source.get_id())
            self._albums[key].songs = []
            self._add_item(
                source, None, self._albums[key], 0, [self.model, 'album'])
            self._add_item(
                source, None, self._albums[key], 0, [self.model, 'artist'])

        self._albums[key].songs.append(item)
        self._add_item(source, None, item, 0, [self.model, 'song'])
コード例 #10
0
ファイル: albumwidget.py プロジェクト: iqHpi/gnome-music
    def update(self, album):
        """Update the album widget.

        :param Grl.Media album: The grilo media album
        """
        # reset view
        self._songs = []
        self._create_model()
        for widget in self._disc_listbox.get_children():
            self._disc_listbox.remove(widget)

        self._cover_stack.update(album)

        self._duration = 0

        self._album_name = utils.get_album_title(album)
        artist = utils.get_artist_name(album)

        self._title_label.props.label = self._album_name
        self._title_label.props.tooltip_text = self._album_name

        self._artist_label.props.label = artist
        self._artist_label.props.tooltip_text = artist

        year = utils.get_media_year(album)
        if not year:
            year = '----'
        self._released_info_label.props.label = year

        self._set_composer_label(album)

        self._player.connect('song-changed', self._update_model)

        grilo.populate_album_songs(album, self.add_item)
コード例 #11
0
ファイル: baseview.py プロジェクト: pratik4/gnome-music
    def _add_item(self, source, param, item, remaining=0, data=None):
        self.window.notification.set_timeout(0)
        if not item:
            if remaining == 0:
                self.view.set_model(self.model)
                self.window.notification.dismiss()
                self.view.show()
            return

        self._offset += 1
        artist = utils.get_artist_name(item)
        title = utils.get_media_title(item)

        _iter = self.model.append(None)

        loading_icon = Gdk.pixbuf_get_from_surface(
            self._loadin_icon_surface, 0, 0,
            self._loading_icon_surface.get_width(),
            self._loading_icon_surface.get_height())

        self.model[_iter][0, 1, 2, 3, 4, 5, 7, 9] = [
            str(item.get_id()), '', title, artist, loading_icon, item, 0, False
        ]
        self.cache.lookup(item, self._iconWidth, self._iconHeight,
                          self._on_lookup_ready, _iter)
コード例 #12
0
    def load(self, media):
        self._progress_scale_zero()
        self._set_duration(media.get_duration())
        self.songTotalTimeLabel.set_label(
            utils.seconds_to_string(media.get_duration()))
        self.progressScale.set_sensitive(True)

        self.playBtn.set_sensitive(True)
        self._sync_prev_next()

        artist = utils.get_artist_name(media)
        self.artistLabel.set_label(artist)

        self._cover_stack.update(media)

        title = utils.get_media_title(media)
        self.titleLabel.set_label(title)

        self._time_stamp = int(time.time())

        url = media.get_url()
        if url != self.player.get_value('current-uri', 0):
            self.player.set_property('uri', url)

        if self.currentTrack and self.currentTrack.valid():
            currentTrack = self.playlist.get_iter(self.currentTrack.get_path())
            self.emit('playlist-item-changed', self.playlist, currentTrack)
            self.emit('current-changed')

        self._validate_next_track()
コード例 #13
0
    def __init__(self, media):
        """Initialize the AlbumCover

        :param Grl.Media media: The media object to use
        """
        super().__init__()

        AlbumCover._nr_albums += 1

        self._media = media

        self._tooltip = TwoLineTip()

        artist = utils.get_artist_name(media)
        title = utils.get_media_title(media)

        self._tooltip.props.title = utils.get_artist_name(media)
        self._tooltip.props.subtitle = utils.get_media_title(media)

        self._artist_label.props.label = artist
        self._title_label.props.label = title

        self.bind_property(
            'selected', self._check, 'active',
            GObject.BindingFlags.BIDIRECTIONAL
            | GObject.BindingFlags.SYNC_CREATE)
        self.bind_property('selection-mode', self._check, 'visible',
                           GObject.BindingFlags.BIDIRECTIONAL)

        self.connect('query-tooltip', self._on_tooltip_query)

        self._events.add_events(Gdk.EventMask.TOUCH_MASK)

        self._cover_stack.props.size = Art.Size.MEDIUM

        self.show()

        # FIXME: To work around slow updating of the albumsview,
        # load album covers with a fixed delay. This results in a
        # quick first show with a placeholder cover and then a
        # reasonably responsive view while loading the actual
        # covers.
        GLib.timeout_add(50 * self._nr_albums,
                         self._cover_stack.update,
                         media,
                         priority=GLib.PRIORITY_LOW)
コード例 #14
0
ファイル: albumcover.py プロジェクト: GNOME/gnome-music
    def __init__(self, media):
        """Initialize the AlbumCover

        :param Grl.Media media: The media object to use
        """
        super().__init__()

        AlbumCover._nr_albums += 1

        self._media = media

        self._tooltip = TwoLineTip()

        artist = utils.get_artist_name(media)
        title = utils.get_media_title(media)

        self._tooltip.props.title = utils.get_artist_name(media)
        self._tooltip.props.subtitle = utils.get_media_title(media)

        self._artist_label.props.label = artist
        self._title_label.props.label = title

        self.bind_property(
            'selected', self._check, 'active',
            GObject.BindingFlags.BIDIRECTIONAL
            | GObject.BindingFlags.SYNC_CREATE)
        self.bind_property(
            'selection-mode', self._check, 'visible',
            GObject.BindingFlags.BIDIRECTIONAL)

        self.connect('query-tooltip', self._on_tooltip_query)

        self._events.add_events(Gdk.EventMask.TOUCH_MASK)

        self._cover_stack.props.size = Art.Size.MEDIUM

        self.show()

        # FIXME: To work around slow updating of the albumsview,
        # load album covers with a fixed delay. This results in a
        # quick first show with a placeholder cover and then a
        # reasonably responsive view while loading the actual
        # covers.
        GLib.timeout_add(
            50 * self._nr_albums, self._cover_stack.update, media,
            priority=GLib.PRIORITY_LOW)
コード例 #15
0
    def __init__(self,
                 media,
                 player,
                 model,
                 header_bar,
                 selection_mode_allowed,
                 size_group=None,
                 cover_size_group=None):
        super().__init__(orientation=Gtk.Orientation.HORIZONTAL)

        self._size_group = size_group
        self._cover_size_group = cover_size_group
        scale = self.get_scale_factor()
        self._cache = AlbumArtCache(scale)
        self._loading_icon_surface = DefaultIcon(scale).get(
            DefaultIcon.Type.loading, ArtSize.MEDIUM)

        self._media = media
        self._player = player
        self._artist = utils.get_artist_name(self._media)
        self._album_title = utils.get_album_title(self._media)
        self._model = model
        self._header_bar = header_bar
        self._selection_mode = False
        self._selection_mode_allowed = selection_mode_allowed

        self._songs = []

        self._header_bar._select_button.connect(
            'toggled', self._on_header_select_button_toggled)

        ui = Gtk.Builder()
        ui.add_from_resource('/org/gnome/Music/ArtistAlbumWidget.ui')

        self.cover = ui.get_object('cover')
        self.cover.set_from_surface(self._loading_icon_surface)

        self._disc_listbox = ui.get_object('disclistbox')
        self._disc_listbox.set_selection_mode_allowed(
            self._selection_mode_allowed)

        ui.get_object('title').set_label(self._album_title)
        creation_date = self._media.get_creation_date()
        if creation_date:
            year = creation_date.get_year()
            ui.get_object('year').set_markup(
                '<span color=\'grey\'>{}</span>'.format(year))

        if self._size_group:
            self._size_group.add_widget(ui.get_object('box1'))

        if self._cover_size_group:
            self._cover_size_group.add_widget(self.cover)

        self.pack_start(ui.get_object('ArtistAlbumWidget'), True, True, 0)

        GLib.idle_add(self._update_album_art)
        grilo.populate_album_songs(self._media, self._add_item)
コード例 #16
0
ファイル: albumartcache.py プロジェクト: GNOME/gnome-music
    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)
コード例 #17
0
ファイル: albumartcache.py プロジェクト: rz6iox/gnome-music
    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)
コード例 #18
0
ファイル: albumartcache.py プロジェクト: rz6iox/gnome-music
    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
コード例 #19
0
ファイル: albumartcache.py プロジェクト: GNOME/gnome-music
    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
コード例 #20
0
ファイル: corealbum.py プロジェクト: Honza0297/test
    def update(self, media):
        """Update the CoreAlbum object with new info

        :param Grl.Media media: A media object
        """
        self.props.media = media
        self.props.artist = utils.get_artist_name(media)
        self.props.composer = media.get_composer()
        self.props.title = utils.get_media_title(media)
        self.props.year = utils.get_media_year(media)
コード例 #21
0
    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)
コード例 #22
0
    def query(self, media):
        """Start the remote query

        :param Grl.Media media: The media object to search art for
        """
        self._album = utils.get_album_title(media)
        self._artist = utils.get_artist_name(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)
コード例 #23
0
    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))
コード例 #24
0
    def _update_view(self, player, playlist, current_iter):
        media = playlist[current_iter][player.Field.SONG]
        self._duration_label.set_label(
            utils.seconds_to_string(media.get_duration()))

        self._play_button.set_sensitive(True)
        self._sync_prev_next()

        self._artist_label.set_label(utils.get_artist_name(media))
        self._title_label.set_label(utils.get_media_title(media))
        self._cover_stack.update(media)
コード例 #25
0
 def update(self, media):
     self.props.media = media
     self.props.album = utils.get_album_title(media)
     self.props.album_disc_number = media.get_album_disc_number()
     self.props.artist = utils.get_artist_name(media)
     self.props.duration = media.get_duration()
     self.props.favorite = media.get_favourite()
     self.props.play_count = media.get_play_count()
     self.props.title = utils.get_media_title(media)
     self.props.track_number = media.get_track_number()
     self.props.url = media.get_url()
コード例 #26
0
ファイル: albumartcache.py プロジェクト: GNOME/gnome-music
    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))
コード例 #27
0
    def _on_child_activated(self, widget, child, user_data=None):
        if self.props.selection_mode:
            return

        item = child.props.media
        # Update and display the album widget if not in selection mode
        self._album_widget.update(item)

        self._headerbar.props.state = HeaderBar.State.CHILD
        self._headerbar.props.title = utils.get_album_title(item)
        self._headerbar.props.subtitle = utils.get_artist_name(item)
        self.set_visible_child(self._album_widget)
コード例 #28
0
ファイル: scrobbler.py プロジェクト: GNOME/gnome-music
    def _lastfm_api_call(self, media, time_stamp, request_type_key):
        """Internal method called by self.scrobble"""
        api_key = self._goa_lastfm.client_id
        sk = self._goa_lastfm.session_key
        secret = self._goa_lastfm.secret

        artist = utils.get_artist_name(media)
        title = utils.get_media_title(media)

        request_type = {
            "update now playing": "track.updateNowPlaying",
            "scrobble": "track.scrobble"
        }

        # The album is optional. So only provide it when it is
        # available.
        album = media.get_album()

        request_dict = {}
        if album:
            request_dict.update({
                "album": album
            })

        if time_stamp is not None:
            request_dict.update({
                "timestamp": str(time_stamp)
            })

        request_dict.update({
            "api_key": api_key,
            "method": request_type[request_type_key],
            "artist": artist,
            "track": title,
            "sk": sk,
        })

        sig = ""
        for key in sorted(request_dict):
            sig += key + request_dict[key]

        sig += secret

        api_sig = md5(sig.encode()).hexdigest()
        request_dict.update({
            "api_sig": api_sig
        })

        msg = Soup.form_request_new_from_hash(
            "POST", "https://ws.audioscrobbler.com/2.0/", request_dict)
        self._soup_session.queue_message(
            msg, self._lastfm_api_callback, request_type_key)
コード例 #29
0
ファイル: mpris.py プロジェクト: rz6iox/gnome-music
    def _get_metadata(self, media=None, index=None):
        song_dbus_path = self._get_song_dbus_path(media, index)
        if not self.player.props.current_song:
            return {'mpris:trackid': GLib.Variant('o', song_dbus_path)}

        if not media:
            media = self.player.props.current_song

        length = media.get_duration() * 1e6
        user_rating = 1.0 if media.get_favourite() else 0.0
        artist = utils.get_artist_name(media)

        metadata = {
            'mpris:trackid': GLib.Variant('o', song_dbus_path),
            'xesam:url': GLib.Variant('s', media.get_url()),
            'mpris:length': GLib.Variant('x', length),
            'xesam:trackNumber': GLib.Variant('i', media.get_track_number()),
            'xesam:useCount': GLib.Variant('i', media.get_play_count()),
            'xesam:userRating': GLib.Variant('d', user_rating),
            'xesam:title': GLib.Variant('s', utils.get_media_title(media)),
            'xesam:album': GLib.Variant('s', utils.get_album_title(media)),
            'xesam:artist': GLib.Variant('as', [artist]),
            'xesam:albumArtist': GLib.Variant('as', [artist])
        }

        genre = media.get_genre()
        if genre is not None:
            metadata['xesam:genre'] = GLib.Variant('as', [genre])

        last_played = media.get_last_played()
        if last_played is not None:
            last_played_str = last_played.format("%FT%T%:z")
            metadata['xesam:lastUsed'] = GLib.Variant('s', last_played_str)

        # If the media has already been part of an MPRIS playlist, its
        # thumbnail is already set. Otherwise, try to look for it in the
        # cache directory and set the media thumbnail for a future use.
        # The search is only through the cache to prevent any delayed
        # loading.
        # FIXME: The thumbnail retrieval should take place in the
        # player.
        art_url = media.get_thumbnail()
        if not art_url:
            thumb_file = lookup_art_file_from_cache(media)
            if thumb_file:
                art_url = GLib.filename_to_uri(thumb_file.get_path())
                media.set_thumbnail(art_url)

        if art_url:
            metadata['mpris:artUrl'] = GLib.Variant('s', art_url)

        return metadata
コード例 #30
0
ファイル: scrobbler.py プロジェクト: csriharsha/gnome-music
    def _lastfm_api_call(self, media, time_stamp, request_type_key):
        """Internal method called by self.scrobble"""
        api_key = self._goa_lastfm.client_id
        sk = self._goa_lastfm.session_key
        secret = self._goa_lastfm.secret

        artist = utils.get_artist_name(media)
        title = utils.get_media_title(media)

        request_type = {
            "update now playing": "track.updateNowPlaying",
            "scrobble": "track.scrobble"
        }

        # The album is optional. So only provide it when it is
        # available.
        album = media.get_album()

        request_dict = {}
        if album:
            request_dict.update({"album": album})

        if time_stamp is not None:
            request_dict.update({"timestamp": time_stamp})

        request_dict.update({
            "api_key": api_key,
            "method": request_type[request_type_key],
            "artist": artist,
            "track": title,
            "sk": sk,
        })

        sig = ""
        for key in sorted(request_dict):
            sig += key + str(request_dict[key])

        sig += secret

        api_sig = md5(sig.encode()).hexdigest()
        request_dict.update({"api_sig": api_sig})

        try:
            r = requests.post("https://ws.audioscrobbler.com/2.0/",
                              request_dict)
            if r.status_code != 200:
                logger.warning("Failed to {} track: {} {}".format(
                    request_type_key, r.status_code, r.reason))
                logger.warning(r.text)
        except Exception as e:
            logger.warning(e)
コード例 #31
0
ファイル: albumartcache.py プロジェクト: rz6iox/gnome-music
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
コード例 #32
0
    def _add_item(self, source, param, item, remaining=0, data=None):
        self.window.notification.set_timeout(0)
        if item is None:
            if remaining == 0:
                self.view.set_model(self.model)
                self.window.notification.dismiss()
                self.view.show()
            return
        self._offset += 1
        artist = utils.get_artist_name(item)
        if not artist.casefold() in self._artists:
            _iter = self.model.insert_with_valuesv(-1, [2], [artist])
            self._artists[artist.casefold()] = {'iter': _iter, 'albums': [], 'widget': None}

        self._artists[artist.casefold()]['albums'].append(item)
コード例 #33
0
    def __init__(self,
                 media,
                 player,
                 model,
                 header_bar,
                 selection_mode_allowed,
                 size_group=None,
                 cover_size_group=None):
        super().__init__(orientation=Gtk.Orientation.HORIZONTAL)

        self._size_group = size_group
        self._cover_size_group = cover_size_group

        self._media = media
        self._player = player
        self._artist = utils.get_artist_name(self._media)
        self._album_title = utils.get_album_title(self._media)
        self._model = model
        self._header_bar = header_bar
        self._selection_mode = False
        self._selection_mode_allowed = selection_mode_allowed

        self._songs = []

        self._cover_stack.props.size = Art.Size.MEDIUM
        self._cover_stack.update(self._media)

        allowed = self._selection_mode_allowed
        self._disc_list_box.props.selection_mode_allowed = allowed

        self.bind_property(
            'selection-mode', self._disc_list_box, 'selection-mode',
            GObject.BindingFlags.BIDIRECTIONAL
            | GObject.BindingFlags.SYNC_CREATE)

        self._title.props.label = self._album_title
        year = utils.get_media_year(self._media)

        if year:
            self._year.props.label = year

        if self._size_group:
            self._size_group.add_widget(self._album_box)

        if self._cover_size_group:
            self._cover_size_group.add_widget(self._cover_stack)

        grilo.populate_album_songs(self._media, self._add_item)
コード例 #34
0
    def _add_item(self, source, param, item, remaining=0, data=None):
        if not item:
            if remaining == 0:
                self._view.set_model(self.model)
                self._window.notifications_popup.pop_loading()
                self._view.show()
            return
        self._offset += 1
        artist = utils.get_artist_name(item)
        title = utils.get_media_title(item)

        itr = self.model.append(None)

        self.model[itr][0, 1, 2, 3, 5, 7, 9] = [
            str(item.get_id()), '', title, artist, item, 0, False
        ]
コード例 #35
0
 def _add_item(self, source, param, item, remaining=0, data=None):
     if (not item and remaining == 0):
         self._view.set_model(self.model)
         self._window.notifications_popup.pop_loading()
         self._view.show()
         return
     self._offset += 1
     artist = utils.get_artist_name(item)
     if not artist.casefold() in self._artists:
         itr = self.model.insert_with_valuesv(-1, [2], [artist])
         self._artists[artist.casefold()] = {
             'iter': itr,
             'albums': [],
             'widget': None
         }
     self._artists[artist.casefold()]['albums'].append(item)
コード例 #36
0
 def _add_item(self, source, param, item, remaining=0, data=None):
     if (not item and remaining == 0):
         self.view.set_model(self.model)
         self.window.pop_loading_notification()
         self.view.show()
         return
     self._offset += 1
     artist = utils.get_artist_name(item)
     if not artist.casefold() in self._artists:
         itr = self.model.insert_with_valuesv(-1, [2], [artist])
         self._artists[artist.casefold()] = {
             'iter': itr,
             'albums': [],
             'widget': None
         }
     self._artists[artist.casefold()]['albums'].append(item)
コード例 #37
0
    def _add_item_to_model(self, item, model):
        if not item:
            self._update_songs_count()
            if self.player.playlist:
                self.player._validate_next_track()
            self.emit('playlist-songs-loaded')
            return

        self._offset += 1
        title = utils.get_media_title(item)
        item.set_title(title)
        artist = utils.get_artist_name(item)
        model.insert_with_valuesv(-1, [2, 3, 5, 9],
                                  [title, artist, item, item.get_favourite()])

        self._songs_count += 1
コード例 #38
0
    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')
コード例 #39
0
ファイル: albumartcache.py プロジェクト: GNOME/gnome-music
    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')
コード例 #40
0
ファイル: albumartcache.py プロジェクト: rz6iox/gnome-music
    def query(self, media):
        """Start the remote query

        :param Grl.Media media: The media object to search art for
        """
        self._album = utils.get_album_title(media)
        self._artist = utils.get_artist_name(media)
        self._media = media

        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)
コード例 #41
0
ファイル: playlistview.py プロジェクト: GNOME/gnome-music
    def _add_song_to_model(self, song, model, index=-1):
        """Add song to a playlist
        :param Grl.Media song: song to add
        :param Gtk.ListStore model: model
        """
        if not song:
            return None

        title = utils.get_media_title(song)
        song.set_title(title)
        artist = utils.get_artist_name(song)
        iter_ = model.insert_with_valuesv(
            index, [2, 3, 5, 9],
            [title, artist, song, song.get_favourite()])

        self._update_songs_count(self._songs_count + 1)
        return iter_
コード例 #42
0
ファイル: scrobbler.py プロジェクト: underhood31/gnome-music
    def _lastfm_api_call(self, media, time_stamp, request_type_key):
        """Internal method called by self.scrobble"""
        api_key = self._goa_lastfm.client_id
        sk = self._goa_lastfm.session_key
        secret = self._goa_lastfm.secret

        artist = utils.get_artist_name(media)
        title = utils.get_media_title(media)

        request_type = {
            "update now playing": "track.updateNowPlaying",
            "scrobble": "track.scrobble"
        }

        # The album is optional. So only provide it when it is
        # available.
        album = media.get_album()

        request_dict = {}
        if album:
            request_dict.update({"album": album})

        if time_stamp is not None:
            request_dict.update({"timestamp": str(time_stamp)})

        request_dict.update({
            "api_key": api_key,
            "method": request_type[request_type_key],
            "artist": artist,
            "track": title,
            "sk": sk,
        })

        sig = ""
        for key in sorted(request_dict):
            sig += key + request_dict[key]

        sig += secret

        api_sig = md5(sig.encode()).hexdigest()
        request_dict.update({"api_sig": api_sig})

        msg = Soup.form_request_new_from_hash(
            "POST", "https://ws.audioscrobbler.com/2.0/", request_dict)
        self._soup_session.queue_message(msg, self._lastfm_api_callback,
                                         request_type_key)
コード例 #43
0
ファイル: albumartcache.py プロジェクト: GNOME/gnome-music
    def query(self, media):
        """Start the remote query

        :param Grl.Media media: The media object to search art for
        """
        self._album = utils.get_album_title(media)
        self._artist = utils.get_artist_name(media)
        self._media = media

        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)
コード例 #44
0
ファイル: mpris.py プロジェクト: GNOME/gnome-music
    def _get_metadata(self, media=None, index=None):
        song_dbus_path = self._get_song_dbus_path(media, index)
        if not self.player.props.current_song:
            return {
                'mpris:trackid': GLib.Variant('o', song_dbus_path)
            }

        if not media:
            media = self.player.props.current_song

        length = media.get_duration() * 1e6
        user_rating = 1.0 if media.get_favourite() else 0.0
        artist = utils.get_artist_name(media)

        metadata = {
            'mpris:trackid': GLib.Variant('o', song_dbus_path),
            'xesam:url': GLib.Variant('s', media.get_url()),
            'mpris:length': GLib.Variant('x', length),
            'xesam:trackNumber': GLib.Variant('i', media.get_track_number()),
            'xesam:useCount': GLib.Variant('i', media.get_play_count()),
            'xesam:userRating': GLib.Variant('d', user_rating),
            'xesam:title': GLib.Variant('s', utils.get_media_title(media)),
            'xesam:album': GLib.Variant('s', utils.get_album_title(media)),
            'xesam:artist': GLib.Variant('as', [artist]),
            'xesam:albumArtist': GLib.Variant('as', [artist])
        }

        genre = media.get_genre()
        if genre is not None:
            metadata['xesam:genre'] = GLib.Variant('as', [genre])

        last_played = media.get_last_played()
        if last_played is not None:
            last_played_str = last_played.format("%FT%T%:z")
            metadata['xesam:lastUsed'] = GLib.Variant('s', last_played_str)

        art_url = media.get_thumbnail()
        if art_url is not None:
            metadata['mpris:artUrl'] = GLib.Variant('s', art_url)

        return metadata
コード例 #45
0
    def _add_item(self, source, param, item, remaining=0, data=None):
        """Adds track item to the model"""
        if not item and not remaining:
            self.view.set_model(self.model)
            self.window.pop_loading_notification()
            self.view.show()
            return

        self._offset += 1
        item.set_title(utils.get_media_title(item))
        artist = utils.get_artist_name(item)

        if not item.get_url():
            return

        self.model.insert_with_valuesv(-1, [2, 3, 5, 9], [
            utils.get_media_title(item),
            artist,
            item,
            item.get_favourite()
        ])
コード例 #46
0
ファイル: albumsview.py プロジェクト: GNOME/gnome-music
    def _on_child_activated(self, widget, child, user_data=None):
        item = child.media_item

        if self.star_handler.star_renderer_click:
            self.star_handler.star_renderer_click = False
            return

        # Toggle the selection when in selection mode
        if self.selection_mode:
            child.check.set_active(not child.check.get_active())
            return

        title = utils.get_media_title(item)
        self._escaped_title = title
        self._artist = utils.get_artist_name(item)

        self._albumWidget.update(self._artist, title, item, self.header_bar, self.selection_toolbar)

        self.header_bar.set_state(ToolbarState.CHILD_VIEW)
        self.header_bar.header_bar.set_title(self._escaped_title)
        self.header_bar.header_bar.sub_title = self._artist
        self.set_visible_child(self._albumWidget)
コード例 #47
0
ファイル: playertoolbar.py プロジェクト: GNOME/gnome-music
    def _update_view(self, player):
        """Updates model when the song changes

        :param Player player: The main player object
        """
        current_song = player.props.current_song
        self._duration_label.set_label(
            utils.seconds_to_string(current_song.get_duration()))

        self._play_button.set_sensitive(True)
        self._sync_prev_next()

        artist = utils.get_artist_name(current_song)
        title = utils.get_media_title(current_song)

        self._title_label.props.label = title
        self._artist_label.props.label = artist

        self._tooltip.props.title = title
        self._tooltip.props.subtitle = artist

        self._cover_stack.update(current_song)
コード例 #48
0
ファイル: albumartcache.py プロジェクト: GNOME/gnome-music
    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
コード例 #49
0
ファイル: player.py プロジェクト: saifulbkhan/gnome-music
    def load(self, media):
        self.progressScale.set_value(0)
        self._set_duration(media.get_duration())
        self.songTotalTimeLabel.set_label(self.seconds_to_string(media.get_duration()))
        self.progressScale.set_sensitive(True)

        self.playBtn.set_sensitive(True)
        self._sync_prev_next()

        artist = utils.get_artist_name(media)
        self.artistLabel.set_label(artist)
        self._currentArtist = artist

        album = _("Unknown Album")
        try:
            assert media.get_album() is not None
            album = media.get_album()
        except:
            self._currentAlbum = album

        self.coverImg.set_from_pixbuf(self._no_artwork_icon)
        self.cache.lookup(
            media, ART_SIZE, ART_SIZE, self._on_cache_lookup, None, artist, album)

        self._currentTitle = AlbumArtCache.get_media_title(media)
        self.titleLabel.set_label(self._currentTitle)

        self._currentTimestamp = int(time.time())

        url = media.get_url()
        if url != self.player.get_value('current-uri', 0):
            self.player.set_property('uri', url)

        if self.currentTrack and self.currentTrack.valid():
            currentTrack = self.playlist.get_iter(self.currentTrack.get_path())
            self.emit('playlist-item-changed', self.playlist, currentTrack)
            self.emit('current-changed')

        self._validate_next_track()
コード例 #50
0
ファイル: albumsview.py プロジェクト: GNOME/gnome-music
    def _create_album_item(self, item):
        artist = utils.get_artist_name(item)
        title = utils.get_media_title(item)

        builder = Gtk.Builder.new_from_resource("/org/gnome/Music/AlbumCover.ui")

        child = Gtk.FlowBoxChild()
        child.image = builder.get_object("image")
        child.check = builder.get_object("check")
        child.title = builder.get_object("title")
        child.subtitle = builder.get_object("subtitle")
        child.events = builder.get_object("events")
        child.media_item = item

        child.title.set_label(title)
        child.subtitle.set_label(artist)

        child.image.set_from_surface(self._loading_icon_surface)
        # In the case of off-sized icons (eg. provided in the soundfile)
        # keep the size request equal to all other icons to get proper
        # alignment with GtkFlowBox.
        child.image.set_property("width-request", ArtSize.medium.width)
        child.image.set_property("height-request", ArtSize.medium.height)

        child.events.connect("button-release-event", self._on_album_event_triggered, child)

        child.check_handler_id = child.check.connect("notify::active", self._on_child_toggled, child)

        child.check.bind_property("visible", self, "selection_mode", GObject.BindingFlags.BIDIRECTIONAL)

        child.add(builder.get_object("main_box"))
        child.show()

        self.cache.lookup(item, ArtSize.medium, self._on_lookup_ready, child)

        return child
コード例 #51
0
ファイル: widgets.py プロジェクト: saifulbkhan/gnome-music
    def update(self, artist, album, item, header_bar, selection_toolbar):
        """Update the album widget.

        :param str artist: The artist name
        :param str album: The album name
        :param item: The grilo media item
        :param header_bar: The header bar object
        :param selection_toolbar: The selection toolbar object
        """
        self.selection_toolbar = selection_toolbar
        self._header_bar = header_bar
        self._album = album
        real_artist = utils.get_artist_name(item)
        self._ui.get_object('cover').set_from_pixbuf(self._loading_icon)
        ALBUM_ART_CACHE.lookup(item, 256, 256, self._on_look_up, None,
                               real_artist, album)
        self._duration = 0
        self._create_model()
        GLib.idle_add(grilo.populate_album_songs, item, self.add_item)
        header_bar._select_button.connect(
            'toggled', self._on_header_select_button_toggled)
        header_bar._cancel_button.connect(
            'clicked', self._on_header_cancel_button_clicked)
        self.view.connect('view-selection-changed',
                          self._on_view_selection_changed)
        self.view.set_model(self.model)
        escaped_artist = GLib.markup_escape_text(artist)
        escaped_album = GLib.markup_escape_text(album)
        self._ui.get_object('artist_label').set_markup(escaped_artist)
        self._ui.get_object('title_label').set_markup(escaped_album)
        if (item.get_creation_date()):
            self._ui.get_object('released_label_info').set_text(
                str(item.get_creation_date().get_year()))
        else:
            self._ui.get_object('released_label_info').set_text('----')
        self._player.connect('playlist-item-changed', self._update_model)
コード例 #52
0
ファイル: albumwidget.py プロジェクト: GNOME/gnome-music
    def update(self, album):
        """Update the album widget.

        :param Grl.Media album: The grilo media album
        """
        # reset view
        self._songs = []
        self._create_model()
        for widget in self._disc_listbox.get_children():
            self._disc_listbox.remove(widget)

        self._cover_stack.update(album)

        self._duration = 0

        self._album_name = utils.get_album_title(album)
        artist = utils.get_artist_name(album)

        self._title_label.props.label = self._album_name
        self._title_label.props.tooltip_text = self._album_name

        self._artist_label.props.label = artist
        self._artist_label.props.tooltip_text = artist

        year = utils.get_media_year(album)
        if not year:
            year = '----'
        self._released_info_label.props.label = year

        self._set_composer_label(album)

        self._album = album

        self._player.connect('song-changed', self._update_model)

        grilo.populate_album_songs(album, self.add_item)
コード例 #53
0
    def _get_metadata(self, media=None):
        if not media:
            media = self.player.get_current_media()
        if not media:
            return {}

        metadata = {
            'mpris:trackid': GLib.Variant('o', self._get_media_id(media)),
            'xesam:url': GLib.Variant('s', media.get_url())
        }

        try:
            length = media.get_duration() * 1000000
            assert length is not None
            metadata['mpris:length'] = GLib.Variant('x', length)
        except:
            pass

        try:
            trackNumber = media.get_track_number()
            assert trackNumber is not None
            metadata['xesam:trackNumber'] = GLib.Variant('i', trackNumber)
        except:
            pass

        try:
            useCount = media.get_play_count()
            assert useCount is not None
            metadata['xesam:useCount'] = GLib.Variant('i', useCount)
        except:
            pass

        try:
            userRating = media.get_rating()
            assert userRating is not None
            metadata['xesam:userRating'] = GLib.Variant('d', userRating)
        except:
            pass

        try:
            title = utils.get_media_title(media)
            assert title is not None
            metadata['xesam:title'] = GLib.Variant('s', title)
        except:
            pass


        album = utils.get_album_title(media)
        metadata['xesam:album'] = GLib.Variant('s', album)

        artist = utils.get_artist_name(media)
        metadata['xesam:artist'] = GLib.Variant('as', [artist])
        metadata['xesam:albumArtist'] = GLib.Variant('as', [artist])

        try:
            genre = media.get_genre()
            assert genre is not None
            metadata['xesam:genre'] = GLib.Variant('as', genre)
        except:
            pass

        try:
            lastUsed = media.get_last_played()
            assert lastUsed is not None
            metadata['xesam:lastUsed'] = GLib.Variant('s', lastUsed)
        except:
            pass

        try:
            artUrl = media.get_thumbnail()
            assert artUrl is not None
            metadata['mpris:artUrl'] = GLib.Variant('s', artUrl)
        except:
            pass

        return metadata
コード例 #54
0
ファイル: widgets.py プロジェクト: saifulbkhan/gnome-music
 def _update_album_art(self):
     artist = utils.get_artist_name(self.album)
     ALBUM_ART_CACHE.lookup(self.album, 128, 128, self._get_album_cover,
                            None, artist, self.album.get_title())
コード例 #55
0
    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)
コード例 #56
0
ファイル: albumsview.py プロジェクト: GNOME/gnome-music
 def _set_album_headerbar(self, album):
     self._headerbar.props.state = HeaderBar.State.CHILD
     self._headerbar.props.title = utils.get_album_title(album)
     self._headerbar.props.subtitle = utils.get_artist_name(album)
コード例 #57
0
    def _add_item(self, source, param, item, remaining=0, data=None):
        if data is None:
            return

        model, category = data

        self.found_items_number = (
            self.model.iter_n_children(self.head_iters[0]) +
            self.model.iter_n_children(self.head_iters[1]) +
            self.model.iter_n_children(self.head_iters[2]) +
            self.model.iter_n_children(self.head_iters[3]))

        if category == 'song' and self.found_items_number == 0 and remaining == 0:
            if grilo.search_source:
                self.emit('no-music-found')

        # We need to remember the view before the search view
        if self.window.curr_view != self.window.views[5] and \
           self.window.prev_view != self.window.views[5]:
            self.previous_view = self.window.prev_view

        if remaining == 0:
            self.window.pop_loading_notification()
            self.view.show()

        if not item or model != self.model:
            return

        self._offset += 1
        title = utils.get_media_title(item)
        item.set_title(title)
        artist = utils.get_artist_name(item)
        # FIXME: Can't be None in treemodel
        composer = item.get_composer() or ""

        group = 3
        try:
            group = {'album': 0, 'artist': 1, 'song': 2}[category]
        except:
            pass

        # FIXME: HiDPI icon lookups return a surface that can't be
        # scaled by GdkPixbuf, so it results in a * scale factor sized
        # icon for the search view.
        _iter = None
        if category == 'album':
            _iter = self.model.insert_with_values(
                self.head_iters[group], -1,
                [0, 2, 3, 4, 5, 9, 11, 13],
                [str(item.get_id()), title, artist,
                 self._loading_icon, item, 2, category, composer])
            self.cache.lookup(item, ArtSize.small, self._on_lookup_ready, _iter)
        elif category == 'song':
            _iter = self.model.insert_with_values(
                self.head_iters[group], -1,
                [0, 2, 3, 4, 5, 9, 11, 13],
                [str(item.get_id()), title, artist,
                 self._loading_icon, item,
                 2 if source.get_id() != 'grl-tracker-source' \
                    else item.get_favourite(), category, composer])
            self.cache.lookup(item, ArtSize.small, self._on_lookup_ready, _iter)
        else:
            if not artist.casefold() in self._artists:
                _iter = self.model.insert_with_values(
                    self.head_iters[group], -1,
                    [0, 2, 4, 5, 9, 11, 13],
                    [str(item.get_id()), artist,
                     self._loading_icon, item, 2, category, composer])
                self.cache.lookup(item, ArtSize.small, self._on_lookup_ready,
                                  _iter)
                self._artists[artist.casefold()] = {'iter': _iter, 'albums': []}

            self._artists[artist.casefold()]['albums'].append(item)

        if self.model.iter_n_children(self.head_iters[group]) == 1:
            path = self.model.get_path(self.head_iters[group])
            path = self.filter_model.convert_child_path_to_path(path)
            self.view.get_generic_view().expand_row(path, False)
コード例 #58
0
    def _lookup_remote(self, item, callback, itr, art_size):
        """Lookup remote art

        Lookup remote art through Grilo and if found copy locally. Call
        _lookup_local to finish retrieving suitable art.
        """
        album = utils.get_album_title(item)
        artist = utils.get_artist_name(item)

        @log
        def delete_cb(src, result, data):
            try:
                src.delete_finish(result)
            except Exception as err:
                logger.warn("Error: %s, %s", err.__class__, err)

        @log
        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)

        @log
        def async_read_cb(src, result, data):
            try:
                istream = src.read_finish(result)
            except Exception as err:
                logger.warn("Error: %s, %s", err.__class__, err)
                art_retrieved(False)
                return

            try:
                [tmp_file, iostream] = Gio.File.new_tmp()
            except Exception as err:
                logger.warn("Error: %s, %s", err.__class__, err)
                art_retrieved(False)
                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,
                                 splice_cb,
                                 [tmp_file, iostream])

        @log
        def album_art_for_item_cb(source, param, item, count, error):
            if error:
                logger.warn("Grilo error %s", error)
                art_retrieved(False)
                return

            thumb_uri = item.get_thumbnail()

            if thumb_uri is None:
                art_retrieved(False)
                return

            src = Gio.File.new_for_uri(thumb_uri)
            src.read_async(GLib.PRIORITY_LOW,
                           None,
                           async_read_cb,
                           None)

        @log
        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)

        grilo.get_album_art_for_item(item, album_art_for_item_cb)