Merge tag 'merge2' into dev-adaptive

This commit is contained in:
Teemu Ikonen 2022-02-04 10:56:20 +02:00
commit 28c5774f89
15 changed files with 214 additions and 152 deletions

View File

@ -33,7 +33,7 @@ import os.path
import platform
import subprocess
import sys
from optparse import OptionParser
from optparse import OptionGroup, OptionParser
logger = logging.getLogger(__name__)
@ -83,6 +83,9 @@ def main():
gpodder.prefix = prefix
# Package managers can install the empty file {prefix}/share/gpodder/no-update-check to disable update checks
gpodder.no_update_check_file = os.path.join(prefix, 'share', 'gpodder', 'no-update-check')
# Enable i18n for gPodder translations
_ = gpodder.gettext
@ -97,21 +100,34 @@ def main():
parser = OptionParser(usage=s_usage, version=s_version)
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose", default=False,
help=_("print logging output on the console"))
grp_subscriptions = OptionGroup(parser, "Subscriptions")
parser.add_option_group(grp_subscriptions)
parser.add_option("-q", "--quiet",
action="store_true", dest="quiet", default=False,
help=_("reduce warnings on the console"))
grp_subscriptions.add_option('-s', '--subscribe', dest='subscribe',
metavar='URL',
help=_('subscribe to the feed at URL'))
parser.add_option('-s', '--subscribe', dest='subscribe', metavar='URL',
help=_('subscribe to the feed at URL'))
grp_logging = OptionGroup(parser, "Logging")
parser.add_option_group(grp_logging)
grp_logging.add_option("-v", "--verbose",
action="store_true", dest="verbose", default=False,
help=_("print logging output on the console"))
grp_logging.add_option("-q", "--quiet",
action="store_true", dest="quiet", default=False,
help=_("reduce warnings on the console"))
grp_advanced = OptionGroup(parser, "Advanced")
parser.add_option_group(grp_advanced)
grp_advanced.add_option("--close-after-startup", action="store_true",
help=_("exit once started up (for profiling)"))
# On Mac OS X, support the "psn" parameter for compatibility (bug 939)
if gpodder.ui.osx:
parser.add_option('-p', '--psn', dest='macpsn', metavar='PSN',
help=_('Mac OS X application process number'))
grp_advanced.add_option('-p', '--psn', dest='macpsn', metavar='PSN',
help=_('Mac OS X application process number'))
options, args = parser.parse_args(sys.argv)

View File

