2 from itertools
import count
4 from django
.shortcuts
import render
5 from django
.contrib
import messages
6 from django
.core
.urlresolvers
import reverse
7 from django
.http
import HttpResponseRedirect
8 from django
.utils
.translation
import ugettext
as _
9 from django
.views
.generic
import TemplateView
10 from django
.utils
.decorators
import method_decorator
12 from mygpo
.admin
.auth
import require_staff
13 from mygpo
.admin
.group
import PodcastGrouper
14 from mygpo
.counter
import Counter
15 from mygpo
.maintenance
.merge
import PodcastMerger
, IncorrectMergeException
16 from mygpo
.users
.models
import User
17 from mygpo
.admin
.clients
import UserAgentStats
, ClientStats
18 from mygpo
.api
.httpresponse
import JsonResponse
19 from mygpo
.db
.couchdb
.episode
import episode_count
20 from mygpo
.db
.couchdb
.podcast
import podcast_count
, podcast_for_url
23 class AdminView(TemplateView
):
25 @method_decorator(require_staff
)
26 def dispatch(self
, *args
, **kwargs
):
27 return super(AdminView
, self
).dispatch(*args
, **kwargs
)
30 class Overview(AdminView
):
31 template_name
= 'admin/overview.html'
34 class MergeSelect(AdminView
):
35 template_name
= 'admin/merge-select.html'
37 def get(self
, request
):
38 num
= int(request
.GET
.get('podcasts', 2))
41 return self
.render_to_response({
46 class MergeBase(AdminView
):
48 def _get_podcasts(self
, request
):
51 podcast_url
= request
.POST
.get('feed%d' % n
, None)
52 if podcast_url
is None:
58 podcast
= podcast_for_url(podcast_url
)
61 raise InvalidPodcast(podcast_url
)
63 podcasts
.append(podcast_for_url(podcast_url
))
68 class MergeVerify(MergeBase
):
70 template_name
= 'admin/merge-grouping.html'
72 def post(self
, request
):
75 podcasts
= self
._get
_podcasts
(request
)
77 except InvalidPodcast
as ip
:
78 messages
.error(request
,
79 _('No podcast with URL {url}').format(url
=str(ip
)))
81 grouper
= PodcastGrouper(podcasts
)
83 get_features
= lambda (e_id
, e
): ((e
.url
, e
.title
), e_id
)
85 num_groups
= grouper
.group(get_features
)
87 return self
.render_to_response({
93 class MergeProcess(MergeBase
):
95 RE_EPISODE
= re
.compile(r
'episode_([0-9a-fA-F]{32})')
97 def post(self
, request
):
100 podcasts
= self
._get
_podcasts
(request
)
102 except InvalidPodcast
as ip
:
103 messages
.error(request
,
104 _('No podcast with URL {url}').format(url
=str(ip
)))
106 grouper
= PodcastGrouper(podcasts
)
109 for key
, feature
in request
.POST
.items():
110 m
= self
.RE_EPISODE
.match(key
)
112 episode_id
= m
.group(1)
113 features
[episode_id
] = feature
115 get_features
= lambda (e_id
, e
): (features
[e_id
], e_id
)
117 num_groups
= grouper
.group(get_features
)
119 if 'renew' in request
.POST
:
120 return render(request
, 'admin/merge-grouping.html', {
121 'podcasts': podcasts
,
122 'groups': num_groups
,
126 elif 'merge' in request
.POST
:
131 # merge podcast, reassign episodes
132 pm
= PodcastMerger(podcasts
, actions
, num_groups
)
135 except IncorrectMergeException
as ime
:
136 messages
.error(request
, str(ime
))
137 return HttpResponseRedirect(reverse('admin-merge'))
139 return render(request
, 'admin/merge-finished.html', {
140 'actions': actions
.items(),
141 'podcast': podcasts
[0],
146 class UserAgentStatsView(AdminView
):
147 template_name
= 'admin/useragents.html'
149 def get(self
, request
):
151 uas
= UserAgentStats()
152 useragents
= uas
.get_entries()
154 return self
.render_to_response({
155 'useragents': useragents
.most_common(),
156 'max_users': uas
.max_users
,
157 'total': uas
.total_users
,
161 class ClientStatsView(AdminView
):
162 template_name
= 'admin/clients.html'
164 def get(self
, request
):
167 clients
= cs
.get_entries()
169 return self
.render_to_response({
170 'clients': clients
.most_common(),
171 'max_users': cs
.max_users
,
172 'total': cs
.total_users
,
176 class ClientStatsJsonView(AdminView
):
177 def get(self
, request
):
180 clients
= cs
.get_entries()
182 return JsonResponse(map(self
.to_dict
, clients
.most_common()))
184 def to_dict(self
, res
):
187 if not isinstance(obj
, tuple):
190 return obj
._asdict
(), count
193 class StatsView(AdminView
):
194 """ shows general stats as HTML page """
196 template_name
= 'admin/stats.html'
198 def _get_stats(self
):
200 'podcasts': podcast_count(),
201 'episodes': episode_count(),
202 'users': User
.count(),
205 def get(self
, request
):
206 stats
= self
._get
_stats
()
207 return self
.render_to_response({
212 class StatsJsonView(StatsView
):
213 """ provides general stats as JSON """
215 def get(self
, request
):
216 stats
= self
._get
_stats
()
217 return JsonResponse(stats
)