Exemplo n.º 1
0
 def _on_activated(self, widget, track):
     """
         Handle playback if album or pass signal
         @param widget as TracksWidget
         @param track as Track
     """
     if self.view_type & (ViewType.ALBUM | ViewType.ARTIST):
         tracks = []
         for child in self.children:
             if child.track.loved != -1 or track.id == child.track.id:
                 tracks.append(child.track)
             child.set_state_flags(Gtk.StateFlags.NORMAL, True)
         # Do not update album list if in party or album already available
         playback_track = App().player.track_in_playback(track)
         if playback_track is not None:
             App().player.load(playback_track)
         elif not App().player.is_party:
             album = Album(track.album.id, [], [])
             album.set_tracks(tracks)
             if not App().settings.get_value("append-albums"):
                 App().player.clear_albums()
             App().player.add_album(album)
             App().player.load(album.get_track(track.id))
         else:
             App().player.load(track)
     else:
         emit_signal(self, "activated", track)
Exemplo n.º 2
0
 def __split_album_row(self, album_row, track_row, direction):
     """
         Split album row at track row with direction
         @param album_row as AlbumRow
         @param track_row as TrackRow
         @param direction as Gtk.DirectionType
         @return AlbumRow
     """
     height = AlbumRow.get_best_height(album_row)
     children = album_row.children
     index = children.index(track_row)
     if direction == Gtk.DirectionType.DOWN:
         index += 1
         if index + 1 > len(children):
             return None
     elif index - 1 < 0:
         return None
     rows = album_row.children[:index]
     split_album = Album(album_row.album.id)
     split_album.set_tracks([row.track for row in rows])
     split_album_row = AlbumRow(split_album, height, self.__view_type)
     split_album_row.reveal()
     split_album_row.show()
     for row in rows:
         empty = album_row.album.remove_track(row.track)
         if empty:
             album_row.destroy()
         row.destroy()
     return split_album_row
Exemplo n.º 3
0
 def save_album_payload_to_db(self, payload, storage_type,
                              notify, cancellable):
     """
         Save album to DB
         @param payload as {}
         @param storage_type as StorageType
         @param notify as bool
         @param cancellable as Gio.Cancellable
         @return CollectionItem/None
     """
     lp_album_id = get_lollypop_album_id(payload["name"],
                                         payload["artists"])
     album_id = App().albums.get_id_for_lp_album_id(lp_album_id)
     if album_id >= 0:
         album = Album(album_id)
         if notify:
             emit_signal(self, "match-album", album_id, storage_type)
         return album.collection_item
     item = self.__save_album(payload, storage_type)
     album = Album(item.album_id)
     if notify:
         self.save_artwork(album,
                           payload["artwork-uri"],
                           cancellable)
         emit_signal(self, "match-album", album.id, storage_type)
     return item
Exemplo n.º 4
0
 def __on_disc_button_press_event(self, button, event, disc):
     """
         Add disc to playback
         @param button as Gtk.Button
         @param event as Gdk.ButtonEvent
         @param disc as Disc
     """
     album = Album(disc.album.id)
     album.set_tracks(disc.tracks)
     App().player.play_album(album)
Exemplo n.º 5
0
 def _append_to_playback(self, action, variant):
     """
         Append track to playback
         @param Gio.SimpleAction
         @param GLib.Variant
     """
     album = Album(self.__track.album.id)
     album.set_tracks([self.__track])
     App().player.add_album(album)
     if App().player.is_playing:
         App().player.add_album(album)
     else:
         App().player.play_album(album)
Exemplo n.º 6
0
 def _on_playlist_track_added(self, playlists, playlist_id, uri):
     """
         Append track to album list
         @param playlists as Playlists
         @param playlist_id as int
         @param uri as str
     """
     if playlist_id == self.__playlist_id:
         track = Track(App().tracks.get_id_by_uri(uri))
         album = Album(track.album.id)
         album.set_tracks([track])
         self.add_reveal_albums([album])
         self.add_value(album)