@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: gPodder\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-07-19 22:46-0600\n"
"PO-Revision-Date: 2021-01-02 02:30+0100\n"
"PO-Revision-Date: 2021-08-23 01:23+0200\n"
"Last-Translator: TZocker\n"
"Language-Team: German (http://www.transifex.com/projects/p/gpodder/language/"
"de/)\n"
@ -18,7 +18,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.3\n"
"X-Generator: Poedit 2.4.2\n"
#: src/gpodder/config.py:53
#, python-format
@ -95,10 +95,8 @@ msgid "Paused"
msgstr "Pause"
#: src/gpodder/download.py:864
#, fuzzy
#| msgid "Select the episodes you want to download:"
msgid "Episode has no URL to download"
msgstr "Wählen Sie die Episoden, die Sie herunterladen möchten:"
msgstr "Episode hat keine URL zum Herunterladen"
#: src/gpodder/download.py:867
msgid "Missing content from server"
@ -538,16 +536,12 @@ msgid "Released"
msgstr "Veröffentlicht"
#: src/gpodder/gtkui/main.py:871
#, fuzzy
#| msgid "Size"
msgid "Size+"
msgstr "Größe"
msgstr "Größe+"
#: src/gpodder/gtkui/main.py:879
#, fuzzy
#| msgid "Duration"
msgid "Duration+"
msgstr "Dauer"
msgstr "Dauer+"
#: src/gpodder/gtkui/main.py:1036 src/gpodder/gtkui/main.py:1185
#: share/gpodder/ui/gtk/gpodder.ui.h:11
@ -718,10 +712,8 @@ msgid "Archive"
msgstr "Archivieren"
#: src/gpodder/gtkui/main.py:1718
#, fuzzy
#| msgid "_Refresh"
msgid "Refresh image"
msgstr "Aktualisierung"
msgstr "Bild aktualisieren"
#: src/gpodder/gtkui/main.py:1722
msgid "Delete podcast"
@ -1306,22 +1298,26 @@ msgid "Subscription paused"
msgstr "Abonnement pausiert"
#: src/gpodder/gtkui/shownotes.py:60
#, python-format
#, fuzzy, python-format
msgid "%(date)s | %(size)s | %(duration)s"
msgstr ""
msgstr "%(date)s | %(size)s | %(duration)s"
#: src/gpodder/gtkui/shownotes.py:147
msgid "Please select an episode"
msgstr "Bitte eine Episode auswählen"
#: src/gpodder/gtkui/shownotes.py:313
#, python-format
#, fuzzy, python-format
msgid ""
"<div id=\"gpodder-title\">\n"
"%(heading)s\n"
"<p>%(subheading)s</p>\n"
"<p>%(details)s</p></div>\n"
msgstr ""
"<div id=\"gpodder-title\">\n"
"%(heading)s\n"
"<p>%(subheading)s</p>\n"
"<p>%(details)s</p></div>\n"
#: src/gpodder/gtkui/shownotes.py:356
msgid "Open shownotes in web browser"
@ -1431,7 +1427,7 @@ msgstr "Sie können nur lokale Dateien und http:// URLs hier her ziehen."
#: src/gpodder/gtkui/desktop/channel.py:223
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:5
msgid "Save"
msgstr ""
msgstr "Speichern"
#: src/gpodder/gtkui/desktop/episodeselector.py:104
msgid "Remove"
@ -1770,6 +1766,9 @@ msgid ""
"the values they had before. The changes are saved immediately after they are "
"made."
msgstr ""
"<b>Hinweis:</b> Die Schaltfläche \"Abbrechen\" setzt die Filtereinstellungen "
"<b>nicht</b> auf die Werte zurück, die sie zuvor hatten. Die Änderungen "
"werden sofort nach der Durchführung gespeichert."
#: share/gpodder/extensions/filter.py:150
msgid "Block"
@ -1793,18 +1792,12 @@ msgstr ""
"blockieren und dann einige zu entsperren."
#: share/gpodder/extensions/filter.py:175
#, fuzzy
#| msgid "Filter Episodes"
msgid "Filter episodes now"
msgstr "Filter Episoden"
msgstr "Folgen jetzt filtern"
#: share/gpodder/extensions/filter.py:179
#, fuzzy
#| msgid "Filter episodes now (undoes any episodes you marked as old)"
msgid "Undoes any episodes you marked as old."
msgstr ""
"Filtert Episoden (macht alle Episoden rückgängig, die Sie als gespielt "
"markiert haben)"
msgstr "Macht alle Folgen rückgängig, die Sie als gespielt markiert haben"
#: share/gpodder/extensions/gtk_statusicon.py:19
msgid "Gtk Status Icon"
@ -1964,17 +1957,17 @@ msgid "Manage Youtube subscriptions using youtube-dl (pip install youtube_dl)"
msgstr "Verwaltung von Youtube Abos mit youtube-dl (pip install youtube_dl)"
#: share/gpodder/extensions/youtube-dl.py:33
#, python-format
#, fuzzy, python-format
msgid ""
"Your version of youtube-dl %(have_version)s has known issues, please upgrade "
"to %(want_version)s or newer."
msgstr ""
"Ihre Version von youtube-dl %(have_version) weist bekannte Probleme auf. "
"Bitte aktualisieren Sie auf %(want_version) oder neuer."
#: share/gpodder/extensions/youtube-dl.py:485
#, fuzzy
#| msgid "Download with Youtube-DL"
msgid "Old Youtube-DL"
msgstr "Download mit Youtube Link"
msgstr "Alte Youtube-DL Version"
#: share/gpodder/extensions/youtube-dl.py:490
msgid "Download with Youtube-DL"
@ -2016,45 +2009,39 @@ msgstr "Neuen Podcast hinzufügen"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:1
msgid "Channel Editor"
msgstr ""
msgstr "Kanal-Editor"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:3
msgid "OK"
msgstr ""
msgstr "OK"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:4
msgid "page0"
msgstr ""
msgstr "Seite 0"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:6
msgid "page1"
msgstr ""
msgstr "Seite 1"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:7
msgid "<b>Feed URL</b>"
msgstr ""
msgstr "<b>Feed-URL</b>"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:8
#, fuzzy
#| msgid "<b>Locations</b>"
msgid "<b>Download location</b>"
msgstr "<b>Orte</b>"
msgstr "<b>Speicherort</b>"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:9
msgid "Info"
msgstr ""
msgstr "Info"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:10
#, fuzzy
#| msgid "No subscriptions"
msgid "Pause subscription"
msgstr "Keine Abonnements"
msgstr "Abonnement pausieren"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:11
#, fuzzy
#| msgid "Synchronize to MP3 player devices"
msgid "Sync to player devices"
msgstr "Mit portablen MP3-Playern synchronisieren"
msgstr "Mit Abspielgeräten synchronisieren"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:12
msgid "Section:"
@ -2079,10 +2066,8 @@ msgid "Password:"
msgstr "Passwort:"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:17
#, fuzzy
#| msgid "Setting"
msgid "Settings"
msgstr "Einstellung"
msgstr "Einstellungen"
#: share/gpodder/ui/gtk/gpodderconfigeditor.ui.h:1
msgid "gPodder Configuration Editor"
@ -2121,10 +2106,8 @@ msgid "Select None"
msgstr "Nichts auswählen"
#: share/gpodder/ui/gtk/gpodderpodcastdirectory.ui.h:7
#, fuzzy
#| msgid "Added"
msgid "Add"
msgstr "Hinzugefügt"
msgstr "hinzufügen"
#: share/gpodder/ui/gtk/gpodderpreferences.ui.h:2
msgid "Video player:"
@ -2193,6 +2176,8 @@ msgstr "Bei neuen Episoden:"
#: share/gpodder/ui/gtk/gpodderpreferences.ui.h:22
msgid "Check connection before updating (if supported)"
msgstr ""
"Vor dem Aktualisieren soll die Verbindung überprüft werden(falls "
"unterstützt)"
#: share/gpodder/ui/gtk/gpodderpreferences.ui.h:23
msgid "Updating"
@ -2324,7 +2309,7 @@ msgstr "Episoden"
#: share/gpodder/ui/gtk/menus.ui.h:26
msgid "Toggle new status"
msgstr "Als \"Neu\" markieren"
msgstr "Als \"gespielt\" markieren"
#: share/gpodder/ui/gtk/menus.ui.h:27
msgid "Change delete lock"
@ -2344,7 +2329,7 @@ msgstr "Ansicht"
#: share/gpodder/ui/gtk/menus.ui.h:33
msgid "Toolbar"
msgstr "Toolbar"
msgstr "Werkzeugleiste"
#: share/gpodder/ui/gtk/menus.ui.h:34
msgid "Episode descriptions"

