you can create and join team + eventplayer and team profile

This commit is contained in:
Danhia 2021-12-28 20:17:39 +01:00
parent 9405fcabde
commit 411896bf01
15 changed files with 551 additions and 272 deletions

View File

@ -41,7 +41,7 @@
<div class="d-none d-md-block col-10 col-md-3 right-sidebar"> <div class="d-none d-md-block col-10 col-md-3 right-sidebar">
<ul class="list-group"> <ul class="list-group">
<li class="list-group-item">{{ user.username }}</li> <li class="list-group-item">{{ user.username }}</li>
<li class="list-group-item">{% trans "Score" %} : {{ user.userprofileinfo.score }}</li> <li class="list-group-item">{% trans "Score" %} : {{ score }}</li>
<li class="list-group-item">{% trans "Rank" %} : {{ rank }}</li> <li class="list-group-item">{% trans "Rank" %} : {{ rank }}</li>
{% if user.userprofileinfo.portfolio_site %} {% if user.userprofileinfo.portfolio_site %}
<li class="list-group-item"> <li class="list-group-item">

View File

@ -144,7 +144,7 @@ def profile(request, user_name):
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,'catsDatas': catsDatas, 'pointDatas': pointDatas, 'rank': rank}) return render(request,'accounts/profile.html', {'user':user_obj, 'solves':solves,'solved':solved,'catsDatas': catsDatas, 'pointDatas': pointDatas, 'rank': rank, 'score' : somme})
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

@ -1,5 +1,5 @@
from django.contrib import admin from django.contrib import admin
from .models import Event, Scores, EventPlayer, Team from .models import Event, EventPlayer, Team
#admin.site.register(Event) #admin.site.register(Event)
#admin.site.register(Scores) #admin.site.register(Scores)
@ -11,7 +11,7 @@ class event(admin.ModelAdmin):
# search list # search list
search_fields = ['name', 'slug', 'description', 'password'] search_fields = ['name', 'slug', 'description', 'password']
@admin.register(Scores) @admin.register(EventPlayer)
class score(admin.ModelAdmin): class score(admin.ModelAdmin):
#list display #list display
list_display = ['user', 'event', 'score'] list_display = ['user', 'event', 'score']
@ -31,11 +31,11 @@ class team(admin.ModelAdmin):
# search list # search list
search_fields = ['name'] search_fields = ['name']
@admin.register(EventPlayer) # @admin.register(EventPlayer)
class eventplayer(admin.ModelAdmin): # class eventplayer(admin.ModelAdmin):
#list display # #list display
list_display = ['user', 'event', 'team'] # list_display = ['user', 'event', 'team']
#list Filter # #list Filter
list_filter = ('event', 'team__name') # list_filter = ('event', 'team__name')
# search list # # search list
search_fields = ['user__username', 'event__name'] # search_fields = ['user__username', 'event__name']

View File

@ -1,4 +1,4 @@
# Generated by Django 3.1.5 on 2021-12-15 21:05 # Generated by Django 3.1.5 on 2021-12-27 15:40
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -14,6 +14,7 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.RenameModel('Scores', 'EventPlayer'),
migrations.CreateModel( migrations.CreateModel(
name='Team', name='Team',
fields=[ fields=[
@ -23,20 +24,7 @@ class Migration(migrations.Migration):
('size', models.PositiveIntegerField(default=1)), ('size', models.PositiveIntegerField(default=1)),
('score', models.PositiveIntegerField(db_index=True, default=0)), ('score', models.PositiveIntegerField(db_index=True, default=0)),
('last_submission_date', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Last Submission Date')), ('last_submission_date', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Last Submission Date')),
], ('event', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='events.event')),
),
migrations.AlterField(
model_name='scores',
name='id',
field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.CreateModel(
name='EventPlayer',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='events.event')),
('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='events.team')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
], ],
), ),
] ]

View File

@ -1,19 +0,0 @@
# Generated by Django 3.1.5 on 2021-12-15 21:24
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('events', '0004_auto_20211215_2105'),
]
operations = [
migrations.AlterField(
model_name='eventplayer',
name='team',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='events.team'),
),
]

View File

@ -0,0 +1,29 @@
# Generated by Django 3.1.5 on 2021-12-27 15:56
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('events', '0004_auto_20211227_1540'),
]
operations = [
migrations.AddField(
model_name='event',
name='team_size',
field=models.PositiveIntegerField(default=1),
),
migrations.AddField(
model_name='eventplayer',
name='team',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='events.team'),
),
migrations.AlterField(
model_name='eventplayer',
name='id',
field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
]

View File