Exemplo n.º 7
0
 def _on_collection_updated(self, scanner, item, scan_update):
     """
         Handles changes in collection
         @param scanner as CollectionScanner
         @param item as CollectionItem
         @param scan_update as ScanUpdate
     """
     if scan_update == ScanUpdate.ADDED:
         wanted = True
         for genre_id in item.genre_ids:
             genre_ids = remove_static(self._genre_ids)
             if genre_ids and genre_id not in genre_ids:
                 wanted = False
         for artist_id in item.artist_ids:
             artist_ids = remove_static(self._artist_ids)
             if artist_ids and artist_id not in artist_ids:
                 wanted = False
         if wanted:
             self.add_value(Album(item.album_id))
     elif scan_update == ScanUpdate.MODIFIED:
         for child in self.children:
             if child.data.id == item.album_id:
                 child.data.reset_tracks()
                 break
     elif scan_update == ScanUpdate.REMOVED:
         for child in self.children:
             if child.data.id == item.album_id:
                 child.destroy()
                 break
Exemplo n.º 8
0
 def get_today_album():
     """
         Get today album
         @return Album/None
     """
     current_date = GLib.DateTime.new_now_local().get_day_of_year()
     (date, album_id) = (0, None)
     try:
         (date,
          album_id) = load(open(LOLLYPOP_DATA_PATH + "/today.bin", "rb"))
         if App().albums.get_storage_type(album_id) == StorageType.NONE:
             date = 0
     except Exception as e:
         Logger.warning("TodayBannerWidget::__get_today_album(): %s", e)
     try:
         if date != current_date:
             storage_type = get_default_storage_type()
             album_id = App().albums.get_randoms(storage_type, None, False,
                                                 1)[0]
             dump((current_date, album_id),
                  open(LOLLYPOP_DATA_PATH + "/today.bin", "wb"))
         return Album(album_id)
     except Exception as e:
         Logger.error("TodayBannerWidget::__get_today_album(): %s", e)
     return None
Exemplo n.º 9
0
def add_artist_to_playback(artist_ids, genre_ids, add):
    """
        Add artist to current playback
        @param artist_ids as [int]
        @param genre_ids as [int]
        @param add as bool
    """
    try:
        storage_type = get_default_storage_type()
        album_ids = App().albums.get_ids(genre_ids, artist_ids, storage_type,
                                         False)
        if App().settings.get_value("play-featured"):
            album_ids += App().artists.get_featured(genre_ids, artist_ids,
                                                    storage_type, False)
        if add:
            albums = []
            for album_id in album_ids:
                if album_id not in App().player.album_ids:
                    album = Album(album_id, genre_ids, artist_ids, False)
                    albums.append(album)
            App().player.add_albums(albums)
        else:
            App().player.remove_album_by_ids(album_ids)
            if len(App().player.albums) == 0:
                App().player.stop()
            elif App().player.current_track.album.id\
                    not in App().player.album_ids:
                App().player.skip_album()
    except Exception as e:
        Logger.error("add_artist_to_playback(): %s" % e)
Exemplo n.º 10
0
 def __add_album_header(self, text, album_id, menu_name):
     """
         Add an header for album to close menu
         @param text as str
         @param album_id as int
         @param menu_name as str
     """
     button = Gtk.ModelButton.new()
     button.set_hexpand(True)
     button.connect("clicked", lambda x: emit_signal(self, "hidden", True))
     button.show()
     label = Gtk.Label.new()
     label.set_markup(text)
     label.set_ellipsize(Pango.EllipsizeMode.END)
     label.show()
     artwork = Gtk.Image.new()
     close_image = Gtk.Image.new_from_icon_name("pan-up-symbolic",
                                                Gtk.IconSize.BUTTON)
     close_image.show()
     grid = Gtk.Grid()
     grid.set_halign(Gtk.Align.START)
     grid.set_column_spacing(MARGIN)
     grid.add(artwork)
     grid.add(label)
     grid.add(close_image)
     button.set_image(grid)
     button.get_style_context().add_class("padding")
     App().art_helper.set_album_artwork(
         Album(album_id), ArtSize.SMALL, ArtSize.SMALL,
         artwork.get_scale_factor(),
         ArtBehaviour.CACHE | ArtBehaviour.CROP_SQUARE, self.__on_artwork,
         artwork)
     self.__boxes[menu_name].add(button)
