Merge branch 'master' into dev-adaptive

This commit is contained in:
Teemu Ikonen 2022-03-25 22:42:37 +02:00
commit 542a3a9a2a
4 changed files with 84 additions and 68 deletions

View File

@ -2334,42 +2334,20 @@ class gPodder(BuilderWidget, dbus.service.Object):
self.update_podcast_list_model(set(e.channel.url for e in episodes))
self.db.commit()
def episode_player(self, episode):
file_type = episode.file_type()
if file_type == 'video' and self.config.player.video \
and self.config.player.video != 'default':
player = self.config.player.video
elif file_type == 'audio' and self.config.player.audio \
and self.config.player.audio != 'default':
player = self.config.player.audio
else:
player = 'default'
return player
def streaming_possible(self, episode=None):
"""
Don't try streaming if the user has not defined a player
or else we would probably open the browser when giving a URL to xdg-open.
If an episode is given, we look at the audio or video player depending on its file type.
:return bool: if streaming is possible
"""
if episode:
player = self.episode_player(episode)
else:
player = self.config.player.audio
return player and player != 'default'
def playback_episodes_for_real(self, episodes):
groups = collections.defaultdict(list)
for episode in episodes:
episode._download_error = None
if episode.download_task is not None and episode.download_task.status == episode.download_task.FAILED:
if not episode.can_stream(self.config):
# Do not cancel failed tasks that can not be streamed
continue
# Cancel failed task and remove from progress list
episode.download_task.cancel()
self.cleanup_downloads()
player = self.episode_player(episode)
player = episode.get_player(self.config)
try:
allow_partial = (player != 'default')
@ -2444,8 +2422,7 @@ class gPodder(BuilderWidget, dbus.service.Object):
def playback_episodes(self, episodes):
# We need to create a list, because we run through it more than once
episodes = list(Model.sort_episodes_by_pubdate(e for e in episodes if
e.was_downloaded(and_exists=True) or self.streaming_possible(e)))
episodes = list(Model.sort_episodes_by_pubdate(e for e in episodes if e.can_play(self.config)))
try:
self.playback_episodes_for_real(episodes)
@ -2459,12 +2436,9 @@ class gPodder(BuilderWidget, dbus.service.Object):
def play_or_download(self, current_page=None):
(open_instead_of_play, can_play, can_download, can_pause, can_cancel, can_delete) = (False,) * 6
can_resume = False
selection = self.treeAvailable.get_selection()
if selection.count_selected_rows() > 0:
(model, paths) = selection.get_selected_rows()
streaming_possible = self.streaming_possible()
for path in paths:
try:
@ -2476,34 +2450,12 @@ class gPodder(BuilderWidget, dbus.service.Object):
logger.error('Invalid episode at path %s', str(path))
continue
if episode.file_type() not in ('audio', 'video'):
open_instead_of_play = True
if episode.was_downloaded():
can_play = episode.was_downloaded(and_exists=True)
if not can_play:
can_download = True
else:
if episode.downloading:
can_cancel = True
if episode.download_task is not None:
if episode.download_task.status in (episode.download_task.PAUSING, episode.download_task.PAUSED):
can_resume = True
elif episode.download_task.status in (episode.download_task.QUEUED, episode.download_task.DOWNLOADING):
can_pause = True
elif episode.download_task is not None and episode.download_task.status == episode.download_task.FAILED:
can_cancel = True
else:
streaming_possible |= self.streaming_possible(episode)
can_download = True
if episode.state != gpodder.STATE_DELETED and not episode.archive:
can_delete = True
can_download = (can_download and not can_cancel) or can_resume
can_play = streaming_possible or (can_play and not can_cancel and not can_download)
can_delete = can_delete and not can_cancel
open_instead_of_play = open_instead_of_play or episode.file_type() not in ('audio', 'video')
can_play = can_play or episode.can_play(self.config)
can_download = can_download or episode.can_download()
can_pause = can_pause or episode.can_pause()
can_cancel = can_cancel or episode.can_cancel()
can_delete = can_delete or episode.can_delete()
self.set_episode_actions(open_instead_of_play, can_play, can_download, can_pause, can_cancel, can_delete)
@ -3945,19 +3897,18 @@ class gPodder(BuilderWidget, dbus.service.Object):
self.play_button.set_sensitive(True)
else:
self.play_button.set_label(_("Stream"))
self.play_button.set_sensitive(self.streaming_possible(ep))
self.play_button.set_sensitive(ep.can_stream(self.config))
self.navigate_to_shownotes()
return True
def on_download_selected_episodes(self, action_or_widget, param=None):
episodes = [e for e in self.get_selected_episodes()
if not e.download_task or e.download_task.status in (e.download_task.PAUSING, e.download_task.PAUSED, e.download_task.FAILED)]
episodes = [e for e in self.get_selected_episodes() if e.can_download()]
self.download_episode_list(episodes)
self.update_downloads_list()
def on_pause_selected_episodes(self, action_or_widget, param=None):
for episode in self.get_selected_episodes():
if episode.download_task is not None:
if episode.can_pause():
episode.download_task.pause()
self.update_downloads_list()

