Categories stats added, css modified, fix responsive display of profile page

This commit is contained in:
ix 2021-09-08 16:53:00 +02:00
parent 8a203161ed
commit 0f92cf3da1
5 changed files with 56 additions and 206 deletions

View File

@ -4,6 +4,32 @@
{% load key_value %} {% load key_value %}
<div class="row"> <div class="row">
<div class="col-sm-12 col-md-9"> <div class="col-sm-12 col-md-9">
<div class="d-block d-md-none right-sidebar">
<ul class="list-group">
<li class="list-group-item">{{ user.username }}</li>
<li class="list-group-item">{% trans "Score" %} : {{ user.userprofileinfo.score }}</li>
{% if user.userprofileinfo.portfolio_site %}
<li class="list-group-item">
<a href="{{ user.userprofileinfo.portfolio_site }}" target="_blank">
{{ user.userprofileinfo.portfolio_site }}
</a>
</li>
{% endif %}
<li class="list-group-item">{% trans "Member since" %} {{ user.date_joined|date:"Y-m-d" }}</li>
</ul>
<ul class="list-group">
<li class="list-group-item">{% trans "Categories stats" %}</li>
{% for cat in catsDatas %}
<li class="list-group-item" style="padding-bottom: 3;padding-top: 0;">
<span>{{ cat.0 }}</span>
<div class="progress">
<div class="progress-bar bg-success" role="progressbar" style="width: {{ cat.3 }}%" aria-valuenow="{{ cat.3 }}" aria-valuemin="0" aria-valuemax="100">{{ cat.3 }} %</div>
</div>
</li>
{% endfor %}
</ul>
</div>
<div> <div>
<h4>Challenges Solved by {{ user.username }}</h4> <h4>Challenges Solved by {{ user.username }}</h4>
{% if solves%} {% if solves%}
@ -51,206 +77,25 @@
{% endif %} {% endif %}
<li class="list-group-item">{% trans "Member since" %} {{ user.date_joined|date:"Y-m-d" }}</li> <li class="list-group-item">{% trans "Member since" %} {{ user.date_joined|date:"Y-m-d" }}</li>
</ul> </ul>
<ul class="list-group">
<li class="list-group-item">{% trans "Categories stats" %}</li>
{% for cat in catsDatas %}
<li class="list-group-item" style="padding-bottom: 3;padding-top: 0;">
<span>{{ cat.0 }}</span>
<div class="progress">
<div class="progress-bar bg-success" role="progressbar" style="width: {{ cat.3 }}%" aria-valuenow="{{ cat.3 }}" aria-valuemin="0" aria-valuemax="100">{{ cat.3 }} %</div>
</div>
</li>
{% endfor %}
</ul>
</div> </div>
</div> </div>
<script src="https://code.highcharts.com/highcharts.src.js"></script> <script src="https://code.highcharts.com/highcharts.src.js"></script>
<script> <script>
Highcharts.theme = { Highcharts.theme={colors:["#2b908f","#90ee7e","#f45b5b","#7798BF","#aaeeee","#ff0066","#eeaaee","#55BF3B","#DF5353","#7798BF","#aaeeee"],chart:{backgroundColor:{linearGradient:{x1:0,y1:0,x2:1,y2:1},stops:[[0,"#1D1D1D"],[1,"#1D1D1D"]]},style:{fontFamily:"'Unica One', sans-serif"},plotBorderColor:"#606063"},title:{style:{color:"#E0E0E3",textTransform:"uppercase",fontSize:"20px"}},subtitle:{style:{color:"#E0E0E3",textTransform:"uppercase"}},xAxis:{gridLineColor:"#707073",labels:{style:{color:"#E0E0E3"}},lineColor:"#707073",minorGridLineColor:"#505053",tickColor:"#707073",title:{style:{color:"#A0A0A3"}}},yAxis:{gridLineColor:"#707073",labels:{style:{color:"#E0E0E3"}},lineColor:"#707073",minorGridLineColor:"#505053",tickColor:"#707073",tickWidth:1,title:{style:{color:"#A0A0A3"}}},tooltip:{backgroundColor:"rgba(0, 0, 0, 0.85)",style:{color:"#F0F0F0"}},plotOptions:{series:{dataLabels:{color:"#F0F0F3",style:{fontSize:"13px"}},marker:{lineColor:"#333"}},boxplot:{fillColor:"#505053"},candlestick:{lineColor:"white"},errorbar:{color:"white"}},legend:{backgroundColor:"#1D1D1D",itemStyle:{color:"#E0E0E3"},itemHoverStyle:{color:"#FFF"},itemHiddenStyle:{color:"#606063"},title:{style:{color:"#C0C0C0"}}},credits:{style:{color:"#666"}},labels:{style:{color:"#707073"}},drilldown:{activeAxisLabelStyle:{color:"#F0F0F3"},activeDataLabelStyle:{color:"#F0F0F3"}},navigation:{buttonOptions:{symbolStroke:"#DDDDDD",theme:{fill:"#505053"}}},rangeSelector:{buttonTheme:{fill:"#505053",stroke:"#000000",style:{color:"#CCC"},states:{hover:{fill:"#707073",stroke:"#000000",style:{color:"white"}},select:{fill:"#000003",stroke:"#000000",style:{color:"white"}}}},inputBoxBorderColor:"#505053",inputStyle:{backgroundColor:"#333",color:"silver"},labelStyle:{color:"silver"}},navigator:{handles:{backgroundColor:"#666",borderColor:"#AAA"},outlineColor:"#CCC",maskFill:"rgba(255,255,255,0.1)",series:{color:"#7798BF",lineColor:"#A6C7ED"},xAxis:{gridLineColor:"#505053"}},scrollbar:{barBackgroundColor:"#808083",barBorderColor:"#808083",buttonArrowColor:"#CCC",buttonBackgroundColor:"#606063",buttonBorderColor:"#606063",rifleColor:"#FFF",trackBackgroundColor:"#404043",trackBorderColor:"#404043"}};
colors: ['#2b908f', '#90ee7e', '#f45b5b', '#7798BF', '#aaeeee', '#ff0066',
'#eeaaee', '#55BF3B', '#DF5353', '#7798BF', '#aaeeee'],
chart: {
backgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 },
stops: [
[0, '#1D1D1D'],
[1, '#1D1D1D']
]
},
style: {
fontFamily: '\'Unica One\', sans-serif'
},
plotBorderColor: '#606063'
},
title: {
style: {
color: '#E0E0E3',
textTransform: 'uppercase',
fontSize: '20px'
}
},
subtitle: {
style: {
color: '#E0E0E3',
textTransform: 'uppercase'
}
},
xAxis: {
gridLineColor: '#707073',
labels: {
style: {
color: '#E0E0E3'
}
},
lineColor: '#707073',
minorGridLineColor: '#505053',
tickColor: '#707073',
title: {
style: {
color: '#A0A0A3'
}
}
},
yAxis: {
gridLineColor: '#707073',
labels: {
style: {
color: '#E0E0E3'
}
},
lineColor: '#707073',
minorGridLineColor: '#505053',
tickColor: '#707073',
tickWidth: 1,
title: {
style: {
color: '#A0A0A3'
}
}
},
tooltip: {
backgroundColor: 'rgba(0, 0, 0, 0.85)',
style: {
color: '#F0F0F0'
}
},
plotOptions: {
series: {
dataLabels: {
color: '#F0F0F3',
style: {
fontSize: '13px'
}
},
marker: {
lineColor: '#333'
}
},
boxplot: {
fillColor: '#505053'
},
candlestick: {
lineColor: 'white'
},
errorbar: {
color: 'white'
}
},
legend: {
backgroundColor: '#1D1D1D',
itemStyle: {
color: '#E0E0E3'
},
itemHoverStyle: {
color: '#FFF'
},
itemHiddenStyle: {
color: '#606063'
},
title: {
style: {
color: '#C0C0C0'
}
}
},
credits: {
style: {
color: '#666'
}
},
labels: {
style: {
color: '#707073'
}
},
drilldown: {
activeAxisLabelStyle: {
color: '#F0F0F3'
},
activeDataLabelStyle: {
color: '#F0F0F3'
}
},
navigation: {
buttonOptions: {
symbolStroke: '#DDDDDD',
theme: {
fill: '#505053'
}
}
},
// scroll charts
rangeSelector: {
buttonTheme: {
fill: '#505053',
stroke: '#000000',
style: {
color: '#CCC'
},
states: {
hover: {
fill: '#707073',
stroke: '#000000',
style: {
color: 'white'
}
},
select: {
fill: '#000003',
stroke: '#000000',
style: {
color: 'white'
}
}
}
},
inputBoxBorderColor: '#505053',
inputStyle: {
backgroundColor: '#333',
color: 'silver'
},
labelStyle: {
color: 'silver'
}
},
navigator: {
handles: {
backgroundColor: '#666',
borderColor: '#AAA'
},
outlineColor: '#CCC',
maskFill: 'rgba(255,255,255,0.1)',
series: {
color: '#7798BF',
lineColor: '#A6C7ED'
},
xAxis: {
gridLineColor: '#505053'
}
},
scrollbar: {
barBackgroundColor: '#808083',
barBorderColor: '#808083',
buttonArrowColor: '#CCC',
buttonBackgroundColor: '#606063',
buttonBorderColor: '#606063',
rifleColor: '#FFF',
trackBackgroundColor: '#404043',
trackBorderColor: '#404043'
}
};
// Apply the theme
Highcharts.setOptions(Highcharts.theme); Highcharts.setOptions(Highcharts.theme);
Highcharts.chart('time-chart', { Highcharts.chart('time-chart', {
@ -264,8 +109,6 @@
}, },
xAxis: { xAxis: {
type: 'datetime', type: 'datetime',
// Use the date format in the
// labels property of the chart
labels: { labels: {
formatter: function() { formatter: function() {
return Highcharts.dateFormat('%d.%b %Y', return Highcharts.dateFormat('%d.%b %Y',

View File

@ -2,7 +2,7 @@ from django.shortcuts import render, redirect, get_object_or_404
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django import forms from django import forms
from ctfs.models import Category, CTF_flags from ctfs.models import Category, CTF_flags, CTF
from ..forms import UserForm,UserProfileInfoForm, UserInfosUpdateForm, UserUpdateForm from ..forms import UserForm,UserProfileInfoForm, UserInfosUpdateForm, UserUpdateForm
from django.contrib.auth import authenticate, login, logout from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User from django.contrib.auth.models import User
@ -113,8 +113,7 @@ def edit(request):
@login_required @login_required
def profile(request, user_name): def profile(request, user_name):
globalLabels= [] catsDatas = []
globalDatas = []
user_obj = get_object_or_404(User, username=user_name) user_obj = get_object_or_404(User, username=user_name)
cats = Category.objects.all() cats = Category.objects.all()
@ -122,14 +121,15 @@ def profile(request, user_name):
for cat in cats: for cat in cats:
# prepare categories # prepare categories
globalLabels.append(cat.name) solved_count = CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat.name).count()
solved_count = CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat.name).order_by('-flag_date').count() max_count = CTF.objects.filter(category__name=cat.name).count()
globalDatas.append(solved_count)
# get datas # get datas
somme = 0 somme = 0
solved = CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat.name).order_by('flag_date') solved = CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat.name).order_by('flag_date')
pointDatas[cat.name] = [] pointDatas[cat.name] = []
pointDatas[cat.name].append([user_obj.date_joined.timestamp() * 1000, 0]) pointDatas[cat.name].append([user_obj.date_joined.timestamp() * 1000, 0])
percent = (solved_count / max_count) * 100
catsDatas.append([cat.name, solved_count, max_count, '{:.0f}'.format(percent)])
for flag in solved: for flag in solved:
somme += flag.ctf.points somme += flag.ctf.points
pointDatas[cat.name].append([flag.flag_date.timestamp() * 1000, somme]) pointDatas[cat.name].append([flag.flag_date.timestamp() * 1000, somme])
@ -141,8 +141,7 @@ def profile(request, user_name):
for s in solves.reverse(): for s in solves.reverse():
somme += s.ctf.points somme += s.ctf.points
solved.append([s.flag_date.timestamp() * 1000,somme]) 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}) return render(request,'accounts/profile.html', {'user':user_obj, 'solves':solves,'solved':solved,'catsDatas': catsDatas, 'pointDatas': pointDatas})
# Create your views here.
def rank(request, token): def rank(request, token):
all_users = UserProfileInfo.objects.filter(score__gt=0).select_related().order_by('-score', 'last_submission_date', 'user__username') all_users = UserProfileInfo.objects.filter(score__gt=0).select_related().order_by('-score', 'last_submission_date', 'user__username')

View File

@ -138,7 +138,7 @@ SITE_ID = 1
STATIC_URL = '/static/' STATIC_URL = '/static/'
STATIC_ROOT = '' STATIC_ROOT = ''
if DEBUG: if DEBUG:
#STATIC_ROOT = os.path.join(BASE_DIR, 'statics') STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'statics'),) STATICFILES_DIRS = (os.path.join(BASE_DIR, 'statics'),)
else: else:
STATIC_ROOT = '/home/user/42ctf/src/statics' STATIC_ROOT = '/home/user/42ctf/src/statics'

View File

@ -43,3 +43,7 @@ input[type=submit]:hover {background-color:#000}
.message {display: block; padding:5px; text-align:center;margin-bottom: 10px;} .message {display: block; padding:5px; text-align:center;margin-bottom: 10px;}
.success-msg {background-color: #42b35e4f;} .success-msg {background-color: #42b35e4f;}
.error-msg {background-color: #9542428c;} .error-msg {background-color: #9542428c;}
.progress {background-color: #2d2d2d;color:#000}
.bg-success {
background-color: #d9d9d9 !important;
}

View File

@ -43,3 +43,7 @@ input[type=submit]:hover {background-color:#000}
.message {display: block; padding:5px; text-align:center;margin-bottom: 10px;} .message {display: block; padding:5px; text-align:center;margin-bottom: 10px;}
.success-msg {background-color: #42b35e4f;} .success-msg {background-color: #42b35e4f;}
.error-msg {background-color: #9542428c;} .error-msg {background-color: #9542428c;}
.progress {background-color: #2d2d2d;}
.bg-success {
background-color: #d9d9d9 !important;color: #000;
}