Beispiel #1
0
 def _get_active_playlist(self):
     playlist = self._get_playlist_from_id(self.player.playlistId) \
         if self.player.playlistType == 'Playlist' else None
     playlistName = utils.get_media_title(playlist) \
         if playlist else ''
     return (playlist is not None, (self._get_playlist_path(playlist),
                                    playlistName, ''))
Beispiel #2
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()
Beispiel #3
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)

        itr = 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[itr][0, 1, 2, 3, 4, 5, 7, 9] = [
            str(item.get_id()),
            '',
            title,
            artist,
            loading_icon,
            item,
            0,
            False
        ]
Beispiel #4
0
 def GetPlaylists(self, index, max_count, order, reverse):
     if order != 'Alphabetical':
         return []
     playlists = [(self._get_playlist_path(playlist),
                   utils.get_media_title(playlist) or '', '')
                  for playlist in self.playlists]
     return playlists[index:index + max_count] if not reverse \
         else playlists[index + max_count - 1:index - 1 if index - 1 >= 0 else None:-1]
Beispiel #5
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()])
Beispiel #6
0
    def _clean_model(self):
        itr = self._model.get_iter_first()

        while itr:
            song = self._model[itr][5]
            song_widget = song.song_widget
            escaped_title = GLib.markup_escape_text(
                utils.get_media_title(song))
            if song_widget.can_be_played:
                song_widget.now_playing_sign.hide()
            song_widget.title.set_markup('<span>%s</span>' % escaped_title)
            itr = self._model.iter_next(itr)

        return False
Beispiel #7
0
 def _add_playlist_item_to_model(self, item, index=None):
     if index is None:
         index = -1
     if not item:
         self._window.pop_loading_notification()
         self.emit('playlists-loaded')
         return
     _iter = self._playlists_model.insert_with_valuesv(
         index, [2, 5], [utils.get_media_title(item), item])
     if self._playlists_model.iter_n_children(None) == 1:
         _iter = self._playlists_model.get_iter_first()
         selection = self._pl_generic_view.get_selection()
         selection.select_iter(_iter)
         self._playlists_sidebar.emit('item-activated', '0',
                                      self._playlists_model.get_path(_iter))
Beispiel #8
0
    def _on_item_activated(self, widget, id, path):
        if self._star_handler.star_renderer_click:
            self._star_handler.star_renderer_click = False
            return

        try:
            child_path = self.filter_model.convert_path_to_child_path(path)
        except TypeError:
            return
        _iter = self.model.get_iter(child_path)
        if self.model[_iter][11] == 'album':
            title = self.model.get_value(_iter, 2)
            artist = self.model.get_value(_iter, 3)
            item = self.model.get_value(_iter, 5)
            self._albumWidget.update(artist, title, item, self._header_bar,
                                     self._selection_toolbar)
            self._header_bar.set_state(ToolbarState.SEARCH_VIEW)
            title = utils.get_media_title(item)
            self._header_bar.header_bar.set_title(title)
            self._header_bar.header_bar.sub_title = artist
            self.set_visible_child(self._albumWidget)
            self._header_bar.searchbar.show_bar(False)
        elif self.model[_iter][11] == 'artist':
            artist = self.model.get_value(_iter, 2)
            albums = self._artists[artist.casefold()]['albums']

            self._artistAlbumsWidget = ArtistAlbumsWidget(
                artist, albums, self.player, self._header_bar,
                self._selection_toolbar, self._window, True)
            self.add(self._artistAlbumsWidget)
            self._artistAlbumsWidget.show()

            self._header_bar.set_state(ToolbarState.SEARCH_VIEW)
            self._header_bar.header_bar.set_title(artist)
            self.set_visible_child(self._artistAlbumsWidget)
            self._header_bar.searchbar.show_bar(False)
        elif self.model[_iter][11] == 'song':
            if self.model.get_value(_iter, 12) != DiscoveryStatus.FAILED:
                child_iter = self.songs_model.convert_child_iter_to_iter(
                    _iter)[1]
                self.player.set_playlist('Search Results', None,
                                         self.songs_model, child_iter, 5, 12)
                self.player.set_playing(True)
        else:  # Headers
            if self._view.get_generic_view().row_expanded(path):
                self._view.get_generic_view().collapse_row(path)
            else:
                self._view.get_generic_view().expand_row(path, False)
Beispiel #9
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_album_title(item)
        model.insert_with_valuesv(-1, [2, 3, 5, 9],
                                  [title, artist, item, item.get_favourite()])

        self._songs_count += 1
Beispiel #10
0
    def _add_item_to_model(self, item):
        """Adds (non-static only) playlists to the model"""

        # Don't show static playlists
        if self._playlist.is_static_playlist(item):
            return None

        # Hide playlist that is going to be deleted
        if (self._playlist_todelete is not None
                and item.get_id() == self._playlist_todelete.get_id()):
            return None

        new_iter = self._model.append()
        self._model[new_iter][0, 1,
                              2] = [utils.get_media_title(item), False, item]

        return new_iter
