Example #1
0
 def _on_lastfm_btn_clicked(self, button):
     if Lp.lastfm is not None:
         if Lp.player.current_track.aartist_id == Type.COMPILATIONS:
             artist = Lp.player.current_track.artist
         else:
             artist = Lp.player.current_track.aartist
         popover = InfosPopover(artist, Lp.player.current_track.title)
         popover.set_relative_to(button)
         popover.populate()
         popover.show()
Example #2
0
 def _on_label_button_release(self, eventbox, event):
     """
         On clicked label, show artist informations in a popover
         @param eventbox as Gtk.EventBox
         @param event as Gdk.Event
     """
     if (Lp.lastfm is not None or self.Wikipedia is not None) and\
             self._album.artist_id != Type.COMPILATIONS:
         popover = InfosPopover(self._album.artist_name)
         popover.set_relative_to(eventbox)
         popover.populate()
         popover.show()
Example #3
0
 def _on_label_button_release(self, eventbox, event):
     """
         On clicked label, show artist informations in a popover
         @param eventbox as Gtk.EventBox
         @param event as Gdk.Event
     """
     if (Lp.lastfm is not None or self.Wikipedia is not None) and\
             self._album.artist_id != Type.COMPILATIONS:
         popover = InfosPopover(self._album.artist_name)
         popover.set_relative_to(eventbox)
         popover.populate()
         popover.show()
Example #4
0
 def _on_infos_btn_clicked(self, button):
     """
         Show current artist informations
         @param button as Gtk.Button
     """
     if InfosPopover.should_be_shown():
         artist_id = Lp.player.current_track.aartist_id
         if artist_id == Type.COMPILATIONS:
             artist = Lp.player.current_track.artist
         else:
             artist = Lp.player.current_track.aartist
         popover = InfosPopover(artist, Lp.player.current_track.id)
         popover.set_relative_to(button)
         popover.populate()
         popover.show()
Example #5
0
 def _on_infos_btn_clicked(self, button):
     """
         Show current artist informations
         @param button as Gtk.Button
     """
     if InfosPopover.should_be_shown():
         artist_id = Lp.player.current_track.album_artist_id
         if artist_id == Type.COMPILATIONS:
             artist = Lp.player.current_track.artist
         else:
             artist = Lp.player.current_track.album_artist
         popover = InfosPopover(artist, Lp.player.current_track.id)
         popover.set_relative_to(button)
         popover.populate()
         popover.show()
Example #6
0
class ArtistView(View):
    """
        Show artist albums and tracks
    """

    def __init__(self, artist_id, genre_id):
        """
            Init ArtistView
            @param artist id as int
            @param genre id as int
        """
        View.__init__(self)
        self._artist_id = artist_id
        self._genre_id = genre_id
        self._signal_id = None

        self._artist_name = Lp.artists.get_name(artist_id)
        if Lp.lastfm is not None:
            self._popover = InfosPopover(self._artist_name)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ArtistView.ui')
        builder.connect_signals(self)
        self.attach(builder.get_object('ArtistView'), 0, 0, 1, 1)
        builder.get_object('artist').set_label(self._artist_name)

        self._pop_allowed = True

        self._albumbox = Gtk.Grid()
        self._albumbox.set_row_spacing(20)
        self._albumbox.set_property("orientation", Gtk.Orientation.VERTICAL)
        self._albumbox.show()

        self._scrolledWindow.set_property('expand', True)
        self._viewport.set_property("valign", Gtk.Align.START)
        self._viewport.add(self._albumbox)
        self.add(self._scrolledWindow)

    def populate(self):
        """
            Populate the view
            @thread safe
        """
        albums = self._get_albums()
        GLib.idle_add(self._add_albums, albums, self._genre_id)


