added weekly top 5 + latest flags to home page

This commit is contained in:
Danhia 2022-01-30 17:59:02 +01:00
parent 33763a13a4
commit 9ff4e7e36b
3 changed files with 77 additions and 11 deletions

View File

@ -4,7 +4,30 @@
{% get_current_language as lang %} {% get_current_language as lang %}
{% load is_member %} {% load is_member %}
<div class="row"> <div class="row">
<div class="col-lg-9 col-sm-12 news-card"> <div class="col-lg-3 col-sm-12 right-sidebar middle-sm">
<ul class="list-group">
<li class="list-group-item">Top 10</li>
{% for t in top %}
{% ismember t.user.userprofileinfo as is_member %}
<li class="list-group-item text-truncate"># {{ forloop.counter }}
<a class="profile_link {{is_member}}" href="{% url 'accounts:profile' user_name=t.user.username %}"> {{ t.user.username }}</a>
<span style="position:absolute;right: 15px;">{{ t.score }}</span></li>
{% endfor %}
</ul>
<ul class="list-group">
<li class="list-group-item">{% trans "Weekly Top 5" %}</li>
{% for user, score in top_weekly %}
{% ismember user as is_member %}
<li class="list-group-item text-truncate"># {{ forloop.counter }}
<a class="profile_link {{is_member}}" href="{% url 'accounts:profile' user_name=user %}"> {{ user }}</a>
<span style="position:absolute;right: 15px;">{{ score }}</span></li>
{% endfor %}
</ul>
</div>
<div class="col-lg-6 col-sm-12 news-card top-sm">
{% if news %} {% if news %}
{% for n in news %} {% for n in news %}
<div class="card text-center news-card"> <div class="card text-center news-card">
@ -33,30 +56,42 @@
<p class="text-center">{% trans "No article available." %}</p> <p class="text-center">{% trans "No article available." %}</p>
{% endif %} {% endif %}
</div> </div>
<div class="col-lg-3 col-sm-12 right-sidebar"> <div class="col-lg-3 col-sm-12 right-sidebar bottom-sm">
<ul class="list-group"> <ul class="list-group">
<li class="list-group-item active">{% trans "Latest challenges added" %}</li> <li class="list-group-item active">{% trans "Latest challenges added" %}</li>
{% if ctfs %} {% if ctfs %}
{% for ctf in ctfs %} {% for ctf in ctfs %}
<a class="list-group-item" href="{% url 'ctf' cat_slug=ctf.category.slug ctf_slug=ctf.slug %}">{{ ctf.name }}</a> <li class="list-group-item">
<a href="{% url 'ctf' cat_slug=ctf.category.slug ctf_slug=ctf.slug %}">{{ ctf.name }}</a> - {{ctf.points}} {% trans "points" %}
</li>
{% endfor %} {% endfor %}
{% else %} {% else %}
<li class="list-group-item">{% trans "No ctf available." %}</li> <li class="list-group-item">{% trans "No ctf available." %}</li>
{% endif %} {% endif %}
</ul> </ul>
<ul class="list-group"> <ul class="list-group">
<li class="list-group-item">Top 10</li> <li class="list-group-item">{% trans "Latest Flags" %}</li>
{% for t in top %} {% for f in latest_flags %}
{% ismember t.user.userprofileinfo as is_member %} {% ismember f.user.userprofileinfo as is_member %}
<li class="list-group-item text-truncate"># {{ forloop.counter }} <li class="list-group-item text-truncate">
<a class="profile_link {{is_member}}" href="{% url 'accounts:profile' user_name=t.user.username %}"> {{ t.user.username }}</a> <a class="profile_link {{is_member}}" href="{% url 'accounts:profile' user_name=f.user.username %}">
<span style="position:absolute;right: 15px;">{{ t.score }}</span></li> {{ f.user.username }}</a> - {{f.ctf}}
{% endfor %} {% endfor %}
</ul> </ul>
<div class="row flex-nowrap">
<div class="col-lg-6 col-sm-3">
<ul class="list-group"> <ul class="list-group">
<li class="list-group-item active">{% trans "Flags counter" %}</li> <li class="list-group-item active">{% trans "Flags counter" %}</li>
<li class="list-group-item"><span>{{ flags }}</span></li> <li class="list-group-item"><span>{{ flags }}</span></li>
</ul> </ul>
</div>
<div class="col-lg-6 col-sm-3">
<ul class="list-group">
<li class="list-group-item active">{% trans "Users" %}</li>
<li class="list-group-item"><span>{{ nb_users }}</span></li>
</ul>
</div>
</div>
</div> </div>
</div> </div>

View File

@ -8,6 +8,9 @@ from django.urls import translate_url
from django.utils.translation import ( from django.utils.translation import (
LANGUAGE_SESSION_KEY, check_for_language, get_language, LANGUAGE_SESSION_KEY, check_for_language, get_language,
) )
import datetime
from collections import defaultdict
import operator
def get_content_by_lang(news): def get_content_by_lang(news):
lang = get_language() lang = get_language()
@ -22,6 +25,19 @@ def get_content_by_lang(news):
ret = news.content_ru ret = news.content_ru
return ret return ret
def get_weekly_top():
week_ago = datetime.datetime.now() - datetime.timedelta(days=7)
weekly_flags = CTF_flags.objects.filter(flag_date__gt=week_ago)
scores = defaultdict(int)
for sol in weekly_flags:
scores[sol.user] += sol.ctf.points
users = sorted(scores.items(), key=operator.itemgetter(1), reverse=True)
users = [(u[0].userprofileinfo, u[1]) for u in users]
return(users[:5])
def home(request): def home(request):
lang_code = get_language() lang_code = get_language()
if hasattr(request, 'session') and LANGUAGE_SESSION_KEY in request.session: if hasattr(request, 'session') and LANGUAGE_SESSION_KEY in request.session:
@ -36,7 +52,11 @@ def home(request):
top10 = UserProfileInfo.objects.select_related().order_by('-score', 'last_submission_date', 'user__username')[:10] top10 = UserProfileInfo.objects.select_related().order_by('-score', 'last_submission_date', 'user__username')[:10]
nb_flags = CTF_flags.objects.count() nb_flags = CTF_flags.objects.count()
nb_users = UserProfileInfo.objects.count() nb_users = UserProfileInfo.objects.count()
return render(request, 'home/home.html', {'news' : news, 'ctfs' : latest_ctfs, 'top' : top10, 'flags' : nb_flags}) latest_flags = CTF_flags.objects.order_by('-flag_date')[:5]
top_weekly = get_weekly_top()
return render(request, 'home/home.html', {'news' : news, 'ctfs' : latest_ctfs, 'top' : top10, 'flags' : nb_flags,
'latest_flags':latest_flags, 'top_weekly': top_weekly, 'nb_users': nb_users})
def cgu(request): def cgu(request):
return render(request, 'cgu.html') return render(request, 'cgu.html')

View File

@ -362,3 +362,14 @@ footer {
.is-member { .is-member {
color: #2b908f; color: #2b908f;
} }
@media only screen and (min-width : 1200px) {
.container { max-width: 1400px; }
}
@media screen and (max-width: 991px) {
.container { display: flex; flex-flow: column; }
.top-sm { order: 1; }
.middle-sm { order: 2; }
.bottom-sm { order: 3 }
}