Compare commits

...

728 Commits

Author SHA1 Message Date
maryjane 98c4bd8536 update rules 2024-02-23 02:18:42 +00:00
maryjane 6e900b6cda Update patches 2024-02-23 02:03:13 +00:00
maryjane 63cb9669fd
Update changelog 2024-02-23 01:51:24 +00:00
maryjane a0151d5b5a
Added libhandy as runtime dependency, updated mantainer field 2024-02-23 01:51:17 +00:00
maryjane 1b8e913b2e
removes patch remove_copyright_character.patch 2024-02-23 01:51:08 +00:00
maryjane d74567b001
Import Debian directory from salsa debian 2024-02-23 01:50:14 +00:00
Teemu Ikonen 5933d63896 Prepare adaptive release 3.11.2+1 2023-08-18 11:40:22 +03:00
Teemu Ikonen 490d5695a9 Merge tag '3.11.2' into dev-adaptive
gPodder 3.11.2 release
2023-08-15 15:08:21 +03:00
auouymous 305d356465 prepare 3.11.2 release 2023-08-13 22:34:59 -06:00
auouymous 3e005d1055 Remove bind_textdomain_codeset call.
It no longer exists in python 3.11.
2023-08-13 04:47:46 -06:00
auouymous 3628451abe Bump CircleCI Xcode version. 2023-08-13 02:37:16 -06:00
auouymous f0c5941106
Merge pull request #1525 from auouymous/codespell
Add codespell to linter.
2023-08-13 02:23:58 -06:00
auouymous 62cbf7f970 update dependencies 2023-08-07 20:05:29 -06:00
auouymous 839b0b2aa5 Fix linter issues for pycodestyle 2.11.0. 2023-08-07 19:46:44 -06:00
auouymous a077b54082 Bump requests version. 2023-08-07 19:25:54 -06:00
auouymous d24b42c5b2
Merge pull request #1529 from Vistaus/master
Updated Dutch translation
2023-07-28 16:07:32 -06:00
Heimen Stoffels b5f95d9f20
Updated Dutch translation 2023-07-24 11:46:39 +02:00
auouymous 74d73231d1
Merge pull request #1527 from gpodder/fr-2023-07
update FR translation
2023-07-20 16:13:59 -06:00
Eric Le Lay d2c56b3c44 upgrade fr translations 2023-07-20 21:31:26 +02:00
auouymous 64fe2648a8 Add codespell to linter. 2023-07-19 02:34:56 -06:00
auouymous 375a94a139 Fix typos found by codespell. 2023-07-19 02:30:44 -06:00
auouymous e362d36ac6
Merge pull request #1484 from auouymous/drop-old-python-versions
Drop old python versions
2023-07-19 01:03:04 -06:00
auouymous 047204394d make messages 2023-07-19 00:53:59 -06:00
auouymous 48fd99d3e9
Merge pull request #1522 from luzpaz/typos
Fix various typos
2023-07-14 06:21:51 -06:00
luzpaz 8a995cb097 Fix various typos
Found via `codespell -q 3 -S *.po -L bloc,extracter,parms`
2023-07-14 12:13:50 +00:00
auouymous 407e930f1a
Merge pull request #1521 from alexis26/patch-2
Update fr.po
2023-07-02 21:05:27 -06:00
alexis26 a224c47b15
Update fr.po
Hi, 
I just change one line (875)
2023-07-02 08:34:10 +02:00
auouymous fccea8a6d9 Bump required yt-dlp version for changes in #1520. 2023-06-30 16:18:54 -06:00
auouymous d575449af2
Merge pull request #1520 from tpikonen/yt-dlp-latest
Adapt youtube-dl plugin to latest yt-dlp
2023-06-30 16:17:15 -06:00
Teemu Ikonen d64eb6e0b2 youtube-dl: In yt-dlp _VALID_URL_RE is now an iterable of regexes 2023-06-30 21:16:00 +03:00
Teemu Ikonen b1492e60e5 youtube-dl: Use 'color': 'no_color' param in yt-dlp
This prevents unnecessary warnings from yt-dlp.
2023-06-30 21:16:00 +03:00
auouymous 0267b448eb
Merge pull request #1507 from auouymous/show-time-in-released-column
Show time in episode released column
2023-05-23 14:35:17 -06:00
auouymous b53ba83d22 Fix issue retrieving channel ID for Youtube pages.
The channelId meta tag was removed from the HTML. Changing to the
channel_id in RSS feed URL tag should be stable.
2023-05-23 14:13:24 -06:00
auouymous 5224565642 Always show released time in shownotes. 2023-04-29 22:11:27 -06:00
auouymous df4195dc5c Add a View menu option to right align the episode released column. 2023-04-29 21:41:38 -06:00
auouymous b0ce535ca9 Add a View menu option to show time in the episode released column. 2023-04-29 21:10:33 -06:00
auouymous 43eb6ca5f5 Log exceptions when searching for podcasts on gpodder.net. 2023-04-02 23:17:13 -06:00
auouymous ddbae467ef Raise exception when gpodder.net queries fail.
This avoids JSON warnings when gpodder.net requests fail with "500
Internal Server" errors.
2023-04-02 22:52:37 -06:00
auouymous 14efcd52df Log 'from' and 'to' sizes when syncing files. 2023-03-26 04:36:09 -06:00
auouymous 7323e0c604 Refactor _receive_configure_event().
Add comment about bug when state event is sent after configure event.
2023-03-11 20:52:05 -07:00
auouymous ab7b93d4d7 Fix commit 1725b471fa.
The window manager needs a position to unmaximize window to.
2023-03-11 16:10:27 -07:00
auouymous 1725b471fa Do not move window if maximised.
The delayed move can reposition the window after it has been maximized.
2023-03-11 03:15:29 -07:00
auouymous 3d690633ee Add empty custom_downloader field in SyncTask to prevent exception.
filename generated by yt-dlp.

