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
12 from forum.settings.base import Setting
13 from forum.settings.forms import SettingsSetForm, MaintenanceModeForm
15 from forum.models import Question, Answer, User, Node, Action
16 from forum import settings
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)
23 return HttpResponseForbidden()
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))
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(),
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_statistics():
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(),
156 def go_bootstrap(request):
157 #todo: this is the quick and dirty way of implementing a bootstrap mode
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)
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)
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_DOWNVOTED.set_value(1)
204 settings.REP_LOST_BY_DOWNVOTING.set_value(0)
205 settings.REP_GAIN_BY_ACCEPTED.set_value(25)
206 settings.REP_GAIN_BY_ACCEPTING.set_value(5)
207 settings.REP_LOST_BY_FLAGGED.set_value(2)
208 settings.REP_LOST_BY_FLAGGED_3_TIMES.set_value(30)
209 settings.REP_LOST_BY_FLAGGED_5_TIMES.set_value(100)
211 settings.SETTINGS_PACK.set_value("bootstrap")
213 request.user.message_set.create(message=_('Bootstrap mode enabled'))
214 return HttpResponseRedirect(reverse('admin_index'))
217 def go_defaults(request):
218 for setting in Setting.sets['badges']:
220 for setting in Setting.sets['minrep']:
222 for setting in Setting.sets['repgain']:
225 settings.SETTINGS_PACK.set_value("default")
227 request.user.message_set.create(message=_('All values reverted to defaults'))
228 return HttpResponseRedirect(reverse('admin_index'))
232 def recalculate_denormalized(request):
233 for n in Node.objects.all():
235 n.score = n.votes.aggregate(score=Sum('value'))['score']
236 if not n.score: n.score = 0
239 for u in User.objects.all():
240 u.reputation = u.reputes.aggregate(reputation=Sum('value'))['reputation']
243 request.user.message_set.create(message=_('All values recalculated'))
244 return HttpResponseRedirect(reverse('admin_index'))
247 def maintenance(request):
249 if 'close' in request.POST or 'adjust' in request.POST:
250 form = MaintenanceModeForm(request.POST)
253 settings.MAINTAINANCE_MODE.set_value({
254 'allow_ips': form.cleaned_data['ips'],
255 'message': form.cleaned_data['message']})
257 if 'close' in request.POST:
258 message = _('Maintenance mode enabled')
260 message = _('Settings adjusted')
262 request.user.message_set.create(message=message)
264 return HttpResponseRedirect(reverse('admin_maintenance'))
265 elif 'open' in request.POST:
266 settings.MAINTAINANCE_MODE.set_value(None)
267 request.user.message_set.create(message=_("Your site is now running normally"))
268 return HttpResponseRedirect(reverse('admin_maintenance'))
270 form = MaintenanceModeForm(initial={'ips': request.META['REMOTE_ADDR'],
271 'message': _('Currently down for maintenance. We\'ll be back soon')})
273 return ('osqaadmin/maintenance.html', {'form': form, 'in_maintenance': settings.MAINTAINANCE_MODE.value is not None})