Merge pull request #1374 from tpikonen/channel-buttons

channel editor: Add buttons next to cover, feed URL, etc.
This commit is contained in:
auouymous 2022-11-08 04:46:23 +00:00 committed by GitHub
commit 98208d4444
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 180 additions and 62 deletions

View File

@ -101,26 +101,47 @@
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-left">16</property>
<property name="margin-right">16</property>
<property name="border-width">8</property>
<property name="orientation">vertical</property>
<property name="spacing">8</property>
<child>
<object class="GtkEventBox" id="imgCoverEventBox">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<child type="center">
<object class="GtkImage" id="imgCover">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-left">16</property>
<property name="margin-right">16</property>
<property name="margin-start">16</property>
<property name="margin-end">16</property>
<property name="xalign">0.5</property>
<property name="pixel-size">80</property>
<property name="icon_size">6</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkMenuButton" id="cover_menubutton">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="valign">center</property>
<property name="relief">none</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">view-more-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack-type">end</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
@ -179,9 +200,6 @@
</packing>
</child>
</object>
<packing>
<property name="name">page0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="title_edit_box">
@ -212,8 +230,8 @@
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="use-underline">True</property>
<property name="valign">center</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="on_title_save_button_clicked" swapped="no"/>
</object>
<packing>
@ -239,6 +257,8 @@
<object class="GtkLabel" id="channel_description">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">16</property>
<property name="margin-end">16</property>
<property name="margin-bottom">4</property>
<property name="label">Channel description</property>
<property name="wrap">True</property>
@ -305,14 +325,40 @@
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Feed URL&lt;/b&gt;</property>
<property name="use-markup">True</property>
<property name="xalign">0</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Feed URL&lt;/b&gt;</property>
<property name="use-markup">True</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="labelURL">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label">URL</property>
<property name="selectable">True</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -321,17 +367,25 @@
</packing>
</child>
<child>
<object class="GtkLabel" id="labelURL">
<object class="GtkButton" id="feed_url_copy_button">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label">URL</property>
<property name="selectable">True</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="valign">center</property>
<property name="relief">none</property>
<signal name="clicked" handler="on_feed_url_copy_button_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">edit-copy-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="fill">False</property>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>
@ -346,14 +400,42 @@
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Download location&lt;/b&gt;</property>
<property name="use-markup">True</property>
<property name="xalign">0</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Download location&lt;/b&gt;</property>
<property name="use-markup">True</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="LabelDownloadTo">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">False</property>
<property name="label">download dir</property>
<property name="selectable">True</property>
<property name="ellipsize">start</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -362,19 +444,25 @@
</packing>
</child>
<child>
<object class="GtkLabel" id="LabelDownloadTo">
<object class="GtkButton" id="open_folder_button">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">False</property>
<property name="label">download dir</property>
<property name="selectable">True</property>
<property name="ellipsize">start</property>
<property name="xalign">0</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="valign">center</property>
<property name="relief">none</property>
<signal name="clicked" handler="on_open_folder_button_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">folder-open-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="fill">False</property>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>

View File

@ -25,6 +25,8 @@
import logging
import os
import shutil
import urllib.parse
import gpodder
from gpodder import util, youtube
@ -67,6 +69,31 @@ class CoverDownloader(object):
if os.path.exists(filename + extension):
return filename + extension
# Handle local files
if cover_url is not None and cover_url.startswith('file://'):
try:
path = urllib.parse.unquote(cover_url).replace('file://', '')
if not os.path.exists(path):
raise ValueError('Cover file not found: %s' % (path))
extension = None
with open(path, 'rb') as fp:
data = fp.read(512)
for filetype, check in list(self.SUPPORTED_EXTENSIONS.items()):
if check(data):
extension = filetype
break
if extension is None:
raise ValueError(
'Unknown file type: %s (%r)' % (cover_url, data[:6]))
# File is ok, copy it
shutil.copyfile(path, filename + extension)
return filename + extension
except Exception as e:
logger.warning('Setting cover art from file failed: %s', e)
return self._fallback_filename(title)
# If allowed to download files, do so here
if download:
# YouTube-specific cover art image resolver

View File

@ -17,7 +17,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from gi.repository import Gdk, GdkPixbuf, Gtk
from gi.repository import Gdk, Gio, Gtk
import gpodder
from gpodder import util
@ -74,6 +74,22 @@ class gPodderChannel(BuilderWidget):
if self.channel.auth_password:
self.FeedPassword.set_text(self.channel.auth_password)
# Cover image
ag = Gio.SimpleActionGroup()
open_cover_action = Gio.SimpleAction.new("openCover", None)
open_cover_action.connect('activate', self.on_open_cover_activate)
ag.add_action(open_cover_action)
refresh_cover_action = Gio.SimpleAction.new("refreshCover", None)
refresh_cover_action.connect('activate', self.on_refresh_cover_activate)
ag.add_action(refresh_cover_action)
self.main_window.insert_action_group("channel", ag)
cover_menu = Gio.Menu()
cover_menu.append("Change cover image", "channel.openCover")
cover_menu.append("Refresh image", "channel.refreshCover")
self.cover_menubutton.set_menu_model(cover_menu)
self.cover_downloader.register('cover-available', self.cover_download_finished)
self.cover_downloader.request_cover(self.channel)
@ -92,8 +108,6 @@ class gPodderChannel(BuilderWidget):
border = 6
size = self.MAX_SIZE + border * 2
self.imgCover.set_size_request(size, size)
self.imgCoverEventBox.connect('button-press-event',
self.on_cover_popup_menu)
# Title save button state
self.title_save_button_saves = True
@ -123,25 +137,7 @@ class gPodderChannel(BuilderWidget):
self.section_list.append([text])
self.combo_section.set_active(len(self.section_list) - 1)
def on_cover_popup_menu(self, widget, event):
if not event.triggers_context_menu():
return
menu = Gtk.Menu()
item = Gtk.MenuItem.new_with_mnemonic(_('_Open'))
item.connect('activate', self.on_btnDownloadCover_clicked)
menu.append(item)
item = Gtk.MenuItem.new_with_mnemonic(_('_Refresh'))
item.connect('activate', self.on_btnClearCover_clicked)
menu.append(item)
menu.attach_to_widget(widget)
menu.show_all()
menu.popup(None, None, None, None, event.button, event.time)
def on_btnDownloadCover_clicked(self, widget):
def on_open_cover_activate(self, action, *args):
dlg = Gtk.FileChooserDialog(
title=_('Select new podcast cover artwork'),
parent=self.gPodderChannel,
@ -156,7 +152,7 @@ class gPodderChannel(BuilderWidget):
dlg.destroy()
def on_btnClearCover_clicked(self, widget):
def on_refresh_cover_activate(self, action, *args):
self.clear_cover_cache(self.channel.url)
self.cover_downloader.replace_cover(self.channel, custom_url=False)
@ -217,6 +213,13 @@ class gPodderChannel(BuilderWidget):
self.title_label.set_text(self.title_entry.get_text())
self.title_stack.set_visible_child(self.title_box)
def on_feed_url_copy_button_clicked(self, button):
clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
clipboard.set_text(self.channel.url, -1)
def on_open_folder_button_clicked(self, button):
util.gui_open(self.channel.save_dir, gui=self)
def on_row_activated(self, listbox, row, *args):
# Find the correct widget in the row to activate
def _do(w, *args):