Exemplo n.º 11
0
 def __init__(self, genre_id, view_type, header=False):
     """
         Init decade menu
         @param genre_id as int
         @param view_type as ViewType
         @param header as bool
     """
     Gio.Menu.__init__(self)
     if header:
         from lollypop.menu_header import RoundedMenuHeader
         name = App().genres.get_name(genre_id)
         artwork_name = "genre_%s" % name
         self.append_item(RoundedMenuHeader(name, artwork_name))
     if not view_type & ViewType.BANNER:
         from lollypop.menu_playback import GenrePlaybackMenu
         self.append_section(_("Playback"), GenrePlaybackMenu(genre_id))
     from lollypop.menu_sync import SyncAlbumsMenu
     section = Gio.Menu()
     self.append_section(_("Add to"), section)
     storage_type = get_default_storage_type()
     album_ids = App().albums.get_ids([genre_id], [],
                                      storage_type,
                                      False)
     album_ids += App().albums.get_compilation_ids([genre_id],
                                                   storage_type,
                                                   False)
     albums = [Album(album_id) for album_id in album_ids]
     section.append_submenu(_("Devices"), SyncAlbumsMenu(albums))
Exemplo n.º 12
0
 def _set_artwork(self):
     """
         Set artist artwork
     """
     if self._artwork is None:
         return
     RoundedFlowBoxWidget.set_artwork(self)
     if App().settings.get_value("artist-artwork"):
         App().art_helper.set_artist_artwork(
                                         self.name,
                                         self._art_size,
                                         self._art_size,
                                         self._artwork.get_scale_factor(),
                                         ArtBehaviour.ROUNDED |
                                         ArtBehaviour.CROP_SQUARE |
                                         ArtBehaviour.CACHE,
                                         self.__on_artist_artwork)
     else:
         album_ids = App().albums.get_ids([], [self._data],
                                          StorageType.ALL, True)
         if album_ids:
             shuffle(album_ids)
             App().art_helper.set_album_artwork(
                                         Album(album_ids[0]),
                                         self._art_size,
                                         self._art_size,
                                         self._artwork.get_scale_factor(),
                                         ArtBehaviour.ROUNDED |
                                         ArtBehaviour.CROP_SQUARE |
                                         ArtBehaviour.CACHE,
                                         self.__on_artist_artwork)
         else:
             self.__on_artist_artwork(None)
Exemplo n.º 13
0
    def __init__(self, track_id=None, album=None):
        """
            Init track
            @param track_id as int
            @param album as Album
        """
        Base.__init__(self, App().tracks)
        self.id = track_id
        self._uri = None

        if album is None:
            from lollypop.objects_album import Album
            self.__album = Album(self.album_id)
            self.__album.set_tracks([self], False)
        else:
            self.__album = album
Exemplo n.º 14
0
 def load():
     items = []
     for year in self._artist_ids:
         items += App().albums.get_compilation_ids_for_year(
             year, self.storage_type, True)
         items += App().albums.get_ids_for_year(year, self.storage_type,
                                                True)
     return [Album(album_id, [Type.YEARS], []) for album_id in items]
Exemplo n.º 15
0
 def load():
     # No skipped albums for this views
     if self._genre_ids and self._genre_ids[0] in [
             Type.POPULARS, Type.LITTLE, Type.RANDOMS, Type.RECENTS
     ]:
         skipped = False
     else:
         skipped = True
     album_ids = get_album_ids_for(self._genre_ids, self._artist_ids,
                                   self.storage_type, skipped)
     albums = []
     for album_id in album_ids:
         album = Album(album_id, self._genre_ids, self._artist_ids,
                       True)
         album.set_storage_type(self.storage_type)
         albums.append(album)
     return albums
Exemplo n.º 16
0
 def __play(self, action, variant):
     """
         Play albums
         @param Gio.SimpleAction
         @param GLib.Variant
     """
     album_ids = self.__get_album_ids()
     albums = [Album(album_id) for album_id in album_ids]
     App().player.play_albums(albums)
Exemplo n.º 17
0
 def load():
     (genre_id, genre) = App().genres.get_random()
     GLib.idle_add(self._label.set_text, genre)
     storage_type = get_default_storage_type()
     album_ids = App().albums.get_randoms(storage_type,
                                          genre_id,
                                          False,
                                          self.ITEMS)
     return [Album(album_id) for album_id in album_ids]
Exemplo n.º 18
0
 def next_album(self):
     """
         Get next album to add
         @return Album
     """
     storage_type = get_default_storage_type()
     for album_id in App().albums.get_randoms(storage_type, None, False, 2):
         if album_id != self.current_track.album.id:
             return Album(album_id)
     return None
