def __on_save_artwork_tags(self, source, result, album_id): """ Save image to tags @param source as GObject.Object @param result as Gio.AsyncResult @param album_id as int """ try: can_set_cover = source.call_finish(result)[0] except: can_set_cover = False if can_set_cover: dbus_helper = DBusHelper() for uri in Lp().albums.get_track_uris(album_id, [], []): path = GLib.filename_from_uri(uri)[0] dbus_helper.call( "SetCover", GLib.Variant("(ss)", (path, "%s/lollypop_cover_tags.jpg" % self._CACHE_PATH)), None, None) self.clean_album_cache(Album(album_id)) # FIXME Should be better to send all covers at once and listen # to as signal but it works like this GLib.timeout_add(2000, self.album_artwork_update, album_id) else: # Lollypop-portal or kid3-cli removed? Lp().settings.set_value("save-to-tags", GLib.Variant("b", False))
def __on_can_set_cover(self, source, result, pop): """ Remove album image from tags @param source as GObject.Object @param result as Gio.AsyncResult @param pop as int """ try: can_set_cover = source.call_finish(result) except: can_set_cover = False if can_set_cover: if pop == 0: value = 0 elif pop == 1: value = 1 elif pop == 2: value = 64 elif pop == 3: value = 128 elif pop == 4: value = 196 else: value = 255 path = GLib.filename_from_uri(self.__object.uri)[0] dbus_helper = DBusHelper() dbus_helper.call("SetPopularity", GLib.Variant("(is)", (value, path)), None, None) return True
def __save_artwork_tags(self, data, album): """ Save artwork in tags @param data as bytes @param album as Album """ if album.is_web: return # https://bugzilla.gnome.org/show_bug.cgi?id=747431 bytes = GLib.Bytes(data) stream = Gio.MemoryInputStream.new_from_bytes(bytes) bytes.unref() pixbuf = GdkPixbuf.Pixbuf.new_from_stream_at_scale( stream, ArtSize.MONSTER, ArtSize.MONSTER, True, None) stream.close() pixbuf.savev( "%s/lollypop_cover_tags.jpg" % self._CACHE_PATH, "jpeg", ["quality"], [str(Lp().settings.get_value("cover-quality").get_int32())]) f = Lio.File.new_for_path("%s/lollypop_cover_tags.jpg" % self._CACHE_PATH) if f.query_exists(): dbus_helper = DBusHelper() dbus_helper.call("CanSetCover", None, self.__on_save_artwork_tags, album.id)
def __set_outputs(self, combo): """ Set outputs in combo @parma combo as Gtk.ComboxBoxText """ renderer = combo.get_cells()[0] renderer.set_property("ellipsize", Pango.EllipsizeMode.END) renderer.set_property("max-width-chars", 60) dbus_helper = DBusHelper() dbus_helper.call("PaListSinks", None, self.__on_pa_list_sinks, combo)
def __edit_tag(self, action, variant): """ Run tag editor @param SimpleAction @param GVariant """ path = GLib.filename_from_uri(self._object.uri)[0] dbus_helper = DBusHelper() dbus_helper.call("LaunchTagEditor", GLib.Variant("(s)", (path,)), None, None)
def __edit_tags(self, args): """ Run tags editor @param args as unused """ path = GLib.filename_from_uri(self.__object.uri)[0] dbus_helper = DBusHelper() dbus_helper.call("LaunchTagEditor", GLib.Variant("(s)", (path, )), None, None) self.__button.emit("clicked")
def __init__(self, object, button): """ Init widget @param object as Track/Album @param button as Gtk.Button """ Gtk.Grid.__init__(self) self.__object = object self.__button = button # Check portal for tag editor dbus_helper = DBusHelper() dbus_helper.call("CanLaunchTagEditor", None, self.__on_can_launch_tag_editor, None) self.__edit = HoverWidget("document-properties-symbolic", self.__edit_tags) self.__edit.set_tooltip_text(_("Modify information")) self.__edit.set_margin_end(10) self.add(self.__edit) playlist = HoverWidget("view-list-symbolic", self.__show_playlist_manager) playlist.set_tooltip_text(_("Add to playlist")) playlist.show() self.add(playlist) if isinstance(self.__object, Album): if Lp().player.album_in_queue(self.__object): queue = HoverWidget("list-remove-symbolic", self.__add_to_queue) queue.set_tooltip_text(_("Remove from queue")) else: queue = HoverWidget("list-add-symbolic", self.__add_to_queue) queue.set_tooltip_text(_("Add to queue")) queue.set_margin_start(10) queue.show() self.add(queue) else: rating = RatingWidget(object) rating.set_margin_top(5) rating.set_margin_end(10) rating.set_margin_bottom(5) rating.set_property("halign", Gtk.Align.END) rating.set_property("hexpand", True) rating.show() loved = LovedWidget(object) loved.set_margin_end(5) loved.set_margin_top(5) loved.set_margin_bottom(5) loved.show() self.add(rating) self.add(loved)
def _on_button_press(self, widget, event): """ On button press, set album popularity @param widget as Gtk.EventBox @param event as Gdk.Event """ if Lp().scanner.is_locked(): return user_rating = self.__object.get_rate() != Type.NONE event_star = widget.get_children()[0] if event_star in self._stars: position = self._stars.index(event_star) else: position = -1 pop = position + 1 if pop == 0: if user_rating: self.__object.set_rate(Type.NONE) else: self.__object.set_popularity(0) elif event.button == 1: self.__object.set_rate(pop) else: self.__object.set_popularity(pop) if isinstance(self.__object, Track): Lp().player.emit("rate-changed") # Save to tags if needed # FIXME We really need a radio object # FIXME We look to kid3-cli here! if Lp().settings.get_value("save-to-tags") and\ GLib.find_program_in_path("kid3-cli") is not None and\ isinstance(self.__object, Track) and\ self.__object.id >= 0 and\ not self.__object.is_web: if pop == 0: value = 0 elif pop == 1: value = 1 elif pop == 2: value = 64 elif pop == 3: value = 128 elif pop == 4: value = 196 else: value = 255 path = GLib.filename_from_uri(self.__object.uri)[0] dbus_helper = DBusHelper() dbus_helper.call("SetPopularity", GLib.Variant("(is)", (value, path)), None, None) return True
def remove_album_artwork(self, album): """ Remove album artwork @param album as Album """ for uri in self.get_album_artworks(album): f = Lio.File.new_for_uri(uri) try: f.trash() except: f.delete(None) dbus_helper = DBusHelper() dbus_helper.call("CanSetCover", None, self.__on_remove_album_artwork, album.id)
def __init__(self, object): """ Init edit menu @param object as Album/Track """ # Ignore genre_ids/artist_ids if isinstance(object, Album): obj = Album(object.id) else: obj = Track(object.id) BaseMenu.__init__(self, obj) dbus_helper = DBusHelper() dbus_helper.call("CanLaunchTagEditor", None, self.__on_can_launch_tag_editor, None)
def __on_remove_album_artwork(self, source, result, album_id): """ Remove album image from tags @param source as GObject.Object @param result as Gio.AsyncResult @param album_id """ can_set_cover = source.call_finish(result) if Lp().settings.get_value("save-to-tags") and can_set_cover: dbus_helper = DBusHelper() for uri in Lp().albums.get_track_uris(album_id, [], []): try: path = GLib.filename_from_uri(uri)[0] dbus_helper.call("SetCover", GLib.Variant("(ss)", (path, "")), None, None) except Exception as e: print("AlbumArt::__on_remove_album_artwork():", e)
def __on_save_artwork_tags(self, source, result, album_id): """ Save image to tags @param source as GObject.Object @param result as Gio.AsyncResult @param album_id as int """ if not source.call_finish(result): return dbus_helper = DBusHelper() for uri in Lp().albums.get_track_uris(album_id, [], []): path = GLib.filename_from_uri(uri)[0] dbus_helper.call( "SetCover", GLib.Variant( "(ss)", (path, "%s/lollypop_cover_tags.jpg" % self._CACHE_PATH)), None, None) self.clean_album_cache(Album(album_id)) GLib.idle_add(self.album_artwork_update, album_id)
def _on_button_press(self, widget, event): """ On button press, set album popularity @param widget as Gtk.EventBox @param event as Gdk.Event """ if Lp().scanner.is_locked(): return user_rating = True rate = self.__object.get_rate() # -1 for compatiblity with previous release if rate in [0, -1]: rate = self.__object.get_popularity() user_rating = False max_star = self.__star_from_rate(rate) event_star = widget.get_children()[0] if event_star in self._stars: position = self._stars.index(event_star) else: position = -1 pop = position + 1 if event.button != 1: self.__object.set_popularity(pop) elif pop == 0 or pop == max_star: if user_rating: self.__object.set_rate(Type.NONE) else: self.__object.set_popularity(0) self._on_leave_notify(None, None) else: self.__object.set_rate(pop) # Save to tags if needed if Lp().settings.get_value("save-to-tags") and\ isinstance(self.__object, Track) and\ self.__object.id >= 0: dbus_helper = DBusHelper() dbus_helper.call("CanSetCover", None, self.__on_can_set_cover, pop) return True
def __init__(self): """ Init dialog """ self.__choosers = [] self.__cover_tid = None self.__mix_tid = None self.__popover = None builder = Gtk.Builder() builder.add_from_resource("/org/gnome/Lollypop/SettingsDialog.ui") self.__progress = builder.get_object("progress") self.__infobar = builder.get_object("infobar") self.__reset_button = builder.get_object("reset_button") if Lp().lastfm is None or Lp().lastfm.is_goa: builder.get_object("lastfm_grid").hide() if Lp().scanner.is_locked(): builder.get_object("reset_button").set_sensitive(False) artists = Lp().artists.count() albums = Lp().albums.count() tracks = Lp().tracks.count() builder.get_object("artists").set_text( ngettext("%d artist", "%d artists", artists) % artists) builder.get_object("albums").set_text( ngettext("%d album", "%d albums", albums) % albums) builder.get_object("tracks").set_text( ngettext("%d track", "%d tracks", tracks) % tracks) self.__popover_content = builder.get_object("popover") duration = builder.get_object("duration") duration.set_range(1, 20) duration.set_value(Lp().settings.get_value("mix-duration").get_int32()) self.__settings_dialog = builder.get_object("settings_dialog") self.__settings_dialog.set_transient_for(Lp().window) if Lp().settings.get_value("disable-csd"): self.__settings_dialog.set_title(_("Preferences")) else: headerbar = builder.get_object("header_bar") headerbar.set_title(_("Preferences")) self.__settings_dialog.set_titlebar(headerbar) switch_scan = builder.get_object("switch_scan") switch_scan.set_state(Lp().settings.get_value("auto-update")) switch_view = builder.get_object("switch_dark") if Lp().gtk_application_prefer_dark_theme: switch_view.set_sensitive(False) else: switch_view.set_state(Lp().settings.get_value("dark-ui")) switch_background = builder.get_object("switch_background") switch_background.set_state(Lp().settings.get_value("background-mode")) switch_state = builder.get_object("switch_state") switch_state.set_state(Lp().settings.get_value("save-state")) switch_mix = builder.get_object("switch_mix") switch_mix.set_state(Lp().settings.get_value("mix")) self._switch_song_notifications = builder.get_object( "switch_song_notifications", ) self._switch_song_notifications.set_state( not Lp().settings.get_value("disable-song-notifications"), ) self._switch_song_notifications.set_sensitive( not Lp().settings.get_value("disable-notifications"), ) Lp().settings.connect( "changed::disable-notifications", self._on_notifications_setting_changed, ) self.__helper = TouchHelper(switch_mix, None, None) self.__helper.set_long_func(self.__mix_long_func, switch_mix) self.__helper.set_short_func(self.__mix_short_func, switch_mix) switch_mix_party = builder.get_object("switch_mix_party") switch_mix_party.set_state(Lp().settings.get_value("party-mix")) switch_artwork_tags = builder.get_object("switch_artwork_tags") grid_behaviour = builder.get_object("grid_behaviour") # Check portal for kid3-cli dbus_helper = DBusHelper() dbus_helper.call("CanSetCover", None, self.__on_can_set_cover, (switch_artwork_tags, grid_behaviour)) if GLib.find_program_in_path("youtube-dl") is None or\ not Lp().settings.get_value("network-access"): builder.get_object("charts_grid").hide() else: switch_charts = builder.get_object("switch_charts") switch_charts.set_state(Lp().settings.get_value("show-charts")) switch_genres = builder.get_object("switch_genres") switch_genres.set_state(Lp().settings.get_value("show-genres")) switch_compilations = builder.get_object("switch_compilations") switch_compilations.set_state( Lp().settings.get_value("show-compilations")) switch_artwork = builder.get_object("switch_artwork") switch_artwork.set_state(Lp().settings.get_value("artist-artwork")) switch_spotify = builder.get_object("switch_spotify") switch_spotify.set_state(Lp().settings.get_value("search-spotify")) switch_itunes = builder.get_object("switch_itunes") switch_itunes.set_state(Lp().settings.get_value("search-itunes")) if GLib.find_program_in_path("youtube-dl") is None: builder.get_object("yt-dl").show() combo_orderby = builder.get_object("combo_orderby") combo_orderby.set_active(Lp().settings.get_enum(("orderby"))) combo_preview = builder.get_object("combo_preview") scale_coversize = builder.get_object("scale_coversize") scale_coversize.set_range(150, 300) scale_coversize.set_value( Lp().settings.get_value("cover-size").get_int32()) self.__settings_dialog.connect("destroy", self.__edit_settings_close) builder.connect_signals(self) main_chooser_box = builder.get_object("main_chooser_box") self.__chooser_box = builder.get_object("chooser_box") self.__set_outputs(combo_preview) # # Music tab # dirs = [] for directory in Lp().settings.get_value("music-uris"): dirs.append(directory) # Main chooser self.__main_chooser = ChooserWidget() image = Gtk.Image.new_from_icon_name("list-add-symbolic", Gtk.IconSize.MENU) self.__main_chooser.set_icon(image) self.__main_chooser.set_action(self.__add_chooser) main_chooser_box.pack_start(self.__main_chooser, False, True, 0) if len(dirs) > 0: uri = dirs.pop(0) else: filename = GLib.get_user_special_dir( GLib.UserDirectory.DIRECTORY_MUSIC) if filename: uri = GLib.filename_to_uri(filename) else: uri = "" self.__main_chooser.set_dir(uri) # Others choosers for directory in dirs: self.__add_chooser(directory) # # Google tab # key = Lp().settings.get_value("cs-api-key").get_string() or\ Lp().settings.get_default_value("cs-api-key").get_string() builder.get_object("cs-entry").set_text(key) from lollypop.helper_passwords import PasswordsHelper helper = PasswordsHelper() # # Last.fm tab # if Lp().lastfm is not None: self.__lastfm_test_image = builder.get_object("lastfm_test_image") self.__lastfm_login = builder.get_object("lastfm_login") self.__lastfm_password = builder.get_object("lastfm_password") helper.get("lastfm", self.__on_get_password) builder.get_object("lastfm_grid").set_sensitive(True) builder.get_object("lastfm_error_label").hide() # # Libre.fm tab # if Lp().librefm is not None: self.__librefm_test_image = builder.get_object( "librefm_test_image") self.__librefm_login = builder.get_object("librefm_login") self.__librefm_password = builder.get_object("librefm_password") helper.get("librefm", self.__on_get_password) builder.get_object("librefm_grid").set_sensitive(True) builder.get_object("librefm_error_label").hide()
def __init__(self, object, button): """ Init widget @param object as Track/Album @param button as Gtk.Button """ Gtk.Grid.__init__(self) self.__object = object self.__button = button if self.__object.is_web: if Type.CHARTS in self.__object.genre_ids: if isinstance(self.__object, Album): save = HoverWidget("document-save-symbolic", self.__save_object) save.set_tooltip_text(_("Save into collection")) save.set_margin_end(10) save.show() self.add(save) else: trash = HoverWidget("user-trash-symbolic", self.__remove_object) if isinstance(self.__object, Album): trash.set_tooltip_text(_("Remove album")) else: trash.set_tooltip_text(_("Remove track")) trash.set_margin_end(10) trash.show() self.add(trash) else: # Check portal for tag editor dbus_helper = DBusHelper() dbus_helper.call("CanLaunchTagEditor", None, self.__on_can_launch_tag_editor, None) self.__edit = HoverWidget("document-properties-symbolic", self.__edit_tags) self.__edit.set_tooltip_text(_("Modify information")) self.__edit.set_margin_end(10) self.add(self.__edit) if Type.CHARTS not in self.__object.genre_ids: playlist = HoverWidget("view-list-symbolic", self.__show_playlist_manager) playlist.set_tooltip_text(_("Add to playlist")) playlist.show() self.add(playlist) if isinstance(self.__object, Album): if Lp().player.album_in_queue(self.__object): queue = HoverWidget("list-remove-symbolic", self.__add_to_queue) queue.set_tooltip_text(_("Remove from queue")) else: queue = HoverWidget("list-add-symbolic", self.__add_to_queue) queue.set_tooltip_text(_("Add to queue")) queue.set_margin_start(10) queue.show() self.add(queue) else: if self.__object.is_web: web = Gtk.LinkButton(self.__object.uri) icon = Gtk.Image.new_from_icon_name("web-browser-symbolic", Gtk.IconSize.MENU) web.set_image(icon) web.get_style_context().add_class("no-padding") web.set_margin_start(5) web.set_tooltip_text(self.__object.uri) web.show_all() uri = "https://www.youtube.com/results?search_query=%s" %\ (self.__object.artists[0] + " " + self.__object.name,) search = Gtk.LinkButton(uri) icon = Gtk.Image.new_from_icon_name("edit-find-symbolic", Gtk.IconSize.MENU) search.set_image(icon) search.get_style_context().add_class("no-padding") search.set_tooltip_text(uri) search.show_all() self.add(web) self.add(search) if Type.CHARTS not in self.__object.genre_ids: rating = RatingWidget(object) rating.set_margin_top(5) rating.set_margin_end(10) rating.set_margin_bottom(5) rating.set_property("halign", Gtk.Align.END) rating.set_property("hexpand", True) rating.show() loved = LovedWidget(object) loved.set_margin_end(5) loved.set_margin_top(5) loved.set_margin_bottom(5) loved.show() self.add(rating) self.add(loved)