View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: gPodder\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-07-19 22:46-0600\n"
"PO-Revision-Date: 2021-07-09 13:37+0200\n"
"PO-Revision-Date: 2021-08-20 13:37+0200\n"
"Last-Translator: Thomas Perl <m@thp.io>\n"
"Language-Team: Slovak (http://www.transifex.com/projects/p/gpodder/language/"
"sk/)\n"
@ -1428,7 +1428,7 @@ msgstr "Sem môžete umiestniť iba lokálne súbory a http:// adresy."
#: src/gpodder/gtkui/desktop/channel.py:223
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:5
msgid "Save"
msgstr ""
msgstr "Uložiť"
#: src/gpodder/gtkui/desktop/episodeselector.py:104
msgid "Remove"
@ -1767,6 +1767,8 @@ msgid ""
"the values they had before. The changes are saved immediately after they are "
"made."
msgstr ""
"<b>Poznámka:</b> Tlačidlo Zrušiť <b>nevráti</b> nastavenia filtra na "
"predchádzajúce hodnoty. Zmeny budú uložené ihneď po ich vykonaní."
#: share/gpodder/extensions/filter.py:150
msgid "Block"
@ -1790,16 +1792,12 @@ msgstr ""
"odblokovanie niektorých)."
#: share/gpodder/extensions/filter.py:175
#, fuzzy
#| msgid "Filter Episodes"
msgid "Filter episodes now"
msgstr "Filtrovať epizódy"
#: share/gpodder/extensions/filter.py:179
#, fuzzy
#| msgid "Filter episodes now (undoes any episodes you marked as old)"
msgid "Undoes any episodes you marked as old."
msgstr "Filtrovať epizódy (vráti späť označenie epizód ako staré)"
msgstr "Vráti späť označenie epizód ako staré."
#: share/gpodder/extensions/gtk_statusicon.py:19
msgid "Gtk Status Icon"
@ -2012,7 +2010,7 @@ msgstr "Pridať nový podcast"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:1
msgid "Channel Editor"
msgstr ""
msgstr "Editor zdrojov"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:3
msgid "OK"
@ -2020,37 +2018,31 @@ msgstr ""
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:4
msgid "page0"
msgstr ""
msgstr "strana0"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:6
msgid "page1"
msgstr ""
msgstr "strana1"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:7
msgid "<b>Feed URL</b>"
msgstr ""
msgstr "<b>URL zdroja</b>"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:8
#, fuzzy
#| msgid "<b>Locations</b>"
msgid "<b>Download location</b>"
msgstr "<b>Umiestnenia</b>"
msgstr "<b>Umiestnenie sťahovania</b>"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:9
msgid "Info"
msgstr ""
msgstr "Informácie"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:10
#, fuzzy
#| msgid "No subscriptions"
msgid "Pause subscription"
msgstr "Žiadne odbery"
msgstr "Pozastaviť odber"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:11
#, fuzzy
#| msgid "Synchronize to MP3 player devices"
msgid "Sync to player devices"
msgstr "Synchronizovať s MP3 prehrávačmi"
msgstr "Synchronizovať s prehrávačmi"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:12
msgid "Section:"
@ -2075,10 +2067,8 @@ msgid "Password:"
msgstr "Heslo:"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:17
#, fuzzy
#| msgid "Setting"
msgid "Settings"
msgstr "Nastavenie"
msgstr "Nastavenia"
#: share/gpodder/ui/gtk/gpodderconfigeditor.ui.h:1
msgid "gPodder Configuration Editor"

