def __init__(self): Query() self.MostPlayed.QUERY = Query.get_most_played_songs() self.NeverPlayed.QUERY = Query.get_never_played_songs() self.RecentlyPlayed.QUERY = Query.get_recently_played_songs() self.RecentlyAdded.QUERY = Query.get_recently_added_songs() self.Favorites.QUERY = Query.get_favorite_songs()
def _setup_view(self): self._box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.player = Player(self) self.selection_toolbar = SelectionToolbar() self.toolbar = Toolbar() self.views = [] self._stack = Gtk.Stack( transition_type=Gtk.StackTransitionType.CROSSFADE, transition_duration=100, visible=True, can_focus=False) # Add the 'background' styleclass so it properly hides the # bottom line of the searchbar self._stack.get_style_context().add_class('background') self._overlay = Gtk.Overlay(child=self._stack) self._overlay.add_overlay(self.toolbar.dropdown) self.set_titlebar(self.toolbar.header_bar) self._box.pack_start(self.toolbar.searchbar, False, False, 0) self._box.pack_start(self._overlay, True, True, 0) self._box.pack_start(self.player.actionbar, False, False, 0) self._box.pack_start(self.selection_toolbar.actionbar, False, False, 0) self.add(self._box) count = 0 cursor = None Query() if Query.music_folder: try: cursor = tracker.query(Query.all_songs_count(), None) if cursor is not None and cursor.next(None): count = cursor.get_integer(0) except Exception as e: logger.error("Tracker query crashed: %s", e) count = 0 if count > 0: self._switch_to_player_view() # To revert to the No Music View when no songs are found else: if self.toolbar._selectionMode is False: self._switch_to_empty_view() else: # Revert to No Music view if XDG dirs are not set self._switch_to_empty_view() self.toolbar._search_button.connect('toggled', self._on_search_toggled) self.toolbar.connect('selection-mode-changed', self._on_selection_mode_changed) self.selection_toolbar._add_to_playlist_button.connect( 'clicked', self._on_add_to_playlist_button_clicked) self.selection_toolbar._remove_from_playlist_button.connect( 'clicked', self._on_remove_from_playlist_button_clicked) self.toolbar.set_state(ToolbarState.MAIN) self.toolbar.header_bar.show() self._overlay.show() self.player.actionbar.show_all() self._box.show() self.show()
def toggle_favorite(self, song_item): # TODO: change "bool(song_item.get_lyrics())" --> song_item.get_favourite() once query works properly # TODO: when .set/get_favourite work, set_favourite outside loop: item.set_favourite(!item.get_favourite()) if bool(song_item.get_lyrics()): # is favorite self.sparqltracker.update(Query.remove_favorite(song_item.get_url()), GLib.PRIORITY_DEFAULT, None) song_item.set_lyrics("") else: # not favorite self.sparqltracker.update(Query.add_favorite(song_item.get_url()), GLib.PRIORITY_DEFAULT, None) song_item.set_lyrics("i'm truthy")
def get_album_art_for_item(self, item, callback, data=None): item_id = item.get_id() query = None if isinstance(item, Grl.MediaAudio): query = Query.get_album_for_song_id(item_id) else: query = Query.get_album_for_album_id(item_id) options = self.full_options.copy() options.set_count(1) self.search_source.query(query, self.METADATA_THUMBNAIL_KEYS, options, callback, data)
def get_album_art_for_item(self, item, callback): item_id = item.get_id() if item.is_audio(): query = Query.get_album_for_song_id(item_id) else: query = Query.get_album_for_album_id(item_id) options = self.full_options.copy() options.set_count(1) self.search_source.query(query, self.METADATA_THUMBNAIL_KEYS, options, callback)
def create_playlist_and_return_id(self, title, tag_text): self.tracker.update_blank(Query.create_tag(tag_text), GLib.PRIORITY_LOW, None) data = self.tracker.update_blank( Query.create_playlist_with_tag(title, tag_text), GLib.PRIORITY_LOW, None) playlist_urn = data.get_child_value(0).get_child_value(0).\ get_child_value(0).get_child_value(1).get_string() cursor = self.tracker.query(Query.get_playlist_with_urn(playlist_urn), None) if not cursor or not cursor.next(): return return cursor.get_integer(0)
def create_playlist_and_return_id(self, title, tag_text): self.tracker.update_blank(Query.create_tag(tag_text), GLib.PRIORITY_DEFAULT, None) data = self.tracker.update_blank( Query.create_playlist_with_tag(title, tag_text), GLib.PRIORITY_DEFAULT, None) playlist_urn = data.get_child_value(0).get_child_value(0).\ get_child_value(0).get_child_value(1).get_string() cursor = self.tracker.query( Query.get_playlist_with_urn(playlist_urn), None) if not cursor or not cursor.next(): return return cursor.get_integer(0)
def tag_created_cb(obj, res, playlist): """ Called when the tag is created """ creation_query = Query.create_playlist_with_tag(title, tag_text) # Start creating the playlist itself self.tracker.update_blank_async(creation_query, GLib.PRIORITY_LOW, None, playlist_created_cb, playlist)
def _on_grilo_ready(self, data=None): """For all static playlists: get ID, if exists; if not, create the playlist and get ID.""" def playlist_id_fetched_cb(cursor, res, playlist): """ Called after the playlist id is fetched """ try: cursor.next_finish(res) except GLib.Error as err: logger.warn("Error: %s, %s", err.__class__, err) return playlist.ID = cursor.get_integer(1) if not playlist.ID: # Create the static playlist self._create_static_playlist(playlist) else: # Update playlist self.update_static_playlist(playlist) def callback(obj, result, playlist): """ Starts retrieving the playlist id """ try: cursor = obj.query_finish(result) except GLib.Error as err: logger.warn("Error: %s, %s", err.__class__, err) return # Search for the playlist ID cursor.next_async(None, playlist_id_fetched_cb, playlist) # Start fetching all the static playlists for playlist in self._static_playlists.get_all(): self.tracker.query_async( Query.get_playlist_with_tag(playlist.TAG_TEXT), None, callback, playlist)
def create_playlist(self, title): def get_callback(source, param, item, count, data, error): if item: self.emit('playlist-created', item) def cursor_callback(cursor, res, data): try: has_next = cursor.next_finish(res) except GLib.Error as err: logger.warn("Error: %s, %s", err.__class__, err) return playlist_id = cursor.get_integer(0) grilo.get_playlist_with_id(playlist_id, get_callback) def query_callback(conn, res, data): try: cursor = conn.query_finish(res) except GLib.Error as err: logger.warn("Error: %s, %s", err.__class__, err) return if not cursor: return cursor.next_async(None, cursor_callback, data) def update_callback(conn, res, data): playlist_urn = conn.update_blank_finish(res)[0][0]['playlist'] self.tracker.query_async(Query.get_playlist_with_urn(playlist_urn), None, query_callback, None) self.tracker.update_blank_async(Query.create_playlist(title), GLib.PRIORITY_LOW, None, update_callback, None)
def add_to_playlist(self, playlist, items): def get_callback(source, param, item, count, data, error): if item: self.emit('song-added-to-playlist', playlist, item) def query_callback(conn, res, data): cursor = conn.query_finish(res) if not cursor or not cursor.next(): return entry_id = cursor.get_integer(0) grilo.get_playlist_song_with_id( playlist.get_id(), entry_id, get_callback ) def update_callback(conn, res, data): entry_urn = conn.update_blank_finish(res)[0][0]['entry'] self.tracker.query_async( Query.get_playlist_song_with_urn(entry_urn), None, query_callback, None ) for item in items: uri = item.get_url() if not uri: continue self.tracker.update_blank_async( Query.add_song_to_playlist(playlist.get_id(), uri), GLib.PRIORITY_DEFAULT, None, update_callback, None )
def add_to_playlist(self, playlist, items): def get_callback(source, param, item, count, data, error): if item: self.emit('song-added-to-playlist', playlist, item) def query_callback(conn, res, data): cursor = conn.query_finish(res) if not cursor or not cursor.next(): return entry_id = cursor.get_integer(0) grilo.get_playlist_song_with_id(playlist.get_id(), entry_id, get_callback) def update_callback(conn, res, data): entry_urn = conn.update_blank_finish(res)[0][0]['entry'] self.tracker.query_async( Query.get_playlist_song_with_urn(entry_urn), None, query_callback, None) for item in items: uri = item.get_url() if not uri: continue self.tracker.update_blank_async( Query.add_song_to_playlist(playlist.get_id(), uri), GLib.PRIORITY_LOW, None, update_callback, None)
def delete_playlist(self, item): def update_callback(conn, res, data): conn.update_finish(res) self.emit('playlist-deleted', item) self.tracker.update_async(Query.delete_playlist(item.get_id()), GLib.PRIORITY_LOW, None, update_callback, None)
def populate_playlists(self, offset, callback, count=-1): """Asynchronously get playlists (user and smart ones) :param int offset: start index :param function callback: callback function :param int count: limit number of results """ self.populate_items(Query.all_playlists(), offset, callback, count)
def _create_static_playlist(self, playlist): """ Create the tag and the static playlist, and fetch the newly created playlist's songs. """ title = playlist.TITLE tag_text = playlist.TAG_TEXT def playlist_next_async_cb(cursor, res, playlist): """ Called after we finished moving the Tracker cursor, and ready to retrieve the playlist id""" # Update the playlist ID try: cursor.next_finish(res) except GLib.Error as err: logger.warn("Error: %s, %s", err.__class__, err) return playlist.ID = cursor.get_integer(0) # Fetch the playlist contents self.update_static_playlist(playlist) def playlist_queried_cb(obj, res, playlist): """ Called after the playlist is created and the ID is fetched """ try: cursor = obj.query_finish(res) except GLib.Error as err: logger.warn("Error: %s, %s", err.__class__, err) return cursor.next_async(None, playlist_next_async_cb, playlist) def playlist_created_cb(obj, res, playlist): """ Called when the static playlist is created """ data = obj.update_blank_finish(res) playlist_urn = data.get_child_value(0).get_child_value(0).\ get_child_value(0).get_child_value(1).get_string() query = Query.get_playlist_with_urn(playlist_urn) # Start fetching the playlist self.tracker.query_async(query, None, playlist_queried_cb, playlist) def tag_created_cb(obj, res, playlist): """ Called when the tag is created """ creation_query = Query.create_playlist_with_tag(title, tag_text) # Start creating the playlist itself self.tracker.update_blank_async(creation_query, GLib.PRIORITY_LOW, None, playlist_created_cb, playlist) # Start the playlist creation by creating the tag self.tracker.update_blank_async(Query.create_tag(tag_text), GLib.PRIORITY_LOW, None, tag_created_cb, playlist)
def populate_album_songs(self, album, callback, count=-1): if album.get_source() == 'grl-tracker-source': self.populate_items(Query.album_songs(album.get_id()), 0, callback, count) else: source = self.sources[album.get_source()] length = len(album.tracks) for i, track in enumerate(album.tracks): callback(source, None, track, length - (i + 1), None) callback(source, None, None, 0, None)
def populate_user_playlists(self, offset, callback, count=-1): """Asynchronously get user playlists :param int offset: start index :param function callback: callback function :param int count: limit number of results """ self.populate_items( Query.all_user_playlists(), offset, callback, count)
def delete_playlist(self, item): def update_callback(conn, res, data): conn.update_finish(res) self.emit('playlist-deleted', item) self.tracker.update_async( Query.delete_playlist(item.get_id()), GLib.PRIORITY_DEFAULT, None, update_callback, None )
def remove_from_playlist(self, playlist, items): def update_callback(conn, res, data): conn.update_finish(res) self.emit('song-removed-from-playlist', playlist, data) for item in items: self.tracker.update_async( Query.remove_song_from_playlist(playlist.get_id(), item.get_id()), GLib.PRIORITY_LOW, None, update_callback, item)
def populate_user_playlists(self, offset, callback, count=-1): """Asynchronously get user playlists :param int offset: start index :param function callback: callback function :param int count: limit number of results """ if self.tracker: GLib.idle_add(self.populate_items, Query.all_user_playlists(), offset, callback, count)
def populate_playlists(self, offset, callback, count=-1, data=None): """Asynchronously get playlists (user and smart ones) :param int offset: start index :param function callback: callback function :param int count: limit number of results :param object data: user data """ self.populate_items( Query.all_playlists(), offset, callback, count, data)
def playlist_created_cb(obj, res, playlist): """ Called when the static playlist is created """ data = obj.update_blank_finish(res) playlist_urn = data.get_child_value(0).get_child_value(0).\ get_child_value(0).get_child_value(1).get_string() query = Query.get_playlist_with_urn(playlist_urn) # Start fetching the playlist self.tracker.query_async(query, None, playlist_queried_cb, playlist)
def get_media_from_uri(self, uri, callback): options = self.options.copy() query = Query.get_song_with_url(uri) def _callback(source, param, item, count, data, error): if not error: callback(source, param, item) return self.tracker.query(query, self.METADATA_KEYS, options, _callback, None)
def remove_from_playlist(self, playlist, items): def update_callback(conn, res, data): conn.update_finish(res) self.emit('song-removed-from-playlist', playlist, data) for item in items: self.tracker.update_async( Query.remove_song_from_playlist( playlist.get_id(), item.get_id() ), GLib.PRIORITY_DEFAULT, None, update_callback, item )
def _setup_view(self): self._box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.player = Player(self) self.selection_toolbar = SelectionToolbar() self.toolbar = Toolbar() self.views = [] self._stack = Gtk.Stack( transition_type=Gtk.StackTransitionType.CROSSFADE, transition_duration=100, visible=True, can_focus=False) # Add the 'background' styleclass so it properly hides the # bottom line of the searchbar self._stack.get_style_context().add_class('background') self._overlay = Gtk.Overlay(child=self._stack) self._overlay.add_overlay(self.toolbar.dropdown) self.set_titlebar(self.toolbar.header_bar) self._box.pack_start(self.toolbar.searchbar, False, False, 0) self._box.pack_start(self._overlay, True, True, 0) self._box.pack_start(self.player.actionbar, False, False, 0) self._box.pack_start(self.selection_toolbar.actionbar, False, False, 0) self.add(self._box) def songs_available_cb(available): if available: self._switch_to_player_view() else: self._switch_to_empty_view() Query() if Query.music_folder: grilo.songs_available(songs_available_cb) else: self._switch_to_empty_view() self.toolbar._search_button.connect('toggled', self._on_search_toggled) self.toolbar.connect('selection-mode-changed', self._on_selection_mode_changed) self.selection_toolbar._add_to_playlist_button.connect( 'clicked', self._on_add_to_playlist_button_clicked) self.selection_toolbar._remove_from_playlist_button.connect( 'clicked', self._on_remove_from_playlist_button_clicked) self.toolbar.set_state(ToolbarState.MAIN) self.toolbar.header_bar.show() self._overlay.show() self.player.actionbar.show_all() self._box.show() self.show()
def _on_content_changed(self, mediaSource, changedMedias, changeType, locationUnknown): try: with self.tracker.handler_block(self.notification_handler): for media in changedMedias: media_id = media.get_id() if changeType == Grl.SourceChangeType.ADDED: # Check that this media is an audio file mime_type = self.tracker.query_sync( Query.is_audio(media_id), [Grl.METADATA_KEY_MIME], self.options)[0].get_mime() if mime_type and mime_type.startswith("audio"): self.changed_media_ids.append(media_id) if changeType == Grl.SourceChangeType.REMOVED: # There is no way to check that removed item is a media # so always do the refresh # todo: remove one single url try: self.changed_media_ids.append(media.get_id()) except Exception as e: logger.warn("Skipping %s", media) if self.changed_media_ids == []: self.pending_changed_medias = [] if self.content_changed_timeout is not None: GLib.source_remove(self.content_changed_timeout) self.content_changed_timeout = None return False self.changed_media_ids = list(set(self.changed_media_ids)) logger.debug("Changed medias: %s", self.changed_media_ids) if len(self.changed_media_ids) >= self.CHANGED_MEDIA_MAX_ITEMS: self.emit_change_signal() elif self.changed_media_ids != []: if self.pending_event_id > 0: GLib.Source.remove(self.pending_event_id) self.pending_event_id = 0 self.pending_event_id = GLib.timeout_add( self.CHANGED_MEDIA_SIGNAL_TIMEOUT, self.emit_change_signal) except Exception as e: logger.warn("Exception in _on_content_changed: %s", e) finally: self.pending_changed_medias = [] if self.content_changed_timeout is not None: GLib.source_remove(self.content_changed_timeout) self.content_changed_timeout = None return False
def reorder_playlist(self, playlist, items, new_positions): """Change the order of songs on a playlist. :param GlrMedia playlist: playlist to reorder :param list items: songs to reorder :param list new_positions: new songs positions """ def update_callback(conn, res, data): conn.update_finish(res) for item, new_position in zip(items, new_positions): self.tracker.update_async( Query.change_song_position(playlist.get_id(), item.get_id(), new_position), GLib.PRIORITY_LOW, None, update_callback, item)
def fetch_or_create_static_playlists(self): """For all static playlists: get ID, if exists; if not, create the playlist and get ID.""" playlists = [cls for name, cls in inspect.getmembers(StaticPlaylists) if inspect.isclass(cls) and not (name == "__class__")] # hacky for playlist in playlists: cursor = self.tracker.query(Query.get_playlist_with_tag(playlist.TAG_TEXT), None) while cursor.next(): playlist_id = cursor.get_string(1)[0] playlist.ID = int(playlist_id) # hacky; shouldn't be reassigned every time if not playlist.ID: # create the playlist playlist.ID = self.create_playlist_and_return_id(playlist.TITLE, playlist.TAG_TEXT) self.update_static_playlist(playlist)
def _on_content_changed(self, mediaSource, changedMedias, changeType, locationUnknown): try: with self.tracker.handler_block(self.notification_handler): for media in changedMedias: media_id = media.get_id() if changeType == Grl.SourceChangeType.ADDED: # Check that this media is an audio file mime_type = self.tracker.query_sync( Query.is_audio(media_id), [Grl.METADATA_KEY_MIME], self.options)[0].get_mime() if mime_type and mime_type.startswith("audio"): self.changed_media_ids.append(media_id) if changeType == Grl.SourceChangeType.REMOVED: # There is no way to check that removed item is a media # so always do the refresh # todo: remove one single url try: self.changed_media_ids.append(media.get_id()) except Exception as e: logger.warn("Skipping %s", media) if self.changed_media_ids == []: self.pending_changed_medias = [] if self.content_changed_timeout is not None: GLib.source_remove(self.content_changed_timeout) self.content_changed_timeout = None return False self.changed_media_ids = list(set(self.changed_media_ids)) logger.debug("Changed medias: %s", self.changed_media_ids) if len(self.changed_media_ids) >= self.CHANGED_MEDIA_MAX_ITEMS: self.emit_change_signal() elif self.changed_media_ids != []: if self.pending_event_id > 0: GLib.Source.remove(self.pending_event_id) self.pending_event_id = 0 self.pending_event_id = GLib.timeout_add(self.CHANGED_MEDIA_SIGNAL_TIMEOUT, self.emit_change_signal) except Exception as e: logger.warn("Exception in _on_content_changed: %s", e) finally: self.pending_changed_medias = [] if self.content_changed_timeout is not None: GLib.source_remove(self.content_changed_timeout) self.content_changed_timeout = None return False
def rename(self, item, new_name): """Rename a playlist :param item: playlist to rename :param new_name: new playlist name :type item: Grl.Media :type new_name: str :return: None :rtype: None """ def update_callback(conn, res, data): conn.update_finish(res) self.emit('playlist-renamed', item) self.tracker.update_async( Query.rename_playlist(item.get_id(), new_name), GLib.PRIORITY_LOW, None, update_callback, None)
def callback(cursor, res, final_query): has_next = False try: has_next = cursor.next_finish(res) except GLib.Error as err: logger.warning("Error: {}, {}".format(err.__class__, err)) # Only perform the update when the cursor reached the end if has_next: uri = cursor.get_string(0)[0] final_query += Query.add_song_to_playlist(playlist.ID, uri) cursor.next_async(None, callback, final_query) else: self._tracker.update_blank_async( final_query, GLib.PRIORITY_LOW, None, self._smart_playlist_update_finished, playlist)
def fetch_or_create_static_playlists(self): """For all static playlists: get ID, if exists; if not, create the playlist and get ID.""" def callback(obj, result, playlist): cursor = obj.query_finish(result) while (cursor.next(None)): playlist.ID = cursor.get_integer(1) if not playlist.ID: # create the playlist playlist.ID = self.create_playlist_and_return_id( playlist.TITLE, playlist.TAG_TEXT) self.update_static_playlist(playlist) for playlist in self._static_playlists.get_all(): self.tracker.query_async( Query.get_playlist_with_tag(playlist.TAG_TEXT), None, callback, playlist)
def songs_available(self, callback): """Checks if there are any songs available Calls a callback function with True or False depending on the availability of songs. :param callback: Function to call on result """ def cursor_next_cb(conn, res, data): try: has_next = conn.next_finish(res) except GLib.Error as err: logger.warning("Error: {}, {}".format(err.__class__, err)) callback(False) return if has_next: count = conn.get_integer(0) if count > 0: callback(True) return callback(False) def songs_query_cb(conn, res, data): try: cursor = conn.query_finish(res) except GLib.Error as err: logger.warning("Error: {}, {}".format(err.__class__, err)) self.props.tracker_available = False callback(False) return cursor.next_async(None, cursor_next_cb, None) # TODO: currently just checks tracker, should work with any # queryable supported Grilo source. if not self.props.tracker_available: callback(False) return self.tracker_sparql.query_async( Query.all_songs_count(), None, songs_query_cb, None)
def _setup_view(self): self._box = Gtk.VBox() self.player = Player() self.selection_toolbar = SelectionToolbar() self.toolbar = Toolbar() self.views = [] self._stack = Gtk.Stack( transition_type=Gtk.StackTransitionType.CROSSFADE, transition_duration=100, visible=True, can_focus=False) self._overlay = Gtk.Overlay(child=self._stack) self._overlay.add_overlay(self.toolbar.dropdown) self.set_titlebar(self.toolbar.header_bar) self._box.pack_start(self.toolbar.searchbar, False, False, 0) self._box.pack_start(self._overlay, True, True, 0) self._box.pack_start(self.player.actionbar, False, False, 0) self._box.pack_start(self.selection_toolbar.actionbar, False, False, 0) self.add(self._box) count = 1 cursor = tracker.query(Query.all_songs_count(), None) if cursor is not None and cursor.next(None): count = cursor.get_integer(0) if count > 0: self._switch_to_player_view() # To revert to the No Music View when no songs are found else: if self.toolbar._selectionMode is False: self._switch_to_empty_view() self.toolbar._search_button.connect('toggled', self._on_search_toggled) self.toolbar.connect('selection-mode-changed', self._on_selection_mode_changed) self.selection_toolbar._add_to_playlist_button.connect( 'clicked', self._on_add_to_playlist_button_clicked) self.selection_toolbar._remove_from_playlist_button.connect( 'clicked', self._on_remove_from_playlist_button_clicked) self.toolbar.set_state(ToolbarState.MAIN) self.toolbar.header_bar.show() self._overlay.show() self.player.actionbar.show_all() self._box.show() self.show()
def callback(cursor, res, final_query): uri = cursor.get_string(0)[0] final_query += Query.add_song_to_playlist(playlist.ID, uri) try: has_next = cursor.next_finish(res) except GLib.Error as err: logger.warn("Error: %s, %s", err.__class__, err) has_next = False # Only perform the update when the cursor reached the end if has_next: cursor.next_async(None, callback, final_query) return self.tracker.update_blank_async(final_query, GLib.PRIORITY_LOW, None, None, None) # tell system we updated the playlist so playlist is reloaded self.emit('playlist-updated', playlist.ID)
def fetch_or_create_static_playlists(self): """For all static playlists: get ID, if exists; if not, create the playlist and get ID.""" playlists = [cls for name, cls in inspect.getmembers(StaticPlaylists) if inspect.isclass(cls) and not (name == "__class__")] # hacky def callback(obj, result, playlist): cursor = obj.query_finish(result) while (cursor.next(None)): playlist.ID = cursor.get_integer(1) if not playlist.ID: # create the playlist playlist.ID = self.create_playlist_and_return_id(playlist.TITLE, playlist.TAG_TEXT) self.update_static_playlist(playlist) for playlist in playlists: self.tracker.query_async( Query.get_playlist_with_tag(playlist.TAG_TEXT), None, callback, playlist)
def create_playlist(self, title): def get_callback(source, param, item, count, data, error): if item: self.emit('playlist-created', item) def query_callback(conn, res, data): cursor = conn.query_finish(res) if not cursor or not cursor.next(): return playlist_id = cursor.get_integer(0) grilo.get_playlist_with_id(playlist_id, get_callback) def update_callback(conn, res, data): playlist_urn = conn.update_blank_finish(res)[0][0]['playlist'] self.tracker.query_async(Query.get_playlist_with_urn(playlist_urn), None, query_callback, None) self.tracker.update_blank_async(Query.create_playlist(title), GLib.PRIORITY_LOW, None, update_callback, None)
def update_static_playlist(self, playlist): """Given a static playlist (subclass of StaticPlaylists), updates according to its query.""" # Clear the playlist self.clear_playlist_with_id(playlist.ID) # Get a list of matching songs cursor = self.tracker.query(playlist.QUERY, None) if not cursor: return # For each song run 'add song to playlist' while cursor.next(): uri = cursor.get_string(0)[0] self.tracker.update_blank_async( Query.add_song_to_playlist(playlist.ID, uri), GLib.PRIORITY_DEFAULT, None, None, None ) # tell system we updated the playlist so playlist is reloaded self.emit('playlist-updated', playlist.ID)
def update_static_playlist(self, playlist): """Given a static playlist (subclass of StaticPlaylists), updates according to its query.""" # Clear the playlist self.clear_playlist_with_id(playlist.ID) final_query = '' # Get a list of matching songs cursor = self.tracker.query(playlist.QUERY, None) if not cursor: return # For each song run 'add song to playlist' while cursor.next(): uri = cursor.get_string(0)[0] final_query += Query.add_song_to_playlist(playlist.ID, uri) self.tracker.update_blank_async(final_query, GLib.PRIORITY_LOW, None, None, None) # tell system we updated the playlist so playlist is reloaded self.emit('playlist-updated', playlist.ID)
def create_playlist(self, title): def get_callback(source, param, item, count, data, error): if item: self.emit('playlist-created', item) def cursor_callback(cursor, res, data): try: has_next = cursor.next_finish(res) except GLib.Error as err: logger.warn("Error: %s, %s", err.__class__, err) return playlist_id = cursor.get_integer(0) grilo.get_playlist_with_id(playlist_id, get_callback) def query_callback(conn, res, data): try: cursor = conn.query_finish(res) except GLib.Error as err: logger.warn("Error: %s, %s", err.__class__, err) return if not cursor: return cursor.next_async(None, cursor_callback, data) def update_callback(conn, res, data): playlist_urn = conn.update_blank_finish(res)[0][0]['playlist'] self.tracker.query_async( Query.get_playlist_with_urn(playlist_urn), None, query_callback, None ) self.tracker.update_blank_async( Query.create_playlist(title), GLib.PRIORITY_LOW, None, update_callback, None )
def playlists_available(self, callback): """Checks if there are any non-static playlists available Calls a callback function with True or False depending on the availability of playlists. :param callback: Function to call on result """ def cursor_next_cb(conn, res, data): try: has_next = conn.next_finish(res) except GLib.Error as err: logger.warn("Error: %s, %s", err.__class__, err) callback(False) return if has_next: count = conn.get_integer(0) if count > 0: callback(True) return callback(False) def playlists_query_cb(conn, res, data): try: cursor = conn.query_finish(res) except GLib.Error as err: logger.warn("Error: %s, %s", err.__class__, err) callback(False) return cursor.next_async(None, cursor_next_cb, None) # TODO: currently just checks tracker, should work with any # queryable supported Grilo source. self.sparqltracker.query_async(Query.all_non_static_playlists_count(), None, playlists_query_cb, None)
def create_playlist(self, title): def get_callback(source, param, item, count, data, error): if item: self.emit('playlist-created', item) def query_callback(conn, res, data): cursor = conn.query_finish(res) if not cursor or not cursor.next(): return playlist_id = cursor.get_integer(0) grilo.get_playlist_with_id(playlist_id, get_callback) def update_callback(conn, res, data): playlist_urn = conn.update_blank_finish(res)[0][0]['playlist'] self.tracker.query_async( Query.get_playlist_with_urn(playlist_urn), None, query_callback, None ) self.tracker.update_blank_async( Query.create_playlist(title), GLib.PRIORITY_DEFAULT, None, update_callback, None )
def _on_changes_pending(self, data=None): count = 1 cursor = tracker.query(Query.all_songs_count(), None) if cursor is not None and cursor.next(None): count = cursor.get_integer(0) if not count > 0: if self.toolbar._selectionMode is False and len(self.views) != 1: self._stack.disconnect(self._on_notify_model_id) self.disconnect(self._key_press_event_id) view_count = len(self.views) for i in range(0, view_count): view = self.views.pop() view.destroy() self.toolbar.hide_stack() self._switch_to_empty_view() else: if (self.views[0] == self.views[-1]): view = self.views.pop() view.destroy() self._switch_to_player_view() self.toolbar._search_button.set_sensitive(True) self.toolbar._select_button.set_sensitive(True) self.toolbar.show_stack()
def get_playlist_song_with_id(self, playlist_id, entry_id, callback): options = self.options.copy() query = Query.get_playlist_song_with_id(playlist_id, entry_id) self.tracker.query(query, self.METADATA_KEYS, options, callback, None)
def populate_playlists(self, offset, callback, count=-1): self.populate_items(Query.all_playlists(), offset, callback, count)
def populate_playlist_songs(self, playlist, callback, count=-1): self.populate_items(Query.playlist_songs(playlist.get_id()), 0, callback, count)