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.
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.
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.
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.
* 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
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.
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
* 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
* 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()
* preferences: Use GtkStack instead of GtkNotebook
* Add Separator and ScrolledWindow to StackSwitcher
* Add ScrolledWindow to preferences Stack
Remove ScrolledWindow from Extensions page.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
* 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
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.
Calling run() with CANCELLED state only returns without performing any
work. The CANCELLING state actually deletes the partial file and
recycles the task.
gpodderexporttolocalfolder.ui:
* Save with Glade 3.38.2
* Replace GTK stock labels with text
exportlocal.py: Set transient for parent (was not set before)
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
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
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
* #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)
* 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
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.
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.
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.
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.
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.
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).
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).
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
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.
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.