View File

@ -1,14 +1,14 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# Serkan ÖNDER <serkanonder@outlook.com>, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: gPodder 3.10.15\n"
"Project-Id-Version: gPodder 3.10.21\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-07-19 22:46-0600\n"
"PO-Revision-Date: 2021-03-12 18:39+0300\n"
"PO-Revision-Date: 2021-08-12 23:49+0300\n"
"Last-Translator: Serkan ÖNDER <serkanonder@outlook.com>\n"
"Language-Team: \n"
"Language: tr\n"
@ -1417,7 +1417,7 @@ msgstr "Buraya yalnızca yerel dosyaları ve http:// URL'leri bırakabilirsiniz.
#: src/gpodder/gtkui/desktop/channel.py:223
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:5
msgid "Save"
msgstr ""
msgstr "Kaydet"
#: src/gpodder/gtkui/desktop/episodeselector.py:104
msgid "Remove"
@ -1747,6 +1747,8 @@ msgid ""
"the values they had before. The changes are saved immediately after they are "
"made."
msgstr ""
"<b>Not:</b> İptal düğmesi, filtre ayarlarını daha önce sahip oldukları "
"değerlere <b>döndürmez</b>. Değişiklikler yapıldıktan hemen sonra kaydedilir."
#: share/gpodder/extensions/filter.py:150
msgid "Block"
@ -1770,18 +1772,12 @@ msgstr ""
"bazılarının engelini kaldırmak için)."
#: share/gpodder/extensions/filter.py:175
#, fuzzy
#| msgid "Filter Episodes"
msgid "Filter episodes now"
msgstr "Bölümleri Filtrele"
msgstr "Bölümleri şimdi filtrele"
#: share/gpodder/extensions/filter.py:179
#, fuzzy
#| msgid "Filter episodes now (undoes any episodes you marked as old)"
msgid "Undoes any episodes you marked as old."
msgstr ""
"Bölümleri şimdi filtrele (eski olarak işaretlediğiniz tüm bölümleri geri "
"alır)"
msgstr "Eski olarak işaretlediğiniz bölümleri geri alır."
#: share/gpodder/extensions/gtk_statusicon.py:19
msgid "Gtk Status Icon"
@ -1996,45 +1992,39 @@ msgstr "Yeni bir podcast ekle"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:1
msgid "Channel Editor"
msgstr ""
msgstr "Kanal Düzenleyici"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:3
msgid "OK"
msgstr ""
msgstr "TAMAM"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:4
msgid "page0"
msgstr ""
msgstr "sayfa0"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:6
msgid "page1"
msgstr ""
msgstr "sayfa1"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:7
msgid "<b>Feed URL</b>"
msgstr ""
msgstr "<b>Besleme URL'si</b>"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:8
#, fuzzy
#| msgid "<b>Locations</b>"
msgid "<b>Download location</b>"
msgstr "<b>Konumlar</b>"
msgstr "<b>İndirme konumu</b>"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:9
msgid "Info"
msgstr ""
msgstr "Bilgi"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:10
#, fuzzy
#| msgid "No subscriptions"
msgid "Pause subscription"
msgstr "Abonelik yok"
msgstr "Aboneliği duraklat"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:11
#, fuzzy
#| msgid "Synchronize to MP3 player devices"
msgid "Sync to player devices"
msgstr "MP3 oynatıcı cihazlarıyla senkronize edin"
msgstr "Oynatıcı cihazlarıyla senkronize et"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:12
msgid "Section:"
@ -2059,8 +2049,6 @@ msgid "Password:"
msgstr "Şifre:"
#: share/gpodder/ui/gtk/gpodderchannel.ui.h:17
#, fuzzy
#| msgid "Setting"
msgid "Settings"
msgstr "Ayarlar"

