remove gevent monkey-patch from feed-downloader
[mygpo.git] / mygpo / directory / toplist.py
blob7da041d5175321cd4438d556b4f05fa28794906e
1 from itertools import product
3 from datetime import date, timedelta
5 from django.core.cache import cache
7 from mygpo.core.models import Episode, Podcast, PodcastGroup
8 from mygpo.data.mimetype import get_type, CONTENT_TYPES
9 from mygpo.utils import daterange
10 from mygpo.db.couchdb.directory import toplist
13 CACHE_SECONDS = 60*60
15 class Toplist(object):
16 """ Base class for Episode and Podcast toplists """
18 def __init__(self, cls, view, language='', view_args={}):
19 self.cls = cls
20 self.language = language
21 self.view = view
22 self.view_args = view_args
25 def _get_query_keys(self):
26 """ Returns an iterator of query keys that are passed to the view """
27 return [self.language]
30 def _query(self, limit):
31 """ Queries the database and returns the sorted results """
33 key = self._get_query_keys()
34 results = self._cache_or_query(limit, key)
35 results = self._sort(results)
36 return results[:limit]
39 def _cache_or_query(self, limit, key):
40 return toplist(self.cls, self.view, key, limit, **self.view_args)
43 def _sort(self, results):
44 return results
47 def __getitem__(self, key):
48 if isinstance(key, slice):
49 start = key.start or 0
50 length = key.stop - start
51 else:
52 start = key
53 length = 1
55 return self._query(length)
59 class EpisodeToplist(Toplist):
60 """ Retrieves the episode toplist for a certain date """
62 def __init__(self, language='', startdate=None):
63 super(EpisodeToplist, self).__init__(Episode,
64 'toplist/episodes', language)
65 self.date = startdate or date.today()
68 def _sort(self, results):
69 results.sort(key=lambda episode: episode.listeners, reverse=True)
70 return results
73 def _get_query_keys(self):
74 """ Returns the query keys based on instance variables """
76 date_str = self.date.strftime('%Y-%m-%d')
77 return [date_str] + super(EpisodeToplist, self)._get_query_keys()
81 class PodcastToplist(Toplist):
82 """ Podcast toplist based on number of subscribers """
84 def __init__(self, language=''):
85 super(PodcastToplist, self).__init__(Podcast, 'toplist/podcasts',
86 language,
87 view_args=dict(classes=[Podcast, PodcastGroup]))
90 def _sort(self, results):
91 # sort by subscriber_count and id to ensure same order when subscriber_count is equal
92 cur = sorted(results, key=lambda p: (p.subscriber_count(), p.get_id()), reverse=True)
93 prev = sorted(results, key=lambda p: (p.prev_subscriber_count(), p.get_id()), reverse=True)
95 res = dict( (p, n) for n, p in enumerate(cur))
97 for old, p in enumerate(prev):
98 new = res.get(p, 0)
99 res[p] = (new, old)
101 return [(old+1, p) for p, (new, old) in sorted(res.items(), key=lambda i: i[1][0])]
104 class TrendingPodcasts(Toplist):
105 """ Trending podcasts based on current / previous subscribers ratio """
107 def __init__(self, language=''):
108 super(TrendingPodcasts, self).__init__(Podcast, 'trending/podcasts',
109 language,
110 view_args=dict(classes=[Podcast, PodcastGroup]))