1 from datetime import datetime, timedelta
 
   4 from django.shortcuts import render_to_response, get_object_or_404
 
   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.forms import MaintenanceModeForm, PageForm
 
  13 from forum.settings.forms import SettingsSetForm
 
  15 from forum.models import Question, Answer, User, Node, Action, Page
 
  16 from forum.actions import NewPageAction, EditPageAction, PublishAction
 
  17 from forum import settings
 
  19 def super_user_required(fn):
 
  20     def wrapper(request, *args, **kwargs):
 
  21         if request.user.is_authenticated() and request.user.is_superuser:
 
  22             return fn(request, *args, **kwargs)
 
  24             return HttpResponseForbidden()
 
  30     def wrapper(request, *args, **kwargs):
 
  31         res = fn(request, *args, **kwargs)
 
  32         if isinstance(res, tuple):
 
  33             template, context = res
 
  34             context['basetemplate'] = settings.DJSTYLE_ADMIN_INTERFACE and "osqaadmin/djstyle_base.html" or "osqaadmin/base.html"
 
  35             context['allsets'] = Setting.sets
 
  36             context['othersets'] = sorted(
 
  37                     [s for s in Setting.sets.values() if not s.name in
 
  38                     ('basic', 'users', 'email', 'paths', 'extkeys', 'repgain', 'minrep', 'voting', 'badges', 'about', 'faq', 'sidebar',
 
  39                     'form', 'moderation', 'css', 'headandfoot', 'head')]
 
  40                     , lambda s1, s2: s1.weight - s2.weight)
 
  42             unsaved = request.session.get('previewing_settings', {})
 
  43             context['unsaved'] = set([getattr(settings, s).set.name for s in unsaved.keys() if hasattr(settings, s)])
 
  45             return render_to_response(template, context, context_instance=RequestContext(request))
 
  52 def dashboard(request):
 
  53     return ('osqaadmin/dashboard.html', {
 
  54     'settings_pack': unicode(settings.SETTINGS_PACK),
 
  55     'statistics': get_statistics(),
 
  56     'recent_activity': get_recent_activity(),
 
  57     'flagged_posts': get_flagged_posts(),
 
  61 def interface_switch(request):
 
  62     if request.GET and request.GET.get('to', None) and request.GET['to'] in ('default', 'djstyle'):
 
  63         settings.DJSTYLE_ADMIN_INTERFACE.set_value(request.GET['to'] == 'djstyle')
 
  65     return HttpResponseRedirect(reverse('admin_index'))
 
  68 def statistics(request):
 
  69     today = datetime.now()
 
  70     last_month = today - timedelta(days=30)
 
  72     last_month_questions = Question.objects.filter_state(deleted=False).filter(added_at__gt=last_month
 
  73                                                                                ).order_by('added_at').values_list(
 
  74             'added_at', flat=True)
 
  76     last_month_n_questions = Question.objects.filter_state(deleted=False).filter(added_at__lt=last_month).count()
 
  77     qgraph_data = simplejson.dumps([
 
  78     (time.mktime(d.timetuple()) * 1000, i + last_month_n_questions)
 
  79     for i, d in enumerate(last_month_questions)
 
  82     last_month_users = User.objects.filter(date_joined__gt=last_month
 
  83                                            ).order_by('date_joined').values_list('date_joined', flat=True)
 
  85     last_month_n_users = User.objects.filter(date_joined__lt=last_month).count()
 
  87     ugraph_data = simplejson.dumps([
 
  88     (time.mktime(d.timetuple()) * 1000, i + last_month_n_users)
 
  89     for i, d in enumerate(last_month_users)
 
  92     return 'osqaadmin/statistics.html', {
 
  95             'id': 'questions_graph',
 
  96             'caption': _("Questions Graph"),
 
 100             'caption': _("Users Graph"),
 
 108 def settings_set(request, set_name):
 
 109     set = Setting.sets.get(set_name, {})
 
 110     current_preview = request.session.get('previewing_settings', {})
 
 116         form = SettingsSetForm(set, data=request.POST, files=request.FILES)
 
 119             if 'preview' in request.POST:
 
 120                 current_preview.update(form.cleaned_data)
 
 121                 request.session['previewing_settings'] = current_preview
 
 123                 return HttpResponseRedirect(reverse('index'))
 
 126                     current_preview.pop(s.name, None)
 
 128                 request.session['previewing_settings'] = current_preview
 
 130                 if not 'reset' in request.POST:
 
 132                     request.user.message_set.create(message=_("'%s' settings saved succesfully") % set_name)
 
 134                     if set_name in ('minrep', 'badges', 'repgain'):
 
 135                         settings.SETTINGS_PACK.set_value("custom")
 
 137                 return HttpResponseRedirect(reverse('admin_set', args=[set_name]))
 
 139         form = SettingsSetForm(set, unsaved=current_preview)
 
 141     return 'osqaadmin/set.html', {
 
 143     'markdown': set.markdown,
 
 147 def get_default(request, set_name, var_name):
 
 148     set = Setting.sets.get(set_name, None)
 
 149     if set is None: raise Http404
 
 151     setting = dict([(s.name, s) for s in set]).get(var_name, None)
 
 152     if setting is None: raise Http404
 
 156     if request.is_ajax():
 
 157         return HttpResponse(setting.default)
 
 159         return HttpResponseRedirect(reverse('admin_set', kwargs={'set_name': set_name}))
 
 162 def get_recent_activity():
 
 163     return Action.objects.order_by('-action_date')[0:30]
 
 165 def get_flagged_posts():
 
 166     return Action.objects.filter(canceled=False, action_type="flag").order_by('-action_date')[0:30]
 
 168 def get_statistics():
 
 170     'total_users': User.objects.all().count(),
 
 171     'users_last_24': User.objects.filter(date_joined__gt=(datetime.now() - timedelta(days=1))).count(),
 
 172     'total_questions': Question.objects.filter_state(deleted=False).count(),
 
 173     'questions_last_24': Question.objects.filter_state(deleted=False).filter(
 
 174             added_at__gt=(datetime.now() - timedelta(days=1))).count(),
 
 175     'total_answers': Answer.objects.filter_state(deleted=False).count(),
 
 176     'answers_last_24': Answer.objects.filter_state(deleted=False).filter(
 
 177             added_at__gt=(datetime.now() - timedelta(days=1))).count(),
 
 181 def go_bootstrap(request):
 
 182 #todo: this is the quick and dirty way of implementing a bootstrap mode
 
 184         from forum_modules.default_badges import settings as dbsets
 
 185         dbsets.POPULAR_QUESTION_VIEWS.set_value(100)
 
 186         dbsets.NOTABLE_QUESTION_VIEWS.set_value(200)
 
 187         dbsets.FAMOUS_QUESTION_VIEWS.set_value(300)
 
 188         dbsets.NICE_ANSWER_VOTES_UP.set_value(2)
 
 189         dbsets.NICE_QUESTION_VOTES_UP.set_value(2)
 
 190         dbsets.GOOD_ANSWER_VOTES_UP.set_value(4)
 
 191         dbsets.GOOD_QUESTION_VOTES_UP.set_value(4)
 
 192         dbsets.GREAT_ANSWER_VOTES_UP.set_value(8)
 
 193         dbsets.GREAT_QUESTION_VOTES_UP.set_value(8)
 
 194         dbsets.FAVORITE_QUESTION_FAVS.set_value(1)
 
 195         dbsets.STELLAR_QUESTION_FAVS.set_value(3)
 
 196         dbsets.DISCIPLINED_MIN_SCORE.set_value(3)
 
 197         dbsets.PEER_PRESSURE_MAX_SCORE.set_value(-3)
 
 198         dbsets.CIVIC_DUTY_VOTES.set_value(15)
 
 199         dbsets.PUNDIT_COMMENT_COUNT.set_value(10)
 
 200         dbsets.SELF_LEARNER_UP_VOTES.set_value(2)
 
 201         dbsets.STRUNK_AND_WHITE_EDITS.set_value(10)
 
 202         dbsets.ENLIGHTENED_UP_VOTES.set_value(2)
 
 203         dbsets.GURU_UP_VOTES.set_value(4)
 
 204         dbsets.NECROMANCER_UP_VOTES.set_value(2)
 
 205         dbsets.NECROMANCER_DIF_DAYS.set_value(30)
 
 206         dbsets.TAXONOMIST_USE_COUNT.set_value(5)
 
 210     settings.REP_TO_VOTE_UP.set_value(0)
 
 211     settings.REP_TO_VOTE_DOWN.set_value(15)
 
 212     settings.REP_TO_FLAG.set_value(15)
 
 213     settings.REP_TO_COMMENT.set_value(0)
 
 214     settings.REP_TO_LIKE_COMMENT.set_value(0)
 
 215     settings.REP_TO_UPLOAD.set_value(0)
 
 216     settings.REP_TO_CREATE_TAGS.set_value(0)
 
 217     settings.REP_TO_CLOSE_OWN.set_value(60)
 
 218     settings.REP_TO_REOPEN_OWN.set_value(120)
 
 219     settings.REP_TO_RETAG.set_value(150)
 
 220     settings.REP_TO_EDIT_WIKI.set_value(200)
 
 221     settings.REP_TO_EDIT_OTHERS.set_value(400)
 
 222     settings.REP_TO_CLOSE_OTHERS.set_value(600)
 
 223     settings.REP_TO_DELETE_COMMENTS.set_value(400)
 
 224     settings.REP_TO_VIEW_FLAGS.set_value(30)
 
 226     settings.INITIAL_REP.set_value(1)
 
 227     settings.MAX_REP_BY_UPVOTE_DAY.set_value(300)
 
 228     settings.REP_GAIN_BY_UPVOTED.set_value(15)
 
 229     settings.REP_LOST_BY_DOWNVOTED.set_value(1)
 
 230     settings.REP_LOST_BY_DOWNVOTING.set_value(0)
 
 231     settings.REP_GAIN_BY_ACCEPTED.set_value(25)
 
 232     settings.REP_GAIN_BY_ACCEPTING.set_value(5)
 
 233     settings.REP_LOST_BY_FLAGGED.set_value(2)
 
 234     settings.REP_LOST_BY_FLAGGED_3_TIMES.set_value(30)
 
 235     settings.REP_LOST_BY_FLAGGED_5_TIMES.set_value(100)
 
 237     settings.SETTINGS_PACK.set_value("bootstrap")
 
 239     request.user.message_set.create(message=_('Bootstrap mode enabled'))
 
 240     return HttpResponseRedirect(reverse('admin_index'))
 
 243 def go_defaults(request):
 
 244     for setting in Setting.sets['badges']:
 
 246     for setting in Setting.sets['minrep']:
 
 248     for setting in Setting.sets['repgain']:
 
 251     settings.SETTINGS_PACK.set_value("default")
 
 253     request.user.message_set.create(message=_('All values reverted to defaults'))
 
 254     return HttpResponseRedirect(reverse('admin_index'))
 
 258 def recalculate_denormalized(request):
 
 259     for n in Node.objects.all():
 
 261         n.score = n.votes.aggregate(score=Sum('value'))['score']
 
 262         if not n.score: n.score = 0
 
 265     for u in User.objects.all():
 
 266         u.reputation = u.reputes.aggregate(reputation=Sum('value'))['reputation']
 
 269     request.user.message_set.create(message=_('All values recalculated'))
 
 270     return HttpResponseRedirect(reverse('admin_index'))
 
 273 def maintenance(request):
 
 275         if 'close' in request.POST or 'adjust' in request.POST:
 
 276             form = MaintenanceModeForm(request.POST)
 
 279                 settings.MAINTAINANCE_MODE.set_value({
 
 280                 'allow_ips': form.cleaned_data['ips'],
 
 281                 'message': form.cleaned_data['message']})
 
 283                 if 'close' in request.POST:
 
 284                     message = _('Maintenance mode enabled')
 
 286                     message = _('Settings adjusted')
 
 288                 request.user.message_set.create(message=message)
 
 290                 return HttpResponseRedirect(reverse('admin_maintenance'))
 
 291         elif 'open' in request.POST:
 
 292             settings.MAINTAINANCE_MODE.set_value(None)
 
 293             request.user.message_set.create(message=_("Your site is now running normally"))
 
 294             return HttpResponseRedirect(reverse('admin_maintenance'))
 
 296         form = MaintenanceModeForm(initial={'ips': request.META['REMOTE_ADDR'],
 
 297                                             'message': _('Currently down for maintenance. We\'ll be back soon')})
 
 299     return ('osqaadmin/maintenance.html', {'form': form, 'in_maintenance': settings.MAINTAINANCE_MODE.value is not None
 
 304 def flagged_posts(request):
 
 305     return ('osqaadmin/flagged_posts.html', {
 
 306     'flagged_posts': get_flagged_posts(),
 
 310 def static_pages(request):
 
 311     pages = Page.objects.all()
 
 313     return ('osqaadmin/static_pages.html', {
 
 318 def edit_page(request, id=None):
 
 320         page = get_object_or_404(Page, id=id)
 
 325         form = PageForm(page, request.POST)
 
 328             if form.has_changed():
 
 330                     page = NewPageAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(data=form.cleaned_data
 
 333                     EditPageAction(user=request.user, node=page, ip=request.META['REMOTE_ADDR']).save(
 
 334                             data=form.cleaned_data)
 
 336             if ('publish' in request.POST) and (not page.published):
 
 337                 PublishAction(user=request.user, node=page, ip=request.META['REMOTE_ADDR']).save()
 
 338             elif ('unpublish' in request.POST) and page.published:
 
 339                 page.nstate.published.cancel(ip=request.META['REMOTE_ADDR'])
 
 341             return HttpResponseRedirect(reverse('admin_edit_page', kwargs={'id': page.id}))
 
 344         form = PageForm(page)
 
 347         published = page.published
 
 351     return ('osqaadmin/edit_page.html', {
 
 354     'published': published