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)
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
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)
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)
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)
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)
def __get_rows_from_rows(self, rows, height): """ Build news rows from rows @param rows as [TrackRow/AlbumRow] @param height as int @return [AlbumRow] """ new_rows = [] for row in rows: if isinstance(row, TrackRow): # Merge with previous if new_rows and new_rows[-1].album.id == row.track.album.id: new_rows[-1].tracks_view.append_row(row.track) # Create a new album else: new_album = Album(row.track.album.id) new_album.set_tracks([row.track]) new_album_row = AlbumRow(new_album, height, self.__view_type) new_album_row.show() new_album_row.reveal() new_rows.append(new_album_row) else: # Merge with previous if new_rows and new_rows[-1].album.id == row.album.id: new_rows[-1].tracks_view.append_rows(row.album.tracks) # Create a new album else: new_album = Album(row.album.id) new_album.set_tracks(row.album.tracks) new_album_row = AlbumRow(new_album, height, self.__view_type) new_album_row.populate() new_album_row.show() new_rows.append(new_album_row) return new_rows
class Track(Base): """ Represent a track """ DEFAULTS = { "name": "", "album_id": None, "artist_ids": [], "genre_ids": [], "popularity": 0, "rate": 0, "album_name": "", "artists": [], "genres": [], "duration": 0, "number": 0, "discnumber": 0, "discname": "", "year": None, "timestamp": 0, "mtime": 1, "loved": False, "storage_type": StorageType.COLLECTION, "mb_track_id": None, "lp_track_id": None, "mb_artist_ids": [] } 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 def __del__(self): """ Remove ref cycles """ self.__album = None # Used by pickle def __getstate__(self): self.db = None return self.__dict__ def __setstate__(self, d): self.__dict__.update(d) self.db = App().tracks def set_album(self, album): """ Set track album @param album as Album """ self.__album = album def set_uri(self, uri): """ Set uri @param uri as string """ self._uri = uri def set_number(self, number): """ Set number @param number as int """ self._number = number def set_name(self, name): """ Set name @param name as str """ self._name = name def set_loved(self, loved): """ Mark album as loved @param loved as bool """ if self.id >= 0: App().tracks.set_loved(self.id, loved) self.loved = loved def get_featuring_artist_ids(self, album_artist_ids): """ Get featuring artist ids @return [int] """ artist_ids = self.db.get_artist_ids(self.id) return list(set(artist_ids) - set(album_artist_ids)) @property def is_web(self): """ True if track is a web track @return bool """ return not self.storage_type & (StorageType.COLLECTION | StorageType.EXTERNAL) @property def is_http(self): """ True if track is a http track @return bool """ parsed = urlparse(self.uri) return parsed.scheme in ["http", "https"] @property def position(self): """ Get track position for album @return int """ i = 0 for track_id in self.__album.track_ids: if track_id == self.id: break i += 1 return i @property def first(self): """ Is track first for album @return bool """ tracks = self.__album.tracks return tracks and self.id == tracks[0].id @property def last(self): """ Is track last for album @return bool """ tracks = self.__album.tracks return tracks and self.id == tracks[-1].id @property def title(self): """ Get track name Alias to Track.name """ return self.name @property def uri(self): """ Get track file uri @return str """ if self._uri is None: self._uri = App().tracks.get_uri(self.id) return self._uri @property def path(self): """ Get track file path @return str """ f = Gio.File.new_for_uri(self.uri) path = f.get_path() if path is None: return "" return path @property def album(self): """ Get track"s album @return Album """ return self.__album @property def album_artists(self): """ Get track album artists, can be != than album.artists as track may not have any album @return str """ if getattr(self, "_album_artists") is None: self._album_artists = self.album.artists return self._album_artists