View File

@ -166,6 +166,8 @@ prefix = None
ENV_HOME, ENV_DOWNLOADS = 'GPODDER_HOME', 'GPODDER_DOWNLOAD_DIR'
no_update_check_file = None
# Function to set a new gPodder home folder
def set_home(new_home):

View File

@ -290,7 +290,10 @@ class gPodderApplication(Gtk.Application):
self.window.mygpo_client.open_website()
def on_check_for_updates_activate(self, action, param):
self.window.check_for_updates(silent=False)
if os.path.exists(gpodder.no_update_check_file):
self.window.check_for_distro_updates()
else:
self.window.check_for_updates(silent=False)
def on_extension_enabled(self, extension):
self.window.on_extension_enabled(extension)

View File

@ -164,7 +164,7 @@ class gPodderChannel(BuilderWidget):
def set_cover(channel, pixbuf):
if self.channel == channel:
if pixbuf is not None:
self.imgCover.set_from_pixbuf(self.scale_pixbuf(pixbuf))
self.imgCover.set_from_pixbuf(util.scale_pixbuf(pixbuf, self.MAX_SIZE))
if self.show_on_cover_load:
self.main_window.show()
self.show_on_cover_load = False
@ -193,22 +193,6 @@ class gPodderChannel(BuilderWidget):
def on_gPodderChannel_destroy(self, widget, *args):
self.cover_downloader.unregister('cover-available', self.cover_download_finished)
def scale_pixbuf(self, pixbuf):
# Resize if width is too large
if pixbuf.get_width() > self.MAX_SIZE:
f = float(self.MAX_SIZE) / pixbuf.get_width()
(width, height) = (int(pixbuf.get_width() * f), int(pixbuf.get_height() * f))
pixbuf = pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.BILINEAR)
# Resize if height is too large
if pixbuf.get_height() > self.MAX_SIZE:
f = float(self.MAX_SIZE) / pixbuf.get_height()
(width, height) = (int(pixbuf.get_width() * f), int(pixbuf.get_height() * f))
pixbuf = pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.BILINEAR)
return pixbuf
# Title editing callbacks
def on_title_edit_button_clicked(self, button):
self.title_save_button_saves = True