#######################
# PRIVATE             #
#######################
    def _get_albums(self):
        """
            Get albums
            @return album ids as [int]
            @thread safe
        """
        sql = Lp.db.get_cursor()
        if self._artist_id == Type.COMPILATIONS:
            albums = Lp.albums.get_compilations(self._genre_id,
                                                sql)
        elif self._genre_id == Type.ALL:
            albums = Lp.albums.get_ids(self._artist_id,
                                       None,
                                       sql)
        else:
            albums = Lp.albums.get_ids(self._artist_id,
                                       self._genre_id,
                                       sql)
        sql.close()
        return albums

    def _get_children(self):
        """
            Return view children
            @return [AlbumWidget]
        """
        return self._albumbox.get_children()

    def _add_albums(self, albums, genre_id):
        """
            Pop an album and add it to the view,
            repeat operation until album list is empty
            @param [album ids as int]
            @param genre id as int
        """
        size_group = Gtk.SizeGroup(mode=Gtk.SizeGroupMode.HORIZONTAL)
        if albums and not self._stop:
            widget = AlbumDetailedWidget(albums.pop(0),
                                         genre_id,
                                         self._pop_allowed,
                                         False,
                                         size_group)
            widget.show()
            start_new_thread(widget.populate, ())
            self._albumbox.add(widget)
            GLib.idle_add(self._add_albums, albums, genre_id)
        else:
            self._stop = False

    def _on_label_realize(self, eventbox):
        """
            Change pointer on label
            @param eventbox as Gtk.EventBox
        """
        if Lp.lastfm is not None and self._artist_id != Type.COMPILATIONS:
            eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1))

    def _on_label_button_release(self, eventbox, event):
        """
            On clicked label, show artist informations in a popover
            @param eventbox as Gtk.EventBox
            @param event as Gdk.Event
        """
        if Lp.lastfm is not None and self._artist_id != Type.COMPILATIONS:
            self._popover.set_relative_to(eventbox)
            self._popover.populate()
            self._popover.show()
Example #7
0
class ArtistView(View):
    """
        Show artist albums and tracks
    """

    try:
        from lollypop.wikipedia import Wikipedia
    except:
        Wikipedia = None

    def __init__(self, artist_id, genre_id):
        """
            Init ArtistView
            @param artist id as int
            @param genre id as int
        """
        View.__init__(self)
        self._artist_id = artist_id
        self._genre_id = genre_id
        self._signal_id = None

        self._artist_name = Lp.artists.get_name(artist_id)
        if Lp.lastfm is not None or self.Wikipedia is not None:
            self._popover = InfosPopover(self._artist_name)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ArtistView.ui')
        builder.connect_signals(self)
        self.attach(builder.get_object('ArtistView'), 0, 0, 1, 1)
        builder.get_object('artist').set_label(self._artist_name)

        self._pop_allowed = True

        self._albumbox = Gtk.Grid()
        self._albumbox.set_row_spacing(20)
        self._albumbox.set_property("orientation", Gtk.Orientation.VERTICAL)
        self._albumbox.show()

        self._scrolledWindow.set_property('expand', True)
        self._viewport.set_property("valign", Gtk.Align.START)
        self._viewport.add(self._albumbox)
        self.add(self._scrolledWindow)

    def populate(self, albums):
        """
            Populate the view
        """
        self._add_albums(albums)


#######################
# PRIVATE             #
#######################

    def _get_children(self):
        """
            Return view children
            @return [AlbumWidget]
        """
        return self._albumbox.get_children()

    def _add_albums(self, albums):
        """
            Pop an album and add it to the view,
            repeat operation until album list is empty
            @param [album ids as int]
        """
        size_group = Gtk.SizeGroup(mode=Gtk.SizeGroupMode.HORIZONTAL)
        widget = AlbumDetailedWidget(albums.pop(0), self._genre_id,
                                     self._pop_allowed, False, size_group)
        widget.connect('finished', self._on_album_finished, albums)
        widget.show()
        start_new_thread(widget.populate, ())
        self._albumbox.add(widget)

    def _on_album_finished(self, album, albums):
        """
            Add another album
            @param album as AlbumDetailedWidget
            @param [album ids as int]
        """
        if albums and not self._stop:
            self._add_albums(albums)
        else:
            self._stop = False

    def _on_label_realize(self, eventbox):
        """
            Change pointer on label
            @param eventbox as Gtk.EventBox
        """
        if (Lp.lastfm is not None or self.Wikipedia is not None) and\
                self._artist_id != Type.COMPILATIONS:
            eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1))

    def _on_label_button_release(self, eventbox, event):
        """
            On clicked label, show artist informations in a popover
            @param eventbox as Gtk.EventBox
            @param event as Gdk.Event
        """
        if (Lp.lastfm is not None or self.Wikipedia is not None) and\
                self._artist_id != Type.COMPILATIONS:
            self._popover.set_relative_to(eventbox)
            self._popover.populate()
            self._popover.show()