View File

@ -453,6 +453,60 @@ class PodcastEpisode(PodcastModelObject):
return task.status in (task.DOWNLOADING, task.QUEUED, task.PAUSING, task.PAUSED, task.CANCELLING)
def get_player(self, config):
file_type = self.file_type()
if file_type == 'video' and config.player.video and config.player.video != 'default':
player = config.player.video
elif file_type == 'audio' and config.player.audio and config.player.audio != 'default':
player = config.player.audio
else:
player = 'default'
return player
def can_play(self, config):
"""
# gPodder.playback_episodes() filters selection with this method.
"""
return self.was_downloaded(and_exists=True) or self.can_stream(config)
def can_stream(self, config):
"""
Don't try streaming if the user has not defined a player
or else we would probably open the browser when giving a URL to xdg-open.
We look at the audio or video player depending on its file type.
"""
player = self.get_player(config)
return player and player != 'default'
def can_download(self):
"""
gPodder.on_download_selected_episodes() filters selection with this method.
PAUSING and PAUSED tasks can be resumed.
"""
return not self.was_downloaded(and_exists=True) and (
not self.download_task
or self.download_task.status in (self.download_task.PAUSING, self.download_task.PAUSED, self.download_task.FAILED))
def can_pause(self):
"""
gPodder.on_pause_selected_episodes() filters selection with this method.
"""
return self.download_task and self.download_task.status in (self.download_task.QUEUED, self.download_task.DOWNLOADING)
def can_cancel(self):
"""
DownloadTask.cancel() only cancels the following tasks.
"""
return self.download_task and self.download_task.status in \
(self.download_task.DOWNLOADING, self.download_task.QUEUED, self.download_task.PAUSED, self.download_task.FAILED)
def can_delete(self):
"""
gPodder.delete_episode_list() filters out locked episodes, and cancels all unlocked tasks in selection.
"""
return self.state != gpodder.STATE_DELETED and not self.archive and (
not self.download_task or self.download_task.status == self.download_task.FAILED)
def check_is_new(self):
return (self.state == gpodder.STATE_NORMAL and self.is_new and
not self.downloading)

View File

@ -799,7 +799,7 @@ class SyncTask(download.DownloadTask):
# Otherwise request cancellation
elif self.status == self.DOWNLOADING:
self.status = self.CANCELLING
self.device.cancel(self)
self.device.cancel()
def removed_from_list(self):
if self.status != self.DONE:

View File

@ -2292,8 +2292,13 @@ def mount_volume_for_file(file, op=None):
fashion
"""
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gio, GLib, Gtk
gi.require_version('Gio', '2.0')
from gi.repository import Gio, GLib
if gpodder.ui.gtk:
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
else:
loop = GLib.MainLoop()
result = True
message = None
@ -2309,10 +2314,16 @@ def mount_volume_for_file(file, op=None):
message = err.message
result = False
finally:
Gtk.main_quit()
if gpodder.ui.gtk:
Gtk.main_quit()
else:
loop.quit()
file.mount_enclosing_volume(Gio.MountMountFlags.NONE, op, None, callback)
Gtk.main()
if gpodder.ui.gtk:
Gtk.main()
else:
loop.run()
return result, message