View File

@ -462,13 +462,11 @@ class gPodderPreferences(BuilderWidget):
if not container or not model:
return
# This is one ugly hack, but it displays the attributes of
# the metadata object of the container..
info = '\n'.join('<b>%s:</b> %s' %
tuple(map(html.escape, list(map(str, (key, value)))))
for key, value in container.metadata.get_sorted())
info = '\n'.join('<b>{}:</b> {}'.format(html.escape(key), html.escape(value))
for key, value in container.metadata.get_sorted()
if key not in ('title', 'description'))
self.show_message(info, _('Extension module info'), important=True)
self.show_message_details(container.metadata.title, container.metadata.description, info)
def open_weblink(self, w, url):
util.open_website(url)

View File

@ -34,10 +34,11 @@ _ = gpodder.gettext
def show_message_dialog(parent, message, title=None):
dlg = Gtk.MessageDialog(parent, Gtk.DialogFlags.MODAL, Gtk.MessageType.INFO, Gtk.ButtonsType.OK)
if title:
dlg.set_title(str(title))
dlg.set_markup('<span weight="bold" size="larger">%s</span>\n\n%s' % (title, message))
dlg.set_title(title)
dlg.set_property('text', title)
dlg.format_secondary_text(message)
else:
dlg.set_markup('<span weight="bold" size="larger">%s</span>' % (message))
dlg.set_property('text', message)
# make message copy/pastable
for lbl in dlg.get_message_area():
if isinstance(lbl, Gtk.Label):
@ -80,6 +81,37 @@ class BuilderWidget(GtkBuilderWidget):
"""Return a Gtk.Window that should be the parent of dialogs"""
return self.main_window
def show_message_details(self, title, message, details):
dlg = Gtk.MessageDialog(self.main_window, Gtk.DialogFlags.MODAL, Gtk.MessageType.INFO, Gtk.ButtonsType.OK)
dlg.set_title(title)
dlg.set_property('text', title)
dlg.format_secondary_text(message)
# make message copy/pastable
for lbl in dlg.get_message_area():
if isinstance(lbl, Gtk.Label):
lbl.set_halign(Gtk.Align.START)
lbl.set_selectable(True)
tv = Gtk.TextView()
tv.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)
tv.set_border_width(10)
tv.set_editable(False)
tb = Gtk.TextBuffer()
tb.insert_markup(tb.get_start_iter(), details, -1)
tv.set_buffer(tb)
tv.set_property('expand', True)
sw = Gtk.ScrolledWindow()
sw.set_size_request(400, 200)
sw.set_property('shadow-type', Gtk.ShadowType.IN)
sw.add(tv)
sw.show_all()
dlg.get_message_area().add(sw)
dlg.get_widget_for_response(Gtk.ResponseType.OK).grab_focus()
dlg.run()
dlg.destroy()
def show_message(self, message, title=None, important=False, widget=None):
if important:
show_message_dialog(self.main_window, message, title)

View File

