refactor / optimize device updates
[mygpo.git] / mygpo / users / subscriptions.py
blobe15f5e918cf6151c63c8342096f103dd52fe3f3f
1 from mygpo.core.proxy import proxy_object
2 from mygpo.db.couchdb.user import get_num_listened_episodes
3 from mygpo.db.couchdb.podcast import podcasts_to_dict
6 class PodcastSorter(object):
7 """ Sorts a list of podcast """
9 def __init__(self, podcasts):
10 self.podcasts = podcasts
11 self.sorted_podcasts = None
14 def _sort(self):
15 return self.podcasts
18 def __len__(self):
19 return len(self.podcasts)
22 def __getitem__(self, val):
23 if self.sorted_podcasts is None:
24 self.sorted_podcasts = self._sort()
26 return self.sorted_podcasts.__getitem__(val)
28 def __iter__(self):
29 if self.sorted_podcasts is None:
30 self.sorted_podcasts = self._sort()
32 return iter(self.sorted_podcasts)
36 class PodcastPercentageListenedSorter(PodcastSorter):
37 """ Sorts podcasts by the percentage of listened episodes
39 Adds the attributes percent_listened and episodes_listened to the podcasts
41 Cost: 1 DB query """
43 def __init__(self, podcasts, user):
44 super(PodcastPercentageListenedSorter, self).__init__(podcasts)
45 self.user = user
48 def _sort(self):
50 SORT_KEY = lambda podcast: podcast.percent_listened
52 counts = dict(get_num_listened_episodes(self.user))
53 for podcast in self.podcasts:
54 c = counts.get(podcast.get_id(), 0)
55 if podcast.episode_count:
56 podcast.percent_listened = c / float(podcast.episode_count)
57 podcast.episodes_listened = c
58 else:
59 podcast.percent_listened = 0
60 podcast.episodes_listened = 0
62 return sorted(self.podcasts, key=SORT_KEY, reverse=True)
65 def subscription_changes(device_id, podcast_states, since, until):
66 """ returns subscription changes for the device and podcast states """
68 add, rem = [], []
69 for p_state in podcast_states:
70 change = p_state.get_change_between(device_id, since, until)
71 if change == 'subscribe':
72 add.append( p_state.ref_url )
73 elif change == 'unsubscribe':
74 rem.append( p_state.ref_url )
76 return add, rem
79 def podcasts_for_states(podcast_states):
80 """ returns the podcasts corresponding to the podcast states """
82 podcast_ids = [state.podcast for state in podcast_states]
83 podcasts = podcasts_to_dict(podcast_ids)
85 for state in podcast_states:
86 podcast = proxy_object(podcasts[state.podcast], url=state.ref_url)
87 podcasts[state.podcast] = podcast
89 return podcasts.values()