Example #8
0
class AlbumDetailedWidget(AlbumWidget):
    """
        Init detailed album widget
        @param album id as int
        @param genre id as int
        @param parent width as int
        @param pop_allowed as bool if widget can show popovers
        @param scrolled as bool
        @param size group as Gtk.SizeGroup
    """
    def __init__(self, album_id, genre_id, pop_allowed, scrolled, size_group):
        AlbumWidget.__init__(self, album_id)

        self._artist_id = Lp.albums.get_artist_id(album_id)
        self._album_id = album_id
        self._genre_id = genre_id

        builder = Gtk.Builder()
        if scrolled:
            builder.add_from_resource(
                '/org/gnome/Lollypop/AlbumContextWidget.ui')
        else:
            builder.add_from_resource(
                '/org/gnome/Lollypop/AlbumDetailedWidget.ui')
        builder.connect_signals(self)

        if scrolled:
            artist = translate_artist_name(Lp.albums.get_artist_name(album_id))
            builder.get_object('artist').set_text(artist)
            builder.get_object('artist').show()
            if Lp.lastfm is not None:
                self._popover = InfosPopover(artist)

        self._stars = []
        self._stars.append(builder.get_object('star0'))
        self._stars.append(builder.get_object('star1'))
        self._stars.append(builder.get_object('star2'))
        self._stars.append(builder.get_object('star3'))
        self._stars.append(builder.get_object('star4'))
        self._on_leave_notify(None, None)

        grid = builder.get_object('tracks')
        self._discs = Lp.albums.get_discs(album_id, genre_id)
        self._tracks_left = {}
        self._tracks_right = {}
        show_label = len(self._discs) > 1
        i = 0
        for disc in self._discs:
            if show_label:
                label = Gtk.Label()
                label.set_text(_("Disc %s") % disc)
                label.set_property('halign', Gtk.Align.START)
                label.get_style_context().add_class('dim-label')
                if i:
                    label.set_property('margin-top', 30)
                label.show()
                grid.attach(label, 0, i, 2, 1)
                i += 1
                sep = Gtk.Separator()
                sep.show()
                grid.attach(sep, 0, i, 2, 1)
                i += 1
            self._tracks_left[disc] = TracksWidget(pop_allowed)
            self._tracks_right[disc] = TracksWidget(pop_allowed)
            grid.attach(self._tracks_left[disc], 0, i, 1, 1)
            grid.attach(self._tracks_right[disc], 1, i, 1, 1)
            size_group.add_widget(self._tracks_left[disc])
            size_group.add_widget(self._tracks_right[disc])

            self._tracks_left[disc].connect('activated', self._on_activated)
            self._tracks_left[disc].connect('button-press-event',
                                            self._on_button_press_event)
            self._tracks_right[disc].connect('activated', self._on_activated)
            self._tracks_right[disc].connect('button-press-event',
                                             self._on_button_press_event)

            self._tracks_left[disc].show()
            self._tracks_right[disc].show()
            i += 1

        self._cover = builder.get_object('cover')
        self.set_cover()

        self._title_label = Lp.albums.get_name(album_id)
        builder.get_object('title').set_label(self._title_label)
        builder.get_object('year').set_label(Lp.albums.get_year(album_id))
        self.add(builder.get_object('AlbumDetailedWidget'))

        if pop_allowed:
            self._menu = builder.get_object('menu')
            self._eventbox = builder.get_object('eventbox')
            self._eventbox.connect('realize', self._on_eventbox_realize)
            self._eventbox.connect("button-press-event",
                                   self._show_web_art)
            self._menu.connect('clicked',
                               self._pop_menu)
            self._menu.show()
        else:
            self._eventbox = None

    """
        Update playing indicator
    """
    def update_playing_indicator(self):
        for disc in self._discs:
            self._tracks_left[disc].update_playing(Lp.player.current_track.id)
            self._tracks_right[disc].update_playing(Lp.player.current_track.id)

    """
        Populate tracks
        @thread safe
    """
    def populate(self):
        self._stop = False
        sql = Lp.db.get_cursor()
        for disc in self._discs:
            mid_tracks = int(0.5+Lp.albums.get_count_for_disc(self._album_id,
                                                              self._genre_id,
                                                              disc,
                                                              sql)/2)
            tracks = Lp.albums.get_tracks_infos(self._album_id,
                                                self._genre_id,
                                                disc,
                                                sql)
            self.populate_list_left(tracks[:mid_tracks],
                                    disc,
                                    1)
            self.populate_list_right(tracks[mid_tracks:],
                                     disc,
                                     mid_tracks + 1)

    """
        Populate left list, thread safe
        @param track's ids as array of int
        @param track position as int
    """
    def populate_list_left(self, tracks, disc, pos):
        GLib.idle_add(self._add_tracks,
                      tracks,
                      self._tracks_left[disc],
                      pos)

    """
        Populate right list, thread safe
        @param track's ids as array of int
        @param track position as int
    """
    def populate_list_right(self, tracks, disc, pos):
        GLib.idle_add(self._add_tracks,
                      tracks,
                      self._tracks_right[disc],
                      pos)

