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")
14 def listener_data(podcasts
, start_date
=datetime(2010, 1, 1), 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
, released__gt
=start_date
)
22 episodes
= {e
.released
.date(): e
for e
in episodes
}
24 history
= EpisodeHistoryEntry
.objects
.filter(
25 episode__podcast__in
=podcasts
, timestamp__gte
=start_date
27 # contains play-counts, indexed by date {date: play-count}
28 play_counts
= playcounts_timerange(history
)
30 # we start either at the first episode-release or the first listen-event
31 events
= list(episodes
.keys()) + list(play_counts
.keys())
34 # if we don't have any events, stop
38 for date
in daterange(start
, leap
=leap
):
39 playcount
= play_counts
.get(date
, 0)
40 episode
= episodes
.get(date
, None)
41 yield ListenerData(date
, playcount
, episode
)
44 def episode_listener_data(
45 episode
, start_date
=datetime(2010, 1, 1), 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
.filter(
52 episode
=episode
, 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
59 list(play_counts
.keys()) + [episode
.released
.date()] if episode
.released
else []
65 # we always start at the first listen-event
67 for date
in daterange(start
, leap
=leap
):
68 playcount
= play_counts
.get(date
, 0)
69 e
= episode
if (episode
.released
.date() == date
) else None
70 yield ListenerData(date
, playcount
, e
)
73 def subscriber_data(podcasts
):
74 coll_data
= defaultdict(int)
81 for podcast
in podcasts
:
82 create_entry
= lambda r
: (r
.timestamp
.strftime("%y-%m"), r
.subscriber_count
)
84 subdata
= [podcast
.subscribers
]
86 data
= dict(map(create_entry
, subdata
))
89 coll_data
[k
] += data
[k
]
91 # create a list of {'x': label, 'y': value}
93 [dict(x
=a
, y
=b
) for (a
, b
) in coll_data
.items()], key
=lambda x
: x
["x"]
99 def check_publisher_permission(user
, podcast
):
100 """Checks if the user has publisher permissions for the given podcast"""
102 if not user
.is_authenticated
:
108 return PublishedPodcast
.objects
.filter(publisher
=user
, podcast
=podcast
).exists()