@ -23,6 +23,7 @@ import logging
import os
import re
import shutil
import sys
import tempfile
import threading
import time
@ -310,7 +311,13 @@ class gPodder(BuilderWidget, dbus.service.Object):
diff = time.time() - self.config.software_update.last_check
if diff > (60 * 60 * 24) * self.config.software_update.interval:
self.config.software_update.last_check = int(time.time())
self.check_for_updates(silent=True)
if not os.path.exists(gpodder.no_update_check_file):
self.check_for_updates(silent=True)
if self.options.close_after_startup:
logger.warning("Startup done, closing (--close-after-startup)")
self.core.db.close()
sys.exit()
def create_actions(self):
g = self.gPodder
@ -2743,11 +2750,10 @@ class gPodder(BuilderWidget, dbus.service.Object):
# Report failed subscriptions to the user
if failed:
title = _('Could not add some podcasts')
message = _('Some podcasts could not be added to your list:') \
+ '\n\n' + '\n'.join(
html.escape('%s: %s' % (
url, error_messages.get(url, _('Unknown')))) for url in failed)
self.show_message(message, title, important=True)
message = _('Some podcasts could not be added to your list:')
details = '\n\n'.join('<b>{}</b>:\n{}'.format(html.escape(url),
html.escape(error_messages.get(url, _('Unknown')))) for url in failed)
self.show_message_details(title, message, details)
# Upload subscription changes to gpodder.net
self.mygpo_client.on_subscribe(worked)
@ -3750,6 +3756,11 @@ class gPodder(BuilderWidget, dbus.service.Object):
def on_homepage_activate(self, widget, *args):
util.open_website(gpodder.__url__)
def check_for_distro_updates(self):
title = _('Managed by distribution')
message = _('Please check your distribution for gPodder updates.')
self.show_message(message, title, important=True)
def check_for_updates(self, silent):
"""Check for updates and (optionally) show a message

View File

@ -169,9 +169,17 @@ class PodcastParserFeed(Feed):
# Detect (and update) existing episode based on GUIDs
existing_episode = existing_guids.get(episode.guid, None)
if existing_episode:
if existing_episode.total_time == 0 and 'youtube' in episode.url:
# query duration for existing youtube episodes that haven't been downloaded or queried
# such as live streams after they have ended
existing_episode.total_time = youtube.get_total_time(episode)
existing_episode.update_from(episode)
existing_episode.save()
continue
elif episode.total_time == 0 and 'youtube' in episode.url:
# query duration for new youtube episodes
episode.total_time = youtube.get_total_time(episode)
episode.save()
new_episodes.append(episode)

View File

@ -2292,3 +2292,20 @@ def mount_volume_for_file(file, op=None):
file.mount_enclosing_volume(Gio.MountMountFlags.NONE, op, None, callback)
Gtk.main()
return result, message
def scale_pixbuf(pixbuf, max):
import gi
from gi.repository import GdkPixbuf
w_cur = pixbuf.get_width()
h_cur = pixbuf.get_height()
if w_cur <= max and h_cur <= max:
return pixbuf
f = max / (w_cur if w_cur >= h_cur else h_cur)
w_new = int(w_cur * f)
h_new = int(h_cur * f)
return pixbuf.scale_simple(w_new, h_new, GdkPixbuf.InterpType.BILINEAR)

View File

@ -220,6 +220,34 @@ def youtube_get_new_endpoint(vid):
return None, ipr.group(1)
def get_total_time(episode):
try:
vid = get_youtube_id(episode.url)
if vid is None:
return 0
url = 'https://www.youtube.com/watch?v=' + vid
r = util.urlopen(url)
if not r.ok:
return 0
ipr = re.search(r'ytInitialPlayerResponse\s*=\s*({.+?})\s*;', r.text)
if ipr is None:
url = get_gdpr_consent_url(r.text)
r = util.urlopen(url)
if not r.ok:
return 0
ipr = re.search(r'ytInitialPlayerResponse\s*=\s*({.+?})\s*;', r.text)
if ipr is None:
return 0
player_response = json.loads(ipr.group(1))
return int(player_response['videoDetails']['lengthSeconds']) # 0 if live
except:
return 0
def get_real_download_url(url, allow_partial, preferred_fmt_ids=None):
if not preferred_fmt_ids:
preferred_fmt_ids, _, _ = formats_dict[22] # MP4 720p

View File

@ -67,7 +67,7 @@ cp -a "$checkout"/tools/mac-osx/make_cert_pem.py "$resources"/bin
# install gPodder hard dependencies
$run_pip install setuptools wheel
$run_pip install podcastparser==0.6.6 mygpoclient==1.8 requests[socks]==2.25.1
$run_pip install podcastparser==0.6.7 mygpoclient==1.8 requests[socks]==2.25.1
# install extension dependencies; no explicit version for youtube_dl
$run_pip install mutagen==1.45.1 html5lib==1.1 youtube_dl

View File

@ -84,7 +84,7 @@ function extract_installer {
}
PIP_REQUIREMENTS="\
podcastparser==0.6.6
podcastparser==0.6.7
mygpoclient==1.8
git+https://github.com/jaraco/pywin32-ctypes.git@f27d6a0
html5lib==1.1