Beispiel #11
0
    def _update_model(self, player, playlist, current_iter):
        """Player changed callback.

        :param player: The player object
        :param playlist: The current playlist
        :param current_iter: The current iter of the playlist model
        """
        if (playlist != self._model):
            return True

        current_song = playlist[current_iter][5]

        self._duration = 0

        song_passed = False
        _iter = playlist.get_iter_first()

        while _iter:
            song = playlist[_iter][5]
            song_widget = song.song_widget
            self._duration += song.get_duration()
            escaped_title = GLib.markup_escape_text(
                utils.get_media_title(song))

            if (song == current_song):
                song_widget.now_playing_sign.show()
                song_widget.title.set_markup("<b>{}</b>".format(escaped_title))
                song_passed = True
            elif (song_passed):
                song_widget.now_playing_sign.hide()
                song_widget.title.set_markup(
                    "<span>{}</span>".format(escaped_title))
            else:
                song_widget.now_playing_sign.hide()
                song_widget.title.set_markup(
                    "<span color=\'grey\'>{}</span>".format(escaped_title))

            _iter = playlist.iter_next(_iter)

        self._builder.get_object('running_length_label_info').set_text(
            _("%d min") % (int(self._duration / 60) + 1))

        return True
Beispiel #12
0
    def _create_album_item(self, item):
        artist = utils.get_artist_name(item)
        title = utils.get_media_title(item)

        builder = Gtk.Builder.new_from_resource('/eu/depau/GSub/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
Beispiel #13
0
    def _update_model(self, player, playlist, current_iter):
        # this is not our playlist, return
        if playlist != self._model:
            # TODO, only clean once, but that can wait util we have clean
            # the code a bit, and until the playlist refactoring.
            # the overhead is acceptable for now
            self._clean_model()
            return False

        current_song = playlist[current_iter][5]
        song_passed = False
        itr = playlist.get_iter_first()

        while itr:
            song = playlist[itr][5]
            song_widget = song.song_widget

            if not song_widget.can_be_played:
                itr = playlist.iter_next(itr)
                continue

            escaped_title = GLib.markup_escape_text(
                utils.get_media_title(song))

            if (song == current_song):
                song_widget.now_playing_sign.show()
                song_widget.title.set_markup('<b>%s</b>' % escaped_title)
                song_passed = True
            elif (song_passed):
                song_widget.now_playing_sign.hide()
                song_widget.title.set_markup('<span>%s</span>' % escaped_title)
            else:
                song_widget.now_playing_sign.hide()
                song_widget.title.set_markup('<span color=\'grey\'>%s</span>' %
                                             escaped_title)
            itr = playlist.iter_next(itr)

        return False
Beispiel #14
0
    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)
Beispiel #15
0
    def _create_song_widget(self, song):
        """Helper function to create a song widget for a
        single song

        :param song: A Grilo media item
        :returns: A complete song widget
        :rtype: Gtk.EventBox
        """
        builder = Gtk.Builder()
        builder.add_from_resource('/eu/depau/GSub/TrackWidget.ui')
        song_widget = builder.get_object('eventbox1')
        self._songs.append(song_widget)

        title = utils.get_media_title(song)

        itr = self._model.append(None)

        self._model[itr][0, 1, 2, 5, 6] = [title, '', '', song, False]

        song_widget.itr = itr
        song_widget.model = self._model

        song_number = song.get_track_number()
        if song_number == 0:
            song_number = ""
        song_widget.number = builder.get_object('num')
        song_widget.number.set_markup(
            '<span color=\'grey\'>{}</span>'.format(song_number))
        song_widget.number.set_no_show_all(True)

        song_widget.title = builder.get_object('title')
        song_widget.title.set_text(title)
        song_widget.title.set_max_width_chars(50)

        song_widget.duration = builder.get_object('duration')
        time = utils.seconds_to_string(song.get_duration())
        song_widget.duration.set_text(time)

        song_widget.check_button = builder.get_object('select')
        song_widget.check_button.set_visible(False)
        song_widget.check_button.connect('toggled', self._check_button_toggled,
                                         song_widget)

        song_widget.now_playing_sign = builder.get_object('image1')
        song_widget.now_playing_sign.set_from_icon_name(
            'media-playback-start-symbolic', Gtk.IconSize.SMALL_TOOLBAR)
        song_widget.now_playing_sign.set_no_show_all(True)
        song_widget.can_be_played = True
        song_widget.connect('button-release-event', self._song_activated)

        song_widget.star_image = builder.get_object('starimage')
        song_widget.star_image.set_favorite(song.get_favourite())
        song_widget.star_image.set_visible(True)

        song_widget.starevent = builder.get_object('starevent')
        song_widget.starevent.connect('button-release-event',
                                      self._toggle_favorite, song_widget)
        song_widget.starevent.connect('enter-notify-event',
                                      song_widget.star_image.hover, None)
        song_widget.starevent.connect('leave-notify-event',
                                      song_widget.star_image.unhover, None)
        return song_widget
Beispiel #16
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
Beispiel #17
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)