diff --git a/share/gpodder/ui/gtk/gpodderpreferences.ui b/share/gpodder/ui/gtk/gpodderpreferences.ui index d3b834a7..a7379166 100644 --- a/share/gpodder/ui/gtk/gpodderpreferences.ui +++ b/share/gpodder/ui/gtk/gpodderpreferences.ui @@ -522,7 +522,7 @@ True - True + False True @@ -537,7 +537,7 @@ True - True + False True @@ -568,6 +568,21 @@ 3 + + + Consider only episodes added in the update as new + True + True + False + 5 + True + + + False + True + 4 + + True @@ -578,7 +593,7 @@ True - True + False True @@ -593,7 +608,7 @@ True - True + False True @@ -607,7 +622,7 @@ False True - 4 + 5 @@ -749,7 +764,7 @@ True - True + False True @@ -763,7 +778,7 @@ True - True + False True @@ -791,7 +806,7 @@ True - True + False True @@ -805,7 +820,7 @@ True - True + False True @@ -861,7 +876,7 @@ True - True + False True @@ -875,7 +890,7 @@ True - True + False True @@ -930,7 +945,7 @@ True - True + False True @@ -944,7 +959,7 @@ True - True + False True diff --git a/src/gpodder/config.py b/src/gpodder/config.py index 8a93f055..fc1d3078 100644 --- a/src/gpodder/config.py +++ b/src/gpodder/config.py @@ -154,6 +154,7 @@ defaults = { 'toolbar': False, 'new_episodes': 'show', # ignore, show, queue, download + 'only_added_are_new': False, # Only just added episodes are considered new after an update 'live_search_delay': 200, 'search_always_visible': False, 'find_as_you_type': True, diff --git a/src/gpodder/gtkui/desktop/preferences.py b/src/gpodder/gtkui/desktop/preferences.py index f61374ac..5c64fea4 100644 --- a/src/gpodder/gtkui/desktop/preferences.py +++ b/src/gpodder/gtkui/desktop/preferences.py @@ -249,6 +249,9 @@ class gPodderPreferences(BuilderWidget): self._config.connect_gtk_spinbutton('limit.episodes', self.spinbutton_episode_limit) + self._config.connect_gtk_togglebutton('ui.gtk.only_added_are_new', + self.checkbutton_only_added_are_new) + self.auto_download_model = NewEpisodeActionList(self._config) self.combo_auto_download.set_model(self.auto_download_model) cellrenderer = Gtk.CellRendererText() diff --git a/src/gpodder/gtkui/main.py b/src/gpodder/gtkui/main.py index 6e13be05..2b810d99 100644 --- a/src/gpodder/gtkui/main.py +++ b/src/gpodder/gtkui/main.py @@ -2863,6 +2863,7 @@ class gPodder(BuilderWidget, dbus.service.Object): def update_feed_cache_proc(): updated_channels = [] nr_update_errors = 0 + new_episodes = [] for updated, channel in enumerate(channels): if self.feed_cache_update_cancelled: break @@ -2876,7 +2877,7 @@ class gPodder(BuilderWidget, dbus.service.Object): try: channel._update_error = None util.idle_add(indicate_updating_podcast, channel) - channel.update(max_episodes=self.config.limit.episodes) + new_episodes.extend(channel.update(max_episodes=self.config.limit.episodes)) self._update_cover(channel) except Exception as e: message = str(e) @@ -2920,7 +2921,7 @@ class gPodder(BuilderWidget, dbus.service.Object): nr_update_errors) % {'count': nr_update_errors}, _('Error while updating feeds'), widget=self.treeChannels) - def update_feed_cache_finish_callback(): + def update_feed_cache_finish_callback(new_episodes): # Process received episode actions for all updated URLs self.process_received_episode_actions() @@ -2933,9 +2934,11 @@ class gPodder(BuilderWidget, dbus.service.Object): # The user decided to abort the feed update self.show_update_feeds_buttons() - # Only search for new episodes in podcasts that have been - # updated, not in other podcasts (for single-feed updates) - episodes = self.get_new_episodes([c for c in updated_channels]) + # The filter extension can mark newly added episodes as old, + # so take only episodes marked as new. + episodes = ((e for e in new_episodes if e.check_is_new()) + if self.config.ui.gtk.only_added_are_new + else self.get_new_episodes([c for c in updated_channels])) if self.config.downloads.chronological_order: # download older episodes first @@ -2986,7 +2989,7 @@ class gPodder(BuilderWidget, dbus.service.Object): self.show_update_feeds_buttons() - util.idle_add(update_feed_cache_finish_callback) + util.idle_add(update_feed_cache_finish_callback, new_episodes) def on_gPodder_delete_event(self, *args): """Called when the GUI wants to close the window diff --git a/src/gpodder/model.py b/src/gpodder/model.py index 10bcfaef..fed62f84 100644 --- a/src/gpodder/model.py +++ b/src/gpodder/model.py @@ -1230,7 +1230,7 @@ class PodcastChannel(PodcastModelObject): next_feed = None # mark episodes not new - real_new_episode_count = 0 + real_new_episodes = [] # Search all entries for new episodes for episode in new_episodes: # Workaround for bug 340: If the episode has been @@ -1242,17 +1242,18 @@ class PodcastChannel(PodcastModelObject): episode.save() if episode.is_new: - real_new_episode_count += 1 + real_new_episodes.append(episode) # Only allow a certain number of new episodes per update if (self.download_strategy == PodcastChannel.STRATEGY_LATEST - and real_new_episode_count > 1): + and len(real_new_episodes) > 1): episode.is_new = False episode.save() self.children.extend(new_episodes) self.remove_unreachable_episodes(existing, seen_guids, max_episodes) + return real_new_episodes def remove_unreachable_episodes(self, existing, seen_guids, max_episodes): # Remove "unreachable" episodes - episodes that have not been @@ -1284,11 +1285,12 @@ class PodcastChannel(PodcastModelObject): def update(self, max_episodes=0): max_episodes = int(max_episodes) + new_episodes = [] try: result = self.feed_fetcher.fetch_channel(self, max_episodes) if result.status == feedcore.UPDATED_FEED: - self._consume_updated_feed(result.feed, max_episodes) + new_episodes = self._consume_updated_feed(result.feed, max_episodes) elif result.status == feedcore.NEW_LOCATION: # FIXME: could return the feed because in autodiscovery it is parsed already url = result.feed @@ -1298,7 +1300,7 @@ class PodcastChannel(PodcastModelObject): self.url = url # With the updated URL, fetch the feed again self.update(max_episodes) - return + return new_episodes elif result.status == feedcore.NOT_MODIFIED: pass @@ -1325,6 +1327,7 @@ class PodcastChannel(PodcastModelObject): self._determine_common_prefix() self.db.commit() + return new_episodes def delete(self): self.db.delete_podcast(self)