remove now unused {% load url from future %}
[mygpo.git] / mygpo / web / heatmap.py
blobca63b584cc0637436f71be4fe9822db3c8c3c0e6
2 # This file is part of my.gpodder.org.
4 # my.gpodder.org is free software: you can redistribute it and/or modify it
5 # under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or (at your
7 # option) any later version.
9 # my.gpodder.org is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
12 # License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with my.gpodder.org. If not, see <http://www.gnu.org/licenses/>.
18 from functools import wraps
20 from mygpo.db.couchdb.episode_state import get_heatmap
23 class EpisodeHeatmap(object):
24 """ Information about how often certain parts of Episodes are played """
26 def __init__(self, podcast_id, episode_id=None, user_id=None,
27 duration=None):
28 """ Initialize a new Episode heatmap
30 EpisodeHeatmap(podcast_id, [episode_id, [user_id]]) """
32 self.podcast_id = podcast_id
34 if episode_id is not None and podcast_id is None:
35 raise ValueError('episode_id can only be used '
36 'if podcast_id is not None')
38 self.episode_id = episode_id
40 if user_id is not None and episode_id is None:
41 raise ValueError('user_id can only be used '
42 'if episode_id is not None')
44 self.user_id = user_id
45 self.duration = duration
46 self.heatmap = None
47 self.borders = None
50 def _query(self):
51 """ Queries the database and stores the heatmap and its borders """
53 self.heatmap, self.borders = get_heatmap(self.podcast_id,
54 self.episode_id, self.user_id)
56 if self.borders and self.heatmap:
57 # heatmap info doesn't reach until the end of the episode
58 # so we extend it with 0 listeners
59 if self.duration > self.borders[-1]:
60 self.heatmap.append(0)
61 self.borders.append(self.duration)
64 def query_if_required():
65 """ If required, queries the database before calling the function """
67 def decorator(f):
68 @wraps(f)
69 def tmp(self, *args, **kwargs):
70 if None in (self.heatmap, self.borders):
71 self._query()
73 return f(self, *args, **kwargs)
74 return tmp
75 return decorator
78 @property
79 @query_if_required()
80 def max_plays(self):
81 """ Returns the highest number of plays of all sections """
83 return max(self.heatmap)
86 @property
87 @query_if_required()
88 def sections(self):
89 """ Returns an iterator that emits (from, to, play-counts) tuples
91 Each tuple represents one part in the heatmap with a distinct
92 play-count. from and to indicate the range of section in seconds."""
94 for i in range(len(self.heatmap)):
95 yield (self.borders[i], self.borders[i+1], self.heatmap[i])
98 @query_if_required()
99 def __nonzero__(self):
100 return any(self.heatmap)