def episode_list(podcast, user, offset=0, limit=None): """ Returns a list of episodes, with their action-attribute set to the latest action. The attribute is unsert if there is no episode-action for the episode. """ listeners = dict(episode_listener_counts(podcast)) episodes = episodes_for_podcast(podcast, descending=True, skip=offset, limit=limit) if user.is_authenticated(): # prepare pre-populated data for HistoryEntry.fetch_data podcasts_dict = dict( (p_id, podcast) for p_id in podcast.get_ids()) episodes_dict = dict( (episode._id, episode) for episode in episodes) actions = get_podcasts_episode_states(podcast, user._id) actions = map(HistoryEntry.from_action_dict, actions) HistoryEntry.fetch_data(user, actions, podcasts=podcasts_dict, episodes=episodes_dict) episode_actions = dict( (action.episode_id, action) for action in actions) else: episode_actions = {} annotate_episode = partial(_annotate_episode, listeners, episode_actions) return map(annotate_episode, episodes)
def get_episode_updates(self, user, subscribed_podcasts, since, max_per_podcast=5): """ Returns the episode updates since the timestamp """ if gevent: # DB: get max_per_podcast episodes for each subscribed podcast episode_jobs = [gevent.spawn(episodes_for_podcast, p, since, limit=max_per_podcast) for p in subscribed_podcasts] gevent.joinall(episode_jobs) episodes = chain.from_iterable(job.get() for job in episode_jobs) # DB: get all episode states for all subscribed podcasts e_action_jobs = [gevent.spawn(get_podcasts_episode_states, p, user._id) for p in subscribed_podcasts] gevent.joinall(e_action_jobs) e_actions = chain.from_iterable(job.get() for job in e_action_jobs) else: episodes = chain.from_iterable(episodes_for_podcast(p, since, limit=max_per_podcast) for p in subscribed_podcasts) e_actions = chain.from_iterable(get_podcasts_episode_states(p, user._id) for p in subscribed_podcasts) # TODO: get_podcasts_episode_states could be optimized by returning # only actions within some time frame e_status = { e._id: EpisodeStatus(e, 'new', None) for e in episodes} for action in e_actions: e_id = action['episode_id'] if not e_id in e_status: continue episode = e_status[e_id].episode e_status[e_id] = EpisodeStatus(episode, action['action'], action) return e_status.itervalues()