Custom feeds: Delete episodes when removed from feed
Up to now, the episodes from non-feed sources (Soundcloud and XSPF) would pile up forever, because they were never deleted from the database, even if they were removed from the original feed. This is now fixed using the same mechanism as the one for normal feeds: If an episode GUID is not found in the feed, it is removed from the database.
This commit is contained in:
parent
a43a3de035
commit
9a6bef5d48
3 changed files with 27 additions and 30 deletions
|
@ -923,19 +923,17 @@ class PodcastChannel(PodcastModelObject):
|
|||
self.cover_url = custom_feed.get_image()
|
||||
self.save()
|
||||
|
||||
guids = [episode.guid for episode in self.get_all_episodes()]
|
||||
existing = self.get_all_episodes()
|
||||
existing_guids = [episode.guid for episode in existing]
|
||||
|
||||
assert self.children is not None
|
||||
|
||||
# Insert newly-found episodes into the database + local cache
|
||||
self.children.extend(custom_feed.get_new_episodes(self, guids))
|
||||
new_episodes, seen_guids = custom_feed.get_new_episodes(self,
|
||||
existing_guids)
|
||||
self.children.extend(new_episodes)
|
||||
|
||||
# Sort episodes by pubdate, descending
|
||||
self.children.sort(key=lambda e: e.published, reverse=True)
|
||||
|
||||
self.save()
|
||||
|
||||
self.db.purge(max_episodes, self.id)
|
||||
self.remove_unreachable_episodes(existing, seen_guids, max_episodes)
|
||||
|
||||
def _consume_updated_feed(self, feed, max_episodes=0, mimetype_prefs=''):
|
||||
#self.parse_error = feed.get('bozo_exception', None)
|
||||
|
@ -1046,6 +1044,9 @@ class PodcastChannel(PodcastModelObject):
|
|||
if self.children is not None:
|
||||
self.children.append(episode)
|
||||
|
||||
self.remove_unreachable_episodes(existing, seen_guids, max_episodes)
|
||||
|
||||
def remove_unreachable_episodes(self, existing, seen_guids, max_episodes):
|
||||
# Remove "unreachable" episodes - episodes that have not been
|
||||
# downloaded and that the feed does not list as downloadable anymore
|
||||
if self.id is not None:
|
||||
|
|
|
@ -188,18 +188,22 @@ class SoundcloudFeed(object):
|
|||
def get_description(self):
|
||||
return _('Tracks published by %s on Soundcloud.') % self.username
|
||||
|
||||
def get_new_episodes(self, channel, guids):
|
||||
tracks = [t for t in self.sc_user.get_tracks('tracks') \
|
||||
if t['guid'] not in guids]
|
||||
def get_new_episodes(self, channel, existing_guids):
|
||||
return self._get_new_episodes(channel, existing_guids, 'tracks')
|
||||
|
||||
def _get_new_episodes(self, channel, existing_guids, track_type):
|
||||
tracks = [t for t in self.sc_user.get_tracks(track_type)]
|
||||
|
||||
seen_guids = [track['guid'] for track in tracks]
|
||||
episodes = []
|
||||
|
||||
for track in tracks:
|
||||
episode = channel.episode_factory(track)
|
||||
episode.save()
|
||||
episodes.append(episode)
|
||||
if track['guid'] not in existing_guids:
|
||||
episode = channel.episode_factory(track)
|
||||
episode.save()
|
||||
episodes.append(episode)
|
||||
|
||||
return episodes
|
||||
return episodes, seen_guids
|
||||
|
||||
class SoundcloudFavFeed(SoundcloudFeed):
|
||||
URL_REGEX = re.compile('http://([a-z]+\.)?soundcloud\.com/([^/]+)/favorites', re.I)
|
||||
|
@ -217,18 +221,8 @@ class SoundcloudFavFeed(SoundcloudFeed):
|
|||
def get_description(self):
|
||||
return _('Tracks favorited by %s on Soundcloud.') % self.username
|
||||
|
||||
def get_new_episodes(self, channel, guids):
|
||||
tracks = [t for t in self.sc_user.get_tracks('favorites') \
|
||||
if t['guid'] not in guids]
|
||||
|
||||
episodes = []
|
||||
|
||||
for track in tracks:
|
||||
episode = channel.episode_factory(track)
|
||||
episode.save()
|
||||
episodes.append(episode)
|
||||
|
||||
return episodes
|
||||
def get_new_episodes(self, channel, existing_guids):
|
||||
return self._get_new_episodes(channel, existing_guids, 'favorites')
|
||||
|
||||
# Register our URL handlers
|
||||
model.register_custom_handler(SoundcloudFeed)
|
||||
|
|
|
@ -134,13 +134,15 @@ class FM4OnDemandPlaylist(object):
|
|||
return self.CONTENT.get(self.category, \
|
||||
(None, None, None, 'XSPF playlist'))[3]
|
||||
|
||||
def get_new_episodes(self, channel, guids):
|
||||
def get_new_episodes(self, channel, existing_guids):
|
||||
tracks = []
|
||||
seen_guids = []
|
||||
|
||||
for track in self.playlist.getElementsByTagName('track'):
|
||||
title = self.get_text_contents(track.getElementsByTagName('title'))
|
||||
url = self.get_text_contents(track.getElementsByTagName('location'))
|
||||
if url in guids:
|
||||
seen_guids.append(url)
|
||||
if url in existing_guids:
|
||||
continue
|
||||
|
||||
filesize, filetype, filedate, filename = get_metadata(url)
|
||||
|
@ -157,7 +159,7 @@ class FM4OnDemandPlaylist(object):
|
|||
episode.save()
|
||||
tracks.append(episode)
|
||||
|
||||
return tracks
|
||||
return tracks, seen_guids
|
||||
|
||||
|
||||
# Register our URL handlers
|
||||
|
|
Loading…
Reference in a new issue