1 from collections
import namedtuple
, defaultdict
2 from datetime
import timedelta
, datetime
, time
4 from mygpo
.podcasts
.models
import Episode
5 from mygpo
.utils
import daterange
6 from mygpo
.history
.models
import EpisodeHistoryEntry
7 from mygpo
.history
.stats
import playcounts_timerange
8 from mygpo
.publisher
.models
import PublishedPodcast
11 ListenerData
= namedtuple('ListenerData', 'date playcount episode')
13 def listener_data(podcasts
, start_date
=datetime(2010, 1, 1),
14 leap
=timedelta(days
=1)):
15 """ Returns data for the podcast listener timeseries
17 An iterator with data for each day (starting from either the first released
18 episode or the earliest play-event) is returned, where each day is
19 reresented by a ListenerData tuple. """
20 # index episodes by releaes-date
21 episodes
= Episode
.objects
.filter(podcast__in
=podcasts
,
22 released__gt
=start_date
)
23 episodes
= {e
.released
.date(): e
for e
in episodes
}
25 history
= EpisodeHistoryEntry
.objects\
26 .filter(episode__podcast__in
=podcasts
,
27 timestamp__gte
=start_date
)\
28 # contains play-counts, indexed by date {date: play-count}
29 play_counts
= playcounts_timerange(history
)
31 # we start either at the first episode-release or the first listen-event
32 events
= list(episodes
.keys()) + list(play_counts
.keys())
35 # if we don't have any events, stop
39 for date
in daterange(start
, leap
=leap
):
40 playcount
= play_counts
.get(date
, 0)
41 episode
= episodes
.get(date
, None)
42 yield ListenerData(date
, playcount
, episode
)
45 def episode_listener_data(episode
, start_date
=datetime(2010, 1, 1),
46 leap
=timedelta(days
=1)):
47 """ Returns data for the episode listener timeseries
49 An iterator with data for each day (starting from the first event
50 is returned, where each day is represented by a ListenerData tuple """
51 history
= EpisodeHistoryEntry
.objects\
52 .filter(episode
=episode
,
53 timestamp__gte
=start_date
)\
54 # contains play-counts, indexed by date {date: play-count}
55 play_counts
= playcounts_timerange(history
)
57 # we start either at the episode-release or the first listen-event
58 events
= list(play_counts
.keys()) + \
59 [episode
.released
.date()] if episode
.released
else []
64 # we always start at the first listen-event
66 for date
in daterange(start
, leap
=leap
):
67 playcount
= play_counts
.get(date
, 0)
68 e
= episode
if (episode
.released
.date() == date
) else None
69 yield ListenerData(date
, playcount
, e
)
72 def subscriber_data(podcasts
):
73 coll_data
= defaultdict(int)
80 for podcast
in podcasts
:
81 create_entry
= lambda r
: (r
.timestamp
.strftime('%y-%m'), r
.subscriber_count
)
83 subdata
= [podcast
.subscribers
]
85 data
= dict(map(create_entry
, subdata
))
88 coll_data
[k
] += data
[k
]
90 # create a list of {'x': label, 'y': value}
91 coll_data
= sorted([dict(x
=a
, y
=b
) for (a
, b
) in coll_data
.items()], key
=lambda x
: x
['x'])
96 def check_publisher_permission(user
, podcast
):
97 """ Checks if the user has publisher permissions for the given podcast """
99 if not user
.is_authenticated
:
105 return PublishedPodcast
.objects
.filter(publisher
=user
, podcast
=podcast
).exists()