From c5dedbfc2614c83a6b2d9448754c4602c2d81d6e Mon Sep 17 00:00:00 2001
From: ix <0x00fi@protonmail.com>
Date: Wed, 8 Sep 2021 03:59:35 +0200
Subject: [PATCH] Charts changed to highcharts
---
src/accounts/templates/accounts/profile.html | 335 +++++++++++++++----
src/accounts/templatetags/__init__.py | 0
src/accounts/templatetags/key_value.py | 11 +
src/accounts/views/views.py | 231 +++++++------
src/templates/base.html | 1 -
5 files changed, 396 insertions(+), 182 deletions(-)
create mode 100644 src/accounts/templatetags/__init__.py
create mode 100644 src/accounts/templatetags/key_value.py
diff --git a/src/accounts/templates/accounts/profile.html b/src/accounts/templates/accounts/profile.html
index fa00efd..9be17d5 100644
--- a/src/accounts/templates/accounts/profile.html
+++ b/src/accounts/templates/accounts/profile.html
@@ -1,6 +1,7 @@
{% extends 'base.html' %}
{% block content %}
{% load i18n %}
+{% load key_value %}
@@ -8,8 +9,8 @@
{% if solves%}
-
@@ -50,79 +51,273 @@
{% endif %}
{% trans "Member since" %} {{ user.date_joined|date:"Y-m-d" }}
-
-
-
-
- var pie_conf= {
- type: 'pie',
- data: {
- datasets: [{
- data: {{ globalDatas|safe }},
- backgroundColor: [
- '#696969', '#808080', '#A9A9A9', '#C0C0C0', '#D3D3D3'
- ],
- label: 'Solved by category'
- }],
- labels: {{ globalLabels|safe }}
- },
- options: {
- legend: {display: false},
- responsive: true
- }
- };
- var time_conf = {
- type: 'line',
- data: {
- datasets: [{
- data: {{ timeDatas|safe }},
- fill: false,
- borderColor: 'rgb(75, 192, 192)',
- pointBackgroundColor: '#fff',
- pointBorderColor: '#fff',
- tension: 0.1,
- label: 'Challenge solved'
- }, {
- }],
- labels: {{ timeLabels|safe }}
+
+ {% for cat in cats %}
+ {
+ name: '{{ cat.name }}',
+ data: {{ pointDatas|keyvalue:cat.name|safe }},
+ visible: false,
+ },
+ {% endfor %}
+ ],
+ responsive: {
+ rules: [{
+ condition: {
+ maxWidth: 500
+ },
+ chartOptions: {
+ legend: {
+ layout: 'horizontal',
+ align: 'center',
+ verticalAlign: 'bottom'
+ }
+ }
+ }]
+ }
+ });
+
{% endblock %}
diff --git a/src/accounts/templatetags/__init__.py b/src/accounts/templatetags/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/accounts/templatetags/key_value.py b/src/accounts/templatetags/key_value.py
new file mode 100644
index 0000000..3594c8b
--- /dev/null
+++ b/src/accounts/templatetags/key_value.py
@@ -0,0 +1,11 @@
+from django import template
+
+register = template.Library()
+
+@register.filter
+def keyvalue(dict, key):
+ return dict[key]
+
+@register.filter
+def timestamp_fromdate(date):
+ return str(date.timestamp() * 1000).replace(',','.')
\ No newline at end of file
diff --git a/src/accounts/views/views.py b/src/accounts/views/views.py
index c6f04b4..125c8c5 100644
--- a/src/accounts/views/views.py
+++ b/src/accounts/views/views.py
@@ -18,130 +18,139 @@ from accounts.models import UserProfileInfo
from . import connection
def signin(request):
- if not request.user.is_authenticated:
- if request.method == 'POST':
- username = request.POST.get('username')
- password = request.POST.get('password')
- user = authenticate(username=username, password=password)
- if user:
- if user.is_active:
- login(request,user)
- return HttpResponseRedirect(reverse('home'))
- else:
- return HttpResponse(_("Your account was inactive."))
- else:
- return render(request, 'accounts/login.html', {'error': True})
- else:
- return render(request, 'accounts/login.html', {})
- else:
- return HttpResponseRedirect(reverse('home'))
+ if not request.user.is_authenticated:
+ if request.method == 'POST':
+ username = request.POST.get('username')
+ password = request.POST.get('password')
+ user = authenticate(username=username, password=password)
+ if user:
+ if user.is_active:
+ login(request,user)
+ return HttpResponseRedirect(reverse('home'))
+ else:
+ return HttpResponse(_("Your account was inactive."))
+ else:
+ return render(request, 'accounts/login.html', {'error': True})
+ else:
+ return render(request, 'accounts/login.html', {})
+ else:
+ return HttpResponseRedirect(reverse('home'))
def signup(request):
- if not request.user.is_authenticated:
- user_form = UserForm()
- profile_form = UserProfileInfoForm()
- registered = False
- if request.method == 'POST':
- pass1 = request.POST.get('password')
- if len(pass1) < 8:
- return render(request,'accounts/register.html', {'user_form':user_form, 'profile_form':profile_form, 'registered_failed':"The new password must be at least %d characters long." % 8})
- first_isalpha = pass1[0].isalpha()
- if not any(c.isdigit() for c in pass1) or not any(c.isalpha() for c in pass1):
- return render(request,'accounts/register.html', {'user_form':user_form, 'profile_form':profile_form, 'registered_failed':_("The password must contain at least one letter and at least one digit or punctuation character.")})
- if User.objects.filter(email=request.POST.get('email')).exists():
- return render(request,'accounts/register.html', {'user_form':user_form, 'profile_form':profile_form, 'registered_failed':_("A user with that email already exists.")})
- user_form = UserForm(data=request.POST)
- profile_form = UserProfileInfoForm(data=request.POST)
- if user_form.is_valid() and profile_form.is_valid():
- user = user_form.save()
- user.set_password(user.password)
- user.save()
- profile = profile_form.save(commit=False)
- profile.user = user
- profile.token = token_hex(16)
- profile.save()
- registered = True
- else:
- return render(request,'accounts/register.html', {'user_form':user_form, 'profile_form':profile_form, 'registered_failed':_("A user with that username already exists.")})
- return render(request,'accounts/register.html',
- {'user_form':user_form,
- 'profile_form':profile_form,
- 'registered':registered})
- else:
- return HttpResponseRedirect(reverse('home'))
+ if not request.user.is_authenticated:
+ user_form = UserForm()
+ profile_form = UserProfileInfoForm()
+ registered = False
+ if request.method == 'POST':
+ pass1 = request.POST.get('password')
+ if len(pass1) < 8:
+ return render(request,'accounts/register.html', {'user_form':user_form, 'profile_form':profile_form, 'registered_failed':"The new password must be at least %d characters long." % 8})
+ first_isalpha = pass1[0].isalpha()
+ if not any(c.isdigit() for c in pass1) or not any(c.isalpha() for c in pass1):
+ return render(request,'accounts/register.html', {'user_form':user_form, 'profile_form':profile_form, 'registered_failed':_("The password must contain at least one letter and at least one digit or punctuation character.")})
+ if User.objects.filter(email=request.POST.get('email')).exists():
+ return render(request,'accounts/register.html', {'user_form':user_form, 'profile_form':profile_form, 'registered_failed':_("A user with that email already exists.")})
+ user_form = UserForm(data=request.POST)
+ profile_form = UserProfileInfoForm(data=request.POST)
+ if user_form.is_valid() and profile_form.is_valid():
+ user = user_form.save()
+ user.set_password(user.password)
+ user.save()
+ profile = profile_form.save(commit=False)
+ profile.user = user
+ profile.token = token_hex(16)
+ profile.save()
+ registered = True
+ else:
+ return render(request,'accounts/register.html', {'user_form':user_form, 'profile_form':profile_form, 'registered_failed':_("A user with that username already exists.")})
+ return render(request,'accounts/register.html',
+ {'user_form':user_form,
+ 'profile_form':profile_form,
+ 'registered':registered})
+ else:
+ return HttpResponseRedirect(reverse('home'))
@login_required
def out(request):
- logout(request)
- return HttpResponseRedirect(reverse('home'))
+ logout(request)
+ return HttpResponseRedirect(reverse('home'))
@login_required
def edit(request):
- if request.method == 'POST':
- umail = request.user.email
- uuser = request.user.username
- p_form = UserInfosUpdateForm(request.POST, instance=request.user.userprofileinfo)
- u_form = UserUpdateForm(request.POST, instance=request.user)
- error = None
- success = None
- if p_form.is_valid() and u_form.is_valid():
- pmail = u_form.cleaned_data['email']
- if pmail == umail:
- pass
- else:
- if User.objects.filter(email=pmail).exists():
- error = _("Email already taken.")
- puser = u_form.cleaned_data['username']
- if puser == uuser:
- pass
- else:
- if User.objects.filter(username=puser).exists():
- error = _("Username already taken.")
- if error is None:
- u_form.save()
- p_form.save()
- success = _("Updated.")
- request.user.username = uuser
-
- context={'p_form': p_form, 'u_form': u_form, 'error':error, 'success' : success}
- return render(request, 'accounts/edit.html', context)
- else:
- p_form = UserInfosUpdateForm(instance=request.user.userprofileinfo)
- u_form = UserUpdateForm(instance=request.user)
- context={'p_form': p_form, 'u_form': u_form, 'token': request.user.userprofileinfo.token}
- return render(request, 'accounts/edit.html',context )
+ if request.method == 'POST':
+ umail = request.user.email
+ uuser = request.user.username
+ p_form = UserInfosUpdateForm(request.POST, instance=request.user.userprofileinfo)
+ u_form = UserUpdateForm(request.POST, instance=request.user)
+ error = None
+ success = None
+ if p_form.is_valid() and u_form.is_valid():
+ pmail = u_form.cleaned_data['email']
+ if pmail == umail:
+ pass
+ else:
+ if User.objects.filter(email=pmail).exists():
+ error = _("Email already taken.")
+ puser = u_form.cleaned_data['username']
+ if puser == uuser:
+ pass
+ else:
+ if User.objects.filter(username=puser).exists():
+ error = _("Username already taken.")
+ if error is None:
+ u_form.save()
+ p_form.save()
+ success = _("Updated.")
+ request.user.username = uuser
+
+ context={'p_form': p_form, 'u_form': u_form, 'error':error, 'success' : success}
+ return render(request, 'accounts/edit.html', context)
+ else:
+ p_form = UserInfosUpdateForm(instance=request.user.userprofileinfo)
+ u_form = UserUpdateForm(instance=request.user)
+ context={'p_form': p_form, 'u_form': u_form, 'token': request.user.userprofileinfo.token}
+ return render(request, 'accounts/edit.html',context )
@login_required
def profile(request, user_name):
- globalLabels= []
- globalDatas = []
- timeLabels = []
- timeDatas= []
+ globalLabels= []
+ globalDatas = []
- user_obj = get_object_or_404(User, username=user_name)
- cats = Category.objects.all()
- for cat in cats:
- globalLabels.append(cat.name)
- solved_count = CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat).order_by('-flag_date').count()
- globalDatas.append(solved_count)
+ user_obj = get_object_or_404(User, username=user_name)
+ cats = Category.objects.all()
+ pointDatas = {}
- solves = CTF_flags.objects.filter(user=user_obj).order_by('flag_date')
- somme = 0
- for flag in solves:
- timeLabels.append(flag.flag_date.strftime('%Y-%m-%d'))
- somme += flag.ctf.points
- timeDatas.append(somme)
- solves = CTF_flags.objects.filter(user=user_obj).order_by('-flag_date')
- return render(request,'accounts/profile.html', {'user':user_obj, 'solves':solves,'globalLabels': globalLabels, 'globalDatas': globalDatas, 'timeLabels': timeLabels, 'timeDatas': timeDatas})
+ for cat in cats:
+ # prepare categories
+ globalLabels.append(cat.name)
+ solved_count = CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat.name).order_by('-flag_date').count()
+ globalDatas.append(solved_count)
+ # get datas
+ somme = 0
+ solved = CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat.name).order_by('flag_date')
+ pointDatas[cat.name] = []
+ pointDatas[cat.name].append([user_obj.date_joined.timestamp() * 1000, 0])
+ for flag in solved:
+ somme += flag.ctf.points
+ pointDatas[cat.name].append([flag.flag_date.timestamp() * 1000, somme])
+
+ solves = CTF_flags.objects.filter(user=user_obj).order_by('-flag_date')
+ solved = []
+ somme = 0
+ solved.append([user_obj.date_joined.timestamp() * 1000, 0])
+ for s in solves.reverse():
+ somme += s.ctf.points
+ solved.append([s.flag_date.timestamp() * 1000,somme])
+ return render(request,'accounts/profile.html', {'user':user_obj, 'solves':solves,'solved':solved,'globalLabels': globalLabels, 'globalDatas': globalDatas, 'pointDatas': pointDatas})
# Create your views here.
def rank(request, token):
- all_users = UserProfileInfo.objects.filter(score__gt=0).select_related().order_by('-score', 'last_submission_date', 'user__username')
-
- rank = 1
- for elem in all_users:
- if elem.token == token:
- break
- rank += 1
- data = {"rank": rank}
- return JsonResponse(data)
+ all_users = UserProfileInfo.objects.filter(score__gt=0).select_related().order_by('-score', 'last_submission_date', 'user__username')
+
+ rank = 1
+ for elem in all_users:
+ if elem.token == token:
+ break
+ rank += 1
+ data = {"rank": rank}
+ return JsonResponse(data)
diff --git a/src/templates/base.html b/src/templates/base.html
index 2db024b..b9b5012 100644
--- a/src/templates/base.html
+++ b/src/templates/base.html
@@ -106,7 +106,6 @@
-