From 63d22cdf6db0e3c638aceab16e82454e28f0d54a Mon Sep 17 00:00:00 2001 From: Danhia Date: Thu, 3 Feb 2022 18:37:24 +0100 Subject: [PATCH] added disabled attribute for challenge + fixed recomputescoreboard --- src/accounts/views/views.py | 11 +++---- src/ctfs/migrations/0007_ctf_disabled.py | 18 ++++++++++++ src/ctfs/models.py | 1 + src/ctfs/views.py | 6 ++-- src/home/views.py | 4 +-- .../commands/recompute_scoreboard.py | 29 ++++++++----------- 6 files changed, 42 insertions(+), 27 deletions(-) create mode 100644 src/ctfs/migrations/0007_ctf_disabled.py diff --git a/src/accounts/views/views.py b/src/accounts/views/views.py index 83e5854..806ad75 100644 --- a/src/accounts/views/views.py +++ b/src/accounts/views/views.py @@ -125,16 +125,17 @@ def profile(request, user_name): else: member = False all_cats = Category.objects.all() - cats = [cat for cat in all_cats if CTF.objects.filter(category__name=cat.name, event=None)] + cats = [cat for cat in all_cats if CTF.objects.filter(category__name=cat.name, event=None, disabled=False)] pointDatas = {} for cat in cats: # prepare categories - solved_count = CTF_flags.objects.filter(user=user_obj, ctf__event=None , ctf__category__name=cat.name).count() - max_count = CTF.objects.filter(category__name=cat.name, event=None).count() + solved = CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat.name, ctf__event=None, ctf__disabled=False).order_by('flag_date') + max_count = CTF.objects.filter(category__name=cat.name, event=None, disabled=False).count() # get datas somme = 0 - solved = CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat.name, ctf__event=None).order_by('flag_date') + solved_count = len(solved) + pointDatas[cat.name] = [] pointDatas[cat.name].append([user_obj.date_joined.timestamp() * 1000, 0]) percent = (solved_count / max_count) * 100 @@ -143,7 +144,7 @@ def profile(request, user_name): somme += flag.ctf.points pointDatas[cat.name].append([flag.flag_date.timestamp() * 1000, somme]) - solves = CTF_flags.objects.filter(user=user_obj, ctf__event=None).order_by('-flag_date') + solves = CTF_flags.objects.filter(user=user_obj, ctf__event=None, ctf__disabled=False).order_by('-flag_date') solved = [] somme = 0 solved.append([user_obj.date_joined.timestamp() * 1000, 0]) diff --git a/src/ctfs/migrations/0007_ctf_disabled.py b/src/ctfs/migrations/0007_ctf_disabled.py new file mode 100644 index 0000000..4d65a87 --- /dev/null +++ b/src/ctfs/migrations/0007_ctf_disabled.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.5 on 2022-02-03 17:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ctfs', '0006_alter_ctf_event'), + ] + + operations = [ + migrations.AddField( + model_name='ctf', + name='disabled', + field=models.BooleanField(default=False), + ), + ] diff --git a/src/ctfs/models.py b/src/ctfs/models.py index 6f49ca7..afec01c 100644 --- a/src/ctfs/models.py +++ b/src/ctfs/models.py @@ -12,6 +12,7 @@ class Category(models.Model): class CTF(models.Model): name = models.CharField(max_length=200) flag = models.CharField(max_length=100) + disabled = models.BooleanField(default=False) description = models.TextField(blank=True) description_en = models.TextField(blank=True) description_ru = models.TextField(blank=True) diff --git a/src/ctfs/views.py b/src/ctfs/views.py index a5de830..b7f1bc8 100644 --- a/src/ctfs/views.py +++ b/src/ctfs/views.py @@ -21,14 +21,14 @@ def get_description_by_lang(ctf): def category(request, cat_slug): cat = get_object_or_404(Category, slug=cat_slug) - ctfs = CTF.objects.filter(category=cat, event=None).order_by('points') + ctfs = CTF.objects.filter(category=cat, event=None, disabled=False).order_by('points') for ex in ctfs: ex.solved_num = CTF_flags.objects.filter(ctf=ex).count() ex.solved = ex.solved_by(request.user) return render(request, 'ctfs/ctfs_list.html', {'ctfs' : ctfs, 'cat' : cat}) def ctf(request, cat_slug, ctf_slug): - ctf_info = get_object_or_404(CTF, slug=ctf_slug) + ctf_info = get_object_or_404(CTF, slug=ctf_slug, event=None) flagged = False solved_list = CTF_flags.objects.filter(ctf=ctf_info).order_by('flag_date') description = get_description_by_lang(ctf_info) @@ -39,7 +39,7 @@ def ctf(request, cat_slug, ctf_slug): if request.user.is_authenticated: form = submit_flag(data=request.POST) if flagged == False and form.is_valid(): - if CTF.objects.filter(flag=request.POST.get('flag'), slug=ctf_slug): + if CTF.objects.filter(flag=request.POST.get('flag'), slug=ctf_slug, event=None): new = CTF_flags(user = request.user, ctf = ctf_info, flag_date = timezone.now()) new.save() profil = UserProfileInfo.objects.get(user=request.user) diff --git a/src/home/views.py b/src/home/views.py index 32c2444..eace7f2 100644 --- a/src/home/views.py +++ b/src/home/views.py @@ -27,7 +27,7 @@ def get_content_by_lang(news): def get_weekly_top(): week_ago = datetime.datetime.now() - datetime.timedelta(days=7) - weekly_flags = CTF_flags.objects.filter(flag_date__gt=week_ago) + weekly_flags = CTF_flags.objects.filter(flag_date__gt=week_ago, ctf__disabled=False, ctf__event=None) scores = defaultdict(int) for sol in weekly_flags: @@ -48,7 +48,7 @@ def home(request): response = HttpResponseRedirect(url_translated) return response news = new.objects.order_by('-pub_date')[:5] - latest_ctfs = CTF.objects.filter(event=None).order_by('-pub_date')[:5] + latest_ctfs = CTF.objects.filter(event=None, disabled=False).order_by('-pub_date')[:5] top10 = UserProfileInfo.objects.select_related().order_by('-score', 'last_submission_date', 'user__username')[:10] nb_flags = CTF_flags.objects.count() nb_users = UserProfileInfo.objects.count() diff --git a/src/scoreboard/management/commands/recompute_scoreboard.py b/src/scoreboard/management/commands/recompute_scoreboard.py index 3099143..380f472 100644 --- a/src/scoreboard/management/commands/recompute_scoreboard.py +++ b/src/scoreboard/management/commands/recompute_scoreboard.py @@ -1,31 +1,26 @@ from collections import defaultdict from django.core.management.base import BaseCommand, CommandError -from accounts import models as acc_models +from accounts.models import UserProfileInfo from ctfs import models as ex_models class Command(BaseCommand): - help = 'Recomputes the score and ranking caches from the solutions' + help = 'Recomputes the score cache from the solutions' def handle(self, *args, **options): - all_sols = ex_models.CTF_flags.objects.select_related().filter(ctf__event=None) + all_sols = ex_models.CTF_flags.objects.select_related().filter(ctf__event=None, ctf__disabled=False) + all_users = UserProfileInfo.objects.all() + scores = defaultdict(int) for sol in all_sols: scores[sol.user] += sol.ctf.points + + for u in all_users: + if u.user not in scores.keys(): + u.score = 0 + u.save() + li = [(s, u) for (u, s) in scores.items()] - li2 = [] - old_rank = None - old_score = None - rank = 0 - for (s, u) in li: - rank += 1 - if s == old_score: - li2.append((u, s, old_rank)) - else: - old_score = s - old_rank = rank - li2.append((u, s, rank)) - - for (u, s, r) in li2: + for (u, s) in li: u.userprofileinfo.score = s u.userprofileinfo.save()