Reported in
https://github.com/gpodder/gpodder/issues/1348#issuecomment-1445273299
2023-03-05 22:33:39 -07:00
auouymous 353a4cc8b6 Add EQL adjectives 'failed' and 'paused'.
Allowing all failed downloads to be filtered with `(failed)`, all paused
episodes with `(paused)`, and all downloading episodes, excluding paused
episodes with `(downloading and not paused)`.
2023-03-04 19:26:36 -07:00
Teemu Ikonen c324f1a11e Prepare adaptive release 3.11.1+1 2023-02-28 14:21:55 +02:00
Teemu Ikonen 8010d831be widgets.py: Fix code style 2023-02-28 14:21:55 +02:00
Teemu Ikonen 4539d8c5e4 Merge tag '3.11.1' into dev-adaptive
gPodder 3.11.1 release
2023-02-27 12:46:18 +02:00
auouymous 8d31d9dd40 Display feed name when logging update errors.
Avoids worthless log entries such as "Error: not found".
2023-02-21 21:23:47 -07:00
auouymous 081fcd6748 Require python 3.7. 2023-02-21 15:03:05 -07:00
auouymous ceabe3db0a Add all python versions to test matrix. 2023-02-21 14:56:32 -07:00
auouymous 34d7d5da2b Fix typo in label.
Reported-by: Karl Ove Hufthammer <karl@huftis.org>
2023-02-20 04:06:05 -07:00
auouymous 4143d36fcf
Merge pull request #1479 from huftis/update-nn-translation-2023-feb
Update Norwegian Nynorsk translation for 3.11.1 release
2023-02-20 03:58:29 -07:00
auouymous fd7d65d9ca
Merge pull request #1480 from tpikonen/appdata-3.11.1
appdata: Update to version 3.11.1, fixes
2023-02-20 00:49:03 -07:00
Teemu Ikonen 530d026516 appdata: Add release 3.11.1 2023-02-19 17:23:44 +02:00
Teemu Ikonen 3cef7a3e11 appdata: Fix syntax, add 3.9-series release dates 2023-02-19 15:56:49 +02:00
Karl Ove Hufthammer 69a7089f94 Update Norwegian Nynorsk translation for 3.11.1 release 2023-02-19 09:18:01 +01:00
auouymous 943c402743
Merge pull request #1477 from Vistaus/master
Updated Dutch translation
2023-02-18 23:06:39 -07:00
Heimen Stoffels c15514b416
Updated Dutch translation 2023-02-18 14:15:35 +01:00
auouymous 38b8cba0e3 prepare 3.11.1 release 2023-02-17 19:18:40 -07:00
auouymous 1452cacbd1 update dependencies 2023-02-17 19:01:45 -07:00
auouymous 44bed10df0 Require new version of youtube-dl/yt-dlp to fix youtube.com change. 2023-02-17 17:56:57 -07:00
auouymous cfc058e4b6 make messages 2023-02-17 00:15:42 -07:00
auouymous f59d688e89
Merge pull request #1465 from steviehs/fix/playlist_absolute_path
correct absolute path config settings for playlist
2023-02-16 22:22:31 -07:00
steviehs 6db358ebb8
additional config to set playlist file extension (#1463)
additional config to set playlist extension, as e.g. Sony NW-MS* players need: m3u8 instead of m3u.
2023-02-16 21:53:54 -07:00
auouymous 96e56482fe
Merge pull request #1464 from tpikonen/svg-cover
Accept coverart as SVG
2023-02-16 21:32:10 -07:00
auouymous 0faa406316 Upgrade deprecated github setup-python action to v4. 2023-02-07 17:28:30 -07:00
auouymous 76c32efdcf Upgrade deprecated github checkout action to v3. 2023-02-07 17:08:42 -07:00
auouymous a3cf8b96ed
Merge pull request #1297 from tpikonen/update-really-new
Treat only really new episodes as new after an update
2023-02-07 02:08:21 -07:00
Stephan Skrodzki 47f2b620c3 absolute path should also be checked in two_way_sync 2023-01-29 19:53:10 +01:00
Stephan Skrodzki b9bb64cc2d self._config.device_sync.playlists.use_absolute_path when checking if absolute path in playlists was desired
This lead to always have the absolute path (which does lead usin non existing config variables not to an error?)
2023-01-29 12:43:04 +01:00
Teemu Ikonen aed3a9fabc Accept coverart as SVG 2023-01-29 13:16:43 +02:00
Eric Le Lay 255d74ffc9
Merge pull request #1461 from auouymous/select-channel-from-episode-menu
Allow channel to be selected from both episode menus.
2023-01-26 21:17:04 +01:00
auouymous 96e3b3bfe9 Allow channel to be selected from both episode menus.
Closes #1170.
2023-01-25 19:26:23 -07:00
auouymous f64440867d Don't display stacktrace for common download errors. 2023-01-25 16:44:06 -07:00
auouymous eb02ddd9d5 Add 'url', 'link' and 'filename' EQL nouns. 2023-01-25 16:30:47 -07:00
auouymous 92c741b02f Log URL when youtube.py can't get channel ID. 2023-01-22 17:21:23 -07:00
auouymous 7c2b8621a3 Document the episode description fields. 2023-01-12 15:04:26 -07:00
auouymous 9d46b2d3de Add comment about unknown external files for youtube-dl/yt-dlp downloads. 2023-01-12 04:10:08 -07:00
auouymous 993b7a5428 Use list of channels and episodes instead of the episode list model.
The model is initialized with 'None' for each entry, and then sets
episode for each one. Renaming immediately after selecting a channel
causes 'state' to be accessed on 'NoneType'.

Fixes #1446.
2023-01-12 03:28:59 -07:00
auouymous 87d9018918 Change 'Finishing...' to something more descriptive of the operation. 2023-01-12 01:17:56 -07:00
auouymous ba93b66382 Use the same dialog title to reduce translation strings. 2023-01-12 00:40:14 -07:00
auouymous ec23dc86b5 Show dialog if no downloaded episodes to rename. 2023-01-12 00:35:05 -07:00
auouymous 9b7d53f9b2 Don't use parameter labels when calling __for_each_task_set_status().
They make the call harder to read and cause it to wrap lines.
2023-01-12 00:26:03 -07:00
auouymous bdecd607c1
Merge pull request #1452 from auouymous/fix-ui-issues
Fix UI issues
2023-01-12 00:12:22 -07:00
Teemu Ikonen f929212d3e preferences.ui: Set 'can-focus' to False on GtkFlowBoxChild widgets 2023-01-06 13:55:20 +02:00
Teemu Ikonen b5ac4034f3 preferences: Add a checkbutton for ui.gtk.only_added_are_new config var 2023-01-06 13:55:20 +02:00
Teemu Ikonen 2552e6e0ec Treat only really new episodes as new after an update
Make PodcastChannel.update() return a list of new episodes. Add a new
config variable ui.gtk.only_added_are_new. If this variable is True,
download, queue or show (depending on the value of config var
auto_download) only these new episodes, instead of all episodes marked
as new, after an update.
2023-01-06 13:55:07 +02:00
auouymous 8b5bf2c361
Merge pull request #1444 from auouymous/add-trim-episode-title-prefix-setting
Add setting to disable trimming episode title prefix.
2023-01-04 01:38:41 -07:00
auouymous 3adfcf7b2f Speed up queueing by not updating download list a second time. 2023-01-04 01:34:02 -07:00
auouymous 9d16460571 Show progress indicator when pausing tasks.
This also significantly speeds up pausing by disabling download update
timer and download queue manager.
2023-01-04 01:27:48 -07:00
auouymous 43afafcc23 Show progress indicator when queueing paused and failed tasks.
The indicator was previously shown only while queueing new tasks, but
not when queueing failed tasks or unpausing paused tasks. It is now
displayed while scanning the episodes and then restarts when queueing
new tasks.

The download update timer and download queue manager are also disabled
earlier to significantly speed up the process.
2023-01-04 01:03:08 -07:00
auouymous bda12a53c1 Allow IdleTimeout to scale based on how long the callback took.
upload_downloads_list() is now called at upto 5 second intervals when
there are a lot of tasks. Previously, it could take 5 seconds to run and
then only sleep for 1.5 seconds, making the UI unresponsive for long
periods.
2023-01-03 15:33:31 -07:00
auouymous 6470ed5484 Add a progress dialog when cancelling tasks. 2023-01-03 15:33:03 -07:00
auouymous 6c7337f5fb Process episode list selection changes every 250ms.
A fast key repeat rate can cause on_episode_list_selection_changed to be
called quicker than it can update the UI. This slows down
shift-selections and results in continued processing long after the key
has been released.

The 250ms timer batches multiple events into a single update, and
improves responsiveness on slower machines.
2023-01-03 06:01:15 -07:00
auouymous e1fc290ef2 Remove all timer deadlocks by using idle_add priority for them.
Add util.idle_timeout_add() to register timers with the same priority as
idle_add(). Change the IdleTimeout to also use the idle_add() priority.
This eliminates the chance of a timer blocking any idle_add from
running.

Change most timeout_add's to idle_timeout_add. Change the timer in
DownloadStatusModel::get_next() back to an idle_add.
2023-01-03 06:01:15 -07:00
auouymous d2f34d0d87 Disable background operations while progress dialogs are open.
Changing task state causes UI to hang while DownloadQueueManager spawns
threads and updates progress tab. And the update_downloads_list() timer
can hang UI for several seconds at a time when thousands of tasks are
queued.

Disabling both of these while a progress dialog is open allows tasks to
be queued faster and the dialog closed sooner.
2023-01-03 06:01:15 -07:00
auouymous 36dbad9c53 Refactor ProgressIndicator.
Add on_ticks() and max_ticks to simplify code using progress indicators.
And support final ticks to set progress to 100% before a final long
operation.

Change interval from 100ms to 250ms, to allow more time to be spent on
the operation.
2023-01-03 05:58:42 -07:00
auouymous 733cdd2169 The rename downloads extension should not improt Gtk when used in gpo. 2022-12-26 13:28:31 -07:00
Teemu Ikonen f00eef5e5c Merge branch 'master' into dev-adaptive 2022-12-19 23:02:01 +02:00
auouymous 54c86d6023
Merge pull request #1363 from tpikonen/ytdl-subs
Embed subtitles to videos downloaded with the youtube-dl extension
2022-12-17 14:49:22 -07:00
Teemu Ikonen e7a32f9371 Download and embed subtitles in youtube-dl downloader
Add a checkbox in youtube-dl preferences to enable subtitle embedding if
ffmpeg is found. If ffmpeg is not found, show an infobox informing the
user that ffmpeg is required.
2022-12-17 23:40:42 +02:00
auouymous 9df414560d Show message when rename extension finishes renaming all episodes. 2022-12-17 05:54:33 -07:00
auouymous d9f05e666a Only update downloads list when no tasks were queued.
Avoids a double update when there are queued tasks.
2022-12-17 01:54:03 -07:00
auouymous 58e678b33f Use length of tasks, not episodes, for download progress indicator. 2022-12-16 18:17:09 -07:00
auouymous 9babf0eb44 Set download list state only once after batch queueing tasks.
Queueing thousands of tasks happens faster when update_download_list()
is not called for each one.
2022-12-16 16:04:33 -07:00
auouymous e05ba2e929 Don't show episodes without URLs in "new episodes available" when
subscribing.
2022-12-15 06:34:00 -07:00
auouymous 6e38e1b527 Set error icon for episodes with invalid URLs. 2022-12-15 06:08:47 -07:00
auouymous 2e7b1678d4 Don't discard episodes with invalid urls and links. 2022-12-15 05:50:27 -07:00
auouymous 6e29aa12ce Add setting to disable trimming episode title prefix. 2022-12-15 03:41:01 -07:00
auouymous 526c335662 Rename showEpisodeDescription's internal names to match other items. 2022-12-15 03:34:24 -07:00
auouymous b842e86101 Organize View menu.
And move all-episodes and sections settings from preferences to View
menu.
2022-12-15 02:46:18 -07:00
auouymous d2253d4acd Cache episode list config values.
Decreases episode list update time by 5% for new episodes.
2022-12-15 00:44:37 -07:00
auouymous f967fa9bda Change include_description parameter to required.
Nothing made use of the optional parameter, and it should always be set
from the config value.
2022-12-14 06:29:54 -07:00
auouymous 808895f287
Merge pull request #1443 from auouymous/remove-legacy-settings
Remove legacy settings
2022-12-09 20:00:58 -07:00
auouymous 3203a0ef81 Remove gPodderSettings_LegacySupport. 2022-12-08 15:59:17 -07:00
auouymous 7aa649e6d1 episode_list_columns -> ui.gtk.episode_list.columns 2022-12-08 15:57:46 -07:00
auouymous 2daa5e9550 podcast_list_hide_boring -> ui.gtk.podcast_list.hide_empty 2022-12-08 15:56:26 -07:00
auouymous f62e4294e0 podcast_list_view_mode -> ui.gtk.podcast_list.view_mode 2022-12-08 15:55:08 -07:00
auouymous fcfb9efe1a episode_list_view_mode -> ui.gtk.episode_list.view_mode 2022-12-08 15:54:24 -07:00
auouymous fe969e8c15 podcast_list_sections -> ui.gtk.podcast_list.sections 2022-12-08 15:52:23 -07:00
auouymous 8ca292e5a5 podcast_list_view_all -> ui.gtk.podcast_list.all_episodes 2022-12-08 15:50:56 -07:00
auouymous ff2c19e186 auto_cleanup_downloads -> ui.gtk.download_list.remove_finished 2022-12-08 15:48:16 -07:00
auouymous bcf84cbdf7 auto_update_feeds -> auto.update.enabled 2022-12-08 15:47:33 -07:00
auouymous f19632c426 auto_update_frequency -> auto.update.frequency 2022-12-08 15:46:11 -07:00
auouymous 599682f4f2 auto_download -> ui.gtk.new_episodes 2022-12-08 15:43:51 -07:00
auouymous 816b5c15f3 show_toolbar -> ui.gtk.toolbar 2022-12-08 15:39:34 -07:00
auouymous b39edcfe83 max_episodes_per_feed -> limit.episodes 2022-12-08 15:37:36 -07:00
auouymous dd269d7b88 auto_remove_unplayed_episodes -> auto.cleanup.unplayed 2022-12-08 15:35:08 -07:00
auouymous b812c62775 auto_remove_unfinished_episodes -> auto.cleanup.unfinished 2022-12-08 15:33:35 -07:00
auouymous 0bcfd29d76 auto_remove_played_episodes -> auto.cleanup.played 2022-12-08 15:32:05 -07:00
auouymous c6695f5b69 episode_old_age -> auto.cleanup.days 2022-12-08 15:25:26 -07:00
auouymous 84c35c76fd max_downloads -> limit.downloads.concurrent 2022-12-08 14:49:33 -07:00
auouymous 04cb6583da max_downloads_enabled -> limit.downloads.enabled 2022-12-08 14:47:03 -07:00
auouymous 8eb60b8ccf limit_rate -> limit.bandwidth.enabled 2022-12-08 14:45:24 -07:00
auouymous 39f0376c81 limit_rate_value -> limit.bandwidth.kbps 2022-12-08 14:41:32 -07:00
auouymous 47aa09199d Get rid of custom icons for each type of audio and video file.
The episode list takes 24% more time to render with this feature. It is
also known to produce incorrect icons for some file types.

Fixes #872.
2022-12-08 04:46:06 -07:00
auouymous e8af8603a0
Merge pull request #1435 from auouymous/optimize-episode-list
Optimize episode list
2022-12-08 04:39:57 -07:00
Yuvraj Singh Pathania 486fa9df7b
add : rename all episodes function (#1442) 2022-12-08 04:22:56 -07:00
Skitals 2fd0e41308
delete tags before modifying (#1441)
add 'remove_before_modify' option to remove existing tags before writing basic tags
2022-12-07 15:41:26 -07:00
auouymous d842a78e4c
Merge pull request #1440 from auouymous/fix-old-versions-of-ytdlp
Fix support for old versions of yt-dlp.
2022-11-22 08:55:48 +00:00
auouymous 87421c83b3 Fix support for old versions of yt-dlp.
PR #1382 broke support for yt-dlp versions prior to 2022.6.22.1.

Fixes #1439.
2022-11-21 20:59:42 -07:00
auouymous fa4196525c Allow different required versions for youtube-dl and yt-dlp. 2022-11-21 20:04:02 -07:00
auouymous d64c06fa92
Merge pull request #1434 from auouymous/resync-on-file-size-change
Check for size mismatch when syncing and send to device again.
2022-11-18 10:50:25 +00:00
auouymous 0e27494361
Merge pull request #1433 from auouymous/remove-localdepends.py
Remove localdepends.py.
2022-11-18 10:44:45 +00:00
auouymous 25991ef8bb Throw exception if youtube channelId is empty.
And try to find it in entries. This prevents description and cover art
from being removed when youtube feed is broken.
2022-11-18 03:09:53 -07:00
auouymous c90e84b45c Show youtube-dl/yt-dlp name and version in preferences. 2022-11-15 02:28:58 -07:00
auouymous a815c345e4
Merge pull request #1431 from tpikonen/flake8
Add flake8 config and fix some code style issues
2022-11-14 22:53:43 +00:00
Teemu Ikonen d87ac85506 Fix 'W504 line break after binary operator' flake8 warnings
Fixed by running

autopep8 -i -r --select=W504 .

and some hand tuning.
2022-11-14 18:32:09 +02:00
Teemu Ikonen 6bd0bb0530 Remove unused imports and pass statements
Fixes flake8 error F401.
Most errors were fixed by running

autoflake -i -r --remove-all-unused-imports .

which also removes unnecessary 'pass' statements, some by hand-editing.
2022-11-14 18:32:09 +02:00
Teemu Ikonen 80cec0d024 setup.cfg: Add section for flake8 config
Set project-wide max-line-length and ignore indentation errors E126 and
E128, and warning W503 (Line break occurred before a binary operator)
for now.
2022-11-14 18:11:23 +02:00
auouymous 1b9ed37064
Merge pull request #1382 from tpikonen/ytdl-rename
Fix yt-dlp output file name
2022-11-14 04:08:49 +00:00
auouymous 9bdc9d966e
Merge pull request #1303 from auouymous/setting-to-disable-find-as-you-type
Add setting to disable find-as-you-type.
2022-11-09 03:42:05 +00:00
auouymous 3f614a1497 Update episode list in 500ms intervals instead 20ms.
The UI is still responsive while performing more work per interval and
updating the list in 90% of the time.
2022-11-08 02:10:21 -07:00
auouymous 57d6f6305c Optimize get_update_fields() tooltip branching.
This can decrease episode list update time by 0.2%.
2022-11-08 02:10:20 -07:00
auouymous f1357ea149 Don't wrap episode fields in tuples, only to immediately unwrap them.
And concatenate episode fields instead of iterating over them.

Simplifies the expression and can decrease episode list update time by
0.2%.
2022-11-08 02:10:19 -07:00
auouymous f9afa2ccaa Only query time and filesize once, instead of three times per episode.
This can decrease episode list update time by 1.5%.
2022-11-08 02:10:17 -07:00
auouymous fa27760a3c Join description while formatting it.
This can decrease episode list update time by 0.2%.
2022-11-08 02:10:16 -07:00
auouymous 980ad522a9 Get default icon theme once, instead of for each call.
This can decrease episode list update time by 1.7%.
2022-11-08 02:10:12 -07:00
auouymous 5c277639de Check for size mismatch when syncing and send to device again.
An interrupted sync results in a partial file on the device and syncing
again would not finish sending the file. Ideally it could also compare
checksums but that would slow down syncing.

Fixes #1416.
2022-11-08 01:05:05 -07:00
auouymous c90c58013d Remove localdepends.py.
As of https://github.com/gpodder/gpodder.github.io/pull/42, it is now
recommended to use pip to install tools/requirements.txt.
2022-11-07 22:51:07 -07:00
auouymous 98208d4444
Merge pull request #1374 from tpikonen/channel-buttons
channel editor: Add buttons next to cover, feed URL, etc.
2022-11-08 04:46:23 +00:00
Teemu Ikonen 44befb77f1 Add can_preview to play_or_download() output
Use it to decide if 'Preview' is shown in episode contect menu.
2022-11-07 15:28:54 +02:00
Teemu Ikonen 9690b13a3a Get preview file name from CustomDownload.partial_filename
Add 'custom_downloader' member var to DownloadTask. Use it in
episode.get_playback_url() to get a preview file name.

Also add episode.can_preview() method and use it in ep.can_play().
2022-11-07 15:28:54 +02:00
Teemu Ikonen 642bf7e738 youtube-dl: Add 'partial_filename' to YoutubeCustomDownload
Add the 'partial_filename' property for a previewable temporary file.

Get this filename from yt-dlp / youtube-dl by splitting the download
into two parts, first get the extractor info which contains the 'ext',
derive the temporary filename from that and the outtmpl and then
download the file.
2022-11-07 15:28:54 +02:00
Teemu Ikonen 7b051d245b Add 'partial_filename' property to DefaultDownload
Derive abstract classes CustomDownload and CustomDownloader from ABC
from the abc module. Decorate abstract methods with @abstractmethod.

Add abstract 'partial_filename' property to CustomDownload and make it
concrete in the derived DefaultDownload class. This property holds the
full path of the temporary file where the episode is being downloaded
or None, if the downloader does not use a previewable temporary file.
2022-11-07 15:28:54 +02:00
Teemu Ikonen abc6370729 youtube-dl: Fix output file renaming
Use separate code paths to rename output files from yt-dlp and
youtube-dl to the requested name ('tempname'). The output is always
renamed with yt-dlp.

Add the 'ext' to the output template. This is needed to unbreak
post-processing (like subtitle embedding). See yt-dlp issue #1844.

Use basename(tempname) for yt-dlp and tempname for youtube-dl as output
template, since we set the output path for yt-dlp in the 'paths' option.
2022-11-07 15:21:22 +02:00
auouymous ccb23494a1
Merge pull request #1429 from auouymous/queue-gpo-episodes-to-allow-resuming
Queue all episodes before download to allow resuming in gpo.
2022-11-04 06:32:47 +00:00
Teemu Ikonen 236a4c9966 Replace is_on_mobile_screen() with have_touchscreen() 2022-11-03 15:03:52 +02:00
Teemu Ikonen 46dbc80d8b Merge branch 'master' into dev-adaptive 2022-10-28 21:59:50 +03:00
auouymous 1594d64813 Queue all episodes before download to allow resuming. 2022-10-27 16:31:16 -06:00
auouymous 89b4b6e796
Merge pull request #1372 from tpikonen/resume-infobar
Replace SimpleMessageArea with GtkInfoBar when resuming
2022-10-27 07:24:01 +00:00
Teemu Ikonen 9130f39e8c Do not hide Progress tab resume infobar on page switch 2022-10-24 11:41:58 +03:00
Teemu Ikonen 70c97522e6 Replace SimpleMessageArea with GtkInfoBar when resuming
Remove unused SimpleMessageArea code.
2022-10-24 11:41:51 +03:00
Eric Le Lay 30f087fae7
Merge pull request #1420 from neodyne/sk-translation-update-6
Update Slovak translation (sk.po)
2022-10-13 21:47:03 +02:00
Eric Le Lay e31591bcc1
Merge pull request #1421 from rene-coty/master
Updated French translation
2022-10-13 21:39:30 +02:00
rene-coty 41ac91ba3f
Correction 2022-10-12 00:18:04 +02:00
rene-coty 220cf8cf05 Updated French translation 2022-10-11 18:00:41 +02:00
neodyne 23e60bed57 Update Slovak translation (sk.po) 2022-10-10 17:02:49 +02:00
Eric Le Lay c41ca22e5d
Merge pull request #1404 from auouymous/use-symbolic-toolbar-icons
Use symbolic toolbar icons.
2022-10-09 12:18:17 +02:00
auouymous fbcc72a906 Disable progress spinbuttons if unchecked at startup.
They correctly enable/disable when the checkbox is clicked, but have
always defaulted to enabled at startup, even when the checkbox is
unchecked.
2022-10-01 05:39:40 -06:00
auouymous 7b07602374
Merge pull request #1412 from huftis/update-nn-translation-2022-sep
Update Norwegian Nynorsk translation for next release
2022-09-30 06:47:06 +00:00
auouymous 557229c08c Update progress widgets when their values are modified via edit config. 2022-09-29 21:20:42 -06:00
auouymous 9a4d5e34cd Add method to clamp a config value between minimum and maximum values. 2022-09-29 21:19:01 -06:00
Karl Ove Hufthammer 3f234a6ffe Update Norwegian Nynorsk translation for next release 2022-09-28 20:54:09 +02:00
auouymous 1dbc8288d1
Merge pull request #1409 from Vistaus/master
Updated Dutch translation
2022-09-27 04:43:37 +00:00
Heimen Stoffels b4d97ebf26
Updated Dutch translation 2022-09-26 18:20:39 +02:00
auouymous 6d3171ecb7 make messages 2022-09-25 20:27:20 -06:00
auouymous 9cadc2735a
Merge pull request #1304 from tpikonen/gpo-description-link
gpo: Add Description and Link fields to info
2022-09-26 02:19:25 +00:00
auouymous a75a2e411b
Merge pull request #1398 from auouymous/fix-format-time
Fix the format_time() function to display times greater than 24 hours.
2022-09-26 01:20:22 +00:00
Eric Le Lay 5825f51183
Merge pull request #1401 from auouymous/catch-sync-device-open-exceptions
Catch unknown sync exceptions when opening device and show error.
2022-09-24 19:20:52 +02:00
Eric Le Lay 1ecdbed0df
Merge pull request #1400 from auouymous/log-unwritable-sync-messages
Write to log when sync directory is not writable.
2022-09-24 19:19:43 +02:00
Eric Le Lay cb59e1e051
Merge pull request #1402 from auouymous/open-logs-folder
Add menu item to open logs folder.
2022-09-24 19:17:27 +02:00
auouymous 26ca4e7649 Use symbolic toolbar icons.
The preferences-desktop icon is not available for 64x64 and larger icon
sizes, and gtk displays a missing icon instead of falling back to
smaller icons. Switching to preferences-other-symbolic would fix the
issue, but the other toolbar icons should probably be changed to
symbolic to match.
2022-09-23 03:40:07 -06:00
auouymous 08ec67d297
Merge pull request #1403 from bahorn/fix/drag-and-drop-urlquote
Quoting file URIs moved by drag and drop
2022-09-23 09:08:14 +00:00
B Horn 4e5168d1ba
Quoting file URIs moved by drag and drop
When dragging and dropping a podcast into another program, e.g VLC, some
filenames would cause issues (i.e ones with `#`).

Signed-off-by: B Horn <b@horn.uk>
2022-09-21 14:18:29 +02:00
auouymous b907183b22 Add menu item to open logs folder. 2022-09-19 23:37:31 -06:00
auouymous 37ad7cac89 Catch unknown sync exceptions when opening device and show error.
Some devices lack writable info and gpodder assumes they are writable.
This can lead to an exception being thrown when not writable.
2022-09-19 22:51:53 -06:00
auouymous e59a25e233 Write to log when sync directory is not writable.
The error message told user to check logs but nothing had been written.
2022-09-19 22:10:31 -06:00
auouymous 83b0aa1c87
Merge pull request #1383 from tpikonen/ytdl-no-audio-video-files2
Don't try to download media files with youtube-dl extension
2022-09-20 02:29:42 +00:00
auouymous 04a0116a31 Close progress dialog immediately in concatenate videos extension. 2022-09-19 18:57:29 -06:00
auouymous 80629f91d7 Fix msgstr errors in Norwegian Bokmål translation.
Fixes #1399.
2022-09-19 18:47:58 -06:00
auouymous 83d99af8ab Make releasetest failures actually generate errors. 2022-09-19 18:47:52 -06:00
auouymous 2659333380 Fix the format_time() function to display times greater than 24 hours.
Using datetime converts the seconds value into date and time components.
A value of 86400 generates a 00:00 time on the 2nd of January 1970.

The new code properly increments the hour field to 24 and beyond instead
of wrapping around to zero.
2022-09-17 19:29:24 -06:00
auouymous b8bbcfa088 Don't use idle_add() for progress dialogs that don't need it.
The dialog is created inside the function and can be destroyed there as
well. This prevents the idle_add from being blocked forever by a
timeout_add, and the dialog never closing.

Fixes #1311.
2022-09-17 00:46:57 -06:00
auouymous fe83a92286 Remove redundant timeout removal when creating progress dialog.
It is somehow possible for source_id to be zero, causing a
g_source_remove assertion warning.
2022-09-16 05:28:14 -06:00
auouymous 5c01b6b036 Fix crash on older versions of python.
Older versions of python do not treat None as False. This causes
set_sensitive() to crash when None is returned from can_pause().

Fixes #1394.
2022-09-12 14:16:31 -06:00
auouymous eb2ceba7a9 Remove download directory when unsubscribing in gpo. 2022-09-08 16:57:19 -06:00
Teemu Ikonen 643d15971c Add appdata.xml for the adaptive version 2022-09-08 11:56:16 +03:00
Eric Le Lay 518a975b87
Merge pull request #1390 from tpikonen/master
Update appdata.xml from the flatpak package
2022-09-07 22:12:42 +02:00
Teemu Ikonen 7562c5a188 appdata: Add missing release dates since version 3.10.0 2022-09-06 19:40:21 +03:00
Teemu Ikonen 2b679d9af9 appdata: Merge appdata.xml from flathub 2022-09-06 19:36:41 +03:00
Teemu Ikonen ce02cf6810 util.sanitize_filename_ext: Return an empty ext, if sanitized_ext is empty
Prevents file names with two periods before the extension.
2022-09-03 15:09:57 +03:00
Teemu Ikonen c1981801c1 Don't try to download media files with youtube-dl extension 2022-09-03 13:44:40 +03:00
auouymous e510b1e059
Merge pull request #1381 from gpodder/revert-1347-ytdl-no-audio-video-files
Revert "Don't try to download media files with youtube-dl extension"
2022-09-02 15:07:42 -07:00
auouymous b9c356f44b Set "New episodes available" tooltip for episodes with html descriptions.
Episodes with an html description did not have a tooltip because the
description field is always empty for them. The new _text_description
field is computed at runtime and should be used for any code wanting a
text description.

Fixes #1350.
2022-08-30 21:04:56 -06:00
Eric Le Lay f5a8e54660 mac-ci: try known working setuptools version 2022-08-30 20:46:23 +02:00
Teemu Ikonen abca020c30 Set adaptive release 3.11.0+1 version and date 2022-08-30 10:15:59 +03:00
auouymous de390ff711
Revert "Don't try to download media files with youtube-dl extension" 2022-08-29 17:33:53 -07:00
auouymous 2c0e70ca5f Log which program the youtube-dl extension is using. 2022-08-29 18:30:57 -06:00
auouymous defcc6f5f4 Display 'Queueing' on dialog instead of 'Queued' when queueing downloads. 2022-08-29 05:09:04 -06:00
auouymous 86cad043c2 Fail CircleCI run if release_on_mac.sh fails. 2022-08-29 04:02:46 -06:00
auouymous b231243430 Fail if mac build has pip errors. 2022-08-29 03:26:18 -06:00
auouymous 871fb2bcd4 Remove unused 'others' variable. 2022-08-29 03:23:52 -06:00
auouymous ec663e1795 Update osx-bundle to 22.8.27. 2022-08-28 00:15:31 -06:00
auouymous 60b3ba6093 Unwrap argument list when calling IdleTimeout function.
This prevented update_downloads_list() from cleaning up the download
list when finished, due to can_call_cleanup being set to ().
2022-08-27 04:50:48 -06:00
auouymous 26c0f8dad8
Merge pull request #1368 from auouymous/progress-dialogs
Progress dialogs
2022-08-26 03:24:55 -07:00
auouymous 839c85a43e
Merge pull request #1367 from auouymous/idle-timeout
Add util.IdleTimeout class to reduce lag when updating progress tab.
2022-08-26 00:07:09 -07:00
Eric Le Lay 098438bb85
Merge pull request #1356 from auouymous/dont-place-hidden-windows
Reset window position if completely off-screen.
2022-08-25 18:45:50 +02:00
Teemu Ikonen 294b047901 Fix 'Invalid episode at path 0' messages on channel change 2022-08-24 11:54:34 +03:00
Teemu Ikonen 209ef01aa5 adaptive/gpodder.ui: Set 'relief' to none in back buttons 2022-08-24 11:54:26 +03:00
Teemu Ikonen c89268fd4b adaptive/menus.ui: Remove 'Refresh image' from channels context menu 2022-08-24 11:54:26 +03:00
Teemu Ikonen 8fd6c5eba6 Add a subtitle with statistics to header bar 2022-08-24 11:54:26 +03:00
Teemu Ikonen da268d4fe2 preferences: Show flap on 'edge-overshot' from top 2022-08-24 11:54:26 +03:00
Teemu Ikonen a071a1472b preferences: Reorganize flap code 2022-08-24 11:54:26 +03:00
Teemu Ikonen 3d678927f2 Show a header (pulley) menu on channel list 'edge-overshot' 2022-08-24 11:54:26 +03:00
Teemu Ikonen b6ac9776d8 Navigate back from shownotes with 'edge-overshot' signal 2022-08-24 11:54:26 +03:00
Teemu Ikonen f5f607d309 Fix setting cover image from local file 2022-08-24 11:54:26 +03:00
Teemu Ikonen 21797b80a4 channel editor: Add buttons next to cover, feed URL, etc.
Remove the cover image context menu and add buttons next to various
items in the channel editor:

 * Cover image: Pop-up a menu to change or refresh the cover image
 * Feed URL: Copy the URL to clipboard
 * Download folder: Open the download folder
2022-08-24 11:54:26 +03:00
Teemu Ikonen df3a093462 Navigate back from episodes with 'edge-overshot' signal
But only do so if on mobile. Compensates for lack of swipes in
TreeViews.
2022-08-24 11:54:26 +03:00
Teemu Ikonen b685022a8c Add function is_on_mobile_screen(window) 2022-08-24 11:54:26 +03:00
Teemu Ikonen 9231e16995 Revert "preferences: Add a hack to maximize on mobile screen"
This reverts commit 6105ec55e4.
2022-08-24 11:54:26 +03:00
Teemu Ikonen a21ed49b67 adaptive/gpodder.ui: Progress window GtkDialog -> GtkWindow 2022-08-24 11:54:26 +03:00
Teemu Ikonen dfc0ebc18d Remove set_transient_for() calls to fix Phosh non-maximization 2022-08-24 11:54:26 +03:00
Teemu Ikonen 2e57489f32 Fix Phosh non-maximization on channel editor 2022-08-24 11:54:26 +03:00
Teemu Ikonen 8e6b88cf7e adaptive/gpodderpodcastdirectory.ui: Get changes from master 2022-08-24 11:54:26 +03:00
Teemu Ikonen f60f0a44d0 Remove adaptive/gpodderpreferences.ui 2022-08-24 11:54:26 +03:00
Teemu Ikonen 525ec32802 adaptive/episodeselector.py: Fix Stream button 2022-08-24 11:54:26 +03:00
Teemu Ikonen f533ed395a Replace SimpleMessageArea with GtkInfoBar when resuming
Remove unused SimpleMessageArea code.
2022-08-24 11:54:26 +03:00
Teemu Ikonen 4f360e62f6 Remove download actions from app.py 2022-08-24 11:54:26 +03:00
Teemu Ikonen d7f2943a70 main.py: Fix whitespace 2022-08-24 11:54:26 +03:00
Teemu Ikonen 10250404e8 Adapt in_downloads() to the adaptive version 2022-08-24 11:54:26 +03:00
Teemu Ikonen 9f168c5bda main.py: Detect if we're in downloads by func in_downloads() 2022-08-24 11:54:26 +03:00
Teemu Ikonen 13e25f1c48 Move actions needed in progress window from 'win' to 'app' 2022-08-24 11:54:26 +03:00
Teemu Ikonen d6b18463d3 main.py: Merge missing changes from master branch 2022-08-24 11:54:26 +03:00
Teemu Ikonen 224818e39f Remove context_popover_show() 2022-08-24 11:54:26 +03:00
Teemu Ikonen cb54577e0c adaptive/menus.ui: Sync with master 2022-08-24 11:54:26 +03:00
Teemu Ikonen be6e595c55 menus.ui: Synchronize with master 2022-08-24 11:54:26 +03:00
Teemu Ikonen 596ee8ca61 Rename funcs on_treeview_podcasts_* to on_treeview_channels_* 2022-08-24 11:54:26 +03:00
Teemu Ikonen a420264400 Remove redundant treeview arg from treeview_*_show_context_menu funcs 2022-08-24 11:54:01 +03:00
auouymous 3a4cd026e9 Reset window position if completely off-screen. 2022-08-22 23:49:11 -06:00
Teemu Ikonen 2665bafe62 Disallow all treeview tooltips when context menu is open
Rename treeview_allow_tooltips() to allow_tooltips(). Remove the
treeview arg, and hard code it to enable or disable tooltips on channel
and episode treeviews.
2022-08-22 21:51:52 +03:00
Teemu Ikonen d1047bc739 Popup context menus with a LongPress gestures 2022-08-22 21:51:52 +03:00
Teemu Ikonen 142c0187d7 Replace downloads context GtkMenu with GtkPopover 2022-08-22 21:51:52 +03:00
Teemu Ikonen f69182308e Add actions for downloads context menu items 2022-08-22 21:51:51 +03:00
Teemu Ikonen 7cd9d3ee3a Remove funcs _add_sub_menu and _submenu_item_activate_hack 2022-08-22 21:51:51 +03:00
Teemu Ikonen 1cf9cf6436 Replace episode context GtkMenu with a GtkPopover 2022-08-22 21:51:33 +03:00
Teemu Ikonen b165447426 Add actions for episode context menu items
Disable 'bluetoothEpisodes' action when Bluetooth is not available.
Add episodeNew and episodeLock to set_episode_actions().
2022-08-22 19:20:28 +03:00
Teemu Ikonen f9ecbaddc6 Replace channel context GtkMenu with GtkPopover 2022-08-22 19:15:37 +03:00
Teemu Ikonen c90c8264d3 Add actions for channel context menu items 2022-08-22 19:10:53 +03:00
Teemu Ikonen aa95987340 common.py: Add ExtensionMenuHelper and Dummy classes 2022-08-22 18:59:02 +03:00
Teemu Ikonen 06cb0aa451 Add func TreeViewHelper.get_popup_rectangle 2022-08-22 18:56:58 +03:00
Teemu Ikonen dc7ebf494d Fix setting cover image from local file 2022-08-16 17:18:09 +03:00
Teemu Ikonen 93b636b6ca channel editor: Add buttons next to cover, feed URL, etc.
Remove the cover image context menu and add buttons next to various
items in the channel editor:

 * Cover image: Pop-up a menu to change or refresh the cover image
 * Feed URL: Copy the URL to clipboard
 * Download folder: Open the download folder
2022-08-16 17:18:09 +03:00
Eric Le Lay ec1b675f45
Merge pull request #1369 from auouymous/clear-add-podcast-url
Add icon to clear URL in the add podcast dialog.
2022-08-14 13:42:30 +02:00
auouymous fc0c1981ed Add icon to clear URL in the add podcast dialog. 2022-08-13 02:51:15 -06:00
auouymous 932a8e7069 Fix stripping of pasted text when adding podcast URL. 2022-08-13 02:34:45 -06:00
auouymous 8fa11335be Add progress dialogs for long running actions.
Make the find partial downloads progress dialog update itself.

Show a progress dialog when queueing and resuming downloads.
2022-08-13 02:12:13 -06:00
auouymous 8d1acbd3ad Improve cancelling of progress dialog and manually updating it. 2022-08-13 02:09:24 -06:00
auouymous 165a45ac0d Add util.IdleTimeout class to reduce lag when updating progress tab. 2022-08-13 01:55:05 -06:00
auouymous bab023a4db
Merge pull request #1353 from auouymous/fix-hang-when-resuming-thousands-of-episodes
Fix hang when resuming thousands of episodes.
2022-08-13 00:06:28 -07:00
auouymous f20f1b3afd Fix hang when resuming thousands of episodes.
When the number of episodes causes update_downloads_list() to exceed 1.5
seconds, the idle_add callback will never be called and cause gpodder to
hang.

Fixes #1311.
2022-08-13 01:04:33 -06:00
auouymous f05ce1fc0a Switch deprecated GObject functions to GLib. 2022-08-13 00:33:28 -06:00
auouymous fdc2bb2eb9 Remove redundant force_start parameters. 2022-08-12 23:05:23 -06:00
auouymous 3f63d53414
Merge pull request #1359 from adasiko/master
Update Russian translation
2022-08-11 22:35:55 -07:00
adasiko b6c00d0d3c Update Russian translation 2022-08-06 21:51:07 +07:00
Eric Le Lay a6e4d39fdd
Merge pull request #1355 from auouymous/keep-dialog-open-longer-before-resume-all
Keep 'find partial downloads' dialog open longer.
2022-08-04 23:43:01 +02:00
auouymous 369c3986cb
Merge pull request #1357 from gpodder/thp/fixup-interpreter
[shebang] Change /usr/bin/python -> /usr/bin/env python3
2022-08-04 14:25:10 -07:00
Thomas Perl 576ae2a762 Remove unneeded shebang lines 2022-08-04 12:39:05 +02:00
Thomas Perl 37e296c629 [shebang] Change /usr/bin/python -> /usr/bin/env python3
This should fix "unusual interpreter" Lintian warnings here:
https://udd.debian.org/lintian/?packages=gpodder
2022-08-04 11:53:08 +02:00
auouymous 97b3aab8de Keep 'find partial downloads' dialog open longer.
It can take a while to populate the list when there are a lot of
downloads to resume. This leaves the list empty and UI, including the
`Resume All` button unresponsive. Keeping the dialog open while Gtk
populates the list prevents this from happening.
2022-08-03 14:03:07 -06:00
auouymous ce9a2a7103 Upgrade to newer version of 7-Zip for portable Windows build. 2022-08-02 19:22:36 -06:00
auouymous c8e4f20506
Merge pull request #1347 from tpikonen/ytdl-no-audio-video-files
Don't try to download media files with youtube-dl extension
2022-08-02 14:54:42 -07:00
Teemu Ikonen 27aed1fbea Merge tag '3.11.0' into dev-adaptive
gPodder 3.11.0 release
2022-08-01 22:04:06 +03:00
Teemu Ikonen 123a550f20 Don't try to download media files with youtube-dl extension 2022-08-01 21:19:17 +03:00
auouymous ef0cb1a3dc Quote python version to avoid 3.10 being detected as 3.1. 2022-07-31 02:04:07 -06:00
auouymous d4ea4fc088 Lint and test using python 3.10. 2022-07-31 01:57:15 -06:00
auouymous 75969b9111 prepare 3.11.0 release 2022-07-30 22:35:28 -06:00
Eric Le Lay 5c28a39db1 macos: try again with python includedir 2022-07-28 16:35:36 +02:00
Eric Le Lay 295009703d macos: debug why pip doesn't use brotli and cryptodomex whl 2022-07-27 17:38:13 +02:00
Eric Le Lay 8453820578 use gpodder-osx-bundle 22.7.27 2022-07-27 17:26:34 +02:00
auouymous 4c1cf5bcb0 Create 'Resume all' button by its clicked handler. 2022-07-18 15:18:36 -06:00
auouymous a3e8816dcf sort and update dependencies 2022-07-13 19:00:29 -06:00
auouymous cf24177462
Merge pull request #1330 from auouymous/inject-extension-preferences
Add/remove extension preferences buttons when loaded/unloaded.
2022-07-13 11:50:32 -07:00
auouymous 925a4975e6
Merge pull request #1335 from tpikonen/sync-no-traceback
sync.py: Don't print traceback on missing libgpod_ctypes and eyed3.mp3
2022-07-12 13:55:37 -07:00
Teemu Ikonen 8ebf566993 sync.py: Don't print traceback on missing libgpod_ctypes and eyed3.mp3 2022-07-12 18:29:31 +03:00
auouymous dc6ac8db12
Merge pull request #1334 from gpodder/thp/ctypes-python312
libgpod_ctypes: Use ctypes.c_time_t on Python 3.12
2022-07-12 01:23:07 -07:00
Thomas Perl a3a6bee1f4 libgpod_ctypes: Use ctypes.c_time_t on Python 3.12 2022-07-12 09:22:34 +02:00
Teemu Ikonen 4212b17bf2 Do not rely on the Extensions page being last in the stack. 2022-07-11 02:08:51 -06:00
auouymous 02e3a91272
Merge pull request #1327 from TZocker/patch-20
Update de.po
2022-07-09 00:14:48 -07:00
auouymous aec5e162cf Add/remove extension preferences buttons when loaded/unloaded.
The user must currently close preferences and reopen to configure
extensions that provide a preferences UI. This is a problem when the
user does not know the extension has preferences, but the sudden
appearance of the button when an extension is enabled might catch the
user's attention.

Furthermore, removing the button when the extension is unloaded prevents
any confusion as to why it is still there.
2022-07-08 16:28:41 -06:00
TZocker ce9b7c98fa
Update de.po 2022-07-08 18:07:46 +02:00
auouymous d291d12ad0
Merge pull request #1313 from auouymous/remove-extension-prefs-border
Remove border around extensions list in preferences.
2022-07-07 01:13:10 -07:00
auouymous db4c6ce8b1
Merge pull request #1325 from neodyne/sk-translation-update-5
Slovak translation updated
2022-07-07 00:19:02 -07:00
auouymous 127052e6fb
Merge pull request #1324 from Vistaus/master
Updated Dutch translation
2022-07-07 00:03:40 -07:00
auouymous 2d363e10f7
Merge pull request #1322 from huftis/update-nn-translation-2022-june
Update Norwegian Nynorsk translation
2022-07-06 23:52:09 -07:00
Karl Ove Hufthammer c16cf4d0d2 Update Norwegian Nynorsk translation 2022-07-06 20:58:03 +02:00
Heimen Stoffels 78bbbeb8ec
Updated Dutch translation 2022-07-06 14:30:26 +02:00
neodyne 833c23fbe8 Slovak translation updated 2022-07-06 13:52:07 +02:00
auouymous a6b2a81d32 make messages 2022-07-05 12:30:11 -06:00
auouymous 35c42227b5
Merge pull request #1317 from ciampix/master
Updated Italian translation
2022-07-05 11:28:25 -07:00
auouymous 6c0adf0d3e
Merge pull request #1320 from tpikonen/open-website-once
util.open_website: Return True to block 'activate-link' default handler
2022-07-05 08:01:37 -07:00
auouymous 95bc019e89
Merge pull request #1321 from tpikonen/channel-title-edit
gpodderchannel.ui: Remove unused strings and title placeholder image
2022-07-05 07:43:21 -07:00
Teemu Ikonen 54ab87f6be gpodderchannel.ui: Remove channel icon placeholder image 2022-07-05 15:27:32 +03:00
Teemu Ikonen f51f49671d gpodderchannel.ui: Remove Invisible title strings from title Stack 2022-07-05 15:24:43 +03:00
Teemu Ikonen 6af0035caf util.open_website: Return True to block 'activate-link' default handler 2022-07-05 14:48:26 +03:00
Marco Ciampa 04fd150638 Updated Italian translation 2022-07-05 10:31:21 +02:00
auouymous 7c75f93083 make messages 2022-07-04 14:53:17 -06:00
auouymous e2f8c64f1a Change "YoutubeDL" and "Youtubedl" to "youtube-dl". 2022-07-04 14:51:45 -06:00
auouymous 4f42533287 Use proper capitalization for YouTube name.
Reported-by: Karl Ove Hufthammer (@huftis)
2022-07-04 14:47:04 -06:00
auouymous 54717b941d Use all lowercase letters in youtube-dl name.
Reported-by: Karl Ove Hufthammer (@huftis)
2022-07-04 14:34:27 -06:00
auouymous f51aba7b40 Do not make default episode limit of 200 a translatable string.
Reported-by: Karl Ove Hufthammer (@huftis)
2022-07-04 14:16:22 -06:00
Teemu Ikonen 2cc1a7614a Merge branch 'master' into dev-adaptive 2022-07-02 23:31:38 +03:00
auouymous 9e29249753 make messages 2022-06-30 01:26:01 -06:00
auouymous 78c2a2df91
Merge pull request #1309 from gpodder/revert-1284-undownload-checkbox
Revert "Fix #864 add undownload checkbox in delete episode confirm dialog"
2022-06-30 00:23:16 -07:00
Eric Le Lay 7410d2c699
Merge pull request #1211 from gpodder/win-taskbar_progress-fix
without the ActivateTab, no progress bar (extended)
2022-06-30 07:52:47 +02:00
auouymous 5a2a2ef9a9 Remove border around extensions list in preferences.
This looks better and provides more space for descriptions on narrow
windows.
2022-06-29 02:39:32 -06:00
auouymous e7184726e1
Merge pull request #1308 from auouymous/fix-1306
Wait for worker threads to finish before quitting.
2022-06-23 12:10:36 -07:00
Eric Le Lay eb638b10fd win, mac packages: update to podcastparser 0.6.8 and mygpoclient 1.9 2022-06-23 19:29:06 +02:00
auouymous 15fa2d4be9 Revert "Fix #864 add undownload checkbox in delete episode confirm dialog (#1284)"
This reverts commit 5eeda318f4.
2022-06-22 14:21:40 -07:00
auouymous 3c62528ec9 Wait for worker threads to finish before quitting.
Closing gpodder while tasks are downloading or pausing causes a hang and
must be killed from task manager or interrupted if launched from command
line. This was introduced in ed5d18e1b0
but only applicable when using python 3.10. The idle_add() callback is
no longer invoked to wake up the dequeue wait_for() condition, likely
due to the main thread terminating early, which didn't happen in older
python versions. Simply waiting for all worker threads to terminate
fixes the issue.

Fixes #1306.
2022-06-22 13:51:23 -06:00
Eric Le Lay b9662ea9e6 windows: update comtypes to 1.1.11 2022-06-20 22:49:46 +02:00
Eric Le Lay dc61815553 taskbar_progress: check windows api return code 2022-06-20 22:49:29 +02:00
Eric Le Lay b1bd429be0
Merge pull request #1246 from auouymous/ondemand-html-description
Generate HTML episode description only when needed.
2022-06-20 13:25:00 +02:00
Eric Le Lay 181617bfa4 taskbar_progress: prevent gpodder never exiting
when closing with download in progress, if not running the event loop a bit
the program is stuck at exit.
Note: taskbar progress doesn't show in windows classic theme
2022-06-19 23:40:19 +02:00
Eric Le Lay 50e12aac52 Merge remote-tracking branch 'origin/master' into win-taskbar_progress-fix 2022-06-19 23:35:09 +02:00
Eric Le Lay 0acaee4ef9 get chapters from feedparser 2022-06-19 11:56:12 -06:00
auouymous 0fe74c18d2 Generate HTML episode description only when needed.
PR #1094 generated an HTML description for any episode that lacked one.
That however increased the database size (almost double in worst case)
because it was storing both text and html versions of each description.
This fixes that by storing the episode thumbnail URL in the database and
generating the HTML description only when shownotes are drawn.

The text description is now cleared for episodes with an HTML
description. This further reduces database size for feeds that provide
both. It also fixes an issue for feeds that provide different text and
HTML descriptions, because the short description would show the text
description and shownotes would show the HTML description. And EQL only
searched the text descriptions, which might not match what the user sees
in the shownotes.
2022-06-19 11:56:12 -06:00
auouymous 97d9459b90 Add episode art URL and chapters to database.
Co-authored-by: Eric Le Lay <elelay@macports.org>
2022-06-19 11:56:12 -06:00
Teemu Ikonen 597d710098 gpo: Add Description and Link fields to info 2022-06-17 10:08:36 +03:00
JKAbrams 0a51542ab5
Add download retry without authentication if auth is set (#1300)
* Add download retry without authentification if auth is set
2022-06-16 15:37:30 -07:00
auouymous 4d4ad7f7cb Make the About dialog text selectable to copy version.
Fixes #1302.
2022-06-16 16:27:05 -06:00
auouymous c9ad2b6884 Add setting to disable find-as-you-type.
The new setting defaults to enabled to preserve the current behavior of
opening search fields in channel and episode lists when the user begins
typing. Disabling the feature ignores the keypresses and requires ctrl-f
or ctrl-shift-f to open or focus the search field.
2022-06-10 23:26:09 -06:00
auouymous 27f445c88b Set current working directory for normalize extension.
This prevents the normalize program from placing files in the directory
gpodder was started from, usually $HOME.
2022-06-08 18:46:35 -06:00
Teemu Ikonen 7019eb8870 Allow marking non-dowloaded episode as deleted 2022-06-08 23:16:18 +03:00
Teemu Ikonen b7b0a87ecd Re-enable update_channel_action after update 2022-06-08 23:16:15 +03:00
auouymous ce6ba8eced Remove space between 'more' and ellipsis character. 2022-06-07 13:37:13 -06:00
auouymous f8d1b22909 Use ellipsis character instead of '...' for deleted titles. 2022-06-07 13:34:15 -06:00
Thomas Perl a9726153c7
iPod support restored using ctypes and libgpod (#1289)
* iPod support restored using ctypes and libgpod
2022-06-02 17:41:42 -07:00
Teemu Ikonen 4996a58475 Fix codestyle (make lint) 2022-06-02 20:59:12 +03:00
Teemu Ikonen 6105ec55e4 preferences: Add a hack to maximize on mobile screen 2022-06-02 20:59:08 +03:00
Teemu Ikonen 223b9fb9a5 Add flap to desktop/preferences.py 2022-06-02 20:58:06 +03:00
Teemu Ikonen 1f9a6cea9c Add flap to gpodderpreferences.ui 2022-06-02 20:58:06 +03:00
Teemu Ikonen b270471c17 Use desktop.preferences dialog 2022-06-02 20:58:06 +03:00
Teemu Ikonen 867fe57185 Require Gdk version 3.0 everywhere 2022-06-02 20:58:06 +03:00
Teemu Ikonen bce111451f Merge branch 'master' into dev-adaptive 2022-05-15 13:55:56 +03:00
Teemu Ikonen 241c656b15 Do not mark episodes streamed from episode selector as played 2022-05-15 13:40:56 +03:00
Teemu Ikonen 40e524b8ab episodeselector: Add a Stream button 2022-05-15 13:40:44 +03:00
auouymous 3e827c771b Recycle forced download tasks when finished.
Using "Start download now" creates a forced task that wasn't recycled
when it finished. This prevented it from being deleted because
can_delete() returns False for tasks in the DONE state.
2022-05-13 20:27:21 -06:00
Eric Le Lay 5eeda318f4
Fix #864 add undownload checkbox in delete episode confirm dialog (#1284)
* Fix #864 add undownload checkbox in delete episode confirm dialog

don't mark episodes new if we don't delete them now

when a mix of downloaded and not downloaded and old episodes
are selected
2022-05-13 01:35:32 -07:00
auouymous 14ea9008fc
Merge pull request #1285 from auouymous/open-episode-download-folder
Add context menu item to open episode download folder.
2022-05-13 00:40:00 -07:00
auouymous b91ea586bc Add open download folder menu item to Episodes menu. 2022-05-13 01:37:13 -06:00
auouymous 741530f5fe
Merge pull request #1287 from auouymous/fix-warnings
Fix warnings
2022-05-13 00:22:08 -07:00
auouymous f6a919759f Remove erroneous logger parameter when failing to get Youtube GDPR URL.
Reported-by: Teemu Ikonen <tpikonen@gmail.com>
2022-05-08 16:09:21 -06:00
Teemu Ikonen 03a6aabf96 Merge branch 'master' into dev-adaptive 2022-04-30 23:48:12 +03:00
auouymous 565a720dbc make messages 2022-04-29 13:03:31 -06:00
auouymous 33aaf2a4eb Close config file after loading it.
Prevents a ResourceWarning when all warnings are enabled.
2022-04-29 02:54:32 -06:00
auouymous 41c312dd68 Change deprecated logger.warn() to logger.warning(). 2022-04-29 02:54:32 -06:00
auouymous 389d096854 Close extension file after reading metadata.
Prevents a ResourceWarning when all warnings are enabled.
2022-04-29 02:54:32 -06:00
auouymous 09556211fc
Merge pull request #1268 from auouymous/ytdl-preferences
Add Youtube-DL extension to preferences dialog.
2022-04-29 01:53:03 -07:00
auouymous 961f0d72bb
Merge pull request #1274 from tpikonen/narrow-prefs
A narrower preferences dialog
2022-04-29 01:48:13 -07:00
Teemu Ikonen 3a5a8ce990 preferences: Ellipsize playlist folder button label 2022-04-29 11:40:28 +03:00
Teemu Ikonen bef33fdd61 preferences: Add Flowboxes to Devices page 2022-04-29 10:49:24 +03:00
Teemu Ikonen 54f3975eed preferences: Set halign to fill in combo_auto_download 2022-04-29 10:15:25 +03:00
auouymous 3b2415ebcd
Merge pull request #1286 from tpikonen/mpris-negpos
MPRIS extension fixes
2022-04-29 00:02:48 -07:00
auouymous e76ebd3538 Bump copyright year in readme. 2022-04-28 22:57:16 -06:00
Teemu Ikonen f26c26bcf9 mpris-listener: Don't set non-existant D-Bus properties
Improves commit 1aae54f14c.
2022-04-28 10:24:48 +03:00
Teemu Ikonen a87d2406b3 mpris-listener: Guard against negative 'pos' from D-Bus
If negative position values are received from MPRIS, treat them as 0.
2022-04-28 10:24:48 +03:00
auouymous 125ee1dfd2 Add context menu item to open episode download folder.
Closes #579.
2022-04-26 04:43:15 -06:00
auouymous f49068311e
Merge pull request #1272 from auouymous/show-episodes-without-enclosures
Show episodes without downloadable content.
2022-04-26 00:12:58 -07:00
Eric Le Lay d21a29bf02
Merge pull request #1280 from gpodder/thp/clickable-shownotes-with-confirmation
left-click open link in browser in HTML shownotes
2022-04-24 14:40:39 +02:00
Thomas Perl 3cbb36167c Gtk UI: Handle links in HTML shownotes 2022-04-23 13:54:31 +02:00
Teemu Ikonen 96d280a90f preferences: Add FlowBoxes to episode limit and autodownload widgets 2022-04-20 11:03:12 +03:00
auouymous 16777ba5eb Enable new status toggle in Episodes menu when any episode is selected.
The menu item was only enabled when the selected episode could be played
or streamed. It was always enabled in the context menu but the keyboard
accelerator could not be used if the episode was not downloaded and not
streamable.

This also forces the play toolbar button to always show the 'open'
label and icon in the progress tab, instead of whatever random state it
was in before.
2022-04-19 04:13:57 -06:00
auouymous 5d304cbf3d Add comments about never unsetting play_or_download() flags once set. 2022-04-19 01:36:03 -06:00
auouymous 3a4b06f3eb
Merge pull request #1269 from auouymous/can-lock
Allow toggling lock of any locked or undeleted episode.
2022-04-19 00:29:10 -07:00
auouymous 1cc7941331 Show episodes without downloadable content.
Non-media RSS feeds only have a textual description and can't be
subscribed to in gpodder. Some media feeds lack downloadable content and
can only be accessed from the website. In both cases, gpodder removes
the episodes without any feedback to the user as to why, making it
appear to be a problem in gpodder.

This patch adds those episodes but prevents automatic download and
displays a proper error when a manual download is attempted. The
episodes also get a web browser icon to indicate they lack downloadable
content. While not downloadable or transferable to media devices,
gpodder can be used to notify the user when new episodes are available
and they can be accessed by clicking through to the website
2022-04-19 01:24:20 -06:00
auouymous 20d58c1174 Add Youtube-DL extension to preferences dialog. 2022-04-17 23:45:05 -06:00
lexolexo 778f5b708c
Added logic to trim away leading/trailing whitespaces in user-clipboard auto-inputted urls (#1276)
* Added logic to trim away leading/trailing whitespaces in user-inputted
urls. Tested against current gpodder-installe executable for correct/
desired behaviour. simplified receive_clipboard_text method of class
gPodderAddPodcast in addpodcast.py
resolves #520
2022-04-16 22:11:10 -07:00
Teemu Ikonen a93f6a9a4c preferences: Increase default size and set Stack width request 2022-04-13 16:28:25 +03:00
Teemu Ikonen d6447d1bfb preferences: Enable word wrapping in checkbox labels 2022-04-13 16:28:25 +03:00
Teemu Ikonen ebbbb50ed1 preferences: Double the spacing in page Boxes to 12 2022-04-13 16:28:25 +03:00
Teemu Ikonen 3d85283bac preferences: Allow a narrower Video page
* Replace Grid with FlowBox in Video page
 * Don't set hexpand on ComboBoxes
 * preferences.py: Ellipsize video format selector combobox strings
2022-04-13 16:28:25 +03:00
Teemu Ikonen b1ef6e0859 preferences: Allow a narrower Devices page
* Enable word wrap in labels
 * Replace GtkGrid with two vertical GtkBoxes
 * Add bottom margins to checkbuttons as label wrapping space
 * preferences.py: Ellipsize device button label, replace deprecated
   set_alignment() with set_xalign()
2022-04-13 16:28:25 +03:00
Teemu Ikonen 73a359aa3a preferences: Hbox to Vbox, align left in Clean-up page 2022-04-13 16:28:25 +03:00
Teemu Ikonen e6594da79f preferences: Make hboxes vboxes in Updates page 2022-04-13 16:28:25 +03:00
Teemu Ikonen 47b10cdc68 preferences: Split Upload button text to a label on gpodder.net page
Also increase bottom margin on the checkbox.
2022-04-13 16:28:25 +03:00
Teemu Ikonen cd15106eac Merge branch 'master' into dev-adaptive 2022-04-12 16:53:23 +03:00
Serkan ÖNDER d7ad5f3f13
Turkish translation fix (#1270)
* Turkish translation update
2022-04-11 01:25:15 -07:00
Teemu Ikonen d3ccce258c
preferences: Use GtkStack instead of GtkNotebook (#1261)
* preferences: Use GtkStack instead of GtkNotebook

* Add Separator and ScrolledWindow to StackSwitcher

* Add ScrolledWindow to preferences Stack

Remove ScrolledWindow from Extensions page.
2022-04-10 04:17:53 -07:00
auouymous 8cefb936c5 Allow toggling lock of any locked or undeleted episode.
This allows undownloaded episodes to be locked with both menus and
guarantees both menus remain consistent.
2022-04-10 03:48:59 -06:00
auouymous 4ac7e1113f Import util namespace instead of each function in youtube-dl extension. 2022-04-09 22:43:43 -06:00
auouymous 93fda2426d
Merge pull request #1265 from tpikonen/mpris-nopos
Fix exceptions on mpris-listener extension
2022-04-09 02:37:30 -07:00
auouymous 160a858856 Prevent crash when gpo sync removes episodes from gpodder.
The _action and _start_action methods expected a second parameter of
values to apply to the format string in first parameter. Many call sites
did not supply the second parameter and messages containing '%' would
cause a crash. Both methods now take a single parameter and call sites
must apply their own format string values.

Fixes #1254.
2022-04-09 00:38:49 -06:00
auouymous 0a3f4f68b2 Toggle `Download with Youtube-DL` menu item with can_download().
Toggling the menu item and filtering episodes with can_download() fixes
an issue where undownloaded episodes in some selections would not offer
the `Download with Youtube-DL` option.
2022-04-08 23:09:49 -06:00
auouymous d1a14cf64b
Merge pull request #1255 from auouymous/toggle-cancel-in-progress-tab
Refactor play_or_download() progress tab action code.
2022-04-08 20:37:45 -07:00
Teemu Ikonen f97116d637 mpris-listener: Fix exceptions on logging 2022-04-04 11:42:17 +03:00
Teemu Ikonen 1aae54f14c mpris-listener: Fix exceptions with unsupported properties 2022-04-04 11:26:36 +03:00
auouymous c8a9ed7ad3
Merge pull request #1262 from tpikonen/link-none
youtube_dl.is_supported_url(): Don't fail on None
2022-03-30 01:11:08 -07:00
Teemu Ikonen 35510160b5 gPodderYoutubeDL.is_supported_url(): Don't fail on None
Return False when url is None. The url can be None for example when an
episode.link attribute is tested for supported media in
PodcastEpisode.from_podcastparser_entry().
2022-03-30 10:54:41 +03:00
auouymous 8e7c8f1448
Merge pull request #1259 from tpikonen/ytdl_import
Remove 'from youtube_dl' imports
2022-03-26 17:05:53 -07:00
Teemu Ikonen 0863d8712d Remove 'from youtube_dl' imports
These caused an exception when run on a system where only yt-dlp is
installed.
2022-03-26 13:49:49 +02:00
Teemu Ikonen 0ab57fb2b1 Fix 'Mark episodes as old' context menu item 2022-03-25 23:43:18 +02:00
Teemu Ikonen c156e15ed3 Don't use shownotes keyboard callback 2022-03-25 23:43:18 +02:00
Teemu Ikonen 52e631bc73 gPodderShownotesLabel: Double html.escape link titles 2022-03-25 23:43:18 +02:00
Teemu Ikonen 542a3a9a2a Merge branch 'master' into dev-adaptive 2022-03-25 22:52:37 +02:00
Teemu Ikonen fb0b45dfe1 Merge commit 'a35e81fe0e52fc1d91ec3ebce4b1da4a4fea0ed9' into dev-adaptive 2022-03-25 22:23:55 +02:00
Teemu Ikonen b4892c3baa Merge commit '5043b0b192b80a061376faee3abecbb7406c61a1' into dev-adaptive 2022-03-25 21:47:56 +02:00
Teemu Ikonen 96db3d7cd4 Merge commit 'bc65930578445e7614a0b99874f33faadba88277' into dev-adaptive 2022-03-25 21:28:15 +02:00
Teemu Ikonen 57589db825 Merge commit '91829b82f6831f1bea7b5d7701117c52463f350b' into dev-adaptive 2022-03-25 21:22:24 +02:00
Teemu Ikonen d3fc65377f Merge commit 'cd35e29fa1d627d206b556421d92907a64ed028c' into dev-adaptive 2022-03-24 22:44:10 +02:00
auouymous 182abc575b Refactor play_or_download() progress tab action code.
Fixes an issue with the toolbar cancel button turning off and on when
entering the progress tab, even though it can't cancel anything until a
selection is made.

Properly cancels failed tasks manually removed from progress tab. Not
cancelling would leave the error icon and prevent downloading or
cancelling.

The download, pause and cancel actions in toolbar and Episodes
menu can now be used to control downloads in the progress tab. The
delete menu item in Episodes menu removes the download from list. This
also allows keyboard accelerators to be used, such as the Delete key
for removing tasks. Accelerators for cancel, and maybe download/pause,
should added in a future PR.

The progress tab context menu now has the same ordering as the other
menus.
2022-03-23 18:53:38 -06:00
auouymous b4d23aae8e
Merge pull request #1252 from auouymous/fix-1248-cancel-failed-tasks
Refactor play_or_download() episode action code.
2022-03-23 17:41:53 -07:00
auouymous 01cd2696f7 Refactor play_or_download() episode action code.
Streaming was always possible (#867) for all audio and video episodes if
an audio player was configured. Now it is only possible if a player is
configured for the episode's type.

Methods have been added to PodcastEpisode that are either now used by
actions or replicate the conditions used by actions to filter
selections. This will help prevent mismatched conditions between
play_or_download() and episode actions. And play_or_download() is easier
to reason about and should prevent future bugs such as #1250.

Fixes #1250.
2022-03-20 02:50:46 -06:00
auouymous 5cbd3175b2 Group Play with Preview and Stream since all three use the same icon. 2022-03-20 02:40:51 -06:00
auouymous 5314617e1f
Merge pull request #1213 from auouymous/fix-1212
mount_volume_for_file() must only use Gtk when the Gtk UI is available.
2022-03-16 16:09:26 -07:00
auouymous f6bae4f780 Remove invalid parameter passed to Device.cancel().
Fixes https://github.com/gpodder/gpodder/issues/1212#issuecomment-1069661280
2022-03-16 17:03:03 -06:00
Eric Le Lay a35e81fe0e
Merge pull request #1249 from auouymous/set-episode-toolbar-menu-actions
Set episode toolbar and menu actions.
2022-03-16 22:44:40 +01:00
Eric Le Lay 2ee8c23b31 fix #1227 pixbuf could be None in some cases
I couldn't reproduce it but I guess it's possible
2022-03-16 22:29:18 +01:00
Eric Le Lay 5043b0b192
Merge pull request #1248 from auouymous/cancel-failed-tasks
Allow failed downloads to be cancelled from episodes list.
2022-03-16 21:10:01 +01:00
auouymous dabd6b3353 Also toggle delete in Episodes menu when toggling lock. 2022-03-16 05:39:19 -06:00
auouymous de2094253a Set episode toolbar and menu actions.
Items in the Episode menu were not disabled when the progess tab was
opened. This consolidates the enabling and disabling of buttons in the
toolbar and items in the Episodes menu, and fixes that issue.

It also changes the label and icon for the toolbar play button to be
Open, Play, Preview or Stream.
2022-03-16 05:15:44 -06:00
auouymous 3a60f36876 Disable episode delete menu item when it can't be used.
Locked episodes can not be deleted, but the delete menu item remained
active for them.
2022-03-16 02:38:12 -06:00
auouymous 7634ccd9b0 Rename menuChannels to menuEpisodes. 2022-03-16 02:25:00 -06:00
auouymous f0156e1bda Directly access the Extras menu to add extension menu items. 2022-03-16 02:20:26 -06:00
auouymous fdccfec41c Fix downloading file count when pausing or cancelling synchronizing tasks.
PR #1243 added separate pausing and cancelling counts, and included them
in the downloading file count. However, synchronizing tasks can also be
pausing or cancelling and would erroneously be included in the
downloading file count.
2022-03-16 01:58:34 -06:00
auouymous f91f9e29b1 Change order of progress button status counts. 2022-03-16 01:47:36 -06:00
auouymous 6731b63706 Allow failed downloads to be cancelled from episodes list.
This not only removes the failed download from the progress list, but
also removes the error icon from the episode list.
2022-03-15 19:51:45 -06:00
auouymous bc65930578
Merge pull request #1244 from auouymous/undelete-episode-on-download
Undelete deleted episodes when a download is attempted.
2022-03-15 15:06:45 -07:00
auouymous 4313db72c0
Merge pull request #1243 from auouymous/nr-cancelling-pausing-tasks
Show number of pausing and cancelling tasks in progress tab.
2022-03-15 15:04:55 -07:00
auouymous 91829b82f6
Merge pull request #1242 from auouymous/pause-resume
Add pausing and resuming from Episodes and context menus, and toolbar.
2022-03-15 14:58:00 -07:00
auouymous cd35e29fa1 make messages 2022-03-08 22:08:59 -07:00
JuanCanham d7b5843123
Make error message more verbose on NotFound sync error (#1235)
* Make error message more verbose on NotFound sync error

* Add Spanish translation

Co-authored-by: Rioting Pacifist <linux@riotingpacifist.net>
2022-03-08 21:59:40 -07:00
auouymous d0ad77b9a7 Undelete deleted episodes when a download is attempted.
In the event of a download failure, the error icon will properly
display, and the episode will remain undeleted after a restart for
another download attempt.
2022-03-08 17:38:50 -07:00
auouymous e1d90d8765 Show number of pausing and cancelling tasks in progress tab.
These transitions can sometimes take a while and this will provide some
feedback to the user that the transition is happening.
2022-03-08 17:06:31 -07:00
auouymous 6f0f623ead Add pausing and resuming from Episodes and context menus, and toolbar.
Queued and downloading episodes can now be paused from the episode list,
and the download button can then be used to resume the paused episode.

Fixes #1162.
2022-03-08 06:21:10 -07:00
auouymous 0bf859bf21
Merge pull request #1233 from auouymous/memoize-youtube-channel-id
Memoize youtube channel ID and feed data.
2022-03-07 15:22:18 -07:00
Eric Le Lay ffbfeb5d92 macOS: updated to python 3.9 2022-03-07 21:46:00 +01:00
Eric Le Lay 92500e92cd update gpodder-osx-bundle to 22.3.7 2022-03-07 21:39:20 +01:00
auouymous a83b750459 Catch youtube 404 errors.
Avoids parsing the 404 error page as XML and then throwing malformed XML
errors.
2022-02-27 20:46:50 -07:00
auouymous 20dd397e9e Memoize youtube channel ID and feed data.
Internal youtube support and the youtube-dl extension both cause the
youtube feed URL to be fetched three times per update. Caching the feed
data from feedcore allows internal support to only load the feed once.
The lru_cache removes one of the youtube-dl fetches, not perfect, but
two is better than three. I saw a 40% decrease in update times when
using the internal youtube code.

Throwing an exception from get_channel_id_url() prevents get_cover() and
get_channel_desc() from attempting to fetch a None URL, and provides
more accurate errors.

The lru_cache on get_youtube_id() saves 1ms per youtube channel when
updating. Which adds up with a lot of channels, and might be more on
slower devices.
2022-02-27 02:52:06 -07:00
auouymous be64fdda43 Tweak description for the youtube-dl extension. 2022-02-20 21:20:51 -07:00
auouymous 8fbb24e8ec
Merge pull request #1228 from auouymous/create-partial-file-when-reusing-task
Create partial file when reusing cancelled tasks.
2022-02-15 15:37:15 -07:00
auouymous f7497c617a Create partial file when reusing cancelled tasks.
The partial file for a cancelled task is deleted, but the task is not
removed from progress list while other tasks are downloading.
Downloading the cancelled episode again would reuse the existing task
without creating a new partial file. This prevented resuming the
download after restarting gPodder, and caused the youtube-dl extension
to fail if used to re-download it.
2022-02-08 03:57:22 -07:00
auouymous 1950a055f9
Merge pull request #1182 from auouymous/add-yt-dlp-support
Use youtube-dl or yt-dlp for the youtube-dl extension.
2022-02-07 23:20:23 -07:00
auouymous 8f9b95bfb8
Merge pull request #1219 from auouymous/ytdl-partial-files
YoutubeDL partial file fixes
2022-02-07 23:17:42 -07:00
auouymous d785b3e7ca
Merge pull request #1221 from auouymous/gpo-after-sync
Perform chosen after sync action in gpo.
2022-02-07 23:09:55 -07:00
auouymous f05c05463a Fix double word in Norwegian Nynorsk translation. 2022-02-07 03:58:59 -07:00
auouymous c765c07612
Merge pull request #1226 from huftis/update-nn-translation-2022-feb
Update Norwegian Nynorsk translation for February 2022 release
2022-02-06 16:30:17 -07:00
Karl Ove Hufthammer e4629829e1 Update Norwegian Nynorsk translation for February 2022 release 2022-02-06 18:20:32 +01:00
auouymous 61b13f514a Add mnemonics for channel and podcast directory dialog buttons. 2022-02-06 02:33:18 -07:00
auouymous a2495beeb9
Merge pull request #1224 from Vistaus/master
Updated Dutch translation
2022-02-05 17:01:24 -07:00
auouymous 7dd48efea7
Merge pull request #1222 from tpikonen/export-headerbar
gPodderExportToLocalFolder: Use GtkDialog.add_buttons()
2022-02-05 16:37:48 -07:00
Teemu Ikonen e9cb4e9eaa Fix typo on do_save_episode() strings 2022-02-05 22:22:38 +02:00
Teemu Ikonen 3f64a58fa9 gPodderExportToLocalFolder: Use GtkDialog.add_buttons()
Create the dialog buttons with GtkDialog.add_buttons(). This places them
either to the dialog action area, or to the headerbar, accoording to the
system setting.

Also set 'do-overwrite-confirmation' property of the Dialog to False.
2022-02-05 22:22:38 +02:00
Heimen Stoffels 74118a2820
Updated Dutch translation 2022-02-05 14:13:26 +01:00
auouymous 044c3f0bde
Merge pull request #1223 from neodyne/sk-translation-update-4
Translation update (sk)
2022-02-05 03:55:20 -07:00
neodyne 301179b32e Translation update (sk) 2022-02-04 18:14:42 +01:00
Teemu Ikonen cab3629813 Merge branch 'master' into dev-adaptive 2022-02-04 12:30:02 +02:00
Teemu Ikonen 4453316aa8 Merge tag 'merge5' into dev-adaptive 2022-02-04 12:22:51 +02:00
Teemu Ikonen 75c3d49b5e Merge tag 'merge4' into dev-adaptive 2022-02-04 12:07:33 +02:00
Teemu Ikonen 9aebe95020 Merge tag 'merge3' into dev-adaptive 2022-02-04 11:39:36 +02:00
Teemu Ikonen 28c5774f89 Merge tag 'merge2' into dev-adaptive 2022-02-04 10:56:20 +02:00
Teemu Ikonen 0e1c0b209e Merge tag 'merge1' into dev-adaptive 2022-02-04 10:55:32 +02:00
auouymous 384a2c6c88 Perform chosen after sync action in gpo.
Fixes #1216.
2022-02-03 20:10:23 -07:00
auouymous aa2459806e Use youtube-dl or yt-dlp for the youtube-dl extension. 2022-02-03 17:16:28 -07:00
auouymous 098c55a754 make messages 2022-02-02 19:44:31 -07:00
auouymous 927a87d5ec
Merge pull request #1188 from tpikonen/stockless-gpodder
Remove deprecated Gtk features from main gPodder window
2022-02-02 19:34:02 -07:00
Teemu Ikonen 222dba31be GtkBuilderWidget: Remove '_builder_expose' kwarg, add '_gtk_properties'
The '_builder_expose' argument to GtkBuilderWidget.__init__() allowed
binding of names in the ui-file to objects defined outside of the
ui-file.

Glade does not allow setting properties to values which are not defined
in the ui-file, so we set GTK/Gobject properties explicitly. This is
made with a new kwarg '_gtk_properties' in GtkBuilderWidget.__init__()
which is a dict with a (object_id, property_name) key.
2022-02-02 12:14:30 +02:00
Teemu Ikonen 0bda795a83 gpodder.ui: Remove extra rows and columns from GtkGrids
Resize:
 * hbox_search_episodes
 * hboxContainer
 * hboxUpdateFeeds
 * vbox_episode_list
 * vbox42
 * vboxChannelNavigator
 * vMain
 * hboxDownloadSettings
 * hboxDownloadLimit
 * hboxDownloadRate
2022-02-02 12:14:30 +02:00
Teemu Ikonen a607aeb498 gpodder.ui: Remove deprecated GTK features
* Replace stock-ids with standard icon names
 * Remove deprecated rules-hint from treeAvailable
 * Set can-focus to True in search entries
 * Remove use-underline from buttons
2022-02-02 12:14:30 +02:00
Teemu Ikonen 146c6e4d2f gpodder.ui: Save with Glade 3.38.2, require GTK 3.16 2022-02-02 12:14:30 +02:00
Teemu Ikonen cb61d76474 Replace Gtk.STOCK_ button labels with strings 2022-02-02 12:13:24 +02:00
Teemu Ikonen 282996cd16 Replace Gtk.STOCK_ icons with standard icon names 2022-02-02 09:31:27 +02:00
Teemu Ikonen 011718c032 gPodderShownotesHTML: Replace Gtk.Action with Gio.SimpleAction
Gtk.Action is deprecated.
2022-02-02 09:31:27 +02:00
auouymous 9d72872c50 Clean up parial files created by cancelled YoutubeDL downloads.
YoutubeDL can append an extension to the partial file, creating
additional partial files. Adaptive formats create up to three more
partial files. Cancelling a download will leave behind these extra
partial files, and requires manual removal outside of gPodder.
2022-02-01 22:09:00 -07:00
auouymous a3815cdf05 YoutubeDL extension should always rename partial files with extensions.
If a partial file exists with an extension appended to it, it should
always be renamed even if the partial file without an extension was
written to. Yt-dlp sometimes writes part of the file to the partial
file (bug), but always writes all of the file to a partial file with an
extension.
2022-02-01 22:00:44 -07:00
Eric Le Lay 2b3e6538c1
Merge pull request #1214 from auouymous/rename-downloading-to-syncing-when-syncing-files
Show 'Syncing' in progress tab instead of 'Downloading' when syncing.
2022-01-30 19:39:48 +01:00
auouymous 41b8f52fbf mount_volume_for_file() must only use Gtk when the Gtk UI is available.
Fixes #1212.
2022-01-25 14:32:04 -07:00
auouymous 3ff7ed37a5 Show 'Syncing' in progress tab instead of 'Downloading' when syncing. 2022-01-25 00:58:27 -07:00
auouymous c2d70b5e29 deviceplaylist should require Gio, not Gtk.
Fixes #1212.
2022-01-24 14:27:23 -07:00
Eric Le Lay 8873604e2d fix #1212 Error when running from CLI
the Gtk import was there by mistake
2022-01-24 21:16:32 +01:00
auouymous 57045619d3 Also open dialog if xdg-open is not found when opening a folder. 2022-01-16 22:02:27 -07:00
auouymous ee769c91b7
Merge pull request #1201 from bwildenhain/1003-check-for-xdg-open
Open error dialog if user tries to use not-installed xdg-open
2022-01-16 21:57:16 -07:00
Benedikt Wildenhain 34098c19fc
Open error dialog if user tries to use not-installed program
Currently trying to use default player (xdg-)open when it's not installed
will only cause messages on the console, which might not be visible to
the user. This PR creates an alert box in this case.

Fixes #1003.
2022-01-16 18:24:41 +01:00
Eric Le Lay e3462bf34e taskbar_progress: move the ActivateTab call when we have the window_handle 2022-01-15 17:30:03 +01:00
Eric Le Lay 1fa310e343 move to Xcode 11.4.1 following circleci deprecation 2022-01-14 09:25:01 +01:00
Eric Le Lay b664e79129 taskbar_progress: add missing import ctypes 2022-01-09 18:05:06 +01:00
Arne Schwarck a66a968c23
Add 64bit Python Support 2022-01-07 21:26:19 +01:00
Arne Schwarck 2748f7a678
without the ActivateTab, no progress bar
https://stackoverflow.com/questions/17607415/python-tkinter-windows-7-taskbar-progress
2022-01-07 21:11:10 +01:00
Eric Le Lay 40fd34b14a
Merge pull request #1206 from auouymous/fix-1195
Fix shownotes for episodes that contain HTML comments.
2022-01-03 09:32:33 +01:00
auouymous 3938809dd5 Fix shownotes for episodes that contain HTML comments.
When html5lib is used, a function is returned for each comment in the
HTML. It should be safe to skip functions until something else is found
to use them that causes issues finding hyperlinks.

Fixes #1195.
2022-01-01 18:15:51 -07:00
Eric Le Lay b8065cadf7 fix 1190 ERROR: Could not create save_dir on windows
"C:\gpodder-xxx\config\Downloads" results in
scheme="c" and path="\gpodder-xxx\config\Downloads"
(not double backslash)
2021-11-28 22:02:12 +01:00
Eric Le Lay fc98f3f95f
Merge pull request #1193 from auouymous/fix-youtube-dl-percent-escaping
Do not try to rename the outtmpl file in the Youtube-DL extension.
2021-11-06 19:09:26 +01:00
Eric Le Lay 28d7c6ce36
Merge pull request #1126 from gpodder/win-comtypes
Add comtypes module to Windows build for the taskbar progress extension.
2021-11-06 16:12:27 +01:00
Eric Le Lay ec6b63960c
Merge pull request #1191 from gpodder/fix-1190-gio-windows
fix #1190 ERROR: Could not create save_dir on windows with gio
2021-11-06 16:12:11 +01:00
auouymous 651cf90e23 Do not try to rename the outtmpl file in the Youtube-DL extension.
The output file does not contain the escaped percents, resulting in a
file not found if renamed.

Youtube-DL also does not use '$' and escaping it is not required. An
episode title containing a '$' will produce a file containing two dollar
signs, and is then renamed to a single dollar sign. But a channel name
containing a dollar sign causes Youtube-DL to create a new channel
directory, with two dollar signs, for the output file. This directory
remains empty after gpodder moves the output file.

Both cases can be tested by renaming a channel to have '%$' and then
downloading episodes with Youtube-DL.

Therefore, dollar signs should not be escaped and renaming outtmpl is
not required as it will always match tempname, when assuming percents
are unescaped.
2021-11-04 11:44:05 -06:00
auouymous 588cc79366
Merge pull request #1179 from comradekingu/patch-1
Norwegian Bokmål translation updated
2021-11-03 14:28:04 -07:00
Eric Le Lay 623b505357 taskbar_progress: fix AttributeError: 'ApplicationWindow' object has no attribute 'window'
adapted from https://stackoverflow.com/a/27236258
2021-11-01 18:34:45 +01:00
Eric Le Lay d423aad602
Merge pull request #1189 from dreamflasher/patch-1
remove unused import
2021-11-01 16:52:47 +01:00
Eric Le Lay 00b421b929 fix #1190 ERROR: Could not create save_dir on windows with gio
util.new_gio_file returned a GDummyFile, where every operation failed,
in this case make_directory_with_parents.
2021-11-01 16:36:57 +01:00
Marcel Ackermann 2f42c11e59
remove unused import
closes https://github.com/gpodder/gpodder/issues/1187
2021-10-30 11:13:00 +02:00
Allan Nordhøy f7d1bfebd1
Suggested changes and new fixes made 2021-10-28 14:20:47 +00:00
auouymous 10e48a3ea5
Merge pull request #1174 from auouymous/fix-youtube-json
Improve Youtube initial player response regular expression.
2021-10-28 03:31:24 -07:00
auouymous ce99daf065
Merge pull request #1171 from auouymous/fix-1147
Fix youtube-dl re-download after a failed download
2021-10-28 03:27:56 -07:00
auouymous 8cb06e3c3e
Merge pull request #1163 from auouymous/disable-ytdl-menu-item-while-downloading
Disable `Download with Youtube-DL` menu item while downloading episode.
2021-10-28 03:25:36 -07:00
auouymous 5499658ee3
Merge pull request #1172 from tpikonen/stockless-episodeselector
Remove deprecated GTK features from episodeselector
2021-10-28 03:23:30 -07:00
Allan Nordhøy 3b80c944ae
Erroneous formatting removed 2021-10-20 15:15:34 +00:00
auouymous 0666aa2abf
Merge pull request #1180 from neodyne/sk-translation-update-3
Slovak translation update
2021-10-20 04:25:27 -07:00
neodyne 0dc09ab56c minor grammatical number fix 2021-10-20 11:53:06 +02:00
Teemu Ikonen 5990e57a81 episodeselector: Add underline mnemonics to all buttons
Set use-underline on all buttons in gpodderepisodeselector.ui.

Add underscore mnemonics to the special 'gpodder-download' button and in
'remove-button' and 'ok-button' args of callers in main.py.
2021-10-18 15:30:54 +03:00
neodyne b302f71c90 Slovak translation update 2021-10-17 12:49:26 +02:00
Allan Nordhøy e640cd2c62
Norwegian Bokmål translation updated 2021-10-16 16:19:00 +02:00
auouymous a5a5cb6065 make messages 2021-10-15 04:03:34 -06:00
auouymous cae617701f Support youtube 'user' feed URLs in for_each_feed_pattern(). 2021-10-14 19:28:05 -06:00
auouymous 8a403d2783 Optimize get_youtube_id().
The watch URL is the most common and should be checked first. The swf
URL probably no longer works but can be kept for compatibility.
2021-10-14 19:19:12 -06:00
auouymous 6ced881d74 Improve Youtube initial player response regular expression.
The text may contain "};" patterns inside the initial player response.
And the non-greedy regex would fail to match the entire IPR, causing it
to fail during JSON decoding.
2021-10-13 21:58:24 -06:00
auouymous 8d0bfce460 Remove dead code in get_foreground_color(). 2021-10-13 15:34:26 -06:00
Teemu Ikonen ce66b5fa62 episodeselector: Remove GtkStock usage
* Rename gPodderEpisodeSelector constructor kwarg 'stock_ok_button'
   to 'ok_button'. Change callers in main.py to use it with text labels
   instead of Gtk.STOCK_* values
 * Set transient for parent widget
2021-10-12 23:14:14 +03:00
Teemu Ikonen a3700e6a3d gpodderepisodeselector.ui: Remove deprecated GTK features
* Replace GTK stock labels with text
 * Replace icon stock-ids with standard icon names
 * Remove deprecated Alignment widgets
 * Set always show image in OK button
2021-10-12 23:13:00 +03:00
Teemu Ikonen 49638aadfc gpodderepisodeselector.ui: Save with Glade 3.38.2 2021-10-12 20:43:08 +03:00
auouymous db2aa385d0 Cancel failed task before streaming.
livestream to be streamed, after realizing it was a livestream. This
however caused the youtube-dl extension to fail when downloading DRM
content after gpodder failed to download it, because the partial file
was missing.

This removes that fix and properly cancels the failed task before
streaming to remove the partial file.

Fixes #1147.
2021-10-11 20:11:18 -06:00
auouymous 263c4ad9fe Actually delete partial file when cancelling.
Calling run() with CANCELLED state only returns without performing any
work. The CANCELLING state actually deletes the partial file and
recycles the task.
2021-10-11 19:53:00 -06:00
auouymous f7ba81ec73 Disable `Download with Youtube-DL` menu item if any downloading episodes.
This includes paused downloads. Avoids any confusion as to whether or
not the downloading or paused episodes will be finished with Youtube-DL.
2021-10-11 15:14:02 -06:00
Eric Le Lay 69e242184c
Merge pull request #1145 from auouymous/delay-window-position-restore
Delay restoring window position until after it has been shown.
2021-10-11 22:16:42 +02:00
Eric Le Lay 3aba6ddea5
Merge pull request #1156 from tpikonen/stockless-dialogs
Remove deprecated GTK features from simple dialogs
2021-10-09 18:06:01 +02:00
auouymous ab61a04d0c
Merge pull request #1161 from auouymous/paused-episode-icon
Paused episode icon
2021-10-05 18:48:25 -07:00
auouymous 9daca64e2e
Merge pull request #1160 from auouymous/use-icons-for-pausing-cancelling
Use icons when pausing or cancelling tasks.
2021-10-05 18:31:11 -07:00
auouymous 46335b9903
Merge pull request #1159 from auouymous/show-paused-tasks-in-progress-tab
Show paused tasks in progress tab.
2021-10-05 18:29:55 -07:00
Teemu Ikonen fb8d71bdb8 gpodderpreferences.ui: Add accelerators to dialog buttons 2021-09-17 22:11:10 +03:00
Teemu Ikonen 5f3e170e72 gpodderexporttolocalfolder.ui: Set can-focus in Dialog, reorder buttons
Also require GTK 3.16.
2021-09-17 22:11:10 +03:00
Teemu Ikonen e8c6969abd gPodderExportToLocalFolder: Remove deprecated GTK stock items
gpodderexporttolocalfolder.ui:
 * Save with Glade 3.38.2
 * Replace GTK stock labels with text

exportlocal.py: Set transient for parent (was not set before)
2021-09-17 22:11:10 +03:00
Teemu Ikonen 6483059d41 gPodderConfigEditor: Remove deprecated GTK features
gpodderconfigeditor.ui:
 * Save with Glade 3.38.2, require GTK 3.16
 * Replace gtk-close with text label
 * Use Dialog internal action_area for Close button
 * Add underline accelerator for '_Show All'

configeditor.py: Set transient for parent
2021-09-17 22:11:10 +03:00
Teemu Ikonen 1ef54e3216 gPodderAddPodcast: Remove deprecated GTK stock items
gpodderaddpodcast.ui:
 * Save with Glade 3.38.2, require GTK 3.16
 * Set can-focus to True where needed
 * Replace GTK stock labels with text

addpodcast.py: Set transient for parent
2021-09-17 22:11:10 +03:00
Teemu Ikonen f1739d3212 gPodderWelcome: Remove deprecated GTK features
gpodderwelcome.ui:
 * Save with Glade 3.38.2
 * Replace gtk-cancel stock with text label
 * Replace padding with margins
 * Replace border-width with margins
 * Set can-focus to True on buttons

welcome.py: Set transient for parent
2021-09-17 22:11:10 +03:00
auouymous 6feb312936 Don't recycle failed or paused tasks. 2021-09-16 18:01:10 -06:00
auouymous d20fbbe8a0 Set a paused icon in episode list when an episode is paused. 2021-09-14 04:10:40 -06:00
auouymous d508a3df8d Show paused tasks in progress tab. 2021-09-14 03:34:27 -06:00
auouymous 65aa1c679a Use icons when pausing or cancelling tasks.
This avoids shifting the list left and then right for single tasks. It
also gives more feedback that the task is being paused or cancelled.
2021-09-14 02:40:17 -06:00
Mark Weaver ed5d18e1b0 fixes #1152 and an odd corner case (#1155)
* #1152: fix re-ordering downloads list

* fix downloading a task that's already been removed from the download list

* fix download/delete/download of the same episode

* fix pausing/cancelling sync tasks; clean up partially synchronised files

* fix cancelling a failed download

* make failed/paused/cancelled mutually exclusive so the code has less paths (and hopefully is easier to follow)
2021-09-14 00:53:15 -07:00
Eric Le Lay 032161c002
Merge pull request #1158 from blushingpenguin/unused_vars
remove unused variables from play_or_download
2021-09-13 21:12:33 +02:00
blushingpenguin c86c7412ae remove unused variables 2021-09-13 15:45:39 +01:00
Teemu Ikonen 2ded35705e
Preferences: Remove deprecated GTK features (#1154)
* gpodderpreferences.ui: Save with Glade 3.38.2

* gpodderpreferences.ui: Add tab label children

* gpodderpreferences.ui: Return notebook pages to correct order

* gpodderpreferences.ui: Use named icons, replace stock-ids

* gpodderpreferences.ui: Remove extra rows and columns from table_video

* gpodderpreferences.ui: Use traditional indicator for CheckButtons

* gpodderpreferences.ui: Set can-focus to True where appropriate

* gpodderpreferences.ui: Add border-width to mygpo_config

* gpodderpreferences.ui: Add margins around dialog ButtonBox

* gpodderpreferences.ui: Replace gtk-close stock label with text

* preferences.py: Set transient for parent

* podcastdirectory.py: Set transient for parent

This was accidentally removed in d9a0c7d15a.

* gpodderchannel.ui: Downgrade GTK requirement to 3.16

* README.md: Increase minimum GTK version to 3.16
2021-09-10 17:14:12 -07:00
auouymous 3d966b95b2
Merge pull request #1149 from blushingpenguin/queue
#1117, #1137: fixes for pause/resume/cancelling download tasks
2021-09-08 16:23:18 -07:00
Eric Le Lay aa9cb3a597
Merge pull request #1151 from ColdIce1/feat/contribution
Add contributing.md
2021-09-04 21:01:14 +02:00
ColdIce1 bd517fe6c0 Add linting details 2021-09-02 21:25:31 +02:00
auouymous 9d92e86bc1
Merge pull request #1141 from auouymous/delay-column-reorder
Delay episode treeview column reordering.
2021-08-31 22:03:40 -07:00
auouymous 42223760e9
Merge pull request #1135 from gpodder/detailed-text-dialog
Gtk UI: Use a TextView for dialogs with multiple text lines
2021-08-31 22:01:24 -07:00
blushingpenguin 20b0ed3aae #1117, #1137: fix another lint issue 2021-08-31 14:43:55 +01:00
blushingpenguin 3c322b610a Merge branch 'master' into queue 2021-08-31 14:42:20 +01:00
blushingpenguin 723c052fc2 #1117, #1137: fix lint issue 2021-08-31 14:40:13 +01:00
blushingpenguin 8760b6d315 #1117, #1137: fix re-introduced race queuing tasks 2021-08-31 14:37:36 +01:00
ColdIce1 ca25b02195 Add contributing.md 2021-08-31 10:31:19 +02:00
blushingpenguin 68195acc00 #1117, #1137: fixes for pause/resume/cancelling download tasks 2021-08-30 15:45:20 +01:00
auouymous dd299bce25 Delay restoring window position until after it has been shown.
The window manager might not honor the move request until after the
window is shown. This can cause window contents to be rendered at
a shifted offset inside the window borders.
2021-08-28 02:59:46 -06:00
Thomas Perl 4310fdbf5e Gtk UI: Use a TextView for dialogs with multiple text lines 2021-08-28 09:06:01 +02:00
Thomas Perl 7a4afcc198 Gtk UI: Use secondary text in Gtk.MessageDialog for formatting 2021-08-28 09:02:24 +02:00
auouymous a8386049af Delay episode treeview column reordering.
Moving columns before shown can produce "Negative content height"
warnings for themes with vertical padding or borders on treeview header
buttons.
2021-08-26 05:34:16 -06:00
TZocker 63217eb2f1
Update de.po (#1140)
* Update de.po
2021-08-23 03:08:02 -07:00
Eric Le Lay 99b2b00950
Merge pull request #1139 from neodyne/sk-translation-update-2
Update Slovak translation
2021-08-20 13:56:32 +02:00
neodyne 3e86bbe44b Update Slovak translation 2021-08-20 12:12:01 +02:00
auouymous e3479b2d7d
Merge pull request #1138 from serkan-maker/master
translation update for turkish
2021-08-19 20:07:59 -07:00
Serkan ÖNDER 1586f0aa52
translation update for turkish 2021-08-19 20:18:36 +03:00
Eric Le Lay 9a3eda7d6b
Merge pull request #1130 from auouymous/youtube-duration
Query duration for youtube episodes when not using youtube-dl.
2021-08-18 14:11:07 +02:00
Eric Le Lay 78bff43731
Merge pull request #1131 from auouymous/move-scale_pixbuf-to-util
Move scale_pixbuf to util.py and apply #1107 refactoring.
2021-08-18 14:09:21 +02:00
Eric Le Lay 90d2112c76
Merge pull request #1108 from ollieparanoid/close-after-startup
bin/gpodder cli: add sections and --close-after-startup option
2021-08-18 14:06:49 +02:00
Eric Le Lay 82fc94f3af
Merge pull request #1132 from auouymous/disable-distro-updates
Allow distributions to disable the update check.
2021-08-18 14:04:02 +02:00
auouymous d0171a7c8c Allow distributions to disable the update check.
Fixes #1103.
2021-08-16 18:37:33 -06:00
auouymous 634738d189 Bump podcastparser version for windows and mac builds. 2021-08-16 05:16:48 -06:00
Oliver Smith ec60a55c36
bin/gpodder: add --close-after-startup option
Add an option that helps with measuring / profiling startup performance.
2021-08-15 20:36:45 +02:00
Oliver Smith 327694ab5a
bin/gpodder: add option groups logging/advanced 2021-08-15 20:35:34 +02:00
auouymous 114f708c74 Move scale_pixbuf to util.py and apply #1107 refactoring. 2021-08-14 23:42:17 -06:00
auouymous bba167b811 Query duration for youtube episodes when not using youtube-dl.
The duration is not available in the youtube feed and requires a request
for each episode. It was set when downloading but the user had no way of
knowing how long an episode was before downloading it. Live streams do
not have a duration until they end, and remain blank until downloaded or
the next update.

This will increase the time it takes to update feeds, with new
subscriptions possibly taking 16x longer to update due to the 16
requests vs the previous single request. Updating existing feeds
will only have an additional request for each new episode.
2021-08-14 23:09:07 -06:00
Teemu Ikonen 360eea3e31 adaptive/preferences.py: Require correct versions of Gdk and Gtk 2021-08-14 19:45:17 +03:00
Teemu Ikonen 526d2128c8 Fix isort / make lint 2021-08-14 19:30:09 +03:00
Teemu Ikonen 3564eedd7d Revert "Swipe hack to fix libhandy behaviour"
This reverts commit 6b62e79f3f.

Nested swipeable containers seem to work better in libhandy 1.2.2.
2021-08-13 10:03:02 +03:00
Teemu Ikonen 6c8583acf9 Remove adaptive ui-files identical to the gtk ones 2021-08-12 19:50:38 +03:00
Teemu Ikonen b8497500e4 Retire adaptive/podcastdirectory.py, patch desktop version 2021-08-12 19:50:38 +03:00
Teemu Ikonen ad7b7a89c9 Set default ui_folder to ui/gtk 2021-08-12 19:50:38 +03:00
Teemu Ikonen 0bcc751051 Load menus.ui from ui/adaptive 2021-08-12 19:50:38 +03:00
Teemu Ikonen 9c9f526dbb Set ui_folder to adaptive in gPodder instance 2021-08-12 19:50:38 +03:00
Teemu Ikonen 14f3584902 Set ui_folder to adaptive in gPodderPreferences instances 2021-08-12 19:50:38 +03:00
Teemu Ikonen ec68adb1d2 Set ui_folder to adaptive in gPodderPodcastDirectory instances 2021-08-12 19:50:38 +03:00
Teemu Ikonen 8ba6122592 Set ui_folder to adaptive in gPodderEpisodeSelector instances 2021-08-12 19:50:38 +03:00
Teemu Ikonen 96a5a31af4 Partially revert "Show Progress button also when syncing to device"
This reverts commit b5b86da519 on the
part of syncui.py.

Remove start_cb, show the progress button on main.py.
2021-08-12 19:50:38 +03:00
Teemu Ikonen 37d93cd5e5 Unbreak Delete Podcasts dialog 2021-08-12 19:50:38 +03:00
Teemu Ikonen bf23ef88ad Remove new_episodes_forward button from episodeselector 2021-08-12 19:50:38 +03:00
Eric Le Lay 3f695b0e56
Merge pull request #1127 from auouymous/click-to-open-channel-settings
Double-click or press Enter to open channel settings.
2021-08-12 18:06:31 +02:00
Eric Le Lay 23ec7a719f
Merge pull request #1124 from gpodder/fix-1099-edit-podcast-escape-folder
fix #1099 folder not escaped when podcast renamed from dialog
2021-08-12 18:02:03 +02:00
auouymous c35c6aa887 Double-click or press Enter to open channel settings.
This provides similar behavior to opening shownotes for episodes.
2021-08-12 06:27:53 -06:00
auouymous cac8100ac7 Add comtypes module to Windows build for the taskbar progress extension. 2021-08-12 05:08:40 -06:00
Eric Le Lay f74eba2e72 fix #1099 folder not escaped when podcast renamed from dialog 2021-08-12 11:15:06 +02:00
Teemu Ikonen b2514bc8c1 Remove episode_list_forward button 2021-08-12 11:50:24 +03:00
Teemu Ikonen cdd573f93f Remove channel_list_forward button 2021-08-12 11:44:51 +03:00
Teemu Ikonen 5eee09ce49 Merge branch 'master' into dev-adaptive 2021-08-12 11:34:46 +03:00
Teemu Ikonen 52a02a9658 gPodderShownotesLabel: Make episode heading a clickable link 2021-08-12 11:33:26 +03:00
Teemu Ikonen 7003148ec8 Merge commit '0578ba503e2dd772b6bdfa4df90ce537ed7c481f' into dev-adaptive 2021-08-12 10:02:45 +03:00
Teemu Ikonen cfc65c6c0c gPodderShownotesLabel: Reset shownotes to top when changing episodes 2021-08-12 09:59:07 +03:00
Teemu Ikonen 7179478d27 Merge commit '7e6e6c002884813c35a33429565823acd40f2cdd' into dev-adaptive 2021-08-12 09:58:29 +03:00
Teemu Ikonen 994ad483b1 Add checkbutton_delete_deleted_episodes to adaptive preferences 2021-08-12 09:53:27 +03:00
Teemu Ikonen 2b84bfe6e7 adaptive/gpodderpreferences.ui: Save with glade 3.38.2 2021-08-12 09:24:55 +03:00
Teemu Ikonen 446a9937bc Use set_download_list_state() in gPodderSyncUI done_cb() 2021-08-11 21:45:54 +03:00
Teemu Ikonen 03a915bbd4 Merge commit '99c46e89e3e2ceb88d0be140789c63419a5fef2c' into dev-adaptive 2021-08-11 20:43:51 +03:00
Eric Le Lay 71f8ee70b3
Merge pull request #1110 from gpodder/fix-missing-audio_webm
Fix missing extension when downloading youtube-dl format=worstaudio (audio/webm mimetype)
2021-08-11 18:20:42 +02:00
Eric Le Lay b034f3dc29
Merge pull request #1120 from tpikonen/version-plus
Allow '+' as a version number separator
2021-08-10 11:14:25 +02:00
Eric Le Lay e72f6ff355 prevent double run of github actions
for pull requests from branches in gpodder repo
2021-08-08 17:56:47 +02:00
Eric Le Lay 0a46e58af9
Merge pull request #1121 from auouymous/ctrl-click-to-sort-episodes
Add option to require control click to sort episodes.
2021-08-08 17:39:37 +02:00
Teemu Ikonen 5bbc920a01 Support PEP 440 local version label
Handle public and local version parts of __version__ in version
comparisons and when parsing __version_info__.
2021-08-06 19:54:24 +03:00
auouymous 5ec9b60e3c Add option to require control click to sort episodes.
This avoids accidental sorting when trying to select the top episode.

Requested by Fourhundred Thecat on mailing list, but is also an issue
I've run into many times.
2021-08-05 04:40:53 -06:00
Teemu Ikonen 93b0bf9c28 Set adaptive release version and date 2021-08-04 16:29:21 +03:00
Teemu Ikonen 6cf12077c8 Remove adaptive version of channel dialog 2021-08-04 15:08:28 +03:00
Teemu Ikonen 7b2a3840e5 Fix pycodestyle errors 2021-08-04 15:06:57 +03:00
Teemu Ikonen 84a68f9e47 Use gPodderChannel ui from gtk/ and code from desktop/ 2021-08-04 14:00:42 +03:00
Teemu Ikonen 33c84d450c BuilderWidget: Allow defining ui_folder per instance 2021-08-04 14:00:15 +03:00
Teemu Ikonen 609968811b Merge tag '3.10.21' into adaptive
gPodder 3.10.21 release
2021-08-04 13:57:04 +03:00
Teemu Ikonen 4a5ef8eb0b gPodderShownotesLabel: Support dict-based details_fmt 2021-08-04 13:21:44 +03:00
Teemu Ikonen c660fe9517 Merge commit '8dd8b6b2cd6b6c7a0a2ef26f9a7597fcd9976437' into adaptive 2021-08-04 13:14:50 +03:00
Teemu Ikonen 803cfc375d Use a string, not stock name for Delete episodes Delete button 2021-08-04 11:07:46 +03:00
Teemu Ikonen 0237397c24 setup.py: Set name=gpodder-adaptive 2021-08-04 11:07:20 +03:00
Teemu Ikonen 2fe21cf3ad Add X-Purism-FormFactor=Workstation;Mobile; to .desktop.in 2021-08-02 16:25:52 +03:00
auouymous 016cde21bb
Merge pull request #1115 from blushingpenguin/master
fix download limit, queued tasks having wrong icon
2021-07-31 18:48:44 -07:00
Eric Le Lay 202427ef1b
Merge pull request #1114 from auouymous/replace-travis-ci
Switch from Travis CI to Github Actions.
2021-07-31 17:30:02 +02:00
auouymous 91b73ca40e Import gi only in function that need it. 2021-07-31 08:05:51 -06:00
blushingpenguin 56291c0f6f #1111: fix download limit not being respected, add new tasks in the queued state so they render correctly in the ui 2021-07-31 08:23:23 +01:00
auouymous b1a8264a94 Switch from Travis CI to Github Actions. 2021-07-29 18:36:48 -06:00
auouymous 776b9b850e Fix additional linting issues. 2021-07-29 18:10:26 -06:00
auouymous 3c2362ebe1
Merge pull request #1112 from auouymous/fix-1054-linting
Fix linting issues from #1054
2021-07-29 17:02:17 -07:00
Eric Le Lay efcdb905e8 fix last linting errors 2021-07-29 21:52:51 +02:00
Eric Le Lay 0f25aefd9c
Merge pull request #1106 from ollieparanoid/fix-hires
gtkui: properly scale cover/pill on high resolution displays
2021-07-29 21:44:44 +02:00
Oliver Smith 9b6149b9f3
gtkui: properly scale cover/pill on hires displays
Fix the cover images and "pill" looking blurry on high resolution
displays. For example, when the adaptive version of gPodder is used with
Phosh on the PinePhone.

Get the scale parameter from the gtkTreeView object and pass it down to
the cover thumbnail size and to draw_text_pill. If the scaling is not 1,
then use the new draw_iconcell_scale() function to draw the pixbuf with
high resolution.
2021-07-29 20:58:57 +02:00
Oliver Smith dbddb12b64
README.md: mention minimum GTK+3.0 version
Set it to 3.10, as it will be required in a follow-up patch. The
currently maintained upstream version is 3.24, which was released in
2018-09.
2021-07-29 20:56:28 +02:00
tkurtbond c27c0cd7da
Add option to rename_download.py to put the sortdate after the podcast title (#1083)
Add option to rename_download.py to put the sortdate after the podcast title.
2021-07-28 15:51:03 -07:00
auouymous 106e2f4fcd Fix linting issues from #1054 2021-07-27 21:44:04 -06:00
Eric Le Lay 5e857fd52a Fix missing extension when downloading youtube-dl format=worstaudio
See #1099 for a repro feed
2021-07-27 19:07:26 +02:00
Eric Le Lay 8f9159ebc7
Merge pull request #1098 from auouymous/make-text-shownotes-title-clickable
Make the text shownotes title a clickable and copyable link.
2021-07-26 21:13:55 +02:00
auouymous dd3a802752
Merge pull request #1107 from ollieparanoid/refactor-resize-pixbuf
gtkui: refactor resize_pixbuf_keep_ratio
2021-07-25 20:16:43 -07:00
Oliver Smith d8d68e19e2
gtkui: refactor resize_pixbuf_keep_ratio
Do all image size calculation before calling scale_simple, so it only
needs to be called once.

Add a debug log message, since scaling cover images actually takes some
time and it's good to know the target resolution. (On my PinePhone,
scaling these cover images delays startup significantly and thumbnails
are too small when the program is scaled in the Phosh UI).

While at it, return early if no resize is needed so the changed and
result variables can be removed.

Calling scale_simple twice happens with the previous code, if the height
of the source image is greater than max_image_side and greater than the
width. In that case, the resulting image has less quality since the
second scale_simple already works with a scaled down image and scaling
takes twice as long. In practice most podcasts have square artwork so
I assume this didn't have much of a practical effect. But I care about
the log message and figured this would be the most elegant way to add it.
2021-07-24 09:21:45 +02:00
auouymous d8ff3bdddf
Merge pull request #1105 from ollieparanoid/fix-cache
gtkui: fix loading of cached thumbnails
2021-07-23 18:41:34 -07:00
Oliver Smith 71709769c4
gtkui: fix loading of cached thumbnails
Due to this bug, thumbnails did not get loaded from the sqlite database,
but instead were regenerated on each start. Depending on the device this
leads to significant startup slowdown (30 podcast -> ~20s slowdown on my
PinePhone).
2021-07-23 20:20:53 +02:00
Eric Le Lay 04d0ea26d7
Merge pull request #1094 from auouymous/create-html-description-when-empty
Create an html description when none provided.
2021-07-23 15:06:53 +02:00
Eric Le Lay 7e6e6c0028
Merge pull request #1093 from auouymous/scroll-shownotes-to-top
Reset shownotes to top when changing episodes.
2021-07-23 15:06:26 +02:00
Eric Le Lay 37c2e2ef8d
Merge pull request #1096 from auouymous/restore-window-maximize-state
Restore window maximize state.
2021-07-23 15:06:14 +02:00
Eric Le Lay 99c46e89e3
Merge pull request #1054 from blushingpenguin/master
use Gio for file system based device sync (allows mtp:// urls)
2021-07-23 15:04:59 +02:00
auouymous 3a4915ca7d prepare 3.10.21 release 2021-07-19 22:58:51 -06:00
auouymous 1dafe6e3d6 Fix link in channel dialog by connecting signal and opening website. 2021-07-18 20:17:17 -06:00
auouymous 39f5f55ef5 Save and restore channel dialog state. 2021-07-18 20:12:30 -06:00
auouymous a5bb8b6652
Merge pull request #1071 from tpikonen/narrow-channel-dialog
Narrow channel dialog
2021-07-18 18:59:31 -07:00
auouymous db651427ee Use util.urlopen instead of requests.get for youtube. 2021-07-18 04:52:01 -06:00
auouymous 75567e618b
Merge pull request #1092 from auouymous/fix-soundcloud-api
Fix soundcloud API change when adding new channels.
2021-07-18 03:35:25 -07:00
auouymous 3dd11edf2b Fix soundcloud API change when adding new channels.
The API no longer uses the username to query user info. This requires an
extra page fetch to find the user ID when adding new users.
2021-07-18 04:27:40 -06:00
auouymous cf5e8ad10f
Merge pull request #1095 from auouymous/fix-about-dialog-links
Fix links in About dialog by connecting signal and opening website.
2021-07-17 21:10:44 -07:00
auouymous 39b3f8eb04 Fix links in About dialog by connecting signal and opening website. 2021-07-17 22:09:34 -06:00
auouymous 0578ba503e Make the text shownotes title a clickable and copyable link. 2021-07-17 20:38:10 -06:00
auouymous 482a52cb79 Restore window maximize state. 2021-07-17 00:56:02 -06:00
auouymous b0ebfd5333 Create an html description when none provided.
The youtube-dl extension code is moved into gPodder to provide this
feature for all feeds lacking an html description. This enables
clickable links inside non-html descriptions. And if available, an image
tag for the episode art URL is prepended to the html description
(currently only available in html shownotes).
2021-07-16 21:03:38 -06:00
auouymous e9353588f3 Reset shownotes to top when changing episodes.
This prevents the title from being partially clipped when moving between
episodes after scrolling the shownotes for one of them.
2021-07-16 05:16:08 -06:00
Eric Le Lay 7b8d437e02
Merge pull request #1089 from adasiko/master
update ru translation
2021-07-14 10:57:17 +02:00
adasiko ce6c9811ce update ru translation 2021-07-13 22:00:43 +07:00
blushingpenguin c9bbc4f799 fix deleting episodes deleted from device (skip_locked was removed in 62bb7efade) 2021-07-12 11:32:49 +01:00
blushingpenguin 874bd35c81 clean up temporary file 2021-07-12 10:52:43 +01:00
blushingpenguin 13fb6e68c9 workaround mtp devices possibly not having partial write capabilities 2021-07-12 07:39:57 +01:00
blushingpenguin e09f5aecad fix playlist sync 2021-07-11 19:52:34 +01:00
Eric Le Lay 79abb4bbc7
Merge pull request #1088 from neodyne/sk-translation-update-1
Update sk.po
2021-07-10 20:57:43 +02:00
Eric Le Lay 29086b1e17 Merge pull request #1080 from serkan-maker/master
tr translation update
2021-07-10 20:55:51 +02:00
Eric Le Lay 8d783775f9 apply @serkan-maker attachment to #1080 2021-07-10 20:48:03 +02:00
Teemu Ikonen ee22a8705f util.linux_get_active_interfaces(): Use 'ip addr' instead of 'ip link' 2021-07-10 20:46:52 +02:00
Teemu Ikonen 3dec09faec util.connection_available(): Prefer 'ip' to 'ifconfig'
Closes #974.
2021-07-10 20:46:52 +02:00
neodyne 963076fde4 Update sk.po 2021-07-09 16:34:06 +02:00
auouymous 328732b6cc update dependencies for windows build 2021-07-08 23:53:06 -06:00
auouymous 4a96be6581 make messages 2021-07-08 23:38:01 -06:00
auouymous 7429bc1904
Merge pull request #1084 from auouymous/change-youtube-endpoint-order
Try new youtube endpoint first and fallback to the old endpoint.
2021-07-08 21:45:06 -07:00
auouymous 70d5f20b94 update XCode version on circleci (deprecated 9.4.1) 2021-07-08 02:01:04 -06:00
auouymous 6e48992b31 Skip non-integer youtube formats. 2021-07-07 01:59:41 -06:00
auouymous 79ef6aa8a2
Merge pull request #1086 from gpodder/win-fix-appveyor
Update appveyor image to VS2019
2021-07-07 00:37:11 -07:00
auouymous 920b2d2100 Update appveyor image to VS2019 2021-07-07 00:19:28 -06:00
auouymous d6dd5b62bf Try new youtube endpoint first and fallback to the old endpoint. 2021-07-06 21:07:47 -06:00
auouymous 14bf8b44b7 Fix issues with #1073 pull request. 2021-07-06 19:05:23 -06:00
auouymous 82d926bcdd
Merge pull request #1073 from 18928172992817182/youtube-gdpr
Fix support for automatically accepting GDPR youtube consents
2021-07-06 17:56:13 -07:00
Teemu Ikonen 7f603ab53f extensions/filter.py: Adapt to a narrower channel dialog
* Add a note about Cancel button not working
 * Add a separator between label and filter button
 * Shorten a long button label, split the tail into a separate label
2021-07-05 13:26:51 +03:00
Teemu Ikonen fe161d0391 Set transient parent in Python code
This was set in the ui-file, but Glade does not like it.
2021-07-05 13:26:51 +03:00
Teemu Ikonen 0ee6598d6a gpodderchannel.ui: New layout
General:

 * Put channel info under 'Info' page in the notebook and settings
   under 'Settings', remove 'Advanced' page
 * Add GtkScrolledWindows to GtkNotebook pages
 * Don't change Channel editor window title to channel title
 * Replace 'Close' button with 'OK' and 'Cancel'

Info tab:

 * Use a GtkBox with a 'view' style class to show podcast info
 * Add a placeholder icon for podcast image
 * Add a GtkStack to switch between title Label and Entry
 * Replace description TextView by a selectable Label
 * Use a selectable label for channel website URL

Settings tab:

 * Use GtkListBox for settings items, activate the correct widget
   in the GtkListBoxRow on 'activate' signal
 * Replace Checkboxes with Switches
 * Replace plus icon with the symbolic version
 * Use GtkGrid for Authentication settings widgets
2021-07-05 13:16:31 +03:00
Teemu Ikonen 0524f9562a gpodderchannel.ui: Save with glade 3.38.2 2021-07-05 13:07:58 +03:00
auouymous 8c56e71b0b Don't parse youtube feed URLs.
This fixes a bug where the feed URL is parsed to the channel URL,
potentially causing issues subscribing to feed URLs, but causing gpo
failures when enabling or disabling youtube channels.
2021-06-30 22:30:40 -06:00
Serkan ÖNDER 233a68366b
translation update 2021-06-29 23:40:25 +03:00
auouymous 73a83f7a4e Add Strawberry player to the enqueue extension.
Closes #1078
2021-06-27 04:00:41 -06:00
auouymous 63196ae0e1 Fix "gpo sync" failure.
The skip_lock parameter was not removed from one of the
delete_episode_list() calls, causing a failure syncing with gpo.

Fixes #1077
2021-06-23 21:17:26 -06:00
blushingpenguin 58ef73b3e6 remove unreachable code 2021-06-20 06:36:16 +01:00
gustaf 3003c8a4c0 Fix support for automatically accepting GDPR youtube consents 2021-06-18 15:40:26 +02:00
blushingpenguin 2e3a9fba2e Merge branch 'master' of github.com:gpodder/gpodder 2021-06-17 22:23:01 +01:00
Eric Le Lay 5011923001
Merge pull request #1070 from neodyne/sk-translation
Add Slovak translation
2021-06-15 19:31:23 +02:00
neodyne 3a928b5ef7 Add slovak translation 2021-06-15 18:39:48 +02:00
auouymous c31ba52f99
Merge pull request #1065 from auouymous/fix-soundcloud
Prevent soundcloud from downloading existing episodes each update.
2021-06-15 01:02:30 -07:00
Teemu Ikonen a11a99b353 Allow translation of shownotes header bar buttons
Change 'Cancel download' to 'Cancel', to make it fit the button.
2021-06-13 14:20:27 +03:00
blushingpenguin b6d5836827 remove old, disabled mtp support 2021-06-12 16:27:30 +01:00
blushingpenguin e2a512a34c add mount call for CLI; fix done_callback not being called if opening device fails; handle errors from querying device 2021-06-12 15:45:53 +01:00
auouymous 140a351bce Fix DRM content detection for youtube episodes. 2021-06-11 04:52:36 -06:00
Eric Le Lay 952e4178ab update fr translation 2021-06-10 10:35:15 +02:00
Eric Le Lay 8057a521df make messages 2021-06-10 10:30:23 +02:00
Eric Le Lay 8dd8b6b2cd fix 'msgid' format string with unnamed arguments cannot be properly localized warning 2021-06-10 10:28:54 +02:00
blushingpenguin 5f6e3ac285 Merge branch 'master' of github.com:blushingpenguin/gpodder 2021-06-09 06:35:57 +01:00
blushingpenguin 975b0338ab Merge branch 'master' of github.com:gpodder/gpodder 2021-06-09 06:35:20 +01:00
blushingpenguin e93dcddb56 windows fixes 2021-06-08 20:55:56 +01:00
auouymous 91cf6c9410 Prevent soundcloud from downloading existing episodes each update.
GUIDs are stored in the database as strings, but soundcloud creates them
as integers. Python no longer succeeds when comparing these integers to
the string keys from the existing database entries. This produces new
episodes on every update which then collide with the existing GUIDs.
2021-06-08 00:55:35 -06:00
blushingpenguin b40f283499 fix race where download ui updates could be turned off for subsequent tasks if after adding a task it completed very quickly on another thread; fix use of Gtk.ListView as a multi-threaded container (sometimes returns None for an item and causes an exception) 2021-06-05 22:24:04 +01:00
blushingpenguin 729dbee534 more threading fixes: fix race cleaning up folders by ignoring failure to remove a folder (two threads could try to do this at the same time); log file copy errors (these seem to get lost by the ui) 2021-06-05 08:07:27 +01:00
blushingpenguin e7fab75c17 fix sync errors if multiple threads try and create the same folder, fix spawning 1 thread per sync task 2021-06-04 07:56:34 +01:00
blushingpenguin c1081c6678 gpo fixes: prevent warning about not setting Gst/Gio versions, not actually mounting volumes always succeeds 2021-05-31 13:21:06 +01:00
blushingpenguin d019a6e99e Merge branch 'master' of github.com:blushingpenguin/gpodder 2021-05-31 07:17:32 +01:00
blushingpenguin 6d40da3cb5 use Gio for file system based device sync (allows mtp:// urls) 2021-05-31 07:12:13 +01:00
174 changed files with 44671 additions and 30540 deletions

View File

@ -6,6 +6,9 @@ branches:
# Start builds on tags only
# skip_non_tags: true
image:
- Visual Studio 2019
environment:
matrix:
- MSYS2_ARCH: i686
@ -15,17 +18,8 @@ build_script:
- set
- set PATH=C:\msys64\%MSYSTEM%\bin;C:\msys64\usr\bin;%PATH%
- set CHERE_INVOKING=yes
# workaround new msys2 packagers
- curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz
- curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig
- bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig"
- bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz"
# remove precisely conflicting packages
- bash -lc "pacman --noconfirm --ask 20 --remove mingw-w64-x86_64-gcc-ada mingw-w64-x86_64-gcc-objc mingw-w64-i686-gcc-ada mingw-w64-i686-gcc-objc"
# https://www.msys2.org/news/#2020-12-26-zstd-exemption-for-core-packages-removed
- bash -lc "pacman --noconfirm -U 'http://repo.msys2.org/msys/x86_64/libzstd-1.4.4-2-x86_64.pkg.tar.xz'"
- bash -lc "pacman --noconfirm -U 'http://repo.msys2.org/msys/x86_64/zstd-1.4.4-2-x86_64.pkg.tar.xz'"
- bash -lc "pacman --noconfirm -U 'http://repo.msys2.org/msys/x86_64/pacman-5.2.1-6-x86_64.pkg.tar.xz'"
# workaround updating msys2-runtime breaks all programs until last one exited
- bash -lc "pacman -Syuu --noconfirm"
- Powershell.exe "Stop-Process -name dirmngr -Erroraction silentlycontinue; echo killing_dirmng"

View File

@ -3,10 +3,10 @@ version: 2
jobs:
release-from-macos:
macos:
xcode: "9.4.1"
xcode: "13.4.1"
shell: /bin/bash --login -o pipefail
environment:
- BUNDLE_TAG: 21.4.27
- BUNDLE_TAG: 22.8.27
steps:
- checkout
- run: >
@ -15,7 +15,7 @@ jobs:
saved_hash=$(awk '{print $1;}' < "pythonbase-$BUNDLE_TAG.zip.sha256");
comp_hash=$(openssl sha256 "pythonbase-$BUNDLE_TAG.zip" | awk '{print $2;}');
if [ "$saved_hash" != "$comp_hash" ]; then echo "E: $saved_hash != $comp_hash"; exit 1; else echo "valid hash"; fi;
LC_CTYPE=C.UTF-8 LANG=C.UTF-8 tools/mac-osx/release_on_mac.sh "$(pwd)/pythonbase-$BUNDLE_TAG.zip";
LC_CTYPE=C.UTF-8 LANG=C.UTF-8 tools/mac-osx/release_on_mac.sh "$(pwd)/pythonbase-$BUNDLE_TAG.zip" || exit 1;
rm -Rf tools/mac-osx/_build/{gPodder.app,*.deps.zip*,gPodder.contents,run-*,gpo,gpodder-migrate2tres}
- store_artifacts:
path: tools/mac-osx/_build/

32
.github/workflows/linttest.yml vendored Normal file
View File

@ -0,0 +1,32 @@
name: lint and test
on: [push, pull_request]
jobs:
linttest:
name: lint and unit tests
if: >-
github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
sudo apt-get update -q
sudo apt-get install intltool desktop-file-utils
pip3 install pytest-cov minimock pycodestyle isort codespell requests pytest pytest-httpserver
pip3 install podcastparser mygpoclient
- name: Lint
run: make lint
- name: Test
run: make releasetest

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ share/applications/gpodder-url-handler.desktop
share/applications/gpodder.desktop
share/dbus-1/services/org.gpodder.service
share/locale/
venv/*

View File

@ -1,13 +0,0 @@
language: python
dist: focal
sudo: required
python:
- "3.8"
install:
- sudo apt-get update -q
- sudo apt-get install intltool desktop-file-utils
- pip3 install pytest-cov minimock pycodestyle isort requests pytest pytest-httpserver
- python3 tools/localdepends.py
script:
- make lint
- make releasetest

30
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,30 @@
# Contributing to this repository <!-- omit in toc -->
## Getting started <!-- omit in toc -->
Before you begin:
- Ensure you are using Python 3.7+
- Check out the [existing issues](https://github.com/gpodder/gpodder/issues)
Contributions are made to this repo via Issues and Pull Requests (PRs). Make sure to search for existing Issues and PRs before creating your own.
## Getting the code and setting up the project
1. Fork this project
2. Clone the repository to your machine
3. Create a separate branch to get started, e.g. for feature `feat/branch-name-here` or fix `fix/fix-name-goes-here`
4. Make sure to create a new virtual environment and activate it:
```shell
python3 -m venv venv
source activate venv/bin/activate
```
5. Install dependencies: [Run from Git](https://gpodder.github.io/docs/run-from-git.html)
6. Start the program with debug mode: `./bin/gpodder -v`
7. Make the changes, commit in a branch and push the branch to your fork and then submit a Pull Request.
## Linting
To ensure code quality, we recommend you to run the linter before pushing the changes to your repo. In order to do so ensure the necessary packages are installed by executing:
```shell
pip3 install pytest-cov minimock pycodestyle isort requests pytest pytest-httpserver
```
Execute the linter in the root directory (Linux only): `make lint unittest`. On Windows execute: `pycodestyle share src/gpodder tools bin/* *.py`

View File

@ -6,7 +6,7 @@
Media aggregator and podcast client
___
Copyright 2005-2018 The gPodder Team
Copyright 2005-2022 The gPodder Team
## License
@ -26,7 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
## Dependencies
- [Python 3.5](http://python.org/) or newer
- [Python 3.7](http://python.org/) or newer
- [Podcastparser](http://gpodder.org/podcastparser/) 0.6.0 or newer
- [mygpoclient](http://gpodder.org/mygpoclient/) 1.7 or newer
- [requests](https://requests.readthedocs.io) 2.24.0 or newer
@ -35,14 +35,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
As an alternative to python-dbus on Mac OS X and Windows, you can use
the dummy (no-op) D-Bus module provided in "tools/fake-dbus-module/".
For quick testing, you can use the script tools/localdepends.py to
install local copies of podcastparser and mygpoclient into "src/" from
PyPI. With this, you get a self-contained gPodder CLI codebase.
For quick testing, see [Run from Git](https://gpodder.github.io/docs/run-from-git.html)
to install dependencies.
### GTK3 UI - Additional Dependencies
- [PyGObject](https://wiki.gnome.org/PyGObject) 3.22.0 or newer
- [GTK+3](https://www.gtk.org/) 3.16 or newer
### Optional Dependencies
@ -51,11 +51,11 @@ PyPI. With this, you get a self-contained gPodder CLI codebase.
- Size detection on Windows: PyWin32
- Native OS X support: ige-mac-integration
- MP3 Player Sync Support: python-eyed3 (0.7 or newer)
- iPod Sync Support: python-gpod
- iPod Sync Support: libgpod (tested with 0.8.3)
- Clickable links in GTK UI show notes: html5lib
- HTML show notes: WebKit2 gobject bindings
(webkit2gtk, webkitgtk4 or gir1.2-webkit2-4.0 packages).
- Better Youtube support (> 15 entries in feeds, download audio-only): youtube_dl
- Better Youtube support (> 15 entries in feeds, download audio-only): youtube_dl or yt-dlp
### Build Dependencies
@ -135,7 +135,7 @@ into an alternative root (default /) and prefix (default /usr):
[*Debian*](https://wiki.debian.org/Python#Deviations_from_upstream) and *Ubuntu* use `dist-packages`
instead of `site-packages` for third party installs, so you'll want something like:
sudo python3 setup.py install --root / --prefix /usr/local --optimize=1 --install-lib=/usr/local/lib/python3.5/dist-packages
sudo python3 setup.py install --root / --prefix /usr/local --optimize=1 --install-lib=/usr/local/lib/python3.10/dist-packages
In fact, first try running `python -c "import sys; print(sys.path)"` to check what is the exact path.
It depends on your version of python.

76
bin/gpo
View File

@ -88,6 +88,7 @@ import pydoc
import re
import shlex
import sys
import textwrap
import threading
try:
@ -216,8 +217,8 @@ class gPodderCli(object):
self._extensions_episode_download_cb)
@contextlib.contextmanager
def _action(self, msg, *args):
self._start_action(msg, *args)
def _action(self, msg):
self._start_action(msg)
try:
yield
self._finish_action()
@ -271,8 +272,8 @@ class gPodderCli(object):
self._info(_('Episode download requested by extensions.'))
self._download_episode(episode)
def _start_action(self, msg, *args):
line = util.convert_bytes(msg % args)
def _start_action(self, msg):
line = util.convert_bytes(msg)
if len(line) > self.COLUMNS - 7:
line = line[:self.COLUMNS - 7 - 3] + '...'
else:
@ -335,7 +336,7 @@ class gPodderCli(object):
return self._model.load_podcast(
url, create=True,
authentication_tokens=auth_tokens.get(url, None),
max_episodes=self._config.max_episodes_per_feed)
max_episodes=self._config.limit.episodes)
except feedcore.AuthenticationRequired as e:
if e.url in auth_tokens:
print(inred(_('Wrong username/password')))
@ -379,7 +380,7 @@ class gPodderCli(object):
podcast.rename(title)
podcast.save()
except Exception as e:
logger.warn('Cannot subscribe: %s', e, exc_info=True)
logger.warning('Cannot subscribe: %s', e, exc_info=True)
if hasattr(e, 'strerror'):
self._error(e.strerror)
else:
@ -438,10 +439,20 @@ class gPodderCli(object):
if podcast is None:
self._error(_('You are not subscribed to %s.') % url)
else:
# Clean up downloads and download directories
common.clean_up_downloads()
podcast.delete()
self._db.commit()
self._error(_('Unsubscribed from %s.') % url)
# Delete downloaded episodes
podcast.remove_downloaded()
# TODO: subscribe and unsubscribe need to sync with mygpo
# Upload subscription list changes to the web service
# self.mygpo_client.on_unsubscribe([podcast.url])
return True
def is_episode_new(self, episode):
@ -481,13 +492,18 @@ class gPodderCli(object):
return "disabled"
return "enabled"
title, url, status = podcast.title, podcast.url, \
feed_update_status_msg(podcast)
title, url, description, link, status = (
podcast.title, podcast.url, podcast.description, podcast.link,
feed_update_status_msg(podcast))
description = '\n'.join(textwrap.wrap(description, subsequent_indent=' ' * 8))
episodes = self._episodesList(podcast)
episodes = '\n '.join(episodes)
self._pager("""
Title: %(title)s
URL: %(url)s
Description:
%(description)s
Link: %(link)s
Feed update is %(status)s
Episodes:
@ -543,7 +559,7 @@ class gPodderCli(object):
return True
def _update_podcast(self, podcast):
with self._action(' %s', podcast.title):
with self._action(' %s' % podcast.title):
podcast.update()
def _pending_message(self, count):
@ -612,17 +628,22 @@ class gPodderCli(object):
show_guid = '--guid' in args
common.find_partial_downloads(self._model.get_podcasts(),
noop,
noop,
noop,
on_finish)
return True
def _download_episode(self, episode):
with self._action('Downloading %s', episode.title):
task = download.DownloadTask(episode, self._config)
with self._action('Downloading %s' % episode.title):
if episode.download_task is None:
task = download.DownloadTask(episode, self._config)
else:
task = episode.download_task
task.add_progress_callback(self._update_action)
task.status = download.DownloadTask.DOWNLOADING
task.run()
task.recycle()
def _download_episodes(self, episodes):
if self._config.downloads.chronological_order:
@ -630,6 +651,11 @@ class gPodderCli(object):
episodes = list(model.Model.sort_episodes_by_pubdate(episodes))
if episodes:
# Queue episodes to create partial files
for e in episodes:
if e.download_task is None:
download.DownloadTask(e, self._config)
last_podcast = None
for episode in episodes:
if episode.channel != last_podcast:
@ -662,6 +688,7 @@ class gPodderCli(object):
self._download_episodes(episodes)
common.find_partial_downloads(self._model.get_podcasts(),
noop,
noop,
noop,
on_finish)
@ -935,6 +962,13 @@ class gPodderCli(object):
def _not_applicable(*args, **kwargs):
pass
def _mount_volume_for_file(file):
result, message = util.mount_volume_for_file(file, None)
if not result:
self._error(_('mounting volume for file %(file)s failed with: %(error)s'
% dict(file=file.get_uri(), error=message)))
return result
class DownloadStatusModel(object):
def register_task(self, ask):
pass
@ -943,11 +977,22 @@ class gPodderCli(object):
def queue_task(x, task):
def progress_updated(progress):
self._update_action(progress)
with self._action(_('Syncing %s'), ep_repr(task.episode)):
with self._action(_('Syncing %s') % ep_repr(task.episode)):
task.status = sync.SyncTask.DOWNLOADING
task.add_progress_callback(progress_updated)
task.run()
if task.notify_as_finished():
if self._config.device_sync.after_sync.mark_episodes_played:
logger.info('Marking as played on transfer: %s', task.episode.url)
task.episode.mark(is_played=True)
if self._config.device_sync.after_sync.delete_episodes:
logger.info('Removing episode after transfer: %s', task.episode.url)
task.episode.delete_from_disk()
task.recycle()
done_lock = threading.Lock()
self.mygpo_client = my.MygPoClient(self._config)
sync_ui = gPodderSyncUI(self._config,
@ -961,7 +1006,8 @@ class gPodderCli(object):
_not_applicable,
self._db.commit,
_delete_episode_list,
_episode_selector)
_episode_selector,
_mount_volume_for_file)
done_lock.acquire()
sync_ui.on_synchronize_episodes(self._model.get_podcasts(), episodes=None, force_played=True, done_callback=done_lock.release)
done_lock.acquire() # block until done
@ -1132,8 +1178,8 @@ class gPodderCli(object):
defaults = defaults or ()
minarg, maxarg = len(args) - len(defaults), len(args)
if (len(command_line) < minarg or
(len(command_line) > maxarg and varargs is None)):
if (len(command_line) < minarg
or (len(command_line) > maxarg and varargs is None)):
self._error('Wrong argument count for %s.' % func.__name__)
return False

View File

@ -33,13 +33,12 @@ import os.path
import platform
import subprocess
import sys
from optparse import OptionParser
from optparse import OptionGroup, OptionParser
logger = logging.getLogger(__name__)
try:
import dbus
from dbus.mainloop.glib import DBusGMainLoop
have_dbus = True
except ImportError:
print("""
@ -83,6 +82,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 +99,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)
@ -127,9 +142,9 @@ def main():
from gpodder import log
log.setup(options.verbose, options.quiet)
if (not (gpodder.ui.win32 or gpodder.ui.osx) and
os.environ.get('DISPLAY', '') == '' and
os.environ.get('WAYLAND_DISPLAY', '') == ''):
if (not (gpodder.ui.win32 or gpodder.ui.osx)
and os.environ.get('DISPLAY', '') == ''
and os.environ.get('WAYLAND_DISPLAY', '') == ''):
logger.error('Cannot start gPodder: $DISPLAY or $WAYLAND_DISPLAY is not set.')
sys.exit(1)
@ -159,10 +174,7 @@ def main():
if gpodder.ui.gtk:
from gpodder.gtkui import app
if gpodder.ui.adaptive:
gpodder.ui_folders.insert(0, os.path.join(ui_folder, 'adaptive'))
else:
gpodder.ui_folders.insert(0, os.path.join(ui_folder, 'gtk'))
gpodder.ui_folders.insert(0, os.path.join(ui_folder, 'gtk'))
app.main(options)
else:
logger.error('No GUI selected.')

View File

@ -26,7 +26,6 @@
import configparser
import os
import re
import shutil
import sys

11
debian/README.debian vendored Normal file
View File

@ -0,0 +1,11 @@
As of gPodder 3.6, alpha support for syncing directly to iPod devices
has been restored. (This was available in gPodder 2.x, but has not
been present in the 3.x version until this release.)
Users may be interested in the gpodder-migrate2tres command which will
migrate gPodder 2.x configurations to the format used by gPodder 3.x.
This binary is included in the gpodder_3.x packages. Similarly, users
can generate a backup of their existing 2.x configurations by using
the gpodder-backup script (currently shipped in the gpodder_2.x packages).
Thank you for using gPodder!

924
debian/changelog vendored Normal file
View File

@ -0,0 +1,924 @@
gpodder-adaptive (3.11.4+1-1.1) UNRELEASED; urgency=medium
[ Maryjane ]
* Updated manitainer to Maryjane
* Added libhandy 1 as a runtime dependency
* Import gpodder Debian directory from the salsa.debian.org repository
-- maryjane <maryjane@disroot.org> Fri, 23 Feb 2024 02:04:31 +0000
gpodder (3.10.17-1) unstable; urgency=medium
* New upstream version 3.10.17
* Refresh patches for new upstream version
-- tony mancill <tmancill@debian.org> Mon, 23 Nov 2020 10:26:51 -0800
gpodder (3.10.16-1) unstable; urgency=medium
* New upstream version 3.10.16
* Refresh patches against new upstream version
* Use debhelper-compat 13
-- tony mancill <tmancill@debian.org> Tue, 23 Jun 2020 21:46:05 -0700
gpodder (3.10.15-1) unstable; urgency=medium
* New upstream version 3.10.15
-- tony mancill <tmancill@debian.org> Wed, 15 Apr 2020 19:13:12 -0700
gpodder (3.10.14-1) unstable; urgency=medium
* New upstream version 3.10.14
* Refresh patches against new upstream version
* Remove address_syntax_warnings patch
-- tony mancill <tmancill@debian.org> Tue, 14 Apr 2020 21:06:01 -0700
gpodder (3.10.13-1) unstable; urgency=medium
* New upstream version 3.10.13
* Refresh patches against new upstream version
* Freshen years in debian/copyright
* Bump Standards-Version to 4.5.0
* Remove unneeded lintian overrides
-- tony mancill <tmancill@debian.org> Mon, 03 Feb 2020 01:05:08 -0800
gpodder (3.10.11-2) unstable; urgency=medium
* Remove Depends on dbus-x11; allow dbus-user-session to satisfy this
dependency. Thank you to John-Paul Durrieu for the bug report.
* Specify debhelper compat via debhelper-compat dependency
* Remove outdated debian NEWS file; it referred to upgrades prior
to old-old-stable.
* Add patch to address syntax warnings.
* Set "Rules-Requires-Root: no" in debian/control
-- tony mancill <tmancill@debian.org> Thu, 26 Dec 2019 20:18:05 -0800
gpodder (3.10.11-1) unstable; urgency=medium
* New upstream version 3.10.11
- Fixes the "Check for new episodes at startup" extension
* Bump Standards-Version to 4.4.1
-- tony mancill <tmancill@debian.org> Sun, 29 Sep 2019 19:05:48 -0700
gpodder (3.10.10-1) unstable; urgency=medium
* New upstream version 3.10.10
- Support for paginated feeds (RFC 5005)
- New extension to manage YouTube subscriptions and downloads
- Updated translations
- Numerous bugs fixes and improvements
(see: https://github.com/gpodder/gpodder/releases/tag/3.10.10)
* Refresh patches
* Bump Standards-Version to 4.4.0
* Use debhelper 12
* Add youtube-dl to Suggests
-- tony mancill <tmancill@debian.org> Sat, 28 Sep 2019 07:48:22 -0700
gpodder (3.10.9-1) unstable; urgency=medium
* New upstream version 3.10.9
- Uses HTTPS for YouTube.
Fixes https://github.com/gpodder/gpodder/issues/625
* Upload to unstable.
-- tony mancill <tmancill@debian.org> Thu, 13 Jun 2019 19:05:17 -0700
gpodder (3.10.8-1) experimental; urgency=medium
* New upstream version 3.10.8
- Updated Russian translation
-- tony mancill <tmancill@debian.org> Sat, 06 Apr 2019 08:12:32 -0700
gpodder (3.10.7-1) unstable; urgency=medium
* New upstream version 3.10.7
* Freshen patches for new upstream release
* debian/copyright: freshen copyright years and add comment regarding
AppStream metadata CC0-1.0 designation
-- tony mancill <tmancill@debian.org> Sat, 02 Feb 2019 15:17:35 -0800
gpodder (3.10.6-1) unstable; urgency=medium
[ Ondřej Nový ]
* d/copyright: Use https protocol in Format field
* d/changelog: Remove trailing whitespaces
[ tony mancill ]
* New upstream version 3.10.6
* Drop get-orig-source target from debian/rules
* Bump Standards-Version to 4.3.0
* Refresh debian/patches for new upstream version.
-- tony mancill <tmancill@debian.org> Sat, 19 Jan 2019 11:58:47 -0800
gpodder (3.10.3-2) unstable; urgency=medium
* Rename variable 'async' in services.py (Closes: #902794)
-- tony mancill <tmancill@debian.org> Sat, 30 Jun 2018 21:23:32 -0700
gpodder (3.10.3-1) unstable; urgency=medium
* New upstream version 3.10.3.
New features:
- #402 extension to run a command on download
- #431 update sonos extension to use soco >= 0.7 API
- #442 gpo command for downloading/deleting a single episode
- #384 YouTube feeds without API key
* Freshen patches for new upstream release
-- tony mancill <tmancill@debian.org> Sun, 17 Jun 2018 16:43:06 -0700
gpodder (3.10.1-2) unstable; urgency=medium
* Update Vcs fields for migration from Alioth -> Salsa
* Apply patch for Ayatana App Indicator (Closes: #898424) and replace
recommends on python3-appindicator with gir1.2-ayatanaappindicator3-0.1
- Thank you to Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
* Bump Standards-Version to 4.1.4
* Use debhelper 11
-- tony mancill <tmancill@debian.org> Sun, 27 May 2018 14:25:36 -0700
gpodder (3.10.1-1) unstable; urgency=medium
* New upstream version 3.10.1
* Update debian/watch to repack with compression=xz
* Update year in debian/copyright
* Freshen patches for new upstream release
-- tony mancill <tmancill@debian.org> Wed, 21 Feb 2018 20:21:19 -0800
gpodder (3.10.0-5) unstable; urgency=medium
* Add python3-all and python3-setuptools to Build-Depends
* Add dbus-x11, python3-gi-cairo, and gir1.2-gtk-3.0 to Depends
Promote default-dbus-session-bus | dbus-session-bus to Depends
-- tony mancill <tmancill@debian.org> Sun, 11 Feb 2018 10:09:30 -0800
gpodder (3.10.0-4) unstable; urgency=medium
* Add missing dependency on python3-cairo (Closes: #889850)
-- tony mancill <tmancill@debian.org> Thu, 08 Feb 2018 20:03:06 -0800
gpodder (3.10.0-3) unstable; urgency=medium
* Replace patch for #888420 with upstream commits through e524572.
- Fixes OPML export.
- Fixes issues with YouTube extension downloads.
-- tony mancill <tmancill@debian.org> Sat, 27 Jan 2018 10:36:33 -0800
gpodder (3.10.0-2) unstable; urgency=medium
* Add patch for exception downloading YouTube videos (Closes: #888420)
-- tony mancill <tmancill@debian.org> Thu, 25 Jan 2018 21:12:06 -0800
gpodder (3.10.0-1) unstable; urgency=medium
* New upstream version 3.10.0
- no longer depends upon pygtk (Closes: #885295)
- now builds for Python3 (only)
* Update debian/watch to scan github
* Update Homepage, Vcs URLs, and freshen copyright years
* Add patches for UTF-8
* Use debhelper 10
* Update debian/rules and dependencies for Python3
* Bump Standards-Version to 4.1.3
-- tony mancill <tmancill@debian.org> Sun, 21 Jan 2018 18:33:01 -0800
gpodder (3.9.3-1) unstable; urgency=medium
* New upstream release.
-- tony mancill <tmancill@debian.org> Mon, 26 Dec 2016 20:47:50 -0800
gpodder (3.9.2-1) unstable; urgency=medium
* New upstream release.
* Replace build-dep on feedparser with podcastparser.
* Use HTTPS for Vcs-Git URL.
* Replace Recommends on dbus-x11 with
default-dbus-session-bus | dbus-session-bus. (Closes: #836099)
-- tony mancill <tmancill@debian.org> Wed, 14 Dec 2016 21:49:07 -0800
gpodder (3.9.1-1) unstable; urgency=medium
* New upstream release.
* Bump Standards-Version to 3.9.8.
-- tony mancill <tmancill@debian.org> Sun, 13 Nov 2016 16:47:26 -0800
gpodder (3.9.0-2) unstable; urgency=medium
* Remove depedency on python-webkit recommends on
libqtwebkit-qmlwebkitplugin. (Closes: #790218)
-- tony mancill <tmancill@debian.org> Mon, 15 Feb 2016 08:34:13 -0800
gpodder (3.9.0-1) unstable; urgency=medium
* New upstream release.
* Drop dependencies on libjs-jquery and libjs-jquery-mobile,
now that the web UI has been removed.
* Drop the use_local_jquery.patch.
-- tony mancill <tmancill@debian.org> Sat, 06 Feb 2016 09:30:56 -0800
gpodder (3.8.5-1) unstable; urgency=medium
* New upstream release.
* Remove .menu file. This package contains a desktop file.
* Clean up debian/copyright; remove files no longer part of the source.
* Drop build-dep on python-dev in favor of python for arch all package.
-- tony mancill <tmancill@debian.org> Thu, 03 Dec 2015 22:01:18 -0800
gpodder (3.8.4-1) unstable; urgency=medium
* New upstream release.
-- tony mancill <tmancill@debian.org> Wed, 27 May 2015 19:13:14 -0700
gpodder (3.8.3-2) unstable; urgency=medium
* Remove Recommends on python-gst0.10. (Closes: #785834)
* Add python-appindicator to Recommends. (Closes: #770717)
-- tony mancill <tmancill@debian.org> Wed, 20 May 2015 21:07:34 -0700
gpodder (3.8.3-1) unstable; urgency=medium
* New upstream release.
* Add patch to set the default for update checks to false.
* Bump Standards-Version to 3.9.6.
* Patch HTML to use local resources.
Adds libjs-jquery and libjs-jquery-mobile to dependencies.
-- tony mancill <tmancill@debian.org> Sun, 05 Apr 2015 21:21:39 -0700
gpodder (3.8.1-1) unstable; urgency=medium
* New upstream release.
- Fixes a bug with mixed-case password.
- Improves support for adding certain YouTube channels/feed URLs.
-- tony mancill <tmancill@debian.org> Tue, 09 Sep 2014 22:44:01 -0700
gpodder (3.8.0-1) unstable; urgency=medium
* New upstream release.
-- tony mancill <tmancill@debian.org> Sat, 26 Jul 2014 20:43:14 -0700
gpodder (3.7.0-2) unstable; urgency=medium
* Convert from python-support to dh-python.
* Bump debhelper dependency to DH9.
-- tony mancill <tmancill@debian.org> Tue, 27 May 2014 21:50:33 -0700
gpodder (3.7.0-1) unstable; urgency=medium
* New upstream release.
-- tony mancill <tmancill@debian.org> Sat, 17 May 2014 11:36:25 -0700
gpodder (3.6.1-1) unstable; urgency=medium
* New upstream release (Closes: #742191)
- Fixes YouTube integration bug.
- Use LC_ALL=C during manpage generation.
- Add prefix to path in desktop file.
-- tony mancill <tmancill@debian.org> Thu, 20 Mar 2014 21:41:43 -0700
gpodder (3.6.0-1) unstable; urgency=medium
* New upstream release.
- (Closes: #681638)
- Adds alpha support for iPod (see #688240)
* Remove gpodder-migrate2tres_manpage.patch; integrated upstream.
* Remove Suggests: python-eyed3 until 0.7 is in Debian (see #740457)
* Bump Standards-Version to 3.9.5.
* Update README.Debian.
-- tony mancill <tmancill@debian.org> Sat, 01 Mar 2014 15:26:20 -0800
gpodder (3.5.2-1) unstable; urgency=low
* New upstream.
* Update Vcs- URLs to canonical forms.
* Update d/copyright years.
-- tony mancill <tmancill@debian.org> Fri, 27 Sep 2013 21:20:17 -0700
gpodder (3.5.1-1) unstable; urgency=low
* New upstream release.
* d/control: declare versioned dependency on python-gtk2 (>= 2.16)
-- tony mancill <tmancill@debian.org> Fri, 12 Apr 2013 22:07:02 -0700
gpodder (3.5.0-1) unstable; urgency=low
* New upstream release.
* Mention gpodder-migrate2tres in NEWS.Debian file. (Closes: #695470)
-- tony mancill <tmancill@debian.org> Fri, 08 Mar 2013 21:21:00 -0800
gpodder (3.4.0-1) unstable; urgency=low
* New upstream release.
* Dependency on python-feedparser is now versioned (>= 5.1.2) to
address problems with some feeds.
-- tony mancill <tmancill@debian.org> Sun, 23 Dec 2012 19:24:26 -0800
gpodder (3.3.0-1) unstable; urgency=low
* New upstream release.
* Bump Standards-Version to 3.9.4.
* Update README.Debian to note that syncing to iPod is still not
supported in the 3.x versions.
-- tony mancill <tmancill@debian.org> Mon, 24 Sep 2012 10:34:12 -0700
gpodder (3.2.0-1) unstable; urgency=low
* New upstream release.
* Upload to unstable now that the 3.x series has feature parity with
2.x. (MP3 player device sync is now part of 3.x.)
* d/control:
- Add libqtwebkit-qmlwebkitplugin to Recommends.
- Move python-webkit from Recommends to Depends.
-- tony mancill <tmancill@debian.org> Wed, 25 Jul 2012 22:03:20 -0700
gpodder (3.1.2-1) experimental; urgency=low
* New upstream release.
- Closes: #582656 - intermittently redownloads all [...] episodes
- Closes: #669194 - Repeatedly shows deleted episode
- Closes: #672583 - when run with web interface errors get thrown
* Freshen gpodder-migrate2tres manpage for 3.1.x build.
-- tony mancill <tmancill@debian.org> Mon, 28 May 2012 18:30:33 -0700
gpodder (3.1.1-1) experimental; urgency=low
* New upstream release.
* Bump Standards-Version to 3.9.3 (no changes).
-- tony mancill <tmancill@debian.org> Tue, 15 May 2012 22:32:06 -0700
gpodder (3.1.0-1) experimental; urgency=low
* New upstream release.
-- tony mancill <tmancill@debian.org> Tue, 17 Apr 2012 23:24:49 -0700
gpodder (2.20.1-1) unstable; urgency=low
* New upstream release.
- Bugfix release containing fixes from 3.x release.
* Update d/copyright years and DEP5 fields.
-- tony mancill <tmancill@debian.org> Sun, 19 Feb 2012 10:37:24 -0800
gpodder (3.0.4-1) experimental; urgency=low
* New upstream release.
-- tony mancill <tmancill@debian.org> Tue, 24 Jan 2012 21:59:59 -0800
gpodder (3.0.3-1) experimental; urgency=low
* New upstream release (Closes: #654546)
-- tony mancill <tmancill@debian.org> Mon, 09 Jan 2012 18:26:11 -0800
gpodder (3.0.2-1) experimental; urgency=low
* New upstream release.
-- tony mancill <tmancill@debian.org> Wed, 14 Dec 2011 00:15:05 -0800
gpodder (3.0.1-1) experimental; urgency=low
* New upstream release.
* Uploading to experimental to allow for testing of 3.x.
-- tony mancill <tmancill@debian.org> Sat, 26 Nov 2011 11:19:43 -0800
gpodder (2.20-1) unstable; urgency=low
* New upstream release.
* Update debian/watch.
* Remove translations.patch.
* Tweak package description to address lintian warning.
-- tony mancill <tmancill@debian.org> Wed, 19 Oct 2011 19:36:49 -0700
gpodder (2.18-1) unstable; urgency=low
* New upstream release.
* Add translations.patch to preserve translations from upstream 2.16.
-- tony mancill <tmancill@debian.org> Tue, 16 Aug 2011 21:52:00 -0700
gpodder (2.16-1) unstable; urgency=low
* New upstream release.
-- tony mancill <tmancill@debian.org> Fri, 08 Jul 2011 21:54:34 -0700
gpodder (2.15-2) unstable; urgency=low
* This time without a patch that reverts the source to 2.14.
-- tony mancill <tmancill@debian.org> Tue, 31 May 2011 22:05:31 -0700
gpodder (2.15-1) unstable; urgency=low
* New upstream release
* Bump standards version to 3.9.2 (no changes necessary).
-- tony mancill <tmancill@debian.org> Tue, 03 May 2011 14:21:32 -0700
gpodder (2.14-1) unstable; urgency=low
* New upstream release
-- tony mancill <tmancill@debian.org> Tue, 05 Apr 2011 21:23:23 -0700
gpodder (2.13-3) unstable; urgency=low
* Incorporate upstream patch for .desktop file. (Closes: #620438)
-- tony mancill <tmancill@debian.org> Sat, 02 Apr 2011 21:02:05 -0700
gpodder (2.13-2) unstable; urgency=low
* Update Vcs-* in debian/control; now using git.debian.org
-- tony mancill <tmancill@debian.org> Sun, 27 Feb 2011 20:22:16 -0800
gpodder (2.13-1) unstable; urgency=low
* New upstream release
* Switch source format to "3.0 (quilt)"
* Simplify debian/rules.
* Build-Depend on debhelper (>= 7.3.7)
-- tony mancill <tmancill@debian.org> Fri, 25 Feb 2011 23:01:30 -0800
gpodder (2.12-1) unstable; urgency=low
* New upstream release (Closes: #607180)
* Update Thomas's email address in debian/control.
-- tony mancill <tmancill@debian.org> Wed, 12 Jan 2011 21:32:36 -0800
gpodder (2.11-1) unstable; urgency=low
* New upstream release
-- tony mancill <tmancill@debian.org> Sun, 19 Dec 2010 15:35:25 -0800
gpodder (2.10-1) unstable; urgency=low
* New upstream release
* Upload to unstable.
-- tony mancill <tmancill@debian.org> Sun, 05 Dec 2010 17:08:02 -0800
gpodder (2.9-1) experimental; urgency=low
* New upstream release
* Removes dependency on python-pymtp.
* Update debian/copyright to DEP5 format.
* Upload to experimental pending release of squeeze.
-- tony mancill <tmancill@debian.org> Tue, 12 Oct 2010 22:21:18 -0700
gpodder (2.8-1~pre0) experimental; urgency=low
* New upstream release
* Remove python-pymad from Suggests (no longer used by software)
* Add python-gst0.10 to Recommends (used for track length detection
and iPod sync)
* Update Standards-Version to 3.9.1 (no changes needed)
* Upload to experimental
-- tony mancill <tmancill@debian.org> Mon, 06 Sep 2010 12:14:32 -0700
gpodder (2.7-1) unstable; urgency=low
* New upstream release: "Proposition Infinity"
* debian/control:
- Update Standards Version to 3.9.0 (no changes).
- Add tmancill@debian.org to Uploaders:
- Add Vcs-Browser and Vcs-Svn fields for Debian packaging
-- tony mancill <tmancill@debian.org> Sun, 18 Jul 2010 16:35:57 -0700
gpodder (2.6-1) unstable; urgency=low
* "The Staircase Implementation" release (Closes: #582907)
* Upstream: Add option "Do nothing" for new episodes (Closes: #561632)
* Upstream: Fix for new GtkBuilder version (Closes: #581780)
* Upstream: Removed feed_update_skipping (Closes: #568853)
* Upstream: Better new episode detection code (Closes: #582656)
* debian/control: Add "Recommends:" on python-webkit
* debian/control: Better package description
* debian/watch: Added
-- Thomas Perl <thp@thpinfo.com> Thu, 27 May 2010 17:41:01 +0200
gpodder (2.3-1) unstable; urgency=low
* "The Adhesive Duck Deficiency" release
* Remove help2man and imagemagick build-dependencies
-- Thomas Perl <thp@thpinfo.com> Sat, 27 Feb 2010 23:02:54 +0100
gpodder (2.2-1) unstable; urgency=low
* The "LA X" release
* Add build dependency and dependency on python-mygpoclient
* Remove recommendation on python-gtkhtml2 (Closes: #561337)
* Remove build-depends on python-dev (not necessary for pure Python modules)
* Add "${misc:Depends}" to Depends in debian/control
* Upgrade to standards-version 3.8.4 (no changes necessary)
-- Thomas Perl <thp@thpinfo.com> Fri, 05 Feb 2010 16:16:28 +0100
gpodder (2.1-1) unstable; urgency=low
* "The Luminous Fish Effect" release
* Add a "Recommends:" on dbus-x11 (Closes: #548524)
* Recommend "python-simplejson" for Soundcloud support
-- Thomas Perl <thp@thpinfo.com> Sat, 12 Dec 2009 17:52:45 +0100
gpodder (2.0-1) unstable; urgency=low
* The "Day of the Tentacle" release
-- Thomas Perl <thp@thpinfo.com> Wed, 16 Sep 2009 17:39:06 +0200
gpodder (0.17.0-1) unstable; urgency=low
* The "Orientation" release
-- Thomas Perl <thp@thpinfo.com> Mon, 27 Jul 2009 14:31:01 +0200
gpodder (0.16.1-1) unstable; urgency=low
* The "Adrift" bugfix release
-- Thomas Perl <thp@thpinfo.com> Fri, 05 Jun 2009 13:23:47 +0200
gpodder (0.16.0-1) unstable; urgency=low
* The "Man of Science, Man of Faith" release
* Make SQLite handling more robust (from upstream) (Closes: #527387)
* Upstream applied dbus error running from cron patch (Closes: #520369)
* debian/control: Removed dependency on python-glade2 (now using GtkBuilder)
-- Thomas Perl <thp@thpinfo.com> Mon, 01 Jun 2009 15:08:14 +0200
gpodder (0.15.2-1) unstable; urgency=low
* "The Long Morrow" bugfix release
* Upstream applied dbus error running from cron patch (Closes: #520369)
* debian/compat: Upgrade to debhelper compatibility level 7 (no changes
needed after looking at the changes in the debhelper(7) manpage)
* debian/control: Update Standards-Version to 3.8.1 (no changes needed
after looking at upgrading-checklist.txt and referring to the policy)
-- Thomas Perl <thp@thpinfo.com> Sat, 11 Apr 2009 13:35:17 +0200
gpodder (0.15.1-1) unstable; urgency=low
* The "Passage on the Lady Anne" bugfix release
* debian/control: Add python-dbus as a dependency (missing from 0.15.0)
-- Thomas Perl <thp@thpinfo.com> Thu, 12 Mar 2009 20:23:39 +0100
gpodder (0.15.0-1) unstable; urgency=low
* "The Invaders" release
* debian/rules: Add ChangeLog to the release (included in tarball)
* debian/rules: Remove outdated exclusion of "gui.py.orig" for dh_clean
* debian/copyright: Update year to 2009; add "and the gPodder Team"
-- Thomas Perl <thp@thpinfo.com> Mon, 09 Mar 2009 13:11:11 +0100
gpodder (0.14.1-1) unstable; urgency=low
* "The Thirty-Fathom Grave" bugfix release
* Recommend python-gtkhtml2 for HTML episode shownotes
-- Thomas Perl <thp@thpinfo.com> Sun, 01 Feb 2009 21:58:50 +0100
gpodder (0.14.0-1) unstable; urgency=low
* The "A Short Drink From a Certain Fountain" release
-- Thomas Perl <thp@thpinfo.com> Thu, 11 Dec 2008 15:25:27 +0100
gpodder (0.13.1-1) unstable; urgency=low
* "The Brain Center at Whipple's" bugfix release
-- Thomas Perl <thp@perli.net> Thu, 30 Oct 2008 13:28:15 +0100
gpodder (0.13.0-1) unstable; urgency=low
* The "A Thing About Machines" release
* Push Standards-Version to 3.8.0
* Use "dh_icons" for updating the icon cache and remove custom postinst file
* Suggest python-pymtp for new Media Transfer Protocol MP3 player support
* Update application description to be more accurate for the recent version
* Update website URL, year and e-mail address in debian/copyright file
-- Thomas Perl <thp@perli.net> Mon, 06 Oct 2008 21:39:41 +0200
gpodder (0.12.2-1) unstable; urgency=low
* The "Of Late I Think of Cliffordville" bugfix release
-- Thomas Perl <thp@perli.net> Sun, 17 Aug 2008 15:51:54 +0200
gpodder (0.12.1-1) unstable; urgency=low
* "The Little People" bugfix release (Closes: #491696, #491610)
-- Thomas Perl <thp@perli.net> Thu, 24 Jul 2008 11:22:35 +0200
gpodder (0.12.0-1) unstable; urgency=low
* The "Metropolis" release (Closes: #478748, #489459)
-- Thomas Perl <thp@perli.net> Tue, 15 Jul 2008 11:01:45 +0200
gpodder (0.11.3-1) unstable; urgency=low
* The "To Serve Man" release (Closes: #481229, #482907)
-- Thomas Perl <thp@perli.net> Mon, 02 Jun 2008 11:30:42 +0200
gpodder (0.11.2-1) unstable; urgency=low
* The "Walk like a Panther" release
-- Thomas Perl <thp@perli.net> Sat, 26 Apr 2008 09:56:53 +0200
gpodder (0.11.1-1) unstable; urgency=low
* The "Attacked by Killer Tomatoes" release (Closes: #469736, #466496)
* Alternative dependency for gnome-bluetooth is bluez-gnome (contains
bluetooth-sendto, which is intended to replace gnome-obex-send)
-- Thomas Perl <thp@perli.net> Thu, 27 Mar 2008 14:32:18 +0100
gpodder (0.11.0-1) unstable; urgency=low
* The "Walking for a change makes me feel normal" release
* Suggest python-bluez or bluez-utils and gnome-bluetooth for Bluetooth file
transfer support (new in 0.11.0)
-- Thomas Perl <thp@perli.net> Mon, 25 Feb 2008 14:58:34 +0100
gpodder (0.10.4-1) unstable; urgency=low
* The "Faster Pussycats Kill" release
* Add a last-minute bugfix for the .desktop file (wrong language)
-- Thomas Perl <thp@perli.net> Tue, 22 Jan 2008 09:44:38 +0100
gpodder (0.10.3-1) unstable; urgency=low
* The "A Stop at Willoughby" release
* Patch from 0.10.2-2 is now included upstream
* Category in gpodder.menu is now "Applications/Network/Web News"
-- Thomas Perl <thp@perli.net> Thu, 13 Dec 2007 09:38:03 +0100
gpodder (0.10.2-2) unstable; urgency=low
* Fix bug that prevents the channel list from being saved when no
channels.opml file exists in gPodder's config directory (first run)
-- Thomas Perl <thp@perli.net> Sat, 01 Dec 2007 15:05:39 +0100
gpodder (0.10.2-1) unstable; urgency=low
* The "Ein schweineschnauzen Sandwich, bitte!" release
* Check for free disk space before saving channel list (Closes: #452490)
-- Thomas Perl <thp@perli.net> Mon, 26 Nov 2007 18:52:14 +0100
gpodder (0.10.1-1) unstable; urgency=low
* The "Nukular, das Wort heißt Nukular" release
-- Thomas Perl <thp@perli.net> Mon, 29 Oct 2007 13:18:08 +0100
gpodder (0.10.0-3) unstable; urgency=low
* Only support Python versions >= 2.4
-- Thomas Perl <thp@perli.net> Fri, 05 Oct 2007 09:37:04 +0200
gpodder (0.10.0-2) unstable; urgency=low
* Set XS-Python-Version to "all" (Closes: #445278)
* Update copyright file to reflect GPLv3 change
-- Thomas Perl <thp@perli.net> Fri, 21 Sep 2007 02:16:59 +0200
gpodder (0.10.0-1) unstable; urgency=low
* The "Hier spricht Frank Drebin" release
* New dependency: python-feedparser
* Removed dependencies: wget, python-xml
* Support for Atom feeds through feedparser (Closes: #430844)
* Deleting not-downloaded episodes enabled (Closes: 441285)
-- Thomas Perl <thp@perli.net> Fri, 21 Sep 2007 02:13:35 +0200
gpodder (0.9.5-2) unstable; urgency=low
* Fix problem with invalid file sizes in RSS feeds (Closes: #441284)
-- Thomas Perl <thp@perli.net> Sat, 08 Sep 2007 17:09:48 +0200
gpodder (0.9.5-1) unstable; urgency=low
* The "we can do funky release titles, too" release
* Change rules file to keep gui.py.orig
* Remove Recommends on python-id3 and mplayer
-- Thomas Perl <thp@perli.net> Sun, 26 Aug 2007 20:23:30 +0200
gpodder (0.9.4-1) unstable; urgency=low
* New upstream release (Closes: #432805, #433029)
* Added gpodder.menu file
* Remove locally-changed files (included upstream)
-- Thomas Perl <thp@perli.net> Sat, 21 Jul 2007 13:53:55 +0200
gpodder (0.9.3-2) unstable; urgency=low
* The "oh so many small bugs" release
* Workaround buggy RSS feeds with no titles, thanks to Holger Leskien
(Closes: #430843)
* Applied patch from Mykola Nikishov to fix a wget bug (Closes: #431446)
-- Thomas Perl <thp@perli.net> Mon, 25 Jun 2007 23:16:12 +0200
gpodder (0.9.3-1) unstable; urgency=low
* New upstream release
* Recommend mplayer, python-id3 and python-gpod and
suggest python-eyed3 and python-pymad as dependencies
-- Thomas Perl <thp@perli.net> Mon, 25 Jun 2007 23:14:00 +0200
gpodder (0.9.2-1) unstable; urgency=low
* New upstream release
-- Thomas Perl <thp@perli.net> Wed, 23 May 2007 15:05:21 +0200
gpodder (0.9.1-3) unstable; urgency=low
* Fixed FSF address from old GPL/LGPL license stanzas, metioned the
location of the full licenses on Debian systems for GPL/LGPL
-- Thomas Perl <thp@perli.net> Sun, 22 Apr 2007 23:33:12 +0200
gpodder (0.9.1-2) unstable; urgency=low
* Updated copyright file to state copyright of tepache and SimpleGladeApp
-- Thomas Perl <thp@perli.net> Sun, 22 Apr 2007 23:32:03 +0200
gpodder (0.9.1-1) unstable; urgency=low
* New upstream release
* Added postinst script (run gtk-update-icon-cache)
-- Thomas Perl <thp@perli.net> Thu, 05 Apr 2007 09:54:54 +0200
gpodder (0.9.0+svn200703221-1) unstable; urgency=low
* New upstream release (Closes: #415059)
-- Thomas Perl <thp@perli.net> Thu, 22 Mar 2007 13:16:46 +0100
gpodder (0.9.0+svn200703141-1) unstable; urgency=low
* New upstream release
-- Thomas Perl <thp@perli.net> Wed, 14 Mar 2007 20:59:20 +0100
gpodder (0.9.0+svn200703101-2) unstable; urgency=low
* Removed some unneeded dh_* commands from rules file
-- Thomas Perl <thp@perli.net> Mon, 12 Mar 2007 21:58:55 +0100
gpodder (0.9.0+svn200703101-1) unstable; urgency=low
* New upstream release
-- Thomas Perl <thp@perli.net> Sat, 10 Mar 2007 18:42:19 +0100
gpodder (0.9.0+svn200703081-1) unstable; urgency=low
* New upstream release
-- Thomas Perl <thp@perli.net> Fri, 9 Mar 2007 18:36:35 +0100
gpodder (0.9.0+svn200703072-1) unstable; urgency=low
* New upstream release
-- Thomas Perl <thp@perli.net> Wed, 7 Mar 2007 16:36:28 +0100
gpodder (0.9.0+svn20070307-1) unstable; urgency=low
* New upstream release
-- Thomas Perl <thp@perli.net> Wed, 7 Mar 2007 11:48:58 +0100
gpodder (0.9.0-3) unstable; urgency=low
* Add build-dependency on imagemagick (for convert call)
* Fix broken artwork installation in setup.py
-- Thomas Perl <thp@perli.net> Wed, 7 Mar 2007 11:09:54 +0100
gpodder (0.9.0-2) unstable; urgency=low
* Package for python-support and mentors.debian.net
* Cleanup of package structure, removed unneeded stuff from rules
-- Thomas Perl <thp@perli.net> Wed, 7 Mar 2007 00:13:40 +0100
gpodder (0.9.0-1etch0) unstable; urgency=low
* New upstream release
-- Thomas Perl <thp@perli.net> Tue, 6 Mar 2007 20:58:22 +0100
gpodder (0.8.9-1etch0) unstable; urgency=low
* New upstream release
-- Thomas Perl <thp@perli.net> Sat, 3 Feb 2007 12:04:19 +0100
gpodder (0.8.0-1sarge0) unstable; urgency=low
* New upstream release
-- Thomas Perl <thp@perli.net> Fri, 28 Jul 2006 14:58:26 +0200
gpodder (0.7.9-1sarge0) unstable; urgency=low
* New upstream release
-- Thomas Perl <thp@perli.net> Mon, 17 Jul 2006 17:36:33 +0200
gpodder (0.7-2) unstable; urgency=low
* Fixed problem with buggy RSS feeds (wrong "size")
-- Thomas Perl <thp@perli.net> Sat, 8 Apr 2006 19:40:20 +0200
gpodder (0.7-1) unstable; urgency=low
* Initial release
-- Thomas Perl <thp@perli.net> Sat, 8 Apr 2006 11:17:28 +0200

47
debian/control vendored Normal file
View File

@ -0,0 +1,47 @@
Source: gpodder-adaptive
Maintainer: Maryjane <maryjane@disroot.org>
XSBC-Original-Maintainer: Thomas Perl <m@thp.io>
Section: x11
Priority: optional
Standards-Version: 4.5.0
Build-Depends: debhelper-compat (= 13),
dh-python,
intltool,
python3,
python3-all,
python3-setuptools
Homepage: https://gpodder.org/
Vcs-Browser: https://salsa.debian.org/debian/gpodder
Vcs-Git: https://salsa.debian.org/debian/gpodder.git
Rules-Requires-Root: no
Package: gpodder-adaptive
Architecture: all
Depends: ${misc:Depends}, ${python3:Depends},
default-dbus-session-bus | dbus-session-bus,
gir1.2-gtk-3.0,
gir1.2-handy-1,
python3-gi,
python3-dbus,
python3-cairo,
python3-gi-cairo,
python3-mygpoclient,
python3-podcastparser,
python3-requests (>= 2.24)
Recommends:
gir1.2-ayatanaappindicator3-0.1,
libgpod4,
normalize-audio,
python3-eyed3,
python3-html5lib,
python3-simplejson
Suggests: mplayer, gnome-bluetooth, yt-dlp (>= 2023.02.17)
Conflicts: gpodder
Description: podcast client and feed aggregator
gPodder is a podcast receiver/catcher. You can subscribe to feeds
("podcasts") and automatically download new audio and video content.
Downloaded content can be played on your computer or synchronized to
iPods, MTP-based players, filesystem-based MP3 players and Bluetooth
enabled mobile phones. YouTube video feeds are also supported.
.
This package provides the "gpodder" GUI and the "gpo" CLI utility.

33
debian/copyright vendored Normal file
View File

@ -0,0 +1,33 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: gPodder
Upstream-Contact: Thomas Perl <thp[at]thpinfo.com>
Source: https://gpodder.org/
Comment: The share/metainfo/org.gpodder.gpodder.appdata.xml
indicates that the AppStream license is CC0-1.0, but that the
project license is GPL-3+.
Files: *
Copyright: 2005-2020, Thomas Perl and the gPodder Team
License: GPL-3+
Files: debian/*
Copyright: 2006-2014, Thomas Perl,
2010-2020, tony mancill <tmancill@debian.org>
License: GPL-3+
License: GPL-3+
gPodder is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
.
gPodder is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
.
On Debian GNU/Linux systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL-3'.

1
debian/gpodder.docs vendored Normal file
View File

@ -0,0 +1 @@
README.md

View File

@ -0,0 +1,18 @@
Description: Modify the default value for check_on_startup to false.
This prevents an privacy/information disclosure unless the user
explicitly opts-in for the update check.
Forwarded: not-needed
Origin: vendor
Author: tony mancill <tmancill@debian.org>
--- a/src/gpodder/config.py
+++ b/src/gpodder/config.py
@@ -93,7 +93,7 @@
# Software updates from gpodder.org
'software_update': {
- 'check_on_startup': True, # check for updates on start
+ 'check_on_startup': False, # check for updates on start
'last_check': 0, # unix timestamp of last update check
'interval': 5, # interval (in days) to check for updates
},

2
debian/patches/series vendored Normal file
View File

@ -0,0 +1,2 @@
disable_update_check_on_startup_default.patch
switch-appindicator-extension-to-AyatanaAppIndicator-and-python3.patch

View File

@ -0,0 +1,11 @@
--- a/share/gpodder/extensions/ubuntu_appindicator.py
+++ b/share/gpodder/extensions/ubuntu_appindicator.py
@@ -12,7 +12,7 @@
_ = gpodder.gettext
-__title__ = _('Ubuntu App Indicator')
+__title__ = _('Ayatana App Indicator')
__description__ = _('Show a status indicator in the top bar.')
__authors__ = 'Thomas Perl <thp@gpodder.org>'
__category__ = 'desktop-integration'

20
debian/rules vendored Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/make -f
CHANGELOG = ChangeLog
DOCS = README.md
PYTHON = /usr/bin/python3
PREFIX = /usr
export DH_VERBOSE = 1
%:
dh $@ --with python3 --buildsystem=pybuild
override_dh_auto_test:
# skip tests
override_dh_auto_install:
PREFIX=$(PREFIX) make messages
PREFIX=$(PREFIX) make share/dbus-1/services/org.gpodder.service
DESTDIR=$(CURDIR)/debian/$(DEB_SOURCE) PREFIX=$(PREFIX) make install
dh_auto_install

1
debian/source/format vendored Normal file
View File

@ -0,0 +1 @@
3.0 (quilt)

3
debian/watch vendored Normal file
View File

@ -0,0 +1,3 @@
version=4
opts=repack,compression=xz,filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/gpodder-$1\.tar\.gz/ \
https://github.com/gpodder/gpodder/tags .*/v?(\d\S+)\.tar\.gz

View File

@ -38,8 +38,8 @@ UIFILES=$(wildcard share/gpodder/ui/gtk/*.ui \
share/gpodder/ui/adaptive/*.ui)
UIFILES_H=$(subst .ui,.ui.h,$(UIFILES))
GETTEXT_SOURCE=$(wildcard src/gpodder/*.py \
src/gpodder/gtkui/*.py \
src/gpodder/gtkui/interface/*.py \
src/gpodder/gtkui/*.py \
src/gpodder/gtkui/interface/*.py \
src/gpodder/gtkui/desktop/*.py \
src/gpodder/plugins/*.py \
share/gpodder/extensions/*.py)
@ -69,16 +69,19 @@ unittest:
ISORTOPTS := -c share src/gpodder tools bin/* *.py
lint:
pycodestyle --version
pycodestyle share src/gpodder tools bin/* *.py
isort -q $(ISORTOPTS) || isort --df $(ISORTOPTS)
isort --version
isort -q $(ISORTOPTS) || isort --df $(ISORTOPTS)
codespell --quiet-level 3 --skip "./.git,*.po,./share/applications/gpodder.desktop"
release: distclean
$(PYTHON) setup.py sdist
releasetest: unittest $(DESKTOP_FILES) $(POFILES)
for f in $(DESKTOP_FILES); do desktop-file-validate $$f; done
for f in $(POFILES); do msgfmt --check $$f; done
for f in $(DESKTOP_FILES); do desktop-file-validate $$f || exit 1; done
for f in $(POFILES); do msgfmt --check $$f || exit 1; done
$(GPODDER_SERVICE_FILE): $(GPODDER_SERVICE_FILE_IN)
sed -e 's#__PREFIX__#$(PREFIX)#' $< >$@
@ -140,7 +143,6 @@ $(MESSAGES): $(GETTEXT_SOURCE)
messages-force:
xgettext --from-code=utf-8 -LPython -k_:1 -kN_:1 -kN_:1,2 -kn_:1,2 -o $(MESSAGES) $(GETTEXT_SOURCE)
##########################################################################
# This only works in a Git working commit, and assumes that the local Git
@ -171,5 +173,3 @@ distclean: clean
.PHONY: help unittest release releasetest install manpages clean distclean messages headlink lint revbump
##########################################################################

1516
po/ca.po

File diff suppressed because it is too large Load Diff

1632
po/cs.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1648
po/da.po

File diff suppressed because it is too large Load Diff

1705
po/de.po

File diff suppressed because it is too large Load Diff

1645
po/el.po

File diff suppressed because it is too large Load Diff

1656
po/es.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1655
po/eu.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1652
po/fi.po

File diff suppressed because it is too large Load Diff

1753
po/fr.po

File diff suppressed because it is too large Load Diff

1645
po/gl.po

File diff suppressed because it is too large Load Diff

1647
po/he.po

File diff suppressed because it is too large Load Diff

1760
po/hu.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1683
po/it.po

File diff suppressed because it is too large Load Diff

1644
po/kk.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2575
po/nb.po

File diff suppressed because it is too large Load Diff

1689
po/nl.po

File diff suppressed because it is too large Load Diff

1649
po/nn.po

File diff suppressed because it is too large Load Diff

1775
po/pl.po

File diff suppressed because it is too large Load Diff

1645
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1642
po/ro.po

File diff suppressed because it is too large Load Diff

1719
po/ru.po

File diff suppressed because it is too large Load Diff

2865
po/sk.po Normal file

File diff suppressed because it is too large Load Diff

1650
po/sv.po

File diff suppressed because it is too large Load Diff

1683
po/tr.po

File diff suppressed because it is too large Load Diff

1661
po/uk.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,3 +7,7 @@ max-line-length = 142
[isort]
known_third_party=dbus,gi,mutagen,cairo,requests,github3,jinja2,magic,youtube_dl,podcastparser,mygpoclient
known_first_party=gpodder,soco
[flake8]
max-line-length = 142
ignore = E126, E128, W503

View File

@ -18,7 +18,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import glob
import os
import re
import sys
@ -26,7 +25,7 @@ from distutils.core import setup
installing = ('install' in sys.argv and '--help' not in sys.argv)
# distutils depends on setup.py beeing executed from the same dir.
# distutils depends on setup.py being executed from the same dir.
# Most of our custom commands work either way, but this makes
# it work in all cases.
os.chdir(os.path.dirname(os.path.realpath(__file__)))
@ -199,7 +198,7 @@ except MissingFile as mf:
setup(
name='gpodder',
name='gpodder-adaptive',
version=metadata['version'],
description=metadata['tagline'],
license=metadata['license'],

View File

@ -9,3 +9,4 @@ Terminal=false
Type=Application
Categories=AudioVideo;Audio;Network;FileTransfer;News;GTK;
StartupWMClass=gpodder
X-Purism-FormFactor=Workstation;Mobile;

View File

@ -1,4 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/env python3
# Example script that can be used as post-play extension in media players
#
# Set the configuration options "audio_played_dbus" and "video_played_dbus"

View File

@ -60,7 +60,7 @@ class gPodderExtension:
#
# https://docs.python.org/3/library/subprocess.html#subprocess.Popen
#
# This is expecially important for extensions responding to
# This is especially important for extensions responding to
# on_episode_downloaded(), which runs whenever a download finishes.
#
# Otherwise that process will inherit ALL file descriptors gPodder

View File

@ -133,7 +133,7 @@ class gPodderExtension:
logger.info('Converted audio file to %(format)s.' % {'format': new_extension})
gpodder.user_extensions.on_notification_show(_('File converted'), episode.title)
else:
logger.warn('Error converting audio file: %s / %s', stdout, stderr)
logger.warning('Error converting audio file: %s / %s', stdout, stderr)
gpodder.user_extensions.on_notification_show(_('Conversion failed'), episode.title)
def _convert_episodes(self, episodes):

View File

@ -6,7 +6,6 @@
import datetime
import logging
import os
import subprocess
import gpodder
from gpodder import util
@ -45,7 +44,7 @@ class gPodderExtension:
def read_episode_info(self, episode):
filename = episode.local_filename(create=False, check_only=True)
if filename is None:
logger.warn("%s: missing episode filename", __title__)
logger.warning("%s: missing episode filename", __title__)
return None
info = {
'filename': filename,
@ -74,4 +73,4 @@ class gPodderExtension:
if proc.returncode == 0:
logger.info("%s succeeded", command)
else:
logger.warn("%s run with exit code %i", command, proc.returncode)
logger.warning("%s run with exit code %i", command, proc.returncode)

View File

@ -5,7 +5,6 @@
import logging
import os
import subprocess
from gi.repository import Gtk
@ -38,8 +37,8 @@ class gPodderExtension:
dlg = Gtk.FileChooserDialog(title=_('Save video'),
parent=self.gpodder.get_dialog_parent(),
action=Gtk.FileChooserAction.SAVE)
dlg.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
dlg.add_button(Gtk.STOCK_SAVE, Gtk.ResponseType.OK)
dlg.add_button(_('_Cancel'), Gtk.ResponseType.CANCEL)
dlg.add_button(_('_Save'), Gtk.ResponseType.OK)
if dlg.run() == Gtk.ResponseType.OK:
filename = dlg.get_filename()
@ -75,7 +74,9 @@ class gPodderExtension:
close_fds=True)
result = ffmpeg.wait()
util.delete_file(list_filename)
util.idle_add(lambda: indicator.on_finished())
indicator.on_finished()
util.idle_add(lambda: self.gpodder.show_message(
_('Videos successfully converted') if result == 0 else
_('Error converting videos'),

View File

@ -5,7 +5,6 @@
# Released under the same license terms as gPodder itself.
import functools
import logging
import subprocess
import gpodder
from gpodder import util
@ -72,7 +71,7 @@ class Win32Player(Player):
self.command = win32_read_registry_key(self.command)
return True
except Exception as e:
logger.warn('Win32 player not found: %s (%s)', self.command, e)
logger.warning('Win32 player not found: %s (%s)', self.command, e)
return False
@ -212,6 +211,9 @@ PLAYERS = [
# Clementine, http://www.clementine-player.org/
FreeDesktopPlayer('clementine', 'Clementine', ['clementine', '--append']),
# Strawberry, https://www.strawberrymusicplayer.org/
FreeDesktopPlayer('strawberry', 'Strawberry', ['strawberry', '--append']),
# Parole, http://docs.xfce.org/apps/parole/start
FreeDesktopPlayer('parole', 'Parole', ['parole', '-a']),
@ -240,7 +242,7 @@ RESUMERS = [
# with https://github.com/Serranya/deadbeef-mpris2-plugin
MPRISResumer('resume in deadbeef', 'DeaDBeeF', ['deadbeef'], 'org.mpris.MediaPlayer2.DeaDBeeF'),
# the gPodder Dowloads directory must be in gmusicbrowser's library
# the gPodder Downloads directory must be in gmusicbrowser's library
MPRISResumer('resume in gmusicbrowser', 'gmusicbrowser', ['gmusicbrowser'], 'org.mpris.MediaPlayer2.gmusicbrowser'),
# Audacious doesn't implement MPRIS2.OpenUri

View File

@ -135,6 +135,13 @@ class gPodderExtension:
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
box.set_border_width(10)
# note about Cancel
note = Gtk.Label(use_markup=True, wrap=True, label=_(
'<b>Note:</b> The Cancel button does <b>not</b> return the '
'filter settings to the values they had before. '
'The changes are saved immediately after they are made.'))
box.add(note)
# block widgets
self.block_widget = BlockExceptFrame(value=block,
enable_re=self.key('block_re') is not False,
@ -163,10 +170,15 @@ class gPodderExtension:
box.add(label)
# re-filter
button = Gtk.Button(_('Filter episodes now (undoes any episodes you marked as old)'))
separator = Gtk.HSeparator()
box.add(separator)
button = Gtk.Button(_('Filter episodes now'))
button.connect('clicked', self.refilter_podcast)
box.add(button)
label2 = Gtk.Label(_('Undoes any episodes you marked as old.'))
box.add(label2)
box.show_all()
return box

View File

@ -121,18 +121,18 @@ class CurrentTrackTracker(object):
# If the position is being updated, and the current status was Playing
# If the status *is* playing, and *was* playing, but the position
# has changed discontinuously, notify a stop for the old position
if (cur['status'] == 'Playing' and
('status' not in kwargs or kwargs['status'] == 'Playing') and not
if (cur['status'] == 'Playing'
and ('status' not in kwargs or kwargs['status'] == 'Playing') and not
subsecond_difference(cur['pos'], kwargs['pos'])):
logger.debug('notify Stopped: playback discontinuity:' +
'calc: %f observed: %f', cur['pos'], kwargs['pos'])
logger.debug('notify Stopped: playback discontinuity:'
+ 'calc: %r observed: %r', cur['pos'], kwargs['pos'])
self.notify_stop()
if ((kwargs['pos']) == 0 and
self.pos is not None and
self.length is not None and
(self.length - USECS_IN_SEC) < self.pos and
self.pos < (self.length + 2 * USECS_IN_SEC)):
if ((kwargs['pos']) <= 0
and self.pos is not None
and self.length is not None
and (self.length - USECS_IN_SEC) < self.pos
and self.pos < (self.length + 2 * USECS_IN_SEC)):
logger.debug('pos=0 end of stream (calculated pos: %f/%f [%f])',
self.pos / USECS_IN_SEC, self.length / USECS_IN_SEC,
(self.pos / USECS_IN_SEC) - (self.length / USECS_IN_SEC))
@ -144,7 +144,8 @@ class CurrentTrackTracker(object):
logger.debug('pos=0 not end of stream (calculated pos: %f/%f [%f])',
self.pos / USECS_IN_SEC, self.length / USECS_IN_SEC,
(self.pos / USECS_IN_SEC) - (self.length / USECS_IN_SEC))
self.pos = kwargs.pop('pos')
newpos = kwargs.pop('pos')
self.pos = newpos if newpos >= 0 else 0
if 'status' in kwargs:
self.status = kwargs.pop('status')
@ -159,7 +160,7 @@ class CurrentTrackTracker(object):
if self.status == 'Playing':
self.notify_playing()
else:
logger.debug('notify Stopped: status %s', self.status)
logger.debug('notify Stopped: status %r', self.status)
self.notify_stop()
def getinfo(self):
@ -173,11 +174,11 @@ class CurrentTrackTracker(object):
self.notify('Playing')
def notify(self, status):
if (self.uri is None or
self.pos is None or
self.status is None or
self.length is None or
self.length <= 0):
if (self.uri is None
or self.pos is None
or self.status is None
or self.length is None
or self.length <= 0):
return
pos = self.pos // USECS_IN_SEC
parsed_url = urllib.parse.urlparse(self.uri)
@ -254,10 +255,10 @@ class MPRISDBusReceiver(object):
invalidated_properties, path=None, sender=None):
if interface_name != self.INTERFACE_MPRIS:
if interface_name not in self.OTHER_MPRIS_INTERFACES:
logger.warn('unexpected interface: %s, props=%r', interface_name, list(changed_properties.keys()))
logger.warning('unexpected interface: %s, props=%r', interface_name, list(changed_properties.keys()))
return
if sender is None:
logger.warn('No sender associated to D-Bus signal, please report a bug')
logger.warning('No sender associated to D-Bus signal, please report a bug')
return
collected_info = {}
@ -274,27 +275,28 @@ class MPRISDBusReceiver(object):
collected_info['rate'] = changed_properties['Rate']
# Fix #788 pos=0 when Stopped resulting in not saving position on VLC quit
if changed_properties.get('PlaybackStatus') != 'Stopped':
collected_info['pos'] = self.query_position(sender)
try:
collected_info['pos'] = self.query_property(sender, 'Position')
except dbus.exceptions.DBusException:
pass
if 'status' not in collected_info:
collected_info['status'] = str(self.query_status(sender))
logger.debug('collected info: %r', collected_info)
try:
collected_info['status'] = str(self.query_property(
sender, 'PlaybackStatus'))
except dbus.exceptions.DBusException:
pass
logger.debug('collected info: %r', collected_info)
self.cur.update(**collected_info)
def on_seeked(self, position):
logger.debug('seeked to pos: %f', position)
self.cur.update(pos=position)
def query_position(self, sender):
def query_property(self, sender, prop):
proxy = self.bus.get_object(sender, self.PATH_MPRIS)
props = dbus.Interface(proxy, self.INTERFACE_PROPS)
return props.Get(self.INTERFACE_MPRIS, 'Position')
def query_status(self, sender):
proxy = self.bus.get_object(sender, self.PATH_MPRIS)
props = dbus.Interface(proxy, self.INTERFACE_PROPS)
return props.Get(self.INTERFACE_MPRIS, 'PlaybackStatus')
return props.Get(self.INTERFACE_MPRIS, prop)
class gPodderNotifier(dbus.service.Object):

View File

@ -91,13 +91,14 @@ class gPodderExtension:
cmd = [CONVERT_COMMANDS.get(extension, 'normalize-audio'), filename]
# Set cwd to prevent normalize from placing files in the directory gpodder was started from.
if gpodder.ui.win32:
p = util.Popen(cmd)
p = util.Popen(cmd, cwd=episode.channel.save_dir)
p.wait()
stdout, stderr = ("<unavailable>",) * 2
else:
p = util.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
p = util.Popen(cmd, cwd=episode.channel.save_dir,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode == 0:
@ -105,7 +106,7 @@ class gPodderExtension:
gpodder.user_extensions.on_notification_show(_('File normalized'),
episode.title)
else:
logger.warn('normalize-audio failed: %s / %s', stdout, stderr)
logger.warning('normalize-audio failed: %s / %s', stdout, stderr)
def convert_episodes(self, episodes):
for episode in episodes:

View File

@ -44,11 +44,6 @@ import tempfile
import gpodder
import gi # isort:skip
gi.require_version('Gtk', '3.0') # isort:skip
from gi.repository import Gtk # isort:skip
logger = logging.getLogger(__name__)
_ = gpodder.gettext
@ -105,7 +100,7 @@ try {{
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($APP_ID).Show($toast)
Remove-Item -LiteralPath $MyInvocation.MyCommand.Path -Force # Delete this script temp file.
}} else {{
# use older Baloon notification when not on Windows 10
# use older Balloon notification when not on Windows 10
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$o = New-Object System.Windows.Forms.NotifyIcon

View File

@ -5,6 +5,7 @@
import logging
import os
import time
import gpodder
from gpodder import util
@ -24,12 +25,14 @@ __category__ = 'post-download'
DefaultConfig = {
'add_sortdate': False, # Add the sortdate as prefix
'add_podcast_title': False, # Add the podcast title as prefix
'sortdate_after_podcast_title': False, # put the sortdate after podcast title
}
class gPodderExtension:
def __init__(self, container):
self.container = container
self.gpodder = None
self.config = self.container.config
def on_episode_downloaded(self, episode):
@ -43,6 +46,39 @@ class gPodderExtension:
os.rename(current_filename, new_filename)
util.rename_episode_file(episode, new_filename)
def on_ui_object_available(self, name, ui_object):
if name == 'gpodder-gtk':
self.gpodder = ui_object
def on_create_menu(self):
return [(_("Rename all downloaded episodes"), self.rename_all_downloaded_episodes)]
def rename_all_downloaded_episodes(self):
episodes = [e for c in self.gpodder.channels for e in [e for e in c.children if e.state == gpodder.STATE_DOWNLOADED]]
number_of_episodes = len(episodes)
if number_of_episodes == 0:
self.gpodder.show_message(_('No downloaded episodes to rename'),
_('Rename all downloaded episodes'), important=True)
from gpodder.gtkui.interface.progress import ProgressIndicator
progress_indicator = ProgressIndicator(
_('Renaming all downloaded episodes'),
'', True, self.gpodder.get_dialog_parent(), number_of_episodes)
for episode in episodes:
self.on_episode_downloaded(episode)
if not progress_indicator.on_tick():
break
renamed_count = progress_indicator.tick_counter
progress_indicator.on_finished()
if renamed_count > 0:
self.gpodder.show_message(_('Renamed %(count)d downloaded episodes') % {'count': renamed_count},
_('Rename all downloaded episodes'), important=True)
def make_filename(self, current_filename, title, sortdate, podcast_title):
dirname = os.path.dirname(current_filename)
filename = os.path.basename(current_filename)
@ -50,10 +86,16 @@ class gPodderExtension:
new_basename = []
new_basename.append(title)
if self.config.add_podcast_title:
new_basename.insert(0, podcast_title)
if self.config.add_sortdate:
new_basename.insert(0, sortdate)
if self.config.sortdate_after_podcast_title:
if self.config.add_sortdate:
new_basename.insert(0, sortdate)
if self.config.add_podcast_title:
new_basename.insert(0, podcast_title)
else:
if self.config.add_podcast_title:
new_basename.insert(0, podcast_title)
if self.config.add_sortdate:
new_basename.insert(0, sortdate)
new_basename = ' - '.join(new_basename)
# Remove unwanted characters and shorten filename (#494)

View File

@ -1,4 +1,3 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
####
# 01/2011 Bernd Schlapsi <brot@gmx.info>
@ -97,4 +96,4 @@ class gPodderExtension:
logger.info('Removed cover art from OGG file: %s', filename)
ogg.save()
except Exception as e:
logger.warn('Failed to remove OGG cover: %s', e, exc_info=True)
logger.warning('Failed to remove OGG cover: %s', e, exc_info=True)

View File

@ -1,4 +1,3 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Requirements: apt-get install python-kaa-metadata ffmpeg python-dbus
# To use, copy it as a Python script into ~/.config/gpodder/extensions/rockbox_mp4_convert.py

View File

@ -39,7 +39,7 @@ class gPodderExtension:
device_folder = device.get_episode_folder_on_device(episode)
episode_art = os.path.join(episode_folder, "folder.jpg")
device_art = os.path.join(device_folder, self.config.art_name_on_device)
# make sure we have art to copy and it doesnt already exist
# make sure we have art to copy and it doesn't already exist
if os.path.isfile(episode_art) and not os.path.isfile(device_art):
logger.info('Syncing cover art for %s', episode.channel.title)
# copy and rename art

View File

@ -1,4 +1,3 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
####
# 01/2011 Bernd Schlapsi <brot@gmx.info>
@ -27,7 +26,6 @@ import base64
import datetime
import logging
import mimetypes
import os
from mutagen import File
from mutagen.easyid3 import EasyID3
@ -64,7 +62,8 @@ DefaultConfig = {
'auto_embed_coverart': False,
'set_artist_to_album': False,
'set_version': 4,
'modify_tags': True
'modify_tags': True,
'remove_before_modify': False
}
@ -84,7 +83,7 @@ class AudioFile(object):
audio.delete()
audio.save()
def write_basic_tags(self, modify_tags, set_artist_to_album, set_version):
def write_basic_tags(self, remove_before_modify, modify_tags, set_artist_to_album, set_version):
audio = File(self.filename, easy=True)
if audio is None:
@ -95,6 +94,9 @@ class AudioFile(object):
audio.add_tags()
if modify_tags:
if remove_before_modify:
audio.delete()
if self.album is not None:
audio.tags['album'] = self.album
@ -129,7 +131,7 @@ class AudioFile(object):
def get_cover_picture(self, cover):
""" Returns mutagen Picture class for the cover image
Usefull for OGG and FLAC format
Useful for OGG and FLAC format
Picture type = cover image
see http://flac.sourceforge.net/documentation_tools_flac.html#encoding_options
@ -261,7 +263,7 @@ class gPodderExtension:
else:
info['title'] = title
info['subtitle'] = episode.description
info['subtitle'] = episode._text_description
if self.container.config.genre_tag is not None:
info['genre'] = self.container.config.genre_tag
@ -286,7 +288,8 @@ class gPodderExtension:
if self.container.config.always_remove_tags:
audio.remove_tags()
else:
audio.write_basic_tags(self.container.config.modify_tags,
audio.write_basic_tags(self.container.config.remove_before_modify,
self.container.config.modify_tags,
self.container.config.set_artist_to_album,
self.container.config.set_version)

View File

@ -20,6 +20,7 @@
# Windows 7 taskbar progress
# Sean Munkel; 2013-01-05
import ctypes
import functools
import logging
from ctypes import (HRESULT, POINTER, Structure, alignment, c_int, c_uint,
@ -30,6 +31,11 @@ from comtypes import COMMETHOD, GUID, IUnknown, client, wireHWND
import gpodder
import gi # isort:skip
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk # isort:skip
_ = gpodder.gettext
@ -53,6 +59,8 @@ TBPFLAG = c_int # enum
TBATF_USEMDITHUMBNAIL = 1
TBATF_USEMDILIVEPREVIEW = 2
TBATFLAG = c_int # enum
# return code
S_OK = HRESULT(0).value
class tagTHUMBBUTTON(Structure):
@ -138,8 +146,14 @@ class ITaskbarList3(ITaskbarList2):
(['in'], POINTER(tagRECT), 'prcClip'))]
assert sizeof(tagTHUMBBUTTON) == 540, sizeof(tagTHUMBBUTTON)
assert alignment(tagTHUMBBUTTON) == 4, alignment(tagTHUMBBUTTON)
assert sizeof(tagTHUMBBUTTON) in [540, 552], sizeof(tagTHUMBBUTTON)
assert alignment(tagTHUMBBUTTON) in [4, 8], alignment(tagTHUMBBUTTON)
def consume_events():
""" consume pending events """
while Gtk.events_pending():
Gtk.main_iteration()
# based on http://stackoverflow.com/a/1744503/905256
@ -153,25 +167,44 @@ class gPodderExtension:
self.taskbar = client.CreateObject(
'{56FDF344-FD6D-11d0-958A-006097C9A090}',
interface=ITaskbarList3)
self.taskbar.HrInit()
ret = self.taskbar.HrInit()
if ret != S_OK:
logger.warning("taskbar.HrInit failed: %r", ret)
del self.taskbar
def on_unload(self):
# let the window change state? otherwise gpodder is stuck on exit
# (tested on windows 7 pro)
consume_events()
if self.taskbar is not None:
self.taskbar.SetProgressState(self.window_handle, TBPF_NOPROGRESS)
# let the taskbar change state otherwise gpodder is stuck on exit
# (tested on windows 7 pro)
consume_events()
def on_ui_object_available(self, name, ui_object):
def callback(self, window, *args):
self.window_handle = window.window.handle
ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p
ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object]
win_gpointer = ctypes.pythonapi.PyCapsule_GetPointer(window.get_window().__gpointer__, None)
gdkdll = ctypes.CDLL("libgdk-3-0.dll")
self.window_handle = gdkdll.gdk_win32_window_get_handle(win_gpointer)
ret = self.taskbar.ActivateTab(self.window_handle)
if ret != S_OK:
logger.warning("taskbar.ActivateTab failed: %r", ret)
del self.taskbar
if name == 'gpodder-gtk':
ui_object.main_window.connect('realize',
functools.partial(callback, self))
def on_download_progress(self, progress):
if not self.taskbar:
return
if self.window_handle is None:
if not self.restart_warning:
return
logger.warn("No window handle available, a restart max fix this")
logger.warning("No window handle available, a restart max fix this")
self.restart_warning = False
return
if 0 < progress < 1:

View File

@ -48,8 +48,8 @@ class gPodderExtension(object):
srtContent = ''
for captionIndex, caption in enumerate(jsonobject['captions'], 1):
startTime = self.milli_to_srt(introduration + caption['startTime'])
endTime = self.milli_to_srt(introduration + caption['startTime'] +
caption['duration'])
endTime = self.milli_to_srt(introduration + caption['startTime']
+ caption['duration'])
srtContent += ''.join([str(captionIndex), os.linesep, startTime,
' --> ', endTime, os.linesep,
caption['content'], os.linesep * 2])
@ -60,7 +60,7 @@ class gPodderExtension(object):
try:
response = util.urlopen(url).read()
except Exception as e:
logger.warn("subtitle url returned error %s", e)
logger.warning("subtitle url returned error %s", e)
return ''
return response
@ -105,7 +105,7 @@ class gPodderExtension(object):
with open(srt_filename, 'w+') as srtFile:
srtFile.write(sub.encode("utf-8"))
except Exception as e:
logger.warn("Can't write srt file: %s", e)
logger.warning("Can't write srt file: %s", e)
def on_episode_delete(self, episode, filename):
srt_filename = self.get_srt_filename(filename)

View File

@ -4,16 +4,12 @@
# Thomas Perl <thp@gpodder.org>; 2012-02-06
import logging
import os
import subprocess
import sys
import gpodder
from gpodder import util
import gi # isort:skip
gi.require_version('Unity', '7.0') # isort:skip
from gi.repository import GObject, Unity # isort:skip
from gi.repository import GLib, Unity # isort:skip
_ = gpodder.gettext
@ -59,4 +55,4 @@ class gPodderExtension:
self.launcher_entry = None
def on_download_progress(self, progress):
GObject.idle_add(self.launcher_entry.set_progress, float(value))
GLib.idle_add(self.launcher_entry.set_progress, float(progress))

View File

@ -11,7 +11,7 @@ import os
import subprocess
import gpodder
from gpodder import util, youtube
from gpodder import util
logger = logging.getLogger(__name__)
@ -114,7 +114,7 @@ class gPodderExtension:
logger.info('Converted video file to %(format)s.' % {'format': self.config.output_format})
gpodder.user_extensions.on_notification_show(_('File converted'), episode.title)
else:
logger.warn('Error converting video file: %s / %s', stdout, stderr)
logger.warning('Error converting video file: %s / %s', stdout, stderr)
gpodder.user_extensions.on_notification_show(_('Conversion failed'), episode.title)
def _convert_episodes(self, episodes):

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Manage Youtube subscriptions using youtube-dl (https://github.com/ytdl-org/youtube-dl)
# Manage YouTube subscriptions using youtube-dl (https://github.com/ytdl-org/youtube-dl)
# Requirements: youtube-dl module (pip install youtube_dl)
# (c) 2019-08-17 Eric Le Lay <elelay.fr:contact>
# Released under the same license terms as gPodder itself.
@ -9,13 +9,23 @@ import os
import re
import sys
import time
from collections.abc import Iterable
import youtube_dl
from youtube_dl.utils import DownloadError, ExtractorError, sanitize_url
try:
import yt_dlp as youtube_dl
program_name = 'yt-dlp'
want_ytdl_version = '2023.06.22'
except:
import youtube_dl
program_name = 'youtube-dl'
want_ytdl_version = '2023.02.17' # youtube-dl has been patched, but not yet released
import gpodder
from gpodder import download, feedcore, model, registry, youtube
from gpodder.util import mimetype_from_extension, remove_html_tags
from gpodder import download, feedcore, model, registry, util, youtube
import gi # isort:skip
gi.require_version('Gtk', '3.0') # isort:skip
from gi.repository import Gtk # isort:skip
_ = gpodder.gettext
@ -23,22 +33,23 @@ _ = gpodder.gettext
logger = logging.getLogger(__name__)
__title__ = 'Youtube-dl'
__description__ = _('Manage Youtube subscriptions using youtube-dl (pip install youtube_dl)')
__title__ = 'youtube-dl'
__description__ = _('Manage YouTube subscriptions using youtube-dl (pip install youtube_dl) or yt-dlp (pip install yt-dlp)')
__only_for__ = 'gtk, cli'
__authors__ = 'Eric Le Lay <elelay.fr:contact>'
__doc__ = 'https://gpodder.github.io/docs/extensions/youtubedl.html'
want_ytdl_version = '2021.02.04'
want_ytdl_version_msg = _('Your version of youtube-dl %(have_version)s has known issues, please upgrade to %(want_version)s or newer.')
want_ytdl_version_msg = _('Your version of youtube-dl/yt-dlp %(have_version)s has known issues, please upgrade to %(want_version)s or newer.')
DefaultConfig = {
# youtube-dl downloads and parses each video page to get informations about it, which is very slow.
# youtube-dl downloads and parses each video page to get information about it, which is very slow.
# Set to False to fall back to the fast but limited (only 15 episodes) gpodder code
'manage_channel': True,
# If for some reason youtube-dl download doesn't work for you, you can fallback to gpodder code.
# Set to False to fall back to default gpodder code (less available formats).
'manage_downloads': True,
# Embed all available subtitles to downloaded videos. Needs ffmpeg.
'embed_subtitles': False,
}
@ -51,7 +62,7 @@ PLAYLIST_RE = re.compile(r'''https://www.youtube.com/feeds/videos.xml\?playlist_
def youtube_parsedate(s):
"""Parse a string into a unix timestamp
Only strings provided by Youtube-dl API are
Only strings provided by youtube-dl API are
parsed with this function (20170920).
"""
if s:
@ -78,6 +89,15 @@ class YoutubeCustomDownload(download.CustomDownload):
self._reporthook = None
self._prev_dl_bytes = 0
self._episode = episode
self._partial_filename = None
@property
def partial_filename(self):
return self._partial_filename
@partial_filename.setter
def partial_filename(self, val):
self._partial_filename = val
def retrieve_resume(self, tempname, reporthook=None):
"""
@ -85,38 +105,52 @@ class YoutubeCustomDownload(download.CustomDownload):
"""
self._reporthook = reporthook
# outtmpl: use given tempname by DownloadTask
# (escape % and $ because outtmpl used as a string template by youtube-dl)
outtmpl = tempname.replace('%', '%%').replace('$', '$$')
res = self._ytdl.fetch_video(self._url, outtmpl, self._my_hook)
if outtmpl != tempname:
if 'ext' in res and os.path.isfile(outtmpl + '.{}'.format(res['ext'])):
os.rename(outtmpl + '.{}'.format(res['ext']), tempname)
else:
os.rename(outtmpl, tempname)
# (escape % because outtmpl used as a string template by youtube-dl)
outtmpl = tempname.replace('%', '%%')
info, opts = self._ytdl.fetch_info(self._url, outtmpl, self._my_hook)
if program_name == 'yt-dlp':
default = opts['outtmpl']['default'] if isinstance(opts['outtmpl'], dict) else opts['outtmpl']
self.partial_filename = os.path.join(opts['paths']['home'], default) % info
elif program_name == 'youtube-dl':
self.partial_filename = opts['outtmpl'] % info
res = self._ytdl.fetch_video(info, opts)
if program_name == 'yt-dlp':
# yt-dlp downloads to whatever file name it wants, so rename
filepath = res.get('requested_downloads', [{}])[0].get('filepath')
if filepath is None:
raise Exception("Could not determine youtube-dl output file")
if filepath != tempname:
logger.debug('yt-dlp downloaded to "%s" instead of "%s", moving',
os.path.basename(filepath),
os.path.basename(tempname))
os.remove(tempname)
os.rename(filepath, tempname)
if 'duration' in res and res['duration']:
self._episode.total_time = res['duration']
headers = {}
# youtube-dl doesn't return a content-type but an extension
if 'ext' in res:
dot_ext = '.{}'.format(res['ext'])
# See #673 when merging multiple formats, the extension is appended to the tempname
# by YoutubeDL resulting in empty .partial file + .partial.mp4 exists
# and #796 .mkv is chosen by ytdl sometimes
tempstat = os.stat(tempname)
if not tempstat.st_size:
if program_name == 'youtube-dl':
# See #673 when merging multiple formats, the extension is appended to the tempname
# by youtube-dl resulting in empty .partial file + .partial.mp4 exists
# and #796 .mkv is chosen by ytdl sometimes
for try_ext in (dot_ext, ".mp4", ".m4a", ".webm", ".mkv"):
tempname_with_ext = tempname + try_ext
if os.path.isfile(tempname_with_ext):
logger.debug('Youtubedl downloaded to "%s" instead of "%s", moving',
logger.debug('youtube-dl downloaded to "%s" instead of "%s", moving',
os.path.basename(tempname_with_ext),
os.path.basename(tempname))
os.remove(tempname)
os.rename(tempname_with_ext, tempname)
dot_ext = try_ext
break
ext_filetype = mimetype_from_extension(dot_ext)
ext_filetype = util.mimetype_from_extension(dot_ext)
if ext_filetype:
# Youtube weba formats have a webm extension and get a video/webm mime-type
# YouTube weba formats have a webm extension and get a video/webm mime-type
# but audio content has no width or height, so change it to audio/webm for correct icon and player
if ext_filetype.startswith('video/') and ('height' not in res or res['height'] is None):
ext_filetype = ext_filetype.replace('video/', 'audio/')
@ -176,7 +210,7 @@ class YoutubeFeed(model.Feed):
return filtered_entries
def get_title(self):
return '{} (Youtube)'.format(self._ie_result.get('title') or self._ie_result.get('id') or self._url)
return '{} (YouTube)'.format(self._ie_result.get('title') or self._ie_result.get('id') or self._url)
def get_link(self):
return self._ie_result.get('webpage_url')
@ -212,10 +246,8 @@ class YoutubeFeed(model.Feed):
episodes = []
for en in self._ie_result['entries']:
guid = video_guid(en['id'])
description = remove_html_tags(en.get('description') or _('No description available'))
html_description = self.nice_html_description(en, description)
if en.get('ext'):
mime_type = mimetype_from_extension('.{}'.format(en['ext']))
mime_type = util.mimetype_from_extension('.{}'.format(en['ext']))
else:
mime_type = 'application/octet-stream'
if en.get('filesize'):
@ -226,8 +258,9 @@ class YoutubeFeed(model.Feed):
ep = {
'title': en.get('title', guid),
'link': en.get('webpage_url'),
'description': description,
'description_html': html_description,
'episode_art_url': en.get('thumbnail'),
'description': util.remove_html_tags(en.get('description') or ''),
'description_html': '',
'url': en.get('webpage_url'),
'file_size': filesize,
'mime_type': mime_type,
@ -250,25 +283,6 @@ class YoutubeFeed(model.Feed):
"""
return None
@staticmethod
def nice_html_description(en, description):
"""
basic html formating + hyperlink highlighting + video thumbnail
"""
description = re.sub(r'''https?://[^\s]+''',
r'''<a href="\g<0>">\g<0></a>''',
description)
description = description.replace('\n', '<br>')
html = """<style type="text/css">
body > img { float: left; max-width: 30vw; margin: 0 1em 1em 0; }
</style>
"""
img = en.get('thumbnail')
if img:
html += '<img src="{}">'.format(img)
html += '<p>{}</p>'.format(description)
return html
class gPodderYoutubeDL(download.CustomDownloader):
def __init__(self, gpodder_config, my_config, force=False):
@ -283,8 +297,14 @@ class gPodderYoutubeDL(download.CustomDownloader):
os.makedirs(cachedir, exist_ok=True)
self._ydl_opts = {
'cachedir': cachedir,
'no_color': True, # prevent escape codes in desktop notifications on errors
'noprogress': True, # prevent progress bar from appearing in console
}
# prevent escape codes in desktop notifications on errors
if program_name == 'yt-dlp':
self._ydl_opts['color'] = 'no_color'
else:
self._ydl_opts['no_color'] = True
if gpodder.verbose:
self._ydl_opts['verbose'] = True
else:
@ -292,12 +312,12 @@ class gPodderYoutubeDL(download.CustomDownloader):
# Don't create downloaders for URLs supported by these youtube-dl extractors
self.ie_blacklist = ["Generic"]
# Cache URL regexes from youtube-dl matches here, seed with youtube regex
self.regex_cache = [re.compile(r'https://www.youtube.com/watch\?v=.+')]
self.regex_cache = [(re.compile(r'https://www.youtube.com/watch\?v=.+'),)]
# #686 on windows without a console, sys.stdout is None, causing exceptions
# when adding podcasts.
# See https://docs.python.org/3/library/sys.html#sys.__stderr__ Note
if not sys.stdout:
logger.debug('no stdout, setting YoutubeDL logger')
logger.debug('no stdout, setting youtube-dl logger')
self._ydl_opts['logger'] = logger
def add_format(self, gpodder_config, opts, fallback=None):
@ -317,17 +337,29 @@ class gPodderYoutubeDL(download.CustomDownloader):
opts['format'] += '/' + fallback
logger.debug('format=%s', opts['format'])
def fetch_video(self, url, tempname, reporthook):
def fetch_info(self, url, tempname, reporthook):
subs = self.my_config.embed_subtitles
opts = {
'outtmpl': tempname,
'paths': {'home': os.path.dirname(tempname)},
# Postprocessing in yt-dlp breaks without ext
'outtmpl': (os.path.basename(tempname) if program_name == 'yt-dlp'
else tempname) + '.%(ext)s',
'nopart': True, # don't append .part (already .partial)
'retries': 3, # retry a few times
'progress_hooks': [reporthook] # to notify UI
'progress_hooks': [reporthook], # to notify UI
'writesubtitles': subs,
'subtitleslangs': ['all'] if subs else [],
'postprocessors': [{'key': 'FFmpegEmbedSubtitle'}] if subs else [],
}
opts.update(self._ydl_opts)
self.add_format(self.gpodder_config, opts)
with youtube_dl.YoutubeDL(opts) as ydl:
return ydl.extract_info(url, download=True)
info = ydl.extract_info(url, download=False)
return info, opts
def fetch_video(self, info, opts):
with youtube_dl.YoutubeDL(opts) as ydl:
return ydl.process_video_result(info, download=True)
def refresh_entries(self, ie_result):
# only interested in video metadata
@ -346,8 +378,8 @@ class gPodderYoutubeDL(download.CustomDownloader):
with youtube_dl.YoutubeDL(opts) as ydl:
ydl.process_ie_result(tmp, download=False)
new_entries.extend(tmp.get('entries'))
except DownloadError as ex:
if ex.exc_info[0] == ExtractorError:
except youtube_dl.utils.DownloadError as ex:
if ex.exc_info[0] == youtube_dl.utils.ExtractorError:
# for instance "This video contains content from xyz, who has blocked it on copyright grounds"
logger.warning('Skipping %s: %s', e.get('title', ''), ex.exc_info[1])
continue
@ -358,7 +390,7 @@ class gPodderYoutubeDL(download.CustomDownloader):
"""
Fetch a channel or playlist contents.
Doesn't yet fetch video entry informations, so we only get the video id and title.
Doesn't yet fetch video entry information, so we only get the video id and title.
"""
# Duplicate a bit of the YoutubeDL machinery here because we only
# want to parse the channel/playlist first, not to fetch video entries.
@ -380,7 +412,7 @@ class gPodderYoutubeDL(download.CustomDownloader):
result_type, has_playlist = extract_type(ie_result)
while not has_playlist:
if result_type in ('url', 'url_transparent'):
ie_result['url'] = sanitize_url(ie_result['url'])
ie_result['url'] = youtube_dl.utils.sanitize_url(ie_result['url'])
if result_type == 'url':
logger.debug("extract_info(%s) to get the video list", ie_result['url'])
# We have to add extra_info to the results because it may be
@ -415,22 +447,29 @@ class gPodderYoutubeDL(download.CustomDownloader):
if m:
url = 'https://www.youtube.com/playlist?list={}'.format(m.group(1))
if url:
logger.info('Youtube-dl Handling %s => %s', channel.url, url)
logger.info('youtube-dl handling %s => %s', channel.url, url)
return self.refresh(url, channel.url, max_episodes)
return None
def is_supported_url(self, url):
if self.regex_cache[0].match(url) is not None:
return True
for r in self.regex_cache[1:]:
if r.match(url) is not None:
self.regex_cache.remove(r)
self.regex_cache.insert(0, r)
if url is None:
return False
for i, res in enumerate(self.regex_cache):
if next(filter(None, (r.match(url) for r in res)), None) is not None:
if i > 0:
self.regex_cache.remove(res)
self.regex_cache.insert(0, res)
return True
with youtube_dl.YoutubeDL(self._ydl_opts) as ydl:
for ie in ydl._ies:
# youtube-dl returns a list, yt-dlp returns a dict
ies = ydl._ies
if isinstance(ydl._ies, dict):
ies = ydl._ies.values()
for ie in ies:
if ie.suitable(url) and ie.ie_key() not in self.ie_blacklist:
self.regex_cache.insert(0, ie._VALID_URL_RE)
self.regex_cache.insert(
0, (ie._VALID_URL_RE if isinstance(ie._VALID_URL_RE, Iterable)
else (ie._VALID_URL_RE,)))
return True
return False
@ -440,6 +479,14 @@ class gPodderYoutubeDL(download.CustomDownloader):
"""
if not self.force and not self.my_config.manage_downloads:
return None
try: # Reject URLs linking to known media files
(_, ext) = util.filename_from_url(episode.url)
if util.file_type_by_extension(ext) is not None:
return None
except Exception:
pass
if self.is_supported_url(episode.url):
return YoutubeCustomDownload(self, episode.url, episode)
@ -450,15 +497,14 @@ class gPodderExtension:
def __init__(self, container):
self.container = container
self.ytdl = None
self.infobar = None
def on_load(self):
self.ytdl = gPodderYoutubeDL(self.container.manager.core.config, self.container.config)
logger.info('Registering youtube-dl.')
logger.info('Registering youtube-dl. (using %s %s)' % (program_name, youtube_dl.version.__version__))
registry.feed_handler.register(self.ytdl.fetch_channel)
registry.custom_downloader.register(self.ytdl.custom_downloader)
logger.debug('Youtube-DL %s' % youtube_dl.version.__version__)
if youtube_dl.utils.version_tuple(youtube_dl.version.__version__) < youtube_dl.utils.version_tuple(want_ytdl_version):
logger.error(want_ytdl_version_msg
% {'have_version': youtube_dl.version.__version__, 'want_version': want_ytdl_version})
@ -482,14 +528,82 @@ class gPodderExtension:
if youtube_dl.utils.version_tuple(youtube_dl.version.__version__) < youtube_dl.utils.version_tuple(want_ytdl_version):
ui_object.notification(want_ytdl_version_msg %
{'have_version': youtube_dl.version.__version__, 'want_version': want_ytdl_version},
_('Old Youtube-DL'), important=True, widget=ui_object.main_window)
_('Old youtube-dl'), important=True, widget=ui_object.main_window)
def on_episodes_context_menu(self, episodes):
if not self.container.config.manage_downloads \
and not all(e.was_downloaded(and_exists=True) for e in episodes):
return [(_("Download with Youtube-DL"), self.download_episodes)]
if not self.container.config.manage_downloads and any(e.can_download() for e in episodes):
return [(_("Download with youtube-dl"), self.download_episodes)]
def download_episodes(self, episodes):
episodes = [e for e in episodes if e.can_download()]
# create a new gPodderYoutubeDL to force using it even if manage_downloads is False
downloader = gPodderYoutubeDL(self.container.manager.core.config, self.container.config, force=True)
self.gpodder.download_episode_list(episodes, downloader=downloader)
def toggle_manage_channel(self, widget):
self.container.config.manage_channel = widget.get_active()
def toggle_manage_downloads(self, widget):
self.container.config.manage_downloads = widget.get_active()
def toggle_embed_subtitles(self, widget):
if widget.get_active():
if not util.find_command('ffmpeg'):
self.infobar.show()
widget.set_active(False)
self.container.config.embed_subtitles = False
else:
self.container.config.embed_subtitles = True
else:
self.container.config.embed_subtitles = False
def show_preferences(self):
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
box.set_border_width(10)
label = Gtk.Label('%s %s' % (program_name, youtube_dl.version.__version__))
box.pack_start(label, False, False, 0)
box.pack_start(Gtk.HSeparator(), False, False, 0)
checkbox = Gtk.CheckButton(_('Parse YouTube channel feeds with youtube-dl to access more than 15 episodes'))
checkbox.set_active(self.container.config.manage_channel)
checkbox.connect('toggled', self.toggle_manage_channel)
box.pack_start(checkbox, False, False, 0)
box.pack_start(Gtk.HSeparator(), False, False, 0)
checkbox = Gtk.CheckButton(_('Download all supported episodes with youtube-dl'))
checkbox.set_active(self.container.config.manage_downloads)
checkbox.connect('toggled', self.toggle_manage_downloads)
box.pack_start(checkbox, False, False, 0)
note = Gtk.Label(use_markup=True, wrap=True, label=_(
'youtube-dl provides access to additional YouTube formats and DRM content.'
' Episodes from non-YouTube channels, that have youtube-dl support, will <b>fail</b> to download unless you manually'
' <a href="https://gpodder.github.io/docs/youtube.html#formats">add custom formats</a> for each site.'
' <b>Download with youtube-dl</b> appears in the episode menu when this option is disabled,'
' and can be used to manually download from supported sites.'))
note.connect('activate-link', lambda label, url: util.open_website(url))
note.set_property('xalign', 0.0)
box.add(note)
box.pack_start(Gtk.HSeparator(), False, False, 0)
checkbox = Gtk.CheckButton(_('Embed all available subtitles in downloaded video'))
checkbox.set_active(self.container.config.embed_subtitles)
checkbox.connect('toggled', self.toggle_embed_subtitles)
box.pack_start(checkbox, False, False, 0)
infobar = Gtk.InfoBar()
infobar.get_content_area().add(Gtk.Label(wrap=True, label=_(
'The "ffmpeg" command was not found. FFmpeg is required for embedding subtitles.')))
self.infobar = infobar
box.pack_end(infobar, False, False, 0)
box.show_all()
infobar.hide()
return box
def on_preferences(self):
return [(_('youtube-dl'), self.show_preferences)]

View File

@ -34,26 +34,6 @@
<child>
<placeholder/>
</child>
<child>
<object class="GtkButton" id="channel_list_forward">
<property name="visible" bind-source="leaflet" bind-property="folded" bind-flags="sync-create">False</property>
<property name="sensitive" bind-source="leaflet" bind-property="can_swipe_forward" bind-flags="sync-create">False</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<signal name="clicked" handler="on_channel_list_forward_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">go-next-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -93,10 +73,11 @@
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<object class="GtkScrolledWindow" id="channels_scrolled_window">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="vexpand">True</property>
<property name="vscrollbar-policy">always</property>
<property name="shadow-type">in</property>
<child>
<object class="GtkTreeView" id="treeChannels">
@ -110,7 +91,7 @@
<property name="show-expanders">False</property>
<property name="activate-on-single-click">True</property>
<signal name="button-press-event" handler="on_treeview_button_pressed" swapped="no"/>
<signal name="button-release-event" handler="on_treeview_podcasts_button_released" swapped="no"/>
<signal name="button-release-event" handler="on_treeview_channels_button_released" swapped="no"/>
<signal name="cursor-changed" handler="on_treeChannels_cursor_changed" swapped="no"/>
<signal name="draw" handler="on_treeview_expose_event" swapped="no"/>
<signal name="query-tooltip" handler="on_treeview_query_tooltip" swapped="no"/>
@ -292,25 +273,6 @@
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="episode_list_forward">
<property name="visible">True</property>
<property name="sensitive" bind-source="deck" bind-property="can_swipe_forward" bind-flags="sync-create">False</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<signal name="clicked" handler="on_episode_list_forward_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">go-next-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="episode_search_toggle">
<property name="visible">True</property>
@ -334,6 +296,7 @@
<property name="visible" bind-source="leaflet" bind-property="folded" bind-flags="sync-create">False</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="relief">none</property>
<signal name="clicked" handler="on_episode_list_back_clicked" swapped="no"/>
<child>
<object class="GtkImage">
@ -386,10 +349,11 @@
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<object class="GtkScrolledWindow" id="episodes_scrolled_window">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="vexpand">True</property>
<property name="vscrollbar-policy">always</property>
<property name="shadow-type">in</property>
<child>
<object class="GtkTreeView" id="treeAvailable">
@ -491,6 +455,7 @@
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="relief">none</property>
<signal name="clicked" handler="on_deck_back_clicked" swapped="no"/>
<child>
<object class="GtkImage">
@ -552,48 +517,149 @@
<headerbar name="details_header_bar"/>
</headerbars>
</object>
<object class="GtkDialog" id="progress_window">
<object class="GtkPopover" id="header_popover">
<property name="width-request">300</property>
<property name="can-focus">False</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<property name="border-width">10</property>
<property name="relative-to">header_bar</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="progress_close_button">
<property name="label" translatable="yes">Close</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_progress_close_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<property name="spacing">8</property>
<child>
<object class="GtkButton" id="hbutton1">
<property name="label" translatable="yes">Preferences</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="action-name">app.preferences</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<!-- n-columns=1 n-rows=2 -->
<object class="GtkGrid" id="vboxDownloadStatusWidgets">
<object class="GtkButton" id="hbutton2">
<property name="label" translatable="yes">Download new episodes</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="action-name">win.downloadAllNew</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="hbutton3">
<property name="label" translatable="yes">Update channels</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="action-name">win.update</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<style>
<class name="menu"/>
</style>
</object>
<object class="GtkWindow" id="progress_window">
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="border-width">5</property>
<property name="orientation">vertical</property>
<property name="row-spacing">5</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<object class="GtkInfoBar" id="resume_all_infobar">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="message-type">question</property>
<property name="show-close-button">True</property>
<property name="revealed">False</property>
<signal name="response" handler="on_resume_all_infobar_response" swapped="no"/>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="spacing">6</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="resume_all_button">
<property name="label" translatable="yes">Resume all</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child internal-child="content_area">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="spacing">16</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Incomplete downloads from a previous session were found.</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<action-widgets>
<action-widget response="-5">resume_all_button</action-widget>
</action-widgets>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
@ -617,21 +683,23 @@
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="vboxDownloadSettings">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<!-- n-columns=3 n-rows=1 -->
<object class="GtkGrid" id="hboxDownloadLimit">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="column-spacing">5</property>
<property name="margin-start">5</property>
<property name="spacing">5</property>
<child>
<object class="GtkCheckButton" id="cbLimitDownloads">
<property name="label" translatable="yes">Limit rate to</property>
@ -642,8 +710,9 @@
<signal name="toggled" handler="on_cbLimitDownloads_toggled" swapped="no"/>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
@ -656,8 +725,9 @@
<property name="digits">1</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
@ -668,8 +738,9 @@
<property name="xalign">0</property>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
@ -680,11 +751,11 @@
</packing>
</child>
<child>
<!-- n-columns=2 n-rows=1 -->
<object class="GtkGrid" id="hboxDownloadRate">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="column-spacing">5</property>
<property name="margin-start">5</property>
<property name="spacing">5</property>
<child>
<object class="GtkCheckButton" id="cbMaxDownloads">
<property name="label" translatable="yes">Limit downloads to</property>
@ -692,10 +763,12 @@
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="draw-indicator">True</property>
<signal name="toggled" handler="on_cbMaxDownloads_toggled" swapped="no"/>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
@ -707,27 +780,56 @@
<property name="climb-rate">1</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="margin-end">5</property>
<property name="margin-bottom">5</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="progress_close_button">
<property name="label" translatable="yes">Close</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_progress_close_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>

View File

@ -1,99 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--*- mode: xml -*-->
<interface>
<object class="GtkDialog" id="gPodderAddPodcast">
<property name="title" translatable="yes">Add a new podcast</property>
<property name="type_hint">dialog</property>
<property name="modal">True</property>
<property name="transient-for">parent_widget</property>
<property name="default_width">400</property>
<child internal-child="vbox">
<object class="GtkBox" id="vboxmain">
<property name="orientation">vertical</property>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="hbuttonbox">
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<object class="GtkButton" id="btn_close">
<property name="visible">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<signal handler="on_btn_close_clicked" name="clicked"/>
</object>
</child>
<child>
<object class="GtkButton" id="btn_add">
<property name="visible">True</property>
<property name="label">gtk-add</property>
<property name="sensitive">false</property>
<property name="use_stock">True</property>
<signal handler="on_btn_add_clicked" name="clicked"/>
</object>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hboxurlentry">
<property name="border_width">10</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">5</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkLabel" id="label_add">
<property name="visible">True</property>
<property name="label" translatable="yes">URL:</property>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry_url">
<property name="visible">True</property>
<property name="has_focus">True</property>
<property name="activates_default">True</property>
<signal handler="on_entry_url_changed" name="changed"/>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn_paste">
<property name="label">gtk-paste</property>
<property name="use_stock">True</property>
<property name="visible">True</property>
<signal handler="on_btn_paste_clicked" name="clicked"/>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">btn_close</action-widget>
<action-widget response="0">btn_add</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -1,506 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<requires lib="libhandy" version="1.0"/>
<object class="GtkDialog" id="gPodderChannel">
<property name="can_focus">False</property>
<property name="modal">True</property>
<property name="window_position">center</property>
<property name="default_width">500</property>
<property name="default_height">620</property>
<property name="type_hint">dialog</property>
<child>
<placeholder/>
</child>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_btnCancel_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Apply</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_btnOK_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</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>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="HdyClamp">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="maximum_size">360</property>
<property name="tightening_threshold">300</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">8</property>
<property name="margin_right">8</property>
<property name="margin_top">8</property>
<property name="margin_bottom">8</property>
<property name="orientation">vertical</property>
<property name="spacing">4</property>
<child>
<object class="GtkImage" id="imgCover">
<property name="visible">True</property>
<property name="can_focus">False</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="title_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Podcast title</property>
<property name="ellipsize">end</property>
<attributes>
<attribute name="scale" value="1.5"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="labelURL">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">URL</property>
<property name="selectable">True</property>
<property name="ellipsize">end</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkTextView" id="channel_description">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
<property name="wrap_mode">word-char</property>
<property name="left_margin">8</property>
<property name="right_margin">8</property>
<property name="top_margin">8</property>
<property name="bottom_margin">8</property>
<property name="cursor_visible">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Website: </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="GtkButton" id="btn_website">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_btn_website_clicked" swapped="no"/>
<child>
<object class="GtkLabel" id="btn_website_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">website URL</property>
<property name="ellipsize">end</property>
<property name="max_width_chars">22</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Pause subscription</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="skip_feed_update_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Sync to player devices</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="enable_device_sync_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">6</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="button_add_section">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_button_add_section_clicked" swapped="no"/>
<child>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-add</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_section">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Section:</property>
<property name="width_chars">7</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>
<child>
<object class="GtkComboBox" id="combo_section">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">7</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="label_strategy">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Strategy:</property>
<property name="width_chars">7</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="GtkComboBox" id="combo_strategy">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">8</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label5">
<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">9</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">10</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;HTTP/FTP Authentication&lt;/b&gt;</property>
<property name="use_markup">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">11</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Username:</property>
<property name="width_chars">8</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="GtkEntry" id="FeedUsername">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">False</property>
<property name="invisible_char">●</property>
<property name="width_chars">8</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="input_purpose">name</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>
<property name="fill">True</property>
<property name="position">12</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Password:</property>
<property name="width_chars">8</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="GtkEntry" id="FeedPassword">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">False</property>
<property name="invisible_char">●</property>
<property name="width_chars">8</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="input_purpose">password</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>
<property name="fill">True</property>
<property name="position">13</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View File

@ -1,156 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--*- mode: xml -*-->
<interface>
<object class="GtkDialog" id="gPodderConfigEditor">
<property name="visible">True</property>
<property name="title" translatable="yes">gPodder Configuration Editor</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="modal">True</property>
<property name="transient-for">parent_widget</property>
<property name="default_width">750</property>
<property name="default_height">450</property>
<property name="destroy_with_parent">False</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<signal handler="on_gPodderConfigEditor_destroy" name="destroy"/>
<child internal-child="vbox">
<object class="GtkBox" id="vbox13">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="vbox_for_episode_selector">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="spacing">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="hbox38">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkLabel" id="label121">
<property name="visible">True</property>
<property name="label" translatable="yes">Search for:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entryFilter">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="max_length">0</property>
<property name="has_frame">True</property>
<property name="invisible_char">●</property>
<property name="activates_default">False</property>
<signal handler="on_entryFilter_changed" name="changed"/>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnShowAll">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Show All</property>
<property name="use_underline">True</property>
<property name="focus_on_click">True</property>
<signal handler="on_btnShowAll_clicked" name="clicked"/>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow8">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<object class="GtkTreeView" id="configeditor">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">True</property>
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
</object>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkHButtonBox" id="hbuttonbox2">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<object class="GtkButton" id="btnClose">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-close</property>
<property name="use_stock">True</property>
<property name="focus_on_click">True</property>
<signal handler="on_btnClose_clicked" name="clicked"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View File

@ -22,26 +22,6 @@
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="title" translatable="yes">Select episodes</property>
<child>
<object class="GtkButton" id="new_episodes_forward">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<signal name="clicked" handler="on_new_episodes_forward_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">go-next-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -79,6 +59,9 @@
<property name="show-expanders">False</property>
<property name="activate-on-single-click">True</property>
<signal name="row-activated" handler="on_row_activated" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
</object>
</child>
</object>
@ -235,6 +218,18 @@
<property name="can-focus">False</property>
<property name="title" translatable="yes">Episode details</property>
<property name="has-subtitle">False</property>
<child>
<object class="GtkButton" id="stream_button">
<property name="label" translatable="yes">Stream</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_stream_button_clicked" swapped="no"/>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
</child>
<child>
<object class="GtkButton" id="notes_back">
<property name="visible">True</property>
@ -249,6 +244,9 @@
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>

View File

@ -1,77 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkFileChooserDialog" id="gPodderExportToLocalFolder">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Select destination</property>
<property name="modal">True</property>
<property name="window_position">center-on-parent</property>
<property name="type_hint">dialog</property>
<property name="action">save</property>
<property name="do_overwrite_confirmation">True</property>
<property name="preview_widget_active">False</property>
<property name="use_preview_label">False</property>
<property name="extra_widget">allsamefolder</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="btnOK">
<property name="label">gtk-save</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_btnOK_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnCancel">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_btnCancel_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<!-- to be recognized by the embedded GtkFileChooser -->
<action-widgets>
<action-widget response="-3">btnOK</action-widget>
<action-widget response="-6">btnCancel</action-widget>
</action-widgets>
</object>
<object class="GtkCheckButton" id="allsamefolder">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
</interface>

View File

@ -150,7 +150,7 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="position">0</property>
</packing>
</child>
<child>
@ -170,7 +170,7 @@
<property name="layout-style">start</property>
<child>
<object class="GtkButton" id="btnSelectAll">
<property name="label" translatable="yes">Select All</property>
<property name="label" translatable="yes">Select _all</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
@ -180,12 +180,12 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnSelectNone">
<property name="label" translatable="yes">Select None</property>
<property name="label" translatable="yes">Select _none</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
@ -195,7 +195,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
<property name="position">1</property>
</packing>
</child>
</object>
@ -213,12 +213,13 @@
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="btnCancel">
<property name="label" translatable="yes">Cancel</property>
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="can-default">True</property>
<property name="has-default">True</property>
<property name="receives-default">False</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="on_btnCancel_clicked" swapped="no"/>
</object>
<packing>

File diff suppressed because it is too large Load Diff

View File

@ -1,121 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--*- mode: xml -*-->
<interface>
<object class="GtkDialog" id="gPodderWelcome">
<property name="default_height">230</property>
<property name="default_width">340</property>
<property name="modal">True</property>
<property name="transient-for">parent_widget</property>
<property name="title" translatable="yes">Getting started</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog1-vbox">
<property name="border_width">2</property>
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="vbox1">
<property name="border_width">12</property>
<property name="spacing">12</property>
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkTable" id="table1">
<property name="column_spacing">6</property>
<property name="n_columns">1</property>
<property name="n_rows">2</property>
<property name="row_spacing">6</property>
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label1">
<property name="label" translatable="yes">&lt;big&gt;Welcome to gPodder&lt;/big&gt;</property>
<property name="use_markup">True</property>
<property name="visible">True</property>
<property name="xalign">0.0</property>
<property name="yalign">1.0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="label" translatable="yes">Your podcast list is empty.</property>
<property name="visible">True</property>
<property name="xalign">0.0</property>
<property name="yalign">0.0</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<object class="GtkBox" id="vbox_buttons">
<property name="spacing">6</property>
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkButton" id="btnOPML">
<property name="is_focus">True</property>
<property name="label" translatable="yes">Choose from a list of example podcasts</property>
<property name="visible">True</property>
<signal handler="on_show_example_podcasts" name="clicked"/>
</object>
</child>
<child>
<object class="GtkButton" id="btnAddURL">
<property name="is_focus">True</property>
<property name="label" translatable="yes">Add a podcast by entering its URL</property>
<property name="visible">True</property>
<signal handler="on_add_podcast_via_url" name="clicked"/>
</object>
</child>
<child>
<object class="GtkButton" id="btnMygPodder">
<property name="label" translatable="yes">Restore my subscriptions from gpodder.net</property>
<property name="visible">True</property>
<signal handler="on_setup_my_gpodder" name="clicked"/>
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog1-action_area">
<property name="border_width">5</property>
<property name="layout_style">end</property>
<property name="spacing">6</property>
<property name="visible">True</property>
<child>
<object class="GtkButton" id="btnCancel">
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="visible">True</property>
<signal handler="on_btnCancel_clicked" name="clicked"/>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="pack_type">end</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View File

@ -7,12 +7,12 @@
<attribute name="label" translatable="yes">Preferences</attribute>
<attribute name="accel">&lt;Primary&gt;p</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">app.gotoMygpo</attribute>
<attribute name="label" translatable="yes">Go to gpodder.net</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.sync</attribute>
<attribute name="label" translatable="yes">Sync to device</attribute>
@ -105,7 +105,7 @@
</item>
</section>
</submenu>
<submenu id="menuChannels">
<submenu id="menuEpisodes">
<attribute name="label" translatable="yes">_Episodes</attribute>
<section>
<item>
@ -118,11 +118,15 @@
<attribute name="label" translatable="yes">Open</attribute>
</item>
<item>
<attribute name="action">win.download</attribute>
<attribute name="action">app.download</attribute>
<attribute name="label" translatable="yes">Download</attribute>
</item>
<item>
<attribute name="action">win.cancel</attribute>
<attribute name="action">app.pause</attribute>
<attribute name="label" translatable="yes">Pause</attribute>
</item>
<item>
<attribute name="action">app.cancel</attribute>
<attribute name="label" translatable="yes">Cancel</attribute>
</item>
<item>
@ -141,6 +145,12 @@
<attribute name="label" translatable="yes">Change delete lock</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.openEpisodeDownloadFolder</attribute>
<attribute name="label" translatable="yes">Open download folder</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.findEpisode</attribute>
@ -210,12 +220,135 @@
<attribute name="action">win.viewHideBoringPodcasts</attribute>
<attribute name="label" translatable="yes">Hide podcasts without episodes</attribute>
</item>
<item>
<attribute name="action">win.viewAlwaysShowNewEpisodes</attribute>
<attribute name="label" translatable="yes">Always show New Episodes</attribute>
</item>
<item>
<attribute name="action">win.viewCtrlClickToSortEpisodes</attribute>
<attribute name="label" translatable="yes">Require control click to sort episodes</attribute>
</item>
</section>
<submenu id="menuViewColumns">
<attribute name="label" translatable="yes">Visible columns</attribute>
</submenu>
</submenu>
</menu>
<menu id="channels-context">
<section>
<item>
<attribute name="action">win.updateChannel</attribute>
<attribute name="label" translatable="yes">Update channel</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.openChannelDownloadFolder</attribute>
<attribute name="label" translatable="yes">Open download folder</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.markEpisodesAsOld</attribute>
<attribute name="label" translatable="yes">Mark episodes as old</attribute>
</item>
<item>
<attribute name="action">win.channelAutoArchive</attribute>
<attribute name="label" translatable="yes">Archive all episodes</attribute>
</item>
<item>
<attribute name="action">win.removeChannel</attribute>
<attribute name="label" translatable="yes">Delete channel</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.editChannel</attribute>
<attribute name="label" translatable="yes">Channel settings</attribute>
</item>
</section>
</menu>
<menu id="episodes-context">
<section>
<item>
<attribute name="action">win.play</attribute>
<attribute name="label" translatable="yes">Play</attribute>
</item>
<item>
<attribute name="action">app.download</attribute>
<attribute name="label" translatable="yes">Download</attribute>
</item>
<!-- Cancel -->
<item>
<attribute name="action">win.delete</attribute>
<attribute name="label" translatable="yes">Delete</attribute>
</item>
</section>
<!-- Extensions -->
<!-- Send To -->
<section>
<item>
<attribute name="action">win.episodeNew</attribute>
<attribute name="label" translatable="yes">New</attribute>
</item>
<item>
<attribute name="action">win.episodeLock</attribute>
<attribute name="label" translatable="yes">Archive</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.toggleShownotes</attribute>
<attribute name="label" translatable="yes">Episode details</attribute>
</item>
<item>
<attribute name="action">win.openEpisodeDownloadFolder</attribute>
<attribute name="label" translatable="yes">Open download folder</attribute>
</item>
</section>
</menu>
<menu id="episodes-context-sendto">
<item>
<attribute name="action">win.saveEpisodes</attribute>
<attribute name="label" translatable="yes">Local folder</attribute>
</item>
<item>
<attribute name="action">win.bluetoothEpisodes</attribute>
<attribute name="label" translatable="yes">Bluetooth device</attribute>
</item>
</menu>
<menu id="downloads-context">
<section>
<item>
<attribute name="action">app.download</attribute>
<attribute name="label" translatable="yes">Start download now</attribute>
</item>
<item>
<attribute name="action">app.pause</attribute>
<attribute name="label" translatable="yes">Pause</attribute>
</item>
<item>
<attribute name="action">app.cancel</attribute>
<attribute name="label" translatable="yes">Cancel</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">app.moveUp</attribute>
<attribute name="label" translatable="yes">Move up</attribute>
</item>
<item>
<attribute name="action">app.moveDown</attribute>
<attribute name="label" translatable="yes">Move down</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">app.remove</attribute>
<attribute name="label" translatable="yes">Remove from list</attribute>
</item>
</section>
</menu>
<menu id="plus-menu">
<section>
<item>
@ -309,89 +442,5 @@
<attribute name="accel">&lt;Primary&gt;2</attribute>
</item>
</menu>
<menu id="channels-context">
<item>
<attribute name="action">win.updateChannel</attribute>
<attribute name="label" translatable="yes">Refresh</attribute>
<attribute name="accel">&lt;Primary&gt;0</attribute>
</item>
<item>
<attribute name="action">win.markAsOld</attribute>
<attribute name="label" translatable="yes">Mark episodes as old</attribute>
<attribute name="accel">&lt;Primary&gt;1</attribute>
</item>
<item>
<attribute name="action">win.editChannel</attribute>
<attribute name="label" translatable="yes">Channel settings</attribute>
<attribute name="accel">&lt;Primary&gt;2</attribute>
</item>
<section>
<item>
<attribute name="action">win.removeChannel</attribute>
<attribute name="label" translatable="yes">Delete</attribute>
<attribute name="accel">&lt;Primary&gt;3</attribute>
</item>
</section>
</menu>
<menu id="episodes-context">
<item>
<attribute name="action">win.play</attribute>
<attribute name="label" translatable="yes">Play</attribute>
<attribute name="accel">&lt;Primary&gt;0</attribute>
</item>
<item>
<attribute name="action">win.download</attribute>
<attribute name="label" translatable="yes">Download</attribute>
<attribute name="accel">&lt;Primary&gt;1</attribute>
</item>
<item>
<attribute name="action">win.delete</attribute>
<attribute name="label" translatable="yes">Delete</attribute>
<attribute name="accel">&lt;Primary&gt;2</attribute>
</item>
<section>
<item>
<attribute name="action">win.episodeNew</attribute>
<attribute name="label" translatable="yes">New</attribute>
<attribute name="accel">&lt;Primary&gt;3</attribute>
</item>
</section>
</menu>
<menu id="episodes-context-send">
<item>
<attribute name="action">win.saveEpisodes</attribute>
<attribute name="label" translatable="yes">Local folder</attribute>
<attribute name="accel">&lt;Primary&gt;0</attribute>
</item>
<item>
<attribute name="action">win.bluetoothEpisodes</attribute>
<attribute name="label" translatable="yes">Bluetooth device</attribute>
<attribute name="accel">&lt;Primary&gt;1</attribute>
</item>
</menu>
<menu id="downloads-context">
<item>
<attribute name="action">app.setDownloadQueued</attribute>
<attribute name="label" translatable="yes">Download</attribute>
<attribute name="accel">&lt;Primary&gt;0</attribute>
</item>
<item>
<attribute name="action">app.setDownloadCancelled</attribute>
<attribute name="label" translatable="yes">Cancel</attribute>
<attribute name="accel">&lt;Primary&gt;1</attribute>
</item>
<item>
<attribute name="action">app.setDownloadPaused</attribute>
<attribute name="label" translatable="yes">Pause</attribute>
<attribute name="accel">&lt;Primary&gt;2</attribute>
</item>
<section>
<item>
<attribute name="action">app.setDownloadRemove</attribute>
<attribute name="label" translatable="yes">Remove from list</attribute>
<attribute name="accel">&lt;Primary&gt;3</attribute>
</item>
</section>
</menu>
</interface>
<!-- :noTabs=true:tabSize=2:indentSize=2: -->

View File

@ -1,54 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<!--*- mode: xml -*-->
<interface>
<!-- interface-requires gtk+ 3.10 -->
<requires lib="gtk+" version="3.16"/>
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">10240</property>
<property name="lower">0.5</property>
<property name="page_increment">0</property>
<property name="step_increment">0.5</property>
<property name="page_size">0</property>
<property name="upper">10240</property>
<property name="step-increment">0.5</property>
</object>
<object class="GtkAdjustment" id="adjustment2">
<property name="upper">16</property>
<property name="lower">1</property>
<property name="page_increment">0</property>
<property name="step_increment">1</property>
<property name="page_size">0</property>
<property name="upper">16</property>
<property name="step-increment">1</property>
</object>
<object class="GtkApplicationWindow" id="gPodder">
<property name="name">gPodder</property>
<property name="application">app</property>
<property name="visible">False</property>
<property name="can-focus">False</property>
<property name="title">gPodder</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>
<property name="modal">False</property>
<property name="destroy_with_parent">False</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<signal handler="on_gPodder_delete_event" name="delete-event"/>
<property name="window-position">center</property>
<signal name="delete-event" handler="on_gPodder_delete_event" swapped="no"/>
<child>
<!-- n-columns=1 n-rows=2 -->
<object class="GtkGrid" id="vMain">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkToolbar" id="toolbar">
<property name="visible">True</property>
<property name="show_arrow">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkToolButton" id="toolDownload">
<object class="GtkToolButton" id="toolPlay">
<property name="visible">True</property>
<property name="label" translatable="yes">Download</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-go-down</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">True</property>
<property name="sensitive">False</property>
<signal handler="on_download_selected_episodes" name="clicked"/>
<property name="can-focus">False</property>
<property name="is-important">True</property>
<property name="label" translatable="yes">Play</property>
<property name="icon-name">media-playback-start-symbolic</property>
<signal name="clicked" handler="on_playback_selected_episodes" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@ -56,14 +45,29 @@
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolPlay">
<object class="GtkToolButton" id="toolDownload">
<property name="visible">True</property>
<property name="stock_id">gtk-media-play</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">True</property>
<property name="sensitive">False</property>
<signal handler="on_playback_selected_episodes" name="clicked"/>
<property name="can-focus">False</property>
<property name="is-important">True</property>
<property name="label" translatable="yes">Download</property>
<property name="icon-name">document-save-symbolic</property>
<signal name="clicked" handler="on_download_selected_episodes" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolPause">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">False</property>
<property name="is-important">True</property>
<property name="label" translatable="yes">Pause</property>
<property name="icon-name">media-playback-pause-symbolic</property>
<signal name="clicked" handler="on_pause_selected_episodes" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@ -73,14 +77,12 @@
<child>
<object class="GtkToolButton" id="toolCancel">
<property name="visible">True</property>
<property name="label" translatable="yes">Cancel</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-cancel</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">True</property>
<property name="sensitive">False</property>
<signal handler="on_item_cancel_download_activate" name="clicked"/>
<property name="can-focus">False</property>
<property name="is-important">True</property>
<property name="label" translatable="yes">Cancel</property>
<property name="icon-name">process-stop-symbolic</property>
<signal name="clicked" handler="on_item_cancel_download_activate" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@ -90,8 +92,7 @@
<child>
<object class="GtkSeparatorToolItem" id="toolbutton3">
<property name="visible">True</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
@ -101,12 +102,10 @@
<child>
<object class="GtkToolButton" id="toolPreferences">
<property name="visible">True</property>
<property name="stock_id">gtk-preferences</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<property name="can-focus">False</property>
<property name="action-name">app.preferences</property>
<property name="label" translatable="yes">Preferences</property>
<property name="icon-name">preferences-other-symbolic</property>
</object>
<packing>
<property name="expand">False</property>
@ -116,8 +115,7 @@
<child>
<object class="GtkSeparatorToolItem" id="toolbutton2">
<property name="visible">True</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
@ -127,12 +125,10 @@
<child>
<object class="GtkToolButton" id="toolQuit">
<property name="visible">True</property>
<property name="stock_id">gtk-quit</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<signal handler="on_gPodder_delete_event" name="clicked"/>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Quit</property>
<property name="icon-name">application-exit-symbolic</property>
<signal name="clicked" handler="on_gPodder_delete_event" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@ -140,348 +136,505 @@
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<!-- n-columns=1 n-rows=1 -->
<object class="GtkGrid" id="hboxContainer">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="border-width">5</property>
<child>
<object class="GtkNotebook" id="wNotebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="show_tabs">True</property>
<property name="show_border">True</property>
<property name="tab_pos">GTK_POS_TOP</property>
<property name="scrollable">False</property>
<property name="enable_popup">False</property>
<signal handler="on_wNotebook_switch_page" name="switch_page"/>
<property name="can-focus">True</property>
<signal name="switch-page" handler="on_wNotebook_switch_page" swapped="no"/>
<child>
<object class="GtkPaned" id="channelPaned">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="orientation">horizontal</property>
<property name="can-focus">True</property>
<property name="border-width">5</property>
<child>
<!-- n-columns=1 n-rows=3 -->
<object class="GtkGrid" id="vboxChannelNavigator">
<property name="visible">True</property>
<property name="row_spacing">5</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="row-spacing">5</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow6">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vexpand">True</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<property name="can-focus">True</property>
<property name="vexpand">True</property>
<property name="shadow-type">in</property>
<child>
<object class="GtkTreeView" id="treeChannels">
<property name="name">treeChannels</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="rules_hint">False</property>
<property name="can-focus">True</property>
<property name="has-tooltip">True</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
<signal handler="on_treeChannels_row_activated" name="row_activated"/>
<signal handler="on_treeChannels_cursor_changed" name="cursor_changed"/>
<signal handler="on_treeview_query_tooltip" name="query-tooltip"/>
<signal handler="on_treeview_expose_event" name="draw"/>
<signal handler="on_treeview_button_pressed" name="button-press-event"/>
<signal handler="on_treeview_podcasts_button_released" name="button-release-event"/>
<property name="headers-visible">False</property>
<signal name="button-press-event" handler="on_treeview_button_pressed" swapped="no"/>
<signal name="button-release-event" handler="on_treeview_channels_button_released" swapped="no"/>
<signal name="cursor-changed" handler="on_treeChannels_cursor_changed" swapped="no"/>
<signal name="draw" handler="on_treeview_expose_event" swapped="no"/>
<signal name="query-tooltip" handler="on_treeview_query_tooltip" swapped="no"/>
<signal name="row-activated" handler="on_treeChannels_row_activated" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<!-- n-columns=1 n-rows=1 -->
<object class="GtkGrid" id="hbox_search_podcasts">
<property name="column_spacing">6</property>
<property name="orientation">horizontal</property>
<property name="can-focus">False</property>
<property name="column-spacing">6</property>
<child>
<object class="GtkEntry" id="entry_search_podcasts">
<property name="hexpand">True</property>
<property name="visible">True</property>
<property name="secondary-icon-stock">gtk-close</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="secondary-icon-name">edit-clear</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<!-- n-columns=1 n-rows=2 -->
<object class="GtkGrid" id="vbox42">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkButton" id="btnUpdateFeeds">
<property name="label" translatable="yes">Check for new episodes</property>
<property name="can_focus">True</property>
<property name="focus_on_click">True</property>
<property name="action-name">win.update</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="hexpand">True</property>
<property name="action-name">win.update</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<!-- n-columns=2 n-rows=1 -->
<object class="GtkGrid" id="hboxUpdateFeeds">
<property name="column_spacing">6</property>
<property name="orientation">horizontal</property>
<property name="can-focus">False</property>
<property name="column-spacing">6</property>
<child>
<object class="GtkProgressBar" id="pbFeedUpdate">
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="pulse_step">0.10000000149</property>
<property name="pulse-step">0.10000000149</property>
<property name="show-text">True</property>
<property name="ellipsize">PANGO_ELLIPSIZE_MIDDLE</property>
<property name="ellipsize">middle</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnCancelFeedUpdate">
<property name="can_focus">True</property>
<property name="focus_on_click">True</property>
<signal handler="on_btnCancelFeedUpdate_clicked" name="clicked"/>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<signal name="clicked" handler="on_btnCancelFeedUpdate_clicked" swapped="no"/>
<child>
<object class="GtkImage" id="image3209">
<property name="visible">True</property>
<property name="stock">gtk-cancel</property>
<property name="icon_size">4</property>
<property name="can-focus">False</property>
<property name="icon-name">process-stop</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</packing>
</child>
</object>
<packing>
<property name="shrink">False</property>
<property name="resize">False</property>
<property name="shrink">False</property>
</packing>
</child>
<child>
<!-- n-columns=1 n-rows=2 -->
<object class="GtkGrid" id="vbox_episode_list">
<property name="visible">True</property>
<property name="row_spacing">6</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="row-spacing">6</property>
<child>
<object class="GtkScrolledWindow" id="scrollAvailable">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="shadow-type">in</property>
<child>
<object class="GtkTreeView" id="treeAvailable">
<property name="name">treeAvailable</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">True</property>
<property name="rules_hint">True</property>
<property name="can-focus">True</property>
<property name="has-tooltip">True</property>
<property name="enable-search">False</property>
<property name="rubber-banding">True</property>
<property name="reorderable">False</property>
<property name="enable_search">False</property>
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
<signal handler="on_treeAvailable_row_activated" name="row_activated"/>
<signal handler="on_treeview_query_tooltip" name="query-tooltip"/>
<signal handler="on_treeview_expose_event" name="draw"/>
<signal handler="on_treeview_button_pressed" name="button-press-event"/>
<signal handler="on_treeview_episodes_button_released" name="button-release-event"/>
<signal name="button-press-event" handler="on_treeview_button_pressed" swapped="no"/>
<signal name="button-release-event" handler="on_treeview_episodes_button_released" swapped="no"/>
<signal name="draw" handler="on_treeview_expose_event" swapped="no"/>
<signal name="query-tooltip" handler="on_treeview_query_tooltip" swapped="no"/>
<signal name="row-activated" handler="on_treeAvailable_row_activated" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<!-- n-columns=2 n-rows=1 -->
<object class="GtkGrid" id="hbox_search_episodes">
<property name="column_spacing">6</property>
<property name="orientation">horizontal</property>
<property name="can-focus">False</property>
<property name="column-spacing">6</property>
<child>
<object class="GtkLabel" id="label_search_episodes">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Filter:</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry_search_episodes">
<property name="hexpand">True</property>
<property name="visible">True</property>
<property name="secondary-icon-stock">gtk-close</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="secondary-icon-name">edit-clear</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">False</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Podcasts</property>
</object>
<packing>
<property name="tab-fill">False</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkInfoBar" id="resume_all_infobar">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="message-type">question</property>
<property name="show-close-button">True</property>
<property name="revealed">False</property>
<signal name="response" handler="on_resume_all_infobar_response" swapped="no"/>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="spacing">6</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="resume_all_button">
<property name="label" translatable="yes">Resume all</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child internal-child="content_area">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="spacing">16</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Incomplete downloads from a previous session were found.</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<action-widgets>
<action-widget response="-5">resume_all_button</action-widget>
</action-widgets>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="margin-start">5</property>
<property name="margin-end">5</property>
<property name="margin-top">5</property>
<property name="margin-bottom">5</property>
<property name="vexpand">True</property>
<property name="shadow-type">in</property>
<child>
<object class="GtkTreeView" id="treeDownloads">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="headers-visible">False</property>
<property name="reorderable">True</property>
<property name="rubber-banding">True</property>
<signal name="button-press-event" handler="on_treeview_button_pressed" swapped="no"/>
<signal name="button-release-event" handler="on_treeview_downloads_button_released" swapped="no"/>
<signal name="draw" handler="on_treeview_expose_event" swapped="no"/>
<signal name="row-activated" handler="on_treeDownloads_row_activated" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
</object>
</child>
</object>
<packing>
<property name="shrink">False</property>
<property name="resize">True</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="tab_expand">False</property>
<property name="tab_fill">True</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">Podcasts</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
</object>
</child>
<child>
<object class="GtkGrid" id="vboxDownloadStatusWidgets">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="row_spacing">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vexpand">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<property name="can-focus">False</property>
<property name="margin-start">5</property>
<property name="margin-end">5</property>
<property name="margin-top">5</property>
<property name="margin-bottom">10</property>
<property name="spacing">5</property>
<child>
<object class="GtkTreeView" id="treeDownloads">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="rules_hint">False</property>
<property name="rubber-banding">True</property>
<property name="reorderable">True</property>
<property name="enable_search">True</property>
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
<signal handler="on_treeDownloads_row_activated" name="row_activated"/>
<signal handler="on_treeview_expose_event" name="draw"/>
<signal handler="on_treeview_button_pressed" name="button-press-event"/>
<signal handler="on_treeview_downloads_button_released" name="button-release-event"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkGrid" id="hboxDownloadSettings">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="column_spacing">10</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkGrid" id="hboxDownloadLimit">
<property name="visible">True</property>
<property name="column_spacing">5</property>
<property name="orientation">horizontal</property>
<property name="can-focus">False</property>
<property name="margin-start">5</property>
<property name="spacing">5</property>
<child>
<object class="GtkCheckButton" id="cbLimitDownloads">
<property name="label" translatable="yes">Limit rate to</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_cbLimitDownloads_toggled"/>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="draw-indicator">True</property>
<signal name="toggled" handler="on_cbLimitDownloads_toggled" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="spinLimitDownloads">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="climb_rate">1</property>
<property name="digits">1</property>
<property name="can-focus">True</property>
<property name="caps-lock-warning">False</property>
<property name="input-purpose">number</property>
<property name="adjustment">adjustment1</property>
<property name="climb-rate">1</property>
<property name="digits">1</property>
<property name="numeric">True</property>
<property name="update-policy">if-valid</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="labelLimitRate">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">KiB/s</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="DownloadSettingsSpacer">
<object class="GtkBox">
<property name="visible">True</property>
<property name="hexpand">True</property>
</object>
</child>
<child>
<object class="GtkGrid" id="hboxDownloadRate">
<property name="visible">True</property>
<property name="column_spacing">5</property>
<property name="orientation">horizontal</property>
<property name="can-focus">False</property>
<property name="spacing">5</property>
<child>
<object class="GtkCheckButton" id="cbMaxDownloads">
<property name="label" translatable="yes">Limit downloads to</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_cbMaxDownloads_toggled"/>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="draw-indicator">True</property>
<signal name="toggled" handler="on_cbMaxDownloads_toggled" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="spinMaxDownloads">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="climb_rate">1</property>
<property name="can-focus">True</property>
<property name="caps-lock-warning">False</property>
<property name="input-purpose">number</property>
<property name="adjustment">adjustment2</property>
<property name="climb-rate">1</property>
<property name="snap-to-ticks">True</property>
<property name="numeric">True</property>
<property name="update-policy">if-valid</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>
<property name="fill">True</property>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="tab_expand">False</property>
<property name="tab_fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="labelDownloads">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Progress</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab-fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
</object>

View File

@ -1,92 +1,114 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<!--*- mode: xml -*-->
<interface>
<requires lib="gtk+" version="3.16"/>
<object class="GtkDialog" id="gPodderAddPodcast">
<property name="can-focus">False</property>
<property name="title" translatable="yes">Add a new podcast</property>
<property name="type_hint">dialog</property>
<property name="modal">True</property>
<property name="transient-for">parent_widget</property>
<property name="default_width">400</property>
<property name="default-width">400</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="vboxmain">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="hbuttonbox">
<property name="layout_style">GTK_BUTTONBOX_END</property>
<object class="GtkButtonBox" id="hbuttonbox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="btn_close">
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<signal handler="on_btn_close_clicked" name="clicked"/>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="on_btn_close_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn_add">
<property name="label" translatable="yes">_Add</property>
<property name="visible">True</property>
<property name="label">gtk-add</property>
<property name="sensitive">false</property>
<property name="use_stock">True</property>
<signal handler="on_btn_add_clicked" name="clicked"/>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="on_btn_add_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
<property name="pack-type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hboxurlentry">
<property name="border_width">10</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="can-focus">False</property>
<property name="border-width">10</property>
<property name="spacing">5</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkLabel" id="label_add">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">URL:</property>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry_url">
<property name="visible">True</property>
<property name="has_focus">True</property>
<property name="activates_default">True</property>
<signal handler="on_entry_url_changed" name="changed"/>
<property name="can-focus">True</property>
<property name="has-focus">True</property>
<property name="activates-default">True</property>
<property name="secondary-icon-name">edit-clear</property>
<signal name="changed" handler="on_entry_url_changed" swapped="no"/>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn_paste">
<property name="label">gtk-paste</property>
<property name="use_stock">True</property>
<property name="label" translatable="yes">_Paste</property>
<property name="visible">True</property>
<signal handler="on_btn_paste_clicked" name="clicked"/>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="on_btn_paste_clicked" swapped="no"/>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>

File diff suppressed because it is too large Load Diff

View File

@ -1,153 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<!--*- mode: xml -*-->
<interface>
<requires lib="gtk+" version="3.16"/>
<object class="GtkDialog" id="gPodderConfigEditor">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="title" translatable="yes">gPodder Configuration Editor</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="modal">True</property>
<property name="transient-for">parent_widget</property>
<property name="default_width">750</property>
<property name="default_height">450</property>
<property name="destroy_with_parent">False</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<signal handler="on_gPodderConfigEditor_destroy" name="destroy"/>
<property name="window-position">center-on-parent</property>
<property name="default-width">750</property>
<property name="default-height">450</property>
<property name="type-hint">dialog</property>
<signal name="destroy" handler="on_gPodderConfigEditor_destroy" swapped="no"/>
<child internal-child="vbox">
<object class="GtkBox" id="vbox13">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="vbox_for_episode_selector">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="spacing">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="hbox38">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkLabel" id="label121">
<property name="visible">True</property>
<property name="label" translatable="yes">Search for:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entryFilter">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="max_length">0</property>
<property name="has_frame">True</property>
<property name="invisible_char">●</property>
<property name="activates_default">False</property>
<signal handler="on_entryFilter_changed" name="changed"/>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnShowAll">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Show All</property>
<property name="use_underline">True</property>
<property name="focus_on_click">True</property>
<signal handler="on_btnShowAll_clicked" name="clicked"/>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow8">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<object class="GtkTreeView" id="configeditor">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">True</property>
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
</object>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkHButtonBox" id="hbuttonbox2">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<child>
<object class="GtkButton" id="btnClose">
<property name="label" translatable="yes">_Close</property>
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-close</property>
<property name="use_stock">True</property>
<property name="focus_on_click">True</property>
<signal handler="on_btnClose_clicked" name="clicked"/>
<property name="can-focus">True</property>
<property name="can-default">True</property>
<property name="has-default">True</property>
<property name="receives-default">False</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="on_btnClose_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="vbox_for_episode_selector">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="border-width">5</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkBox" id="hbox38">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label121">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Search for:</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entryFilter">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="has-focus">True</property>
<property name="invisible-char">●</property>
<signal name="changed" handler="on_entryFilter_changed" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnShowAll">
<property name="label" translatable="yes">_Show All</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="on_btnShowAll_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow8">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="shadow-type">in</property>
<child>
<object class="GtkTreeView" id="configeditor">
<property name="visible">True</property>
<property name="can-focus">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>

View File

@ -1,294 +1,241 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<!--*- mode: xml -*-->
<interface>
<requires lib="gtk+" version="3.16"/>
<object class="GtkDialog" id="gPodderEpisodeSelector">
<property name="visible">False</property>
<property name="can-focus">False</property>
<property name="title" translatable="yes">Select episodes</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="modal">True</property>
<property name="transient-for">parent_widget</property>
<property name="destroy_with_parent">False</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<property name="window-position">center-on-parent</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="vbox10">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="vbox_for_episode_selector">
<property name="border_width">5</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="hbox35">
<property name="visible">True</property>
<property name="spacing">5</property>
<property name="orientation">vertical</property>
<property name="can-focus">False</property>
<child>
<object class="GtkLabel" id="labelInstructions">
<property name="label">additional text</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<object class="GtkButton" id="btnRemoveAction">
<property name="label" translatable="yes">_Remove</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="on_remove_action_activate" swapped="no"/>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnCancel">
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="on_btnCancel_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnOK">
<property name="label" translatable="yes">_OK</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="can-default">True</property>
<property name="has-default">True</property>
<property name="receives-default">False</property>
<property name="use-underline">True</property>
<property name="always-show-image">True</property>
<signal name="clicked" handler="on_btnOK_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="vbox_for_episode_selector">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="border-width">5</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkLabel" id="labelInstructions">
<property name="can-focus">False</property>
<property name="label">additional text</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow7">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<property name="can-focus">True</property>
<property name="shadow-type">in</property>
<child>
<object class="GtkTreeView" id="treeviewEpisodes">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="headers_visible">False</property>
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">False</property>
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
<signal name="row_activated" handler="on_row_activated"/>
<property name="can-focus">True</property>
<property name="has-focus">True</property>
<property name="headers-visible">False</property>
<property name="enable-search">False</property>
<signal name="row-activated" handler="on_row_activated" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
</object>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hboxButtons">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="can-focus">False</property>
<property name="spacing">5</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkButton" id="btnCheckAll">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">True</property>
<signal handler="on_btnCheckAll_clicked" name="clicked"/>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<signal name="clicked" handler="on_btnCheckAll_clicked" swapped="no"/>
<child>
<object class="GtkAlignment" id="alignment22">
<object class="GtkBox" id="hbox34">
<property name="visible">True</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">0</property>
<property name="right_padding">0</property>
<property name="can-focus">False</property>
<property name="spacing">2</property>
<child>
<object class="GtkBox" id="hbox34">
<object class="GtkImage" id="image2636">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage" id="image2636">
<property name="visible">True</property>
<property name="stock">gtk-apply</property>
<property name="icon_size">4</property>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label107">
<property name="visible">True</property>
<property name="label" translatable="yes">Select all</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<property name="can-focus">False</property>
<property name="icon-name">object-select</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label107">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Select _all</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnCheckNone">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">True</property>
<signal handler="on_btnCheckNone_clicked" name="clicked"/>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<signal name="clicked" handler="on_btnCheckNone_clicked" swapped="no"/>
<child>
<object class="GtkAlignment" id="alignment21">
<object class="GtkBox" id="hbox33">
<property name="visible">True</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">0</property>
<property name="right_padding">0</property>
<property name="can-focus">False</property>
<property name="spacing">2</property>
<child>
<object class="GtkBox" id="hbox33">
<object class="GtkImage" id="image2635">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage" id="image2635">
<property name="visible">True</property>
<property name="stock">gtk-revert-to-saved</property>
<property name="icon_size">4</property>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label106">
<property name="visible">True</property>
<property name="label" translatable="yes">Select none</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<property name="can-focus">False</property>
<property name="icon-name">document-revert</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label106">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Select _none</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="labelTotalSize">
<property name="visible">True</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_RIGHT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="can-focus">False</property>
<property name="justify">right</property>
<property name="xalign">1</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkBox" id="hbox35">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">5</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkButton" id="btnRemoveAction">
<property name="visible">False</property>
<property name="can_focus">True</property>
<property name="label">Remove</property>
<property name="use_stock">True</property>
<property name="focus_on_click">True</property>
<signal handler="on_remove_action_activate" name="clicked"/>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnCancel">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="focus_on_click">True</property>
<signal handler="on_btnCancel_clicked" name="clicked"/>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnOK">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="focus_on_click">True</property>
<signal handler="on_btnOK_clicked" name="clicked"/>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>

View File

@ -1,57 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<requires lib="gtk+" version="3.16"/>
<object class="GtkCheckButton" id="allsamefolder">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="draw-indicator">True</property>
</object>
<object class="GtkFileChooserDialog" id="gPodderExportToLocalFolder">
<property name="can_focus">False</property>
<property name="can-focus">True</property>
<property name="title" translatable="yes">Select destination</property>
<property name="modal">True</property>
<property name="window_position">center-on-parent</property>
<property name="type_hint">dialog</property>
<property name="window-position">center-on-parent</property>
<property name="type-hint">dialog</property>
<property name="action">save</property>
<property name="do_overwrite_confirmation">True</property>
<property name="preview_widget_active">False</property>
<property name="use_preview_label">False</property>
<property name="extra_widget">allsamefolder</property>
<property name="do-overwrite-confirmation">False</property>
<property name="extra-widget">allsamefolder</property>
<property name="preview-widget-active">False</property>
<property name="use-preview-label">False</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="btnOK">
<property name="label">gtk-save</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_btnOK_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
<placeholder/>
</child>
<child>
<object class="GtkButton" id="btnCancel">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_btnCancel_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
<placeholder/>
</child>
</object>
<packing>
@ -62,16 +43,5 @@
</child>
</object>
</child>
<!-- to be recognized by the embedded GtkFileChooser -->
<action-widgets>
<action-widget response="-3">btnOK</action-widget>
<action-widget response="-6">btnCancel</action-widget>
</action-widgets>
</object>
<object class="GtkCheckButton" id="allsamefolder">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
</interface>

View File

@ -172,7 +172,7 @@
<property name="layout-style">start</property>
<child>
<object class="GtkButton" id="btnSelectAll">
<property name="label" translatable="yes">Select All</property>
<property name="label" translatable="yes">Select _all</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
@ -187,7 +187,7 @@
</child>
<child>
<object class="GtkButton" id="btnSelectNone">
<property name="label" translatable="yes">Select None</property>
<property name="label" translatable="yes">Select _none</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
@ -215,12 +215,13 @@
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="btnCancel">
<property name="label" translatable="yes">Cancel</property>
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="can-default">True</property>
<property name="has-default">True</property>
<property name="receives-default">False</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="on_btnCancel_clicked" swapped="no"/>
</object>
<packing>

File diff suppressed because it is too large Load Diff

View File

@ -1,93 +1,189 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<!--*- mode: xml -*-->
<interface>
<requires lib="gtk+" version="3.16"/>
<object class="GtkDialog" id="gPodderWelcome">
<property name="default_height">230</property>
<property name="default_width">340</property>
<property name="modal">True</property>
<property name="transient-for">parent_widget</property>
<property name="can-focus">False</property>
<property name="title" translatable="yes">Getting started</property>
<property name="modal">True</property>
<property name="default-width">340</property>
<property name="default-height">230</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog1-vbox">
<property name="border_width">2</property>
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">2</property>
<property name="margin-end">2</property>
<property name="margin-top">2</property>
<property name="margin-bottom">2</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="vbox1">
<property name="border_width">12</property>
<property name="spacing">12</property>
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="label1">
<property name="label" translatable="yes">&lt;big&gt;Welcome to gPodder&lt;/big&gt;</property>
<property name="use_markup">True</property>
<property name="visible">True</property>
<property name="xalign">0.0</property>
<property name="yalign">1.0</property>
</object>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="label" translatable="yes">Your podcast list is empty.</property>
<property name="visible">True</property>
<property name="xalign">0.0</property>
<property name="yalign">0.0</property>
</object>
</child>
<child>
<object class="GtkBox" id="vbox_buttons">
<property name="spacing">6</property>
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkButton" id="btnOPML">
<property name="is_focus">True</property>
<property name="label" translatable="yes">Choose from a list of example podcasts</property>
<property name="visible">True</property>
<signal handler="on_show_example_podcasts" name="clicked"/>
</object>
</child>
<child>
<object class="GtkButton" id="btnAddURL">
<property name="is_focus">True</property>
<property name="label" translatable="yes">Add a podcast by entering its URL</property>
<property name="visible">True</property>
<signal handler="on_add_podcast_via_url" name="clicked"/>
</object>
</child>
<child>
<object class="GtkButton" id="btnMygPodder">
<property name="label" translatable="yes">Restore my subscriptions from gpodder.net</property>
<property name="visible">True</property>
<signal handler="on_setup_my_gpodder" name="clicked"/>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog1-action_area">
<property name="border_width">5</property>
<property name="layout_style">end</property>
<property name="spacing">6</property>
<object class="GtkButtonBox" id="dialog1-action_area">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">5</property>
<property name="margin-end">5</property>
<property name="margin-top">5</property>
<property name="margin-bottom">5</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="btnCancel">
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<signal handler="on_btnCancel_clicked" name="clicked"/>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="on_btnCancel_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="pack_type">end</property>
<property name="fill">False</property>
<property name="pack-type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="vbox1">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">&lt;big&gt;Welcome to gPodder&lt;/big&gt;</property>
<property name="use-markup">True</property>
<property name="xalign">0</property>
<property name="yalign">1</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="label2">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Your podcast list is empty.</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="vbox_buttons">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkButton" id="btnOPML">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="has-focus">True</property>
<property name="is-focus">True</property>
<property name="receives-default">False</property>
<signal name="clicked" handler="on_show_example_podcasts" swapped="no"/>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="label" translatable="yes">Choose from a list of example podcasts</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnAddURL">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="is-focus">True</property>
<property name="receives-default">False</property>
<signal name="clicked" handler="on_add_podcast_via_url" swapped="no"/>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="label" translatable="yes">Add a podcast by entering its URL</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnMygPodder">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="is-focus">True</property>
<property name="receives-default">False</property>
<signal name="clicked" handler="on_setup_my_gpodder" swapped="no"/>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="label" translatable="yes">Restore my subscriptions from gpodder.net</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>

View File

@ -19,6 +19,10 @@
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Open Logs</attribute>
<attribute name="action">app.logs</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Help</attribute>
<attribute name="action">app.help</attribute>
@ -100,7 +104,7 @@
</item>
</section>
</submenu>
<submenu id="menuChannels">
<submenu id="menuEpisodes">
<attribute name="label" translatable="yes">_Episodes</attribute>
<section>
<item>
@ -116,6 +120,10 @@
<attribute name="action">win.download</attribute>
<attribute name="label" translatable="yes">Download</attribute>
</item>
<item>
<attribute name="action">win.pause</attribute>
<attribute name="label" translatable="yes">Pause</attribute>
</item>
<item>
<attribute name="action">win.cancel</attribute>
<attribute name="label" translatable="yes">Cancel</attribute>
@ -136,6 +144,16 @@
<attribute name="label" translatable="yes">Change delete lock</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.openEpisodeDownloadFolder</attribute>
<attribute name="label" translatable="yes">Open download folder</attribute>
</item>
<item>
<attribute name="action">win.selectChannel</attribute>
<attribute name="label" translatable="yes">Select channel</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.findEpisode</attribute>
@ -164,16 +182,25 @@
<attribute name="label" translatable="yes">Toolbar</attribute>
<attribute name="accel">&lt;Primary&gt;t</attribute>
</item>
<item>
<attribute name="action">win.showEpisodeDescription</attribute>
<attribute name="label" translatable="yes">Episode descriptions</attribute>
<attribute name="accel">&lt;Primary&gt;d</attribute>
</item>
<item>
<attribute name="action">win.searchAlwaysVisible</attribute>
<attribute name="label" translatable="yes">Always show Find entries</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.viewHideBoringPodcasts</attribute>
<attribute name="label" translatable="yes">Hide podcasts without episodes</attribute>
</item>
<item>
<attribute name="action">win.viewShowAllEpisodes</attribute>
<attribute name="label" translatable="yes">"All episodes" in podcast list</attribute>
</item>
<item>
<attribute name="action">win.viewShowPodcastSections</attribute>
<attribute name="label" translatable="yes">Use sections for podcast list</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.viewEpisodes</attribute>
@ -201,19 +228,155 @@
</item>
</section>
<section>
<item>
<attribute name="action">win.viewHideBoringPodcasts</attribute>
<attribute name="label" translatable="yes">Hide podcasts without episodes</attribute>
</item>
<item>
<attribute name="action">win.viewAlwaysShowNewEpisodes</attribute>
<attribute name="label" translatable="yes">Always show New Episodes</attribute>
</item>
<item>
<attribute name="action">win.viewTrimEpisodeTitlePrefix</attribute>
<attribute name="label" translatable="yes">Trim episode title prefix</attribute>
</item>
<item>
<attribute name="action">win.viewShowEpisodeDescription</attribute>
<attribute name="label" translatable="yes">Episode descriptions</attribute>
<attribute name="accel">&lt;Primary&gt;d</attribute>
</item>
<item>
<attribute name="action">win.viewShowEpisodeReleasedTime</attribute>
<attribute name="label" translatable="yes">Show episode released time</attribute>
</item>
<item>
<attribute name="action">win.viewRightAlignEpisodeReleasedColumn</attribute>
<attribute name="label" translatable="yes">Right align episode released column</attribute>
</item>
<item>
<attribute name="action">win.viewCtrlClickToSortEpisodes</attribute>
<attribute name="label" translatable="yes">Require control click to sort episodes</attribute>
</item>
</section>
<submenu id="menuViewColumns">
<attribute name="label" translatable="yes">Visible columns</attribute>
</submenu>
</submenu>
</menu>
<menu id="channels-context">
<section>
<item>
<attribute name="action">win.updateChannel</attribute>
<attribute name="label" translatable="yes">Update channel</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.openChannelDownloadFolder</attribute>
<attribute name="label" translatable="yes">Open download folder</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.markEpisodesAsOld</attribute>
<attribute name="label" translatable="yes">Mark episodes as old</attribute>
</item>
<item>
<attribute name="action">win.channelAutoArchive</attribute>
<attribute name="label" translatable="yes">Archive all episodes</attribute>
</item>
<item>
<attribute name="action">win.refreshImage</attribute>
<attribute name="label" translatable="yes">Refresh image</attribute>
</item>
<item>
<attribute name="action">win.removeChannel</attribute>
<attribute name="label" translatable="yes">Delete channel</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.editChannel</attribute>
<attribute name="label" translatable="yes">Channel settings</attribute>
</item>
</section>
</menu>
<menu id="episodes-context">
<section>
<item>
<attribute name="action">win.play</attribute>
<attribute name="label" translatable="yes">Play</attribute>
</item>
<item>
<attribute name="action">win.download</attribute>
<attribute name="label" translatable="yes">Download</attribute>
</item>
<!-- Cancel -->
<item>
<attribute name="action">win.delete</attribute>
<attribute name="label" translatable="yes">Delete</attribute>
</item>
</section>
<!-- Extensions -->
<!-- Send To -->
<section>
<item>
<attribute name="action">win.episodeNew</attribute>
<attribute name="label" translatable="yes">New</attribute>
</item>
<item>
<attribute name="action">win.episodeLock</attribute>
<attribute name="label" translatable="yes">Archive</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.toggleShownotes</attribute>
<attribute name="label" translatable="yes">Episode details</attribute>
</item>
<item>
<attribute name="action">win.openEpisodeDownloadFolder</attribute>
<attribute name="label" translatable="yes">Open download folder</attribute>
</item>
</section>
</menu>
<menu id="episodes-context-sendto">
<item>
<attribute name="action">win.saveEpisodes</attribute>
<attribute name="label" translatable="yes">Local folder</attribute>
</item>
<item>
<attribute name="action">win.bluetoothEpisodes</attribute>
<attribute name="label" translatable="yes">Bluetooth device</attribute>
</item>
</menu>
<menu id="downloads-context">
<section>
<item>
<attribute name="action">win.download</attribute>
<attribute name="label" translatable="yes">Start download now</attribute>
</item>
<item>
<attribute name="action">win.pause</attribute>
<attribute name="label" translatable="yes">Pause</attribute>
</item>
<item>
<attribute name="action">win.cancel</attribute>
<attribute name="label" translatable="yes">Cancel</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.moveUp</attribute>
<attribute name="label" translatable="yes">Move up</attribute>
</item>
<item>
<attribute name="action">win.moveDown</attribute>
<attribute name="label" translatable="yes">Move down</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.remove</attribute>
<attribute name="label" translatable="yes">Remove from list</attribute>
</item>
</section>
</menu>
</interface>
<!-- :noTabs=true:tabSize=2:indentSize=2: -->

View File

@ -1,4 +1,4 @@
.TH GPO "1" "June 2021" "gpodder 3.10.20" "User Commands"
.TH GPO "1" "August 2023" "gpodder 3.11.2" "User Commands"
.SH NAME
gpo \- Text mode interface of gPodder
.SH SYNOPSIS

Some files were not shown because too many files have changed in this diff Show More