@ -1,19 +0,0 @@
# Generated by Django 3.1.5 on 2021-12-15 22:16
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('events', '0005_auto_20211215_2124'),
]
operations = [
migrations.AddField(
model_name='team',
name='event',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='events.event'),
),
]

View File

@ -14,17 +14,10 @@ class Event(models.Model):
end_date = models.DateTimeField() end_date = models.DateTimeField()
password = models.CharField(max_length=200, blank=True) password = models.CharField(max_length=200, blank=True)
slug = models.SlugField(max_length=55) slug = models.SlugField(max_length=55)
team_size = models.PositiveIntegerField(default=1)
def __str__(self): def __str__(self):
return self.name return self.name
class Scores(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
event = models.ForeignKey(Event, on_delete=models.CASCADE)
score = models.PositiveIntegerField(default=0, db_index=True)
last_submission_date = models.DateTimeField('Last Submission Date', default=timezone.now)
class Meta:
ordering = ['-score', 'last_submission_date', 'user__username']
class Team(models.Model): class Team(models.Model):
name = models.CharField(max_length=200) name = models.CharField(max_length=200)
password = models.CharField(max_length=200) password = models.CharField(max_length=200)
@ -36,9 +29,12 @@ class Team(models.Model):
return self.name return self.name
class EventPlayer(models.Model): class EventPlayer(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE)
event = models.ForeignKey(Event, on_delete=models.CASCADE) event = models.ForeignKey(Event, on_delete=models.CASCADE)
# score = models.PositiveIntegerField(default=0, db_index=True) score = models.PositiveIntegerField(default=0, db_index=True)
# last_submission_date = models.DateTimeField('Last Submission Date', default=timezone.now) last_submission_date = models.DateTimeField('Last Submission Date', default=timezone.now)
team = models.ForeignKey(Team, on_delete=models.CASCADE, null=True) team = models.ForeignKey(Team, on_delete=models.CASCADE, null=True)
class Meta:
ordering = ['-score', 'last_submission_date', 'user__username']

View File

@ -6,7 +6,7 @@
<div class="ctf-block"> <div class="ctf-block">
<div class="ctf-head"> <div class="ctf-head">
<h3>{{ event.name }}</h3> <h3>{{ event.name }}</h3>
<small>{% trans "This event start at" %} : {{ event.start_date }}</small> <small>{% trans "This event starts at" %} : {{ event.start_date }}</small>
</div> </div>
<div class="ctf-footer"> <div class="ctf-footer">
@ -18,6 +18,8 @@
<span class="message error-msg">{% trans "Team does not exist." %}</span> <span class="message error-msg">{% trans "Team does not exist." %}</span>
{% elif wrongpwd == True %} {% elif wrongpwd == True %}
<span class="message error-msg">{% trans "Wrong password submited." %}</span> <span class="message error-msg">{% trans "Wrong password submited." %}</span>
{% elif max == True %}
<span class="message error-msg">{% trans "Maximum size reached." %}</span>
{% endif %} {% endif %}
<h2>Create Team</h2> <h2>Create Team</h2>
<form method="post" action="{% url 'events:create_team' event_slug=event.slug %}" class="create-team-form"> <form method="post" action="{% url 'events:create_team' event_slug=event.slug %}" class="create-team-form">
@ -25,8 +27,6 @@
<div class="form-group"> <div class="form-group">
<input class="form-control" type="text" name="teamname" placeholder="{% trans "Team name" %} *" maxlength="150" required="" id="id_teamname"></br> <input class="form-control" type="text" name="teamname" placeholder="{% trans "Team name" %} *" maxlength="150" required="" id="id_teamname"></br>
<input class="form-control" type="password" name="password" placeholder="{% trans "Password" %} *" required="" id="id_password"></br> <input class="form-control" type="password" name="password" placeholder="{% trans "Password" %} *" required="" id="id_password"></br>
<!-- <input class="form-control" type="email" name="email" placeholder="pleasedontgivemy@private.infos*" required="" maxlength="254" id="id_email"></br> -->
<!-- <input class="form-control" type="url" name="portfolio_site" placeholder="{% trans "Personal website" %}"maxlength="200" id="id_portfolio_site"></br> -->
<input type="submit" name="" class="form-control" value="{% trans "Create Team" %}"> <input type="submit" name="" class="form-control" value="{% trans "Create Team" %}">
</div> </div>
</form> </form>
@ -36,8 +36,6 @@
<div class="form-group"> <div class="form-group">
<input class="form-control" type="text" name="teamname" placeholder="{% trans "Team name" %} *" maxlength="150" required="" id="id_teamname"></br> <input class="form-control" type="text" name="teamname" placeholder="{% trans "Team name" %} *" maxlength="150" required="" id="id_teamname"></br>
<input class="form-control" type="password" name="password" placeholder="{% trans "Password" %} *" required="" id="id_password"></br> <input class="form-control" type="password" name="password" placeholder="{% trans "Password" %} *" required="" id="id_password"></br>
<!-- <input class="form-control" type="email" name="email" placeholder="pleasedontgivemy@private.infos*" required="" maxlength="254" id="id_email"></br> -->
<!-- <input class="form-control" type="url" name="portfolio_site" placeholder="{% trans "Personal website" %}"maxlength="200" id="id_portfolio_site"></br> -->
<input type="submit" name="" class="form-control" value="{% trans "Join Team" %}"> <input type="submit" name="" class="form-control" value="{% trans "Join Team" %}">
</div> </div>
</form> </form>

View File

@ -74,11 +74,19 @@
</thead> </thead>
<tbody> <tbody>
{% for s in solved_list %} {% for s in solved_list %}
{% if event.team_size == 1%}
<tr> <tr>
<th scope="row"><a class="profile_link" href="{% url 'accounts:profile' user_name=s.user.username %}"> {{ s.user.username }}</a></th> <th scope="row"><a class="profile_link" href="{% url 'events:profile' user_name=s.user.username %}"> {{ s.0.username }}</a></th>
<td>{{ s.user.userprofileinfo.portfolio_site }}</td> <td>{{ s.0.userprofileinfo.portfolio_site }}</td>
<td>{{ s.flag_date }}</td> <td>{{ s.1 }}</td>
</tr> </tr>
{% else %}
<tr>
<th scope="row"><a class="profile_link" href="{% url 'events:team_info' name=s.2 event_slug=event.slug %}"> {{ s.2 }}</a></th>
<td></td>
<td>{{ s.1 }}</td>
</tr>
{% endif %}
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>

View File

@ -55,6 +55,7 @@
<div> <div>
<h4>{% trans "ScoreBoard" %}</h4> <h4>{% trans "ScoreBoard" %}</h4>
{% if solved_list %} {% if solved_list %}
{% if event.team_size == 1 %}
<table class="table table-dark"> <table class="table table-dark">
<thead> <thead>
<tr> <tr>
@ -69,7 +70,7 @@
<tr> <tr>
<th scope="row"># {{ forloop.counter0|add:1 }}</th> <th scope="row"># {{ forloop.counter0|add:1 }}</th>
<th scope="row"> <th scope="row">
<a class="profile_link" href="{% url 'accounts:profile' user_name=s.user.username %}"> {{ s.user.username }}</a> <a class="profile_link" href="{% url 'events:profile' user_name=s.user.username event_slug=event.slug %}"> {{ s.user.username }}</a>
</th> </th>
<td>{{ s.user.userprofileinfo.site }}</td> <td>{{ s.user.userprofileinfo.site }}</td>
<td>{{ s.score }}</td> <td>{{ s.score }}</td>
@ -78,6 +79,28 @@
</tbody> </tbody>
</table> </table>
{% else %} {% else %}
<table class="table table-dark">
<thead>
<tr>
<th scope="col">{% trans "Rank" %}</th>
<th scope="col">{% trans "Team" %}</th>
<th scope="col">{% trans "Score" %}</th>
</tr>
</thead>
<tbody>
{% for s in solved_list %}
<tr>
<th scope="row"># {{ forloop.counter0|add:1 }}</th>
<th scope="row">
<a class="profile_link" href="{% url 'events:team_info' name=s.name event_slug=event.slug %}"> {{ s.name }}</a>
</th>
<td>{{ s.score }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% else %}
<p>{% trans "No one have earn point yet, you gonna be the first ?" %}</p> <p>{% trans "No one have earn point yet, you gonna be the first ?" %}</p>
{% endif %} {% endif %}
</div> </div>

View File

@ -0,0 +1,144 @@
{% extends 'base.html' %}
{% block content %}
{% load i18n %}
{% load key_value %}
<div class="row">
<div class="col-sm-12 col-md-9">
<div>
<h4>Challenges Solved by {{ team.name }}</h4>
{% if solves%}
<div class="table table-dark">
<div class="card-body">
<div id="time-chart"></div>
</div>
</div>
<table class="table table-dark">
<thead>
<tr>
<th scope="col">{% trans "Challenge Name" %}</th>
<th scope="col">{% trans "Category" %}</th>
<th scope="col">{% trans "Points" %}</th>
<th scope="col">{% trans "Date" %}</th>
</tr>
</thead>
<tbody>
{% for s in solves %}
<tr>
<th scope="row"><a href="{% url 'ctf' cat_slug=s.ctf.category.slug ctf_slug=s.ctf.slug %}">{{ s.ctf.name }}</a></th>
<td>{{ s.ctf.category.name}}</td>
<td>{{ s.ctf.points }}</td>
<td>{{ s.flag_date|date:"Y-m-d H:i:s" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>{% trans "It seems that this team has not solved any challenge yet..." %}</p>
{% endif %}
</div>
</div>
<div class="d-none d-md-block col-10 col-md-3 right-sidebar">
<ul class="list-group">
<li class="list-group-item">{{ team.name }}</li>
<li class="list-group-item">{% trans "Score" %} : {{ score }}</li>
<li class="list-group-item">{% trans "Rank" %} : {{ rank }}</li>
</ul>
<ul class="list-group">
<li class="list-group-item">{% trans "Members" %}</li>
{% for user in users %}
<li class="list-group-item"><a class="profile_link" href="{% url 'accounts:profile' user_name=user.username %}">{{ user.username }}</a></li>
{% endfor %}
</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">
{% if cat.3 == '0' %}
<div class="progress-bar bg-success" role="progressbar" style="width: 0%;color:#d9d9d9;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0 %</div>
{% else %}
<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>
{% endif %}
</div>
</li>
{% endfor %}
</ul>
</div>
</div>
<script src="https://code.highcharts.com/highcharts.src.js"></script>
<script>
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"}};
Highcharts.setOptions(Highcharts.theme);
Highcharts.chart('time-chart', {
title: {
text: 'Points earned for each category'
},
yAxis: {
title: {
text: 'Points earned'
}
},
xAxis: {
type: 'datetime',
labels: {
formatter: function() {
return Highcharts.dateFormat('%d.%b %Y',
this.value);
}
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
plotOptions: {
pointStart: {{ event.start_date|timestamp_fromdate }},
series: {
label: {
connectorAllowed: false
},
allowPointSelect: true,
marker: {
enabled: true
}
}
},
series: [
{
name: 'Total',
data: {{ solved|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'
}
}
}]
}
});
</script>
{% endblock %}

View File

@ -1,10 +1,25 @@
from django import template from django import template
from ctfs.models import CTF_flags from ctfs.models import CTF_flags
from events.models import EventPlayer
register = template.Library() register = template.Library()
@register.simple_tag @register.simple_tag
def isflagged(user, ctf): def isflagged(user, ctf):
if CTF_flags.objects.filter(user=user, ctf=ctf): flagged = False
return "success-msg" event_info = ctf.event
return ""
if event_info.team_size == 1:
if CTF_flags.objects.filter(user=user, ctf=ctf):
flagged = True
elif EventPlayer.objects.filter(user=user, event=event_info):
player = EventPlayer.objects.get(user=user, event=event_info)
solved_list = CTF_flags.objects.filter(ctf=ctf)
for s in solved_list:
tmp = EventPlayer.objects.get(user=s.user, event=event_info)
if tmp.team == player.team:
flagged = True
if flagged:
return "success-msg"
return ""

View File

@ -11,5 +11,7 @@ urlpatterns = [
path('submitEventFlag/<str:event_slug>/<str:chall_slug>', views.submit_event_flag, name='submit_event_flag'), path('submitEventFlag/<str:event_slug>/<str:chall_slug>', views.submit_event_flag, name='submit_event_flag'),
path('subscribe/<str:event_slug>', views.subscribe_to_event, name='subscribe_event'), path('subscribe/<str:event_slug>', views.subscribe_to_event, name='subscribe_event'),
path('create_team/<str:event_slug>', views.create_team, name='create_team'), path('create_team/<str:event_slug>', views.create_team, name='create_team'),
path('join_team/<str:event_slug>', views.join_team, name='join_team'), path('join_team/<str:event_slug>', views.join_team, name='join_team'),
path('<str:event_slug>/profile/<str:user_name>', views.profile, name='profile'),
path('<str:event_slug>/team/<str:name>', views.team_info, name='team_info'),
] ]

View File

@ -2,214 +2,328 @@ from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import timezone from django.contrib.auth.models import timezone
from .forms import submit_flag from .forms import submit_flag
from .models import Event, Scores, EventPlayer, Team from .models import Event, EventPlayer, Team
from ctfs.models import CTF, CTF_flags from ctfs.models import CTF, CTF_flags, Category
from django.utils.translation import get_language from django.utils.translation import get_language
from django.contrib.auth.models import User
from accounts.models import UserProfileInfo
from django.db.models import Q
def get_description_by_lang(ctf): def get_description_by_lang(ctf):
lang = get_language() lang = get_language()
ret = None ret = None
if lang == "fr": if lang == "fr":
ret = ctf.description ret = ctf.description
elif lang == "en": elif lang == "en":
ret = ctf.description_en ret = ctf.description_en
elif lang == "de": elif lang == "de":
ret = ctf.description_de ret = ctf.description_de
elif lang == "ru": elif lang == "ru":
ret = ctf.description_ru ret = ctf.description_ru
return ret return ret
# Create your views here. # Create your views here.
def events(request): def events(request):
list_events = Event.objects.filter().order_by('-end_date', 'start_date') list_events = Event.objects.filter().order_by('-end_date', 'start_date')
return render(request, 'events/events_list.html', {'events' : list_events, 'curdate': timezone.now()}) return render(request, 'events/events_list.html', {'events' : list_events, 'curdate': timezone.now()})
def chall_event_info(request, event_slug, chall_slug): def chall_event_info(request, event_slug, chall_slug):
event_info = get_object_or_404(Event, slug=event_slug) event_info = get_object_or_404(Event, slug=event_slug)
ctf_info = get_object_or_404(CTF, event__slug=event_info.slug, slug=chall_slug) ctf_info = get_object_or_404(CTF, event__slug=event_info.slug, slug=chall_slug)
if timezone.now() < ctf_info.pub_date: if timezone.now() < ctf_info.pub_date:
return redirect('events:event_info', event_slug=event_slug) return redirect('events:event_info', event_slug=event_slug)
eventisover = False eventisover = False
alreadyflag = False alreadyflag = False
congrat = False congrat = False
wrongflag = False wrongflag = False
errorform = False errorform = False
notsub = False notsub = False
if request.user.is_authenticated and not request.user.is_staff: player = None
userScore = Scores.objects.filter(event=event_info, user=request.user) if request.user.is_authenticated and not request.user.is_staff:
if not userScore: player = EventPlayer.objects.filter(event=event_info, user=request.user)
return redirect('/') if not player:
elif not request.user.is_authenticated: return redirect('events:event_info', event_slug=event_slug)
return redirect('/') elif not request.user.is_authenticated:
if request.GET.get('EventIsOver'): return redirect('accounts:signin')
eventisover = True if request.GET.get('EventIsOver'):
if request.GET.get('AlreadyFlagged'): eventisover = True
alreadyflag = True if request.GET.get('AlreadyFlagged'):
if request.GET.get('Congrat'): alreadyflag = True
congrat = True if request.GET.get('Congrat'):
if request.GET.get('WrongFlag'): congrat = True
wrongflag = True if request.GET.get('WrongFlag'):
if request.GET.get('ErrorInForm'): wrongflag = True
errorform = True if request.GET.get('ErrorInForm'):
if request.GET.get('NotRegistered'): errorform = True
notsub = True if request.GET.get('NotRegistered'):
solved_list = CTF_flags.objects.filter(ctf=ctf_info).order_by('flag_date') notsub = True
description = get_description_by_lang(ctf_info) solved_challs = CTF_flags.objects.filter(ctf=ctf_info).order_by('flag_date')
return render(request, 'events/ctf_info.html', { 'ctf' : ctf_info, 'event':event_info, 'solved_list': solved_list, 'description': description, 'eventisover': eventisover, 'alreadyflag': alreadyflag, 'congrat': congrat, 'wrongflag': wrongflag, 'errorform': errorform, 'notsub': notsub}) solved_list = []
for s in solved_challs:
solved_list.append([s.user, s.flag_date, EventPlayer.objects.get(event=event_info, user=s.user).team.name])
description = get_description_by_lang(ctf_info)
return render(request, 'events/ctf_info.html', { 'ctf' : ctf_info, 'event':event_info, 'solved_list': solved_list, 'description': description, 'eventisover': eventisover, 'alreadyflag': alreadyflag,
'congrat': congrat, 'wrongflag': wrongflag, 'errorform': errorform, 'notsub': notsub})
def event(request, event_slug): def event(request, event_slug):
event_info = get_object_or_404(Event, slug=event_slug) event_info = get_object_or_404(Event, slug=event_slug)
IsRegistered = False IsRegistered = False
wrongpwd = False wrongpwd = False
alreadyregistered = False alreadyregistered = False
subisover = False subisover = False
if request.GET.get('WrongPassword'): if request.GET.get('WrongPassword'):
wrongpwd = True wrongpwd = True
if request.GET.get('AlreadyRegistered'): if request.GET.get('AlreadyRegistered'):
alreadyregistered = True alreadyregistered = True
if request.GET.get('SubscriptionIsOver'): if request.GET.get('SubscriptionIsOver'):
subisover = True subisover = True
if request.user.is_authenticated: if request.user.is_authenticated:
userScore = Scores.objects.filter(event=event_info, user=request.user) player = EventPlayer.objects.filter(event=event_info, user=request.user)
player = EventPlayer.objects.filter(event=event_info, user=request.user) if player:
if userScore or player: IsRegistered = True
IsRegistered = True if event_info.password:
if event_info.password: if request.user.is_authenticated:
if request.user.is_authenticated: if request.user.is_staff is False:
if request.user.is_staff is False: if not player:
if not userScore and not player: return render(request, 'events/event_pwd.html', {'event' : event_info, 'logged': True, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered})
return render(request, 'events/event_pwd.html', {'event' : event_info, 'logged': True, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered}) else:
else: return render(request, 'events/event_pwd.html', {'event' : event_info, 'logged': False, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered})
return render(request, 'events/event_pwd.html', {'event' : event_info, 'logged': False, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered}) ended = False
ended = False if timezone.now() >= event_info.end_date:
if timezone.now() >= event_info.end_date: ended = True
ended = True begun = False
begun = False if timezone.now() >= event_info.start_date:
if timezone.now() >= event_info.start_date: begun = True
begun = True challenges = CTF.objects.filter(event=event_info).order_by('category', 'points')
challenges = CTF.objects.filter(event=event_info).order_by('category', 'points') if event_info.team_size == 1:
solved_list = Scores.objects.filter(event=event_info).order_by('-score', 'last_submission_date', 'user__username') solved_list = EventPlayer.objects.filter(event=event_info).order_by('-score', 'last_submission_date', 'user__username')
return render(request, 'events/event_info.html', {'event' : event_info, 'IsRegistered': IsRegistered, 'ctfs': challenges, 'solved_list':solved_list, 'ended': ended, 'begun': begun, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered, 'subisover': subisover}) else:
solved_list = Team.objects.filter(event=event_info).order_by('-score', 'last_submission_date', 'name')
return render(request, 'events/event_info.html', {'event' : event_info, 'IsRegistered': IsRegistered, 'ctfs': challenges, 'solved_list':solved_list, 'ended': ended, 'begun': begun, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered, 'subisover': subisover})
@login_required @login_required
def submit_event_flag(request, event_slug, chall_slug): def submit_event_flag(request, event_slug, chall_slug):
ev = get_object_or_404(Event, slug=event_slug) ev = get_object_or_404(Event, slug=event_slug)
response = redirect('events:event_chall_info', event_slug=event_slug, chall_slug=chall_slug) response = redirect('events:event_chall_info', event_slug=event_slug, chall_slug=chall_slug)
if timezone.now() >= ev.end_date:
response['Location'] += '?EventIsOver=1'
return response
if request.method == 'POST': if timezone.now() >= ev.end_date:
ctf_info = CTF.objects.get(event=ev, slug=chall_slug) response['Location'] += '?EventIsOver=1'
if not ctf_info: return response
response['Location'] += '?ChallengeNotFound=1'
return response if request.method == 'POST':
flagged = False ctf_info = CTF.objects.get(event=ev, slug=chall_slug)
if CTF_flags.objects.filter(user=request.user, ctf=ctf_info): if not ctf_info:
flagged = True response['Location'] += '?ChallengeNotFound=1'
response['Location'] += '?AlreadyFlagged=1' return response
return response
try: flagged = False
score = Scores.objects.get(user=request.user, event=ev) player = EventPlayer.objects.get(user=request.user, event=ev)
except:
score = None if player:
if score: if ev.team_size == 1 and CTF_flags.objects.filter(user=request.user, ctf=ctf_info):
form = submit_flag(data=request.POST) flagged = True
if flagged == False and form.is_valid(): else:
if ctf_info.flag == request.POST.get('flag'): solved_list = CTF_flags.objects.filter(ctf=ctf_info)
new = CTF_flags(user = request.user, ctf = ctf_info, flag_date = timezone.now()) for s in solved_list:
new.save() tmp = EventPlayer.objects.get(user=s.user, event=ev)
score.last_submission_date = timezone.now() if tmp.team == player.team:
score.score += ctf_info.points flagged = True
score.save() if flagged == True:
response['Location'] += '?Congrat=1' response['Location'] += '?AlreadyFlagged=1'
return response return response
else:
response['Location'] += '?WrongFlag=1' form = submit_flag(data=request.POST)
return response
else: if form.is_valid():
response['Location'] += '?ErrorInForm=1' if ctf_info.flag == request.POST.get('flag'):
return response new = CTF_flags(user = request.user, ctf = ctf_info, flag_date = timezone.now())
else: new.save()
response['Location'] += '?NotRegistered=1' player.last_submission_date = timezone.now()
return response player.score += ctf_info.points
return response player.save()
if player.team:
player.team.last_submission_date = timezone.now()
player.team.score += ctf_info.points
player.team.save()
response['Location'] += '?Congrat=1'
return response
else:
response['Location'] += '?WrongFlag=1'
return response
else:
response['Location'] += '?ErrorInForm=1'
return response
else:
response['Location'] += '?NotRegistered=1'
return response
return response
@login_required @login_required
def submit_pwd(request, event_slug): def submit_pwd(request, event_slug):
response = redirect('events:event_info', event_slug=event_slug) response = redirect('events:event_info', event_slug=event_slug)
event_info = get_object_or_404(Event, slug=event_slug) event_info = get_object_or_404(Event, slug=event_slug)
if request.method == 'POST': if request.method == 'POST':
if request.user.is_authenticated: if request.user.is_authenticated:
ev = get_object_or_404(Event, slug=event_slug) ev = get_object_or_404(Event, slug=event_slug)
if ev == False: if ev == False:
response['Location'] += '?NoEventFound=1' response['Location'] += '?NoEventFound=1'
return response return response
if request.POST.get('password') != ev.password: if request.POST.get('password') != ev.password:
response['Location'] += '?WrongPassword=1' response['Location'] += '?WrongPassword=1'
return response return response
if Scores.objects.filter(user=request.user, event=ev).exists() or EventPlayer.objects.filter(user=request.user, event=ev).exists(): if EventPlayer.objects.filter(user=request.user, event=ev).exists() or EventPlayer.objects.filter(user=request.user, event=ev).exists():
response['Location'] += '?AlreadyRegistered=1' response['Location'] += '?AlreadyRegistered=1'
return response return response
else: else:
new = EventPlayer(user=request.user, event=ev) new = EventPlayer(user=request.user, event=ev)
# new = Scores(user=request.user, event=ev, score=0) new.save()
new.save() if event_info.team_size > 1:
# return redirect('events:event_info', event_slug=event_slug) return render(request, 'events/create_team.html', {'event' : event_info, 'logged': True, 'wrongpwd': False, 'registered' : True, 'notexist' : False})
return render(request, 'events/create_team.html', {'event' : event_info, 'logged': True, 'wrongpwd': False, 'registered' : True, 'notexist' : False}) return redirect('events:event_info', event_slug=event_slug)
# return redirect('events:create_team', event_slug=event_slug)
@login_required @login_required
def subscribe_to_event(request, event_slug): def subscribe_to_event(request, event_slug):
response = redirect('events:event_info', event_slug=event_slug) response = redirect('events:event_info', event_slug=event_slug)
if request.method == 'POST': if request.method == 'POST':
if request.user.is_authenticated: if request.user.is_authenticated:
ev = get_object_or_404(Event, slug=event_slug) ev = get_object_or_404(Event, slug=event_slug)
if ev == False: if ev == False:
response['Location'] += '?NoEventFound=1' response['Location'] += '?NoEventFound=1'
return response return response
if timezone.now() >= ev.end_date: if timezone.now() >= ev.end_date:
response['Location'] += '?SubscriptionIsOver=1' response['Location'] += '?SubscriptionIsOver=1'
return response return response
if Scores.objects.filter(user=request.user, event=ev).exists(): if EventPlayer.objects.filter(user=request.user, event=ev).exists():
response['Location'] += '?AlreadyRegistered=1' response['Location'] += '?AlreadyRegistered=1'
return response return response
else: else:
new = Scores(user=request.user, event=ev, score=0) new = EventPlayer(user=request.user, event=ev, score=0)
new.save() new.save()
return redirect('events:event_info', event_slug=event_slug) if ev.team_size > 1:
return render(request, 'events/create_team.html', {'event' : ev, 'logged': True, 'wrongpwd': False, 'registered' : True, 'notexist' : False})
return redirect('events:event_info', event_slug=event_slug)
@login_required @login_required
def create_team(request, event_slug): def create_team(request, event_slug):
response = redirect('events:create_team', event_slug=event_slug) response = redirect('events:create_team', event_slug=event_slug)
if request.method == 'POST': if request.method == 'POST':
if request.user.is_authenticated: if request.user.is_authenticated:
ev = get_object_or_404(Event, slug=event_slug) ev = get_object_or_404(Event, slug=event_slug)
new = Team(name=request.POST.get('teamname'), password=request.POST.get('password'), event=ev) new = Team(name=request.POST.get('teamname'), password=request.POST.get('password'), event=ev)
new.save() new.save()
player = EventPlayer.objects.get(user=request.user, event=ev) player = EventPlayer.objects.get(user=request.user, event=ev)
player.team = new player.team = new
player.save() player.save()
return redirect('events:event_info', event_slug=event_slug) return redirect('events:event_info', event_slug=event_slug)
@login_required @login_required
def join_team(request, event_slug): def join_team(request, event_slug):
response = redirect('events:join_team', event_slug=event_slug) response = redirect('events:join_team', event_slug=event_slug)
if request.method == 'POST': if request.method == 'POST':
if request.user.is_authenticated: if request.user.is_authenticated:
ev = get_object_or_404(Event, slug=event_slug) ev = get_object_or_404(Event, slug=event_slug)
try: try:
team = Team.objects.get(name=request.POST.get('teamname'), event=ev) team = Team.objects.get(name=request.POST.get('teamname'), event=ev)
except: except:
team = None team = None
if team is None: if team is None:
return render(request, 'events/create_team.html', {'event' : ev, 'logged': True, 'wrongpwd': True, 'registered' : True, 'notexist' : True}) return render(request, 'events/create_team.html', {'event' : ev, 'logged': True, 'wrongpwd': True, 'registered' : True, 'notexist' : True})
if request.POST.get('password') != team.password: else:
return render(request, 'events/create_team.html', {'event' : ev, 'logged': True, 'wrongpwd': True, 'registered' : True, 'notexist' : False}) members = EventPlayer.objects.filter(team=team)
else: if request.POST.get('password') != team.password:
player = EventPlayer.objects.get(user=request.user, event=ev) return render(request, 'events/create_team.html', {'event' : ev, 'logged': True, 'wrongpwd': True, 'registered' : True, 'notexist' : False})
player.team = team if members.count() >= ev.team_size:
player.save() return render(request, 'events/create_team.html', {'event' : ev, 'logged': True, 'wrongpwd': False, 'registered' : True, 'notexist' : False, 'max' : True})
return redirect('events:event_info', event_slug=event_slug) else:
player = EventPlayer.objects.get(user=request.user, event=ev)
player.team = team
player.save()
return redirect('events:event_info', event_slug=event_slug)
@login_required
def profile(request, user_name, event_slug):
catsDatas = []
event_info = get_object_or_404(Event, slug=event_slug)
user_obj = get_object_or_404(User, username=user_name)
player = EventPlayer.objects.get(user=user_obj, event=event_info)
all_players = list(EventPlayer.objects.filter(event=event_info).order_by('-score', 'last_submission_date', 'user__username'))
rank = all_players.index(get_object_or_404(EventPlayer, user=user_obj, event=event_info)) + 1
cats = Category.objects.all()
pointDatas = {}
for cat in cats:
# prepare categories
solved_count = CTF_flags.objects.filter(user=user_obj, ctf__event=event_info , ctf__category__name=cat.name).count()
max_count = CTF.objects.filter(category__name=cat.name, event=event_info).count()
# get datas
somme = 0
solved = CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat.name, ctf__event=event_info).order_by('flag_date')
pointDatas[cat.name] = []
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:
somme += flag.ctf.points
pointDatas[cat.name].append([flag.flag_date.timestamp() * 1000, somme])
solves = CTF_flags.objects.filter(user=user_obj, ctf__event=event_info).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,'catsDatas': catsDatas, 'pointDatas': pointDatas, 'rank': rank, 'score' : somme})
@login_required
def team_info(request, name, event_slug):
event_info = get_object_or_404(Event, slug=event_slug)
team = Team.objects.get(name=name, event=event_info)
catsDatas = []
players = EventPlayer.objects.filter(team=team, event=event_info)
users = [p.user for p in players]
all_teams = list(Team.objects.filter(event=event_info).order_by('-score', 'last_submission_date', 'name'))
rank = all_teams.index(get_object_or_404(Team, id=team.id, event=event_info)) + 1
cats = Category.objects.all()
pointDatas = {}
for cat in cats:
# prepare categories
solved_count = 0
solved = []
max_count = CTF.objects.filter(category__name=cat.name, event=event_info).count()
somme = 0
pointDatas[cat.name] = [[event_info.start_date.timestamp()*1000, 0]]
for user_obj in users:
# get datas
solved_count += CTF_flags.objects.filter(user=user_obj, ctf__event=event_info , ctf__category__name=cat.name).count()
solved += CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat.name, ctf__event=event_info).order_by('flag_date')
# 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:
somme += flag.ctf.points
pointDatas[cat.name].append([flag.flag_date.timestamp() * 1000, somme])
query = Q()
for user_obj in users:
query |= Q(user=user_obj)
query &= Q(ctf__event=event_info)
solves = CTF_flags.objects.filter(query).order_by('-flag_date')
solved = []
somme = 0
solved.append([event_info.start_date.timestamp() * 1000, 0])
for s in solves.reverse():
somme += s.ctf.points
solved.append([s.flag_date.timestamp() * 1000,somme])
return render(request,'events/team.html', {'users':users, 'solves':solves,'solved':solved,'catsDatas': catsDatas, 'pointDatas': pointDatas,
'rank': rank, 'team':team, 'score':somme, 'event':event_info})