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
15 class Toplist(object):
16 """ Base class for Episode and Podcast toplists """
18 def __init__(self
, cls
, view
, language
='', view_args
={}):
20 self
.language
= language
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
):
47 def __getitem__(self
, key
):
48 if isinstance(key
, slice):
49 start
= key
.start
or 0
50 length
= key
.stop
- start
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)
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',
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
):
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',
110 view_args
=dict(classes
=[Podcast
, PodcastGroup
]))