Podium added and working, logo and website of campuses added in campus model #76
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 3.2.11 on 2022-08-18 15:41
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('accounts', '0012_auto_20220801_2212'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='campus',
|
||||
name='logo',
|
||||
field=models.URLField(default='https://42.fr'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='campus',
|
||||
name='url',
|
||||
field=models.URLField(default='https://42.fr', max_length=100),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 3.2.11 on 2022-08-18 15:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('accounts', '0013_auto_20220818_1741'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
Danhia marked this conversation as resolved
|
||||
model_name='campus',
|
||||
name='logo',
|
||||
field=models.URLField(blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='campus',
|
||||
name='url',
|
||||
field=models.URLField(blank=True, max_length=100),
|
||||
),
|
||||
]
|
|
@ -28,6 +28,8 @@ class UserProfileInfo(models.Model):
|
|||
class Campus(models.Model):
|
||||
id = models.IntegerField(primary_key=True, unique=True)
|
||||
name = models.CharField(max_length=50)
|
||||
url = models.URLField(max_length=100,blank=True)
|
||||
logo = models.URLField(max_length=200,blank=True)
|
||||
def __str__(self):
|
||||
return self.name
|
||||
class Meta:
|
||||
|
|
|
@ -4,9 +4,7 @@ register = template.Library()
|
|||
|
||||
@register.simple_tag
|
||||
def get_chall_by_lang(chall, lang):
|
||||
print(chall.slug)
|
||||
filepath = "ctfs/templates/challenges/"+ lang + "/" + chall.slug + ".html"
|
||||
print(filepath)
|
||||
try:
|
||||
with open(filepath) as fp:
|
||||
return fp.read()
|
||||
|
|
|
@ -2,28 +2,61 @@
|
|||
{% load i18n %}
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-12 ctf-head">
|
||||
<h1>{% trans "42Network Scoreboard" %}</h1>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div>
|
||||
<h4>Scoreboard</h4>
|
||||
<table class="table table-dark">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{% trans "Rank" %}</th>
|
||||
<th scope="col">{% trans "Campus" %}</th>
|
||||
<th scope="col">{% trans "Score" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for name, score in scores.items %}
|
||||
<div class="row justify-content-md-center justify-content-sm-center">
|
||||
<div class="col-4 col-sm-3 col-md-2 podium podium-two text-center">
|
||||
<img src="{{ top3.1.0.logo }}" alt="{{ top3.1.0 }}" width="100%"/>
|
||||
<h3>#2 :</h3>
|
||||
<p>
|
||||
Score : {{ top3.1.1 }}
|
||||
<br>
|
||||
{{ top3.1.0 }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-4 col-sm-3 col-md-2 podium podium-one text-center">
|
||||
<img src="{{ top3.0.0.logo }}" alt="{{ top3.0.0 }}" width="100%"/>
|
||||
<h3>#1 : </h3>
|
||||
<p>
|
||||
Score : {{ top3.0.1 }}
|
||||
<br>
|
||||
{{ top3.0.0 }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-4 col-sm-3 col-md-2 podium podium-three text-center">
|
||||
<img src="{{ top3.2.0.logo }}" alt="{{ top3.2.0 }}" width="100%"/>
|
||||
<h3>#3 : </h3>
|
||||
<p>
|
||||
Score : {{ top3.2.1 }}
|
||||
<br>
|
||||
{{ top3.2.0 }}
|
||||
</p>
|
||||
</div>
|
||||
ix marked this conversation as resolved
Danhia
commented
Did you hardcode the campuses logo for the podium ? Did you hardcode the campuses logo for the podium ?
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<table class="table table-dark">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{% trans "Rank" %}</th>
|
||||
<th scope="col">{% trans "Campus" %}</th>
|
||||
<th scope="col">{% trans "Score" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for name, score in scores.items %}
|
||||
{% if forloop.counter0 > 2 %}
|
||||
<tr>
|
||||
<th scope="row"># {{ forloop.counter0|add:1 }}</th>
|
||||
<th><a href="{% url 'scoreboard:campus' campus=name %}"> {{ name }}</a></th>
|
||||
<td>{{ score}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -4,43 +4,43 @@
|
|||
{% load is_member %}
|
||||
<div class="row">
|
||||
<div class="col-12 ctf-head">
|
||||
<h1>{% trans "Scoreboard" %}</h1>
|
||||
<h1>{% trans "Global Scoreboard" %}</h1>
|
||||
</div>
|
||||
<table class="table table-dark">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{% trans "Rank" %}</th>
|
||||
<th scope="col">{% trans "Username" %}</th>
|
||||
<th scope="col">{% trans "Website" %}</th>
|
||||
<th scope="col">{% trans "Campus" %}</th>
|
||||
<th scope="col">{% trans "Score" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for s in scores %}
|
||||
{% ismember s.user.userprofileinfo as is_member %}
|
||||
<tr>
|
||||
<th scope="row"># {{ forloop.counter0|add:scores.start_index }}</th>
|
||||
<th><a class="profile_link {{is_member}}" href="{% url 'accounts:profile' user_name=s.user.username %}"> {{ s.user.username }}</a></th>
|
||||
<td>
|
||||
{% if s.user.userprofileinfo.portfolio_site %}
|
||||
<a href="{{ s.user.userprofileinfo.portfolio_site }}" target="_blank">{{ s.user.userprofileinfo.portfolio_site }}</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if s.user.userprofileinfo.campus %}
|
||||
<a href="{% url 'scoreboard:campus' campus=s.user.userprofileinfo.campus %}">
|
||||
{{ s.user.userprofileinfo.campus }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ s.user.userprofileinfo.score }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="col-12">
|
||||
<div>
|
||||
<table class="table table-dark">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{% trans "Rank" %}</th>
|
||||
<th scope="col">{% trans "Username" %}</th>
|
||||
<th scope="col">{% trans "Website" %}</th>
|
||||
<th scope="col">{% trans "Campus" %}</th>
|
||||
<th scope="col">{% trans "Score" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for s in scores %}
|
||||
{% ismember s.user.userprofileinfo as is_member %}
|
||||
<tr>
|
||||
<th scope="row"># {{ forloop.counter0|add:scores.start_index }}</th>
|
||||
<th><a class="profile_link {{is_member}}" href="{% url 'accounts:profile' user_name=s.user.username %}"> {{ s.user.username }}</a></th>
|
||||
<td>
|
||||
{% if s.user.userprofileinfo.portfolio_site %}
|
||||
<a href="{{ s.user.userprofileinfo.portfolio_site }}" target="_blank">{{ s.user.userprofileinfo.portfolio_site }}</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if s.user.userprofileinfo.campus %}
|
||||
<a href="{% url 'scoreboard:campus' campus=s.user.userprofileinfo.campus %}">
|
||||
{{ s.user.userprofileinfo.campus }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ s.user.userprofileinfo.score }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="pagination">
|
||||
<span class="step-links">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from django.shortcuts import render
|
||||
from django.core.paginator import Paginator
|
||||
from accounts.models import UserProfileInfo, Campus
|
||||
import itertools
|
||||
|
||||
def scoreboard(request):
|
||||
scores = UserProfileInfo.objects.filter(score__gt=0).select_related().order_by('-score', 'last_submission_date', 'user__username')
|
||||
|
@ -19,12 +20,12 @@ def campus(request, campus):
|
|||
def network(request):
|
||||
campuses = Campus.objects.all()
|
||||
scores = {}
|
||||
|
||||
for campus in campuses:
|
||||
users = UserProfileInfo.objects.filter(score__gt=0, campus__name__exact=campus).select_related().order_by('-score', 'last_submission_date', 'user__username')[:10]
|
||||
scores[campus] = sum([u.score for u in users])
|
||||
|
||||
sorted_scores = {k: v for k, v in sorted(scores.items(), key=lambda item: item[1], reverse=True)}
|
||||
return render(request, 'scoreboard/network.html', {'scores':sorted_scores})
|
||||
top3 = list(itertools.islice(sorted_scores.items(), 3))
|
||||
return render(request, 'scoreboard/network.html', {'scores':sorted_scores, 'top3': top3})
|
||||
|
||||
# Create your views here.
|
||||
|
|
|
@ -313,3 +313,20 @@ footer {
|
|||
color: #a9a9a9;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.podium{
|
||||
margin-top:80px;
|
||||
margin-bottom:30px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.podium h3 {margin-top:-5%;}
|
||||
.podium img{position:relative;top: -55px}
|
||||
.podium-one{
|
||||
background-color: #313131;
|
||||
height: 25vh;}
|
||||
.podium-two{
|
||||
background-color: #252525;
|
||||
height: 20vh;margin-top:auto;}
|
||||
.podium-three{
|
||||
background-color: #1a1a1a;
|
||||
height: 15vh;margin-top:auto;}
|
|
@ -65,7 +65,7 @@
|
|||
{% trans "Scoreboard" %}
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
<a class="dropdown-item" href="{% url 'scoreboard:main' %}">{% trans "Main" %}</a>
|
||||
<a class="dropdown-item" href="{% url 'scoreboard:main' %}">{% trans "Global" %}</a>
|
||||
<a class="dropdown-item" href="{% url 'scoreboard:network' %}">{% trans "42 Network" %}</a>
|
||||
</div>
|
||||
</li>
|
||||
|
|
Loading…
Reference in New Issue
Maybe you could merge this migration with the last one ?
C'est à dire ?
T'as une migration de création de champs, et une migration de modification de ces même champs, donc tu pourrais juste créer les champs directement avec les bons attributs
So apparently there is a feature in Django to squash migrations so we can worry about it later.
I will merge this PR as I currently really want to have the pretty scoreboard in production.