Exemplo n.º 19
0
 def load():
     if self.__artist_id == Type.COMPILATIONS:
         album_ids = App().albums.get_compilation_ids(
             self.__genre_ids, self.storage_type, True)
     else:
         album_ids = App().albums.get_ids(
             self.__genre_ids, [self.__artist_id],
             self.storage_type, True)
     if excluded_album_id in album_ids:
         album_ids.remove(excluded_album_id)
     return [Album(album_id) for album_id in album_ids]
Exemplo n.º 20
0
 def set_artwork(self, width, height, callback, behaviour):
     """
         Set artwork
         @param width as int
         @param height as int
         @param callback as function
     """
     scale_factor = self.get_scale_factor()
     if App().player.current_track.id is not None:
         if self.__per_track_cover:
             behaviour |= ArtBehaviour.NO_CACHE
             album = Album(App().player.current_track.album.id)
             App().art.clean_album_cache(album, width * scale_factor,
                                         height * scale_factor)
             album.set_tracks([App().player.current_track])
         else:
             album = App().player.current_track.album
         App().art_helper.set_album_artwork(album, width, height,
                                            scale_factor, behaviour,
                                            callback)
     else:
         self.set_from_surface(None)
Exemplo n.º 21
0
 def _on_album_match(self, spotify_helper, album_id, storage_type):
     """
         Handles changes in collection
         @param scanner as CollectionScanner
         @param album_id as int
         @param storage_type as StorageType
     """
     count = len(self.children)
     if count == self.ITEMS:
         return
     if self.__storage_type & storage_type:
         self.add_value(Album(album_id))
         self.show()
Exemplo n.º 22
0
 def __init__(self, object):
     """
         Init edit menu
         @param object as Album/Track
     """
     Gio.Menu.__init__(self)
     # Ignore genre_ids/artist_ids
     if isinstance(object, Album):
         self.__object = Album(object.id)
     else:
         self.__object = Track(object.id)
     self.__set_save_action()
     if self.__object.storage_type & StorageType.COLLECTION:
         self.__set_open_action()
Exemplo n.º 23
0
 def __cache_albums_artwork(self):
     """
         Cache albums artwork (from queue)
         @thread safe
     """
     self.__in_albums_download = True
     try:
         while self.__albums_queue:
             album_id = self.__albums_queue.pop()
             album = App().albums.get_name(album_id)
             artist_ids = App().albums.get_artist_ids(album_id)
             is_compilation = artist_ids and\
                 artist_ids[0] == Type.COMPILATIONS
             if is_compilation:
                 artist = ""
             else:
                 artist = ", ".join(App().albums.get_artists(album_id))
             found = False
             for api in self.__album_methods.keys():
                 result = self.__album_methods[api](artist, album)
                 for uri in result:
                     (status,
                      data) = App().task_helper.load_uri_content_sync(uri,
                                                                      None)
                     if status:
                         found = True
                         App().art.save_album_artwork(Album(album_id), data)
                         break
                 # Found, do not search in another helper
                 if found:
                     break
             # Not found, save empty artwork
             if not found:
                 App().art.save_album_artwork(Album(album_id), None)
     except Exception as e:
         Logger.error("DownloaderArt::__cache_albums_artwork: %s" % e)
     self.__in_albums_download = False
Exemplo n.º 24
0
 def _on_tertiary_press_gesture(self, x, y, event):
     """
         Play artist
         @param x as int
         @param y as int
         @param event as Gdk.Event
     """
     child = self._box.get_child_at_pos(x, y)
     if child is None or child.artwork is None:
         return
     album_ids = App().albums.get_ids([child.data], [], self.storage_type,
                                      False)
     albums = [Album(album_id) for album_id in album_ids]
     if albums:
         App().player.play_album_for_albums(albums[0], albums)
Exemplo n.º 25
0
 def __on_banner_play_all(self, banner, random):
     """
         Play all albums
         @param banner as AlbumsBannerWidget
         @param random as bool
     """
     album_ids = App().genres.get_album_ids(True)
     if not album_ids:
         return
     albums = [Album(album_id) for album_id in album_ids]
     if random:
         shuffle(albums)
         App().player.play_album_for_albums(albums[0], albums)
     else:
         App().player.play_album_for_albums(albums[0], albums)