#######################
# PRIVATE             #
#######################
    """
        Popup menu for album
        @param widget as Gtk.Button
        @param album id as int
    """
    def _pop_menu(self, widget):
        pop_menu = AlbumMenuPopover(self._album_id, self._genre_id)
        popover = Gtk.Popover.new_from_model(self._menu, pop_menu)
        popover.connect('closed', self._on_closed)
        self.get_style_context().add_class('album-menu-selected')
        popover.show()

    """
        Remove selected style
        @param widget as Gtk.Popover
    """
    def _on_closed(self, widget):
        self.get_style_context().remove_class('album-menu-selected')

    """
        Add tracks for to tracks widget
        @param tracks as [(track_id, title, length, [artist ids])]
        @param widget as TracksWidget
        @param i as int
    """
    def _add_tracks(self, tracks, widget, i):
        if not tracks or self._stop:
            self._stop = False
            return

        track = tracks.pop(0)
        track_id = track[0]
        title = escape(track[1])
        length = track[2]
        tracknumber = track[3]
        artist_ids = track[4]

        # If we are listening to a compilation, prepend artist name
        if self._artist_id == Type.COMPILATIONS or\
           len(artist_ids) > 1 or\
           self._artist_id not in artist_ids:
            artist_name = ""
            for artist_id in artist_ids:
                artist_name += translate_artist_name(
                    Lp.artists.get_name(artist_id)) + ", "
            title = "<b>%s</b>\n%s" % (escape(artist_name[:-2]),
                                       title)

        # Get track position in queue
        pos = None
        if Lp.player.is_in_queue(track_id):
            pos = Lp.player.get_track_position(track_id)

        if Lp.settings.get_value('show-tag-tracknumber'):
            widget.add_track(track_id,
                             tracknumber,
                             title,
                             length,
                             pos)
        else:
            widget.add_track(track_id,
                             i,
                             title,
                             length,
                             pos)
        GLib.idle_add(self._add_tracks, tracks, widget, i+1)

    """
        On track activation, play track
        @param widget as TracksWidget
        @param track id as int
    """
    def _on_activated(self, widget, track_id):
        Lp.player.context.next = NextContext.NONE
        if not Lp.player.is_party():
            Lp.player.set_albums(track_id,
                                 self._artist_id,
                                 self._genre_id)
        Lp.player.load(Track(track_id))
        if self._button_state & Gdk.ModifierType.CONTROL_MASK:
            Lp.player.context.next = NextContext.STOP_TRACK

    """
        Keep track of mask
        @param widget as TrackWidget
        @param event as Gdk.Event
    """
    def _on_button_press_event(self, widget, event):
        self._button_state = event.get_state()

    """
        Change cursor over eventbox
        @param eventbox as Gdk.Eventbox
    """
    def _on_eventbox_realize(self, eventbox):
        eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.PENCIL))

    """
        Change pointer on label
        @param eventbox as Gtk.EventBox
    """
    def _on_label_realize(self, eventbox):
        if Lp.lastfm is not None and self._artist_id != Type.COMPILATIONS:
            eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1))

    """
        On clicked label, show artist informations in a popover
        @param eventbox as Gtk.EventBox
        @param event as Gdk.Event
    """
    def _on_label_button_release(self, eventbox, event):
        if Lp.lastfm is not None and self._artist_id != Type.COMPILATIONS:
            self._popover.set_relative_to(eventbox)
            self._popover.populate()
            self._popover.show()

    """
        Popover with album art downloaded from the web (in fact google :-/)
        @param: widget as eventbox
        @param: data as unused
    """
    def _show_web_art(self, widget, data):
        popover = CoversPopover(self._artist_id, self._album_id)
        popover.set_relative_to(widget)
        popover.populate()
        popover.show()

    """
        On enter notify, change star opacity
        @param widget as Gtk.EventBox
        @param event as Gdk.Event
    """
    def _on_enter_notify(self, widget, event):
        event_star = widget.get_children()[0]
        # First star is hidden (used to clear score)
        if event_star.get_property("opacity") == 0.0:
            found = True
        else:
            found = False
        for star in self._stars:
            if found:
                star.set_property("opacity", 0.2)
            else:
                star.set_property("opacity", 0.8)
            if star == event_star:
                found = True

    """
        On leave notify, change star opacity
        @param widget as Gtk.EventBox (can be None)
        @param event as Gdk.Event (can be None)
    """
    def _on_leave_notify(self, widget, event):
        avg_popularity = Lp.albums.get_avg_popularity()
        if avg_popularity > 0:
            popularity = Lp.albums.get_popularity(self._album_id)
            stars = popularity*5/avg_popularity+0.5
            if stars < 1:
                for i in range(5):
                    self._stars[i].set_property("opacity", 0.2)
            else:
                if stars >= 1:
                    self._stars[0].set_property("opacity", 0.8)
                else:
                    self._stars[0].set_property("opacity", 0.2)
                if stars >= 2:
                    self._stars[1].set_property("opacity", 0.8)
                else:
                    self._stars[1].set_property("opacity", 0.2)
                if stars >= 3:
                    self._stars[2].set_property("opacity", 0.8)
                else:
                    self._stars[2].set_property("opacity", 0.2)
                if stars >= 4:
                    self._stars[3].set_property("opacity", 0.8)
                else:
                    self._stars[3].set_property("opacity", 0.2)
                if stars >= 4.75:
                    self._stars[4].set_property("opacity", 0.8)
                else:
                    self._stars[4].set_property("opacity", 0.2)
        else:
            for i in range(5):
                self._stars[i].set_property("opacity", 0.2)

    """
        On button press, set album popularity
        @param widget as Gtk.EventBox
        @param event as Gdk.Event
    """
    def _on_button_press(self, widget, event):
        if Lp.scanner.is_locked():
            return
        event_star = widget.get_children()[0]
        try:
            position = self._stars.index(event_star)
            avg_popularity = Lp.albums.get_avg_popularity()
            popularity = int(((position+1)*avg_popularity/5)+0.5)
            Lp.albums.set_popularity(self._album_id, popularity)
        except:
            Lp.albums.set_popularity(self._album_id, 0)
        Lp.sql.commit()