]> git.openstreetmap.org Git - osqa.git/blob - forum/views/admin.py
Some extra admin stuff and applied a patch from Ekalinin on OSQA 95.
[osqa.git] / forum / views / admin.py
1 from datetime import datetime, timedelta
2 import time
3
4 from django.shortcuts import render_to_response
5 from django.core.urlresolvers import reverse
6 from django.http import HttpResponseRedirect, HttpResponse, HttpResponseForbidden, Http404
7 from django.template import RequestContext
8 from django.utils.translation import ugettext as _
9 from django.utils import simplejson
10 from django.db.models import Sum
11
12 from forum.settings.base import Setting
13 from forum.settings.forms import SettingsSetForm
14
15 from forum.models import Question, Answer, User, Node, Action
16 from forum import settings
17
18 def super_user_required(fn):
19     def wrapper(request, *args, **kwargs):
20         if request.user.is_authenticated() and request.user.is_superuser:
21             return fn(request, *args, **kwargs)
22         else:
23             return HttpResponseForbidden()
24
25     return wrapper
26
27 def admin_page(fn):
28     @super_user_required
29     def wrapper(request, *args, **kwargs):
30         res = fn(request, *args, **kwargs)
31         if isinstance(res, tuple):
32             template, context = res
33             context['basetemplate'] = settings.DJSTYLE_ADMIN_INTERFACE and "osqaadmin/djstyle_base.html" or "osqaadmin/base.html"
34             context['allsets'] = Setting.sets
35             context['othersets'] = sorted(
36                     [s for s in Setting.sets.values() if not s.name in
37                     ('basic', 'users', 'email', 'paths', 'extkeys', 'repgain', 'minrep', 'voting', 'badges', 'about', 'faq', 'sidebar',
38                     'form', 'moderation')]
39                     , lambda s1, s2: s1.weight - s2.weight)
40             return render_to_response(template, context, context_instance=RequestContext(request))
41         else:
42             return res
43
44     return wrapper
45
46 @admin_page
47 def dashboard(request):
48     return ('osqaadmin/dashboard.html', {
49         'settings_pack': unicode(settings.SETTINGS_PACK),
50         'statistics': get_statistics(),
51         'recent_activity': get_recent_activity(),
52     })
53
54 @super_user_required
55 def interface_switch(request):
56     if request.GET and request.GET.get('to', None) and request.GET['to'] in ('default', 'djstyle'):
57         settings.DJSTYLE_ADMIN_INTERFACE.set_value(request.GET['to'] == 'djstyle')
58
59     return HttpResponseRedirect(reverse('admin_index'))
60
61 @admin_page
62 def statistics(request):
63     today = datetime.now()
64     last_month = today - timedelta(days=30)
65
66     last_month_questions = Question.objects.filter(deleted=None, added_at__gt=last_month
67                                                   ).order_by('added_at').values_list('added_at', flat=True)
68
69     last_month_n_questions = Question.objects.filter(deleted=None, added_at__lt=last_month).count()
70     qgraph_data = simplejson.dumps([
71             (time.mktime(d.timetuple()) * 1000, i + last_month_n_questions)
72             for i, d in enumerate(last_month_questions)
73     ])
74
75     last_month_users = User.objects.filter(date_joined__gt=last_month
76                                                   ).order_by('date_joined').values_list('date_joined', flat=True)
77
78     last_month_n_users = User.objects.filter(date_joined__lt=last_month).count()
79
80     ugraph_data = simplejson.dumps([
81             (time.mktime(d.timetuple()) * 1000, i + last_month_n_users)
82             for i, d in enumerate(last_month_users)
83     ])
84
85     return 'osqaadmin/statistics.html', {
86         'graphs': [
87             {
88                 'id': 'questions_graph',
89                 'caption': _("Questions Graph"),
90                 'data': qgraph_data
91             },{
92                 'id': 'userss_graph',
93                 'caption': _("Users Graph"),
94                 'data': ugraph_data
95             }
96         ]
97     }
98
99
100 @admin_page
101 def settings_set(request, set_name):
102     set = Setting.sets.get(set_name, None)
103
104     if set is None:
105         raise Http404
106
107     if request.POST:
108         form = SettingsSetForm(set, data=request.POST, files=request.FILES)
109
110         if form.is_valid():
111             form.save()
112             request.user.message_set.create(message=_("'%s' settings saved succesfully") % set_name)
113
114             if set_name in ('minrep', 'badges', 'repgain'):
115                 settings.SETTINGS_PACK.set_value("custom")
116
117             return HttpResponseRedirect(reverse('admin_set', args=[set_name]))
118     else:
119         form = SettingsSetForm(set)
120
121     return 'osqaadmin/set.html', {
122         'form': form,
123         'markdown': set.markdown,
124     }
125
126 @super_user_required
127 def get_default(request, set_name, var_name):
128     set = Setting.sets.get(set_name, None)
129     if set is None: raise Http404
130
131     setting = dict([(s.name, s) for s in set]).get(var_name, None)
132     if setting is None: raise Http404
133
134     setting.to_default()
135
136     if request.is_ajax():
137         return HttpResponse(setting.default)
138     else:
139         return HttpResponseRedirect(reverse('admin_set', kwargs={'set_name': set_name}))
140
141
142 def get_recent_activity():
143     return Action.objects.order_by('-action_date')[0:30]
144
145 def get_statistics():
146     return {
147         'total_users': User.objects.all().count(),
148         'users_last_24': User.objects.filter(date_joined__gt=(datetime.now() - timedelta(days=1))).count(),
149         'total_questions': Question.objects.filter(deleted=None).count(),
150         'questions_last_24': Question.objects.filter(deleted=None, added_at__gt=(datetime.now() - timedelta(days=1))).count(),
151         'total_answers': Answer.objects.filter(deleted=None).count(),
152         'answers_last_24': Answer.objects.filter(deleted=None, added_at__gt=(datetime.now() - timedelta(days=1))).count(),
153     }
154
155 @super_user_required
156 def go_bootstrap(request):
157     #todo: this is the quick and dirty way of implementing a bootstrap mode
158     try:
159         from forum_modules.default_badges import settings as dbsets
160         dbsets.POPULAR_QUESTION_VIEWS.set_value(100)
161         dbsets.NOTABLE_QUESTION_VIEWS.set_value(200)
162         dbsets.FAMOUS_QUESTION_VIEWS.set_value(300)
163         dbsets.NICE_ANSWER_VOTES_UP.set_value(2)
164         dbsets.NICE_QUESTION_VOTES_UP.set_value(2)
165         dbsets.GOOD_ANSWER_VOTES_UP.set_value(4)
166         dbsets.GOOD_QUESTION_VOTES_UP.set_value(4)
167         dbsets.GREAT_ANSWER_VOTES_UP.set_value(8)
168         dbsets.GREAT_QUESTION_VOTES_UP.set_value(8)
169         dbsets.FAVORITE_QUESTION_FAVS.set_value(1)
170         dbsets.STELLAR_QUESTION_FAVS.set_value(3)
171         dbsets.DISCIPLINED_MIN_SCORE.set_value(3)
172         dbsets.PEER_PRESSURE_MAX_SCORE.set_value(-3)
173         dbsets.CIVIC_DUTY_VOTES.set_value(15)
174         dbsets.PUNDIT_COMMENT_COUNT.set_value(10)
175         dbsets.SELF_LEARNER_UP_VOTES.set_value(2)
176         dbsets.STRUNK_AND_WHITE_EDITS.set_value(10)
177         dbsets.ENLIGHTENED_UP_VOTES.set_value(2)
178         dbsets.GURU_UP_VOTES.set_value(4)
179         dbsets.NECROMANCER_UP_VOTES.set_value(2)
180         dbsets.NECROMANCER_DIF_DAYS.set_value(30)
181         dbsets.TAXONOMIST_USE_COUNT.set_value(5)
182     except:
183         pass
184
185     settings.REP_TO_VOTE_UP.set_value(0)
186     settings.REP_TO_VOTE_DOWN.set_value(15)
187     settings.REP_TO_FLAG.set_value(15)
188     settings.REP_TO_COMMENT.set_value(0)
189     settings.REP_TO_LIKE_COMMENT.set_value(0)
190     settings.REP_TO_UPLOAD.set_value(0)
191     settings.REP_TO_CLOSE_OWN.set_value(60)
192     settings.REP_TO_REOPEN_OWN.set_value(120)
193     settings.REP_TO_RETAG.set_value(150)
194     settings.REP_TO_EDIT_WIKI.set_value(200)
195     settings.REP_TO_EDIT_OTHERS.set_value(400)
196     settings.REP_TO_CLOSE_OTHERS.set_value(600)
197     settings.REP_TO_DELETE_COMMENTS.set_value(400)
198     settings.REP_TO_VIEW_FLAGS.set_value(30)
199
200     settings.INITIAL_REP.set_value(1)
201     settings.MAX_REP_BY_UPVOTE_DAY.set_value(300)
202     settings.REP_GAIN_BY_UPVOTED.set_value(15)
203     settings.REP_LOST_BY_UPVOTE_CANCELED.set_value(15)
204     settings.REP_LOST_BY_DOWNVOTED.set_value(1)
205     settings.REP_LOST_BY_DOWNVOTING.set_value(0)
206     settings.REP_GAIN_BY_DOWNVOTE_CANCELED.set_value(1)
207     settings.REP_GAIN_BY_CANCELING_DOWNVOTE.set_value(0)
208     settings.REP_GAIN_BY_ACCEPTED.set_value(25)
209     settings.REP_LOST_BY_ACCEPTED_CANCELED.set_value(25)
210     settings.REP_GAIN_BY_ACCEPTING.set_value(5)
211     settings.REP_LOST_BY_CANCELING_ACCEPTED.set_value(5)
212     settings.REP_LOST_BY_FLAGGED.set_value(2)
213     settings.REP_LOST_BY_FLAGGED_3_TIMES.set_value(30)
214     settings.REP_LOST_BY_FLAGGED_5_TIMES.set_value(100)
215
216     settings.SETTINGS_PACK.set_value("bootstrap")
217
218     request.user.message_set.create(message=_('Bootstrap mode enabled'))
219     return HttpResponseRedirect(reverse('admin_index'))
220
221 @super_user_required
222 def go_defaults(request):
223     for setting in Setting.sets['badges']:
224         setting.to_default()
225     for setting in Setting.sets['minrep']:
226         setting.to_default()
227     for setting in Setting.sets['repgain']:
228         setting.to_default()
229
230     settings.SETTINGS_PACK.set_value("default")
231
232     request.user.message_set.create(message=_('All values reverted to defaults'))
233     return HttpResponseRedirect(reverse('admin_index'))
234
235
236 @super_user_required
237 def recalculate_denormalized(request):
238     for n in Node.objects.all():
239         n = n.leaf
240         n.score = n.votes.aggregate(score=Sum('value'))['score']
241         if not n.score: n.score = 0
242         n.save()
243
244     for u in User.objects.all():
245         u.reputation = u.reputes.aggregate(reputation=Sum('value'))['reputation']
246         u.save()
247
248     request.user.message_set.create(message=_('All values recalculated'))
249     return HttpResponseRedirect(reverse('admin_index'))
250