Exemplo n.º 26
0
 def __get_album_from_artists(self,  similar_artist_ids):
     """
         Add a new album to playback
         @param similar_artist_ids as [int]
         @return Album
     """
     # Get an album
     storage_type = get_default_storage_type()
     album_ids = App().albums.get_ids(
         [], similar_artist_ids, storage_type, False)
     shuffle(album_ids)
     while album_ids:
         album_id = album_ids.pop(0)
         if album_id not in self.album_ids:
             return Album(album_id, [], [], False)
     return None
 def _get_child(self, album_id):
     """
         Get an album view widget
         @param album_id as int
         @return AlbumView
     """
     if self.destroyed:
         return None
     album = Album(album_id, self.__genre_ids, self.__artist_ids)
     widget = AlbumView(album,
                        self.storage_type,
                        ViewType.ARTIST)
     widget.show()
     widget.set_property("valign", Gtk.Align.START)
     self.__list.add(widget)
     return widget
Exemplo n.º 28
0
 def __on_banner_play_all(self, banner, random):
     """
         Play all albums
         @param banner as AlbumsBannerWidget
         @param random as bool
     """
     album_ids = App().albums.get_ids([], [], self.storage_type, False,
                                      OrderBy.YEAR_ASC)
     if not album_ids:
         return
     albums = [Album(album_id, [], [], False) for album_id in album_ids]
     if random:
         shuffle(albums)
         App().player.play_album_for_albums(albums[0], albums)
     else:
         App().player.play_album_for_albums(albums[0], albums)
Exemplo n.º 29
0
 def set_party_ids(self):
     """
         Set party mode ids
     """
     if not self._is_party:
         return
     party_ids = App().settings.get_value("party-ids")
     storage_type = get_default_storage_type()
     album_ids = App().albums.get_ids(party_ids, [], storage_type, False)
     emit_signal(self, "playback-setted", [])
     self._albums = []
     if album_ids:
         emit_signal(self, "loading-changed", True, Track())
     for album_id in album_ids:
         album = Album(album_id, [], [], False)
         self._albums.append(album)
     emit_signal(self, "playback-setted", list(self._albums))
Exemplo n.º 30
0
 def __init__(self, artist_id, storage_type, view_type, header=False):
     """
         Init artist menu
         @param artist_id as int
         @param storage_type as StorageType
         @param view_type as ViewType
         @param header as bool
     """
     Gio.Menu.__init__(self)
     if header:
         from lollypop.menu_header import ArtistMenuHeader
         self.append_item(ArtistMenuHeader(artist_id))
     if view_type & ViewType.BANNER:
         show_artist_tracks = App().settings.get_value("show-artist-tracks")
         action = Gio.SimpleAction.new_stateful(
             "show-artist-tracks", None,
             GLib.Variant.new_boolean(show_artist_tracks))
         App().add_action(action)
         action.connect("change-state", self.__on_change_state)
         self.append(_("Show tracks"), "app.show-artist-tracks")
         if not show_artist_tracks:
             action = Gio.SimpleAction.new_stateful(
                 "show-year-below-name", None,
                 GLib.Variant.new_boolean(
                     App().settings.get_value("show-year-below-name")))
             App().add_action(action)
             action.connect("change-state", self.__on_change_state)
             self.append(_("Show year"), "app.show-year-below-name")
         action = Gio.SimpleAction.new_stateful(
             "play-featured", None,
             GLib.Variant.new_boolean(
                 App().settings.get_value("play-featured")))
         App().add_action(action)
         action.connect("change-state", self.__on_change_state)
         self.append(_("Play featured"), "app.play-featured")
     else:
         from lollypop.menu_playback import ArtistPlaybackMenu
         self.append_section(_("Playback"),
                             ArtistPlaybackMenu(artist_id, storage_type))
     menu = Gio.Menu()
     self.append_section(_("Artist"), menu)
     storage_type = get_default_storage_type()
     album_ids = App().albums.get_ids([], [artist_id], storage_type, False)
     albums = [Album(album_id) for album_id in album_ids]
     menu.append_submenu(_("Devices"), SyncAlbumsMenu(albums))
     menu.append_submenu(_("Playlists"), PlaylistsMenu(albums))