1 from datetime import datetime, timedelta
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 from forum.settings.base import Setting
12 from forum.settings.forms import SettingsSetForm, MaintenanceModeForm
14 from forum.models import Question, Answer, User, Node, Action
15 from forum import settings
17 def super_user_required(fn):
18 def wrapper(request, *args, **kwargs):
19 if request.user.is_authenticated() and request.user.is_superuser:
20 return fn(request, *args, **kwargs)
22 return HttpResponseForbidden()
28 def wrapper(request, *args, **kwargs):
29 res = fn(request, *args, **kwargs)
30 if isinstance(res, tuple):
31 template, context = res
32 context['basetemplate'] = settings.DJSTYLE_ADMIN_INTERFACE and "osqaadmin/djstyle_base.html" or "osqaadmin/base.html"
33 context['allsets'] = Setting.sets
34 context['othersets'] = sorted(
35 [s for s in Setting.sets.values() if not s.name in
36 ('basic', 'users', 'email', 'paths', 'extkeys', 'repgain', 'minrep', 'voting', 'badges', 'about', 'faq', 'sidebar',
37 'form', 'moderation')]
38 , lambda s1, s2: s1.weight - s2.weight)
39 return render_to_response(template, context, context_instance=RequestContext(request))
46 def dashboard(request):
47 return ('osqaadmin/dashboard.html', {
48 'settings_pack': unicode(settings.SETTINGS_PACK),
49 'statistics': get_statistics(),
50 'recent_activity': get_recent_activity(),
51 'flagged_posts': get_flagged_posts(),
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')
59 return HttpResponseRedirect(reverse('admin_index'))
62 def statistics(request):
63 today = datetime.now()
64 last_month = today - timedelta(days=30)
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)
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)
75 last_month_users = User.objects.filter(date_joined__gt=last_month
76 ).order_by('date_joined').values_list('date_joined', flat=True)
78 last_month_n_users = User.objects.filter(date_joined__lt=last_month).count()
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)
85 return 'osqaadmin/statistics.html', {
88 'id': 'questions_graph',
89 'caption': _("Questions Graph"),
93 'caption': _("Users Graph"),
101 def settings_set(request, set_name):
102 set = Setting.sets.get(set_name, None)
108 form = SettingsSetForm(set, data=request.POST, files=request.FILES)
112 request.user.message_set.create(message=_("'%s' settings saved succesfully") % set_name)
114 if set_name in ('minrep', 'badges', 'repgain'):
115 settings.SETTINGS_PACK.set_value("custom")
117 return HttpResponseRedirect(reverse('admin_set', args=[set_name]))
119 form = SettingsSetForm(set)
121 return 'osqaadmin/set.html', {
123 'markdown': set.markdown,
127 def get_default(request, set_name, var_name):
128 set = Setting.sets.get(set_name, None)
129 if set is None: raise Http404
131 setting = dict([(s.name, s) for s in set]).get(var_name, None)
132 if setting is None: raise Http404
136 if request.is_ajax():
137 return HttpResponse(setting.default)
139 return HttpResponseRedirect(reverse('admin_set', kwargs={'set_name': set_name}))
142 def get_recent_activity():
143 return Action.objects.order_by('-action_date')[0:30]
145 def get_flagged_posts():
146 return Action.objects.filter(action_type="flag").order_by('-action_date')[0:30]
148 def get_statistics():
150 'total_users': User.objects.all().count(),
151 'users_last_24': User.objects.filter(date_joined__gt=(datetime.now() - timedelta(days=1))).count(),
152 'total_questions': Question.objects.filter(deleted=None).count(),
153 'questions_last_24': Question.objects.filter(deleted=None, added_at__gt=(datetime.now() - timedelta(days=1))).count(),
154 'total_answers': Answer.objects.filter(deleted=None).count(),
155 'answers_last_24': Answer.objects.filter(deleted=None, added_at__gt=(datetime.now() - timedelta(days=1))).count(),
159 def go_bootstrap(request):
160 #todo: this is the quick and dirty way of implementing a bootstrap mode
162 from forum_modules.default_badges import settings as dbsets
163 dbsets.POPULAR_QUESTION_VIEWS.set_value(100)
164 dbsets.NOTABLE_QUESTION_VIEWS.set_value(200)
165 dbsets.FAMOUS_QUESTION_VIEWS.set_value(300)
166 dbsets.NICE_ANSWER_VOTES_UP.set_value(2)
167 dbsets.NICE_QUESTION_VOTES_UP.set_value(2)
168 dbsets.GOOD_ANSWER_VOTES_UP.set_value(4)
169 dbsets.GOOD_QUESTION_VOTES_UP.set_value(4)
170 dbsets.GREAT_ANSWER_VOTES_UP.set_value(8)
171 dbsets.GREAT_QUESTION_VOTES_UP.set_value(8)
172 dbsets.FAVORITE_QUESTION_FAVS.set_value(1)
173 dbsets.STELLAR_QUESTION_FAVS.set_value(3)
174 dbsets.DISCIPLINED_MIN_SCORE.set_value(3)
175 dbsets.PEER_PRESSURE_MAX_SCORE.set_value(-3)
176 dbsets.CIVIC_DUTY_VOTES.set_value(15)
177 dbsets.PUNDIT_COMMENT_COUNT.set_value(10)
178 dbsets.SELF_LEARNER_UP_VOTES.set_value(2)
179 dbsets.STRUNK_AND_WHITE_EDITS.set_value(10)
180 dbsets.ENLIGHTENED_UP_VOTES.set_value(2)
181 dbsets.GURU_UP_VOTES.set_value(4)
182 dbsets.NECROMANCER_UP_VOTES.set_value(2)
183 dbsets.NECROMANCER_DIF_DAYS.set_value(30)
184 dbsets.TAXONOMIST_USE_COUNT.set_value(5)
188 settings.REP_TO_VOTE_UP.set_value(0)
189 settings.REP_TO_VOTE_DOWN.set_value(15)
190 settings.REP_TO_FLAG.set_value(15)
191 settings.REP_TO_COMMENT.set_value(0)
192 settings.REP_TO_LIKE_COMMENT.set_value(0)
193 settings.REP_TO_UPLOAD.set_value(0)
194 settings.REP_TO_CLOSE_OWN.set_value(60)
195 settings.REP_TO_REOPEN_OWN.set_value(120)
196 settings.REP_TO_RETAG.set_value(150)
197 settings.REP_TO_EDIT_WIKI.set_value(200)
198 settings.REP_TO_EDIT_OTHERS.set_value(400)
199 settings.REP_TO_CLOSE_OTHERS.set_value(600)
200 settings.REP_TO_DELETE_COMMENTS.set_value(400)
201 settings.REP_TO_VIEW_FLAGS.set_value(30)
203 settings.INITIAL_REP.set_value(1)
204 settings.MAX_REP_BY_UPVOTE_DAY.set_value(300)
205 settings.REP_GAIN_BY_UPVOTED.set_value(15)
206 settings.REP_LOST_BY_DOWNVOTED.set_value(1)
207 settings.REP_LOST_BY_DOWNVOTING.set_value(0)
208 settings.REP_GAIN_BY_ACCEPTED.set_value(25)
209 settings.REP_GAIN_BY_ACCEPTING.set_value(5)
210 settings.REP_LOST_BY_FLAGGED.set_value(2)
211 settings.REP_LOST_BY_FLAGGED_3_TIMES.set_value(30)
212 settings.REP_LOST_BY_FLAGGED_5_TIMES.set_value(100)
214 settings.SETTINGS_PACK.set_value("bootstrap")
216 request.user.message_set.create(message=_('Bootstrap mode enabled'))
217 return HttpResponseRedirect(reverse('admin_index'))
220 def go_defaults(request):
221 for setting in Setting.sets['badges']:
223 for setting in Setting.sets['minrep']:
225 for setting in Setting.sets['repgain']:
228 settings.SETTINGS_PACK.set_value("default")
230 request.user.message_set.create(message=_('All values reverted to defaults'))
231 return HttpResponseRedirect(reverse('admin_index'))
235 def recalculate_denormalized(request):
236 for n in Node.objects.all():
238 n.score = n.votes.aggregate(score=Sum('value'))['score']
239 if not n.score: n.score = 0
242 for u in User.objects.all():
243 u.reputation = u.reputes.aggregate(reputation=Sum('value'))['reputation']
246 request.user.message_set.create(message=_('All values recalculated'))
247 return HttpResponseRedirect(reverse('admin_index'))
250 def maintenance(request):
252 if 'close' in request.POST or 'adjust' in request.POST:
253 form = MaintenanceModeForm(request.POST)
256 settings.MAINTAINANCE_MODE.set_value({
257 'allow_ips': form.cleaned_data['ips'],
258 'message': form.cleaned_data['message']})
260 if 'close' in request.POST:
261 message = _('Maintenance mode enabled')
263 message = _('Settings adjusted')
265 request.user.message_set.create(message=message)
267 return HttpResponseRedirect(reverse('admin_maintenance'))
268 elif 'open' in request.POST:
269 settings.MAINTAINANCE_MODE.set_value(None)
270 request.user.message_set.create(message=_("Your site is now running normally"))
271 return HttpResponseRedirect(reverse('admin_maintenance'))
273 form = MaintenanceModeForm(initial={'ips': request.META['REMOTE_ADDR'],
274 'message': _('Currently down for maintenance. We\'ll be back soon')})
276 return ('osqaadmin/maintenance.html', {'form': form, 'in_maintenance': settings.MAINTAINANCE_MODE.value is not None})
280 def flagged_posts(request):
281 return ('osqaadmin/flagged_posts.html', {
282 'flagged_posts': get_flagged_posts(),