Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions challenge/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@
from django.contrib.admin import ModelAdmin

from challenge.forms import ChallengeAdminForm
from challenge.models import Challenge, ChallengeUser, ChallengeTroll, VoteReaction
from challenge.models import Challenge, ChallengeUser, ChallengeTroll, VoteReaction, ChallengeTopic


class ChallengeTrollAdmin(admin.StackedInline):
model = ChallengeTroll
extra = 1


class VoteReactionAdmin(admin.StackedInline):
model = VoteReaction
extra = 1


class ChallengeAdmin(ModelAdmin):
form = ChallengeAdminForm
inlines = [ChallengeTrollAdmin, VoteReactionAdmin]


admin.site.register(Challenge, admin_class=ChallengeAdmin)
admin.site.register(ChallengeTopic)
admin.site.register(Challenge, ChallengeAdmin)
admin.site.register(ChallengeUser)
admin.site.register(ChallengeTroll)
admin.site.register(VoteReaction)
4 changes: 2 additions & 2 deletions challenge/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


class ChallengeAdminForm(ModelForm):
solution_code = forms.CharField(initial='', required=False)
solution_code = forms.CharField(initial='', required=False, max_length=100)

def save(self, commit=True):
solution_code = self.cleaned_data.get('solution_code', '')
Expand All @@ -20,7 +20,7 @@ class Meta:


class ChallengeTryForm(Form):
code = forms.CharField(initial='', required=True)
code = forms.CharField(initial='', required=True, max_length=100)


class VoteForm(ModelForm):
Expand Down
26 changes: 26 additions & 0 deletions challenge/migrations/0002_auto_20220228_1619.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 3.2.8 on 2022-02-28 16:19

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('challenge', '0001_initial'),
]

operations = [
migrations.CreateModel(
name='ChallengeTopic',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
],
),
migrations.AddField(
model_name='challenge',
name='topic',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='challenge.challengetopic'),
),
]
4 changes: 2 additions & 2 deletions challenge/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ def dispatch(self, request, *args, **kwargs):
if challenge.order != 1:
c_order = challenge.order - 1
success = ChallengeUser.objects.filter(challenge__order=c_order, user=request.user,
success=True).count()
challenges = Challenge.objects.filter(order=c_order).count()
success=True, challenge__topic=challenge.topic).count()
challenges = Challenge.objects.filter(order=c_order, topic=challenge.topic).count()
if challenges > success:
return self.handle_no_permission()
return super().dispatch(request, *args, **kwargs)
10 changes: 9 additions & 1 deletion challenge/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
from django.template import Template, Context


class ChallengeTopic(models.Model):
name = models.CharField(max_length=100)

def __str__(self):
return self.name


class Challenge(models.Model):
TYPE_IMAGE = 'img'
TYPE_FILE = 'file'
Expand All @@ -29,9 +36,10 @@ class Challenge(models.Model):
solution = models.CharField(max_length=1000)
file = models.FileField()
activation_date = models.DateTimeField(default=datetime.now)
topic = models.ForeignKey(ChallengeTopic, on_delete=models.SET_NULL, null=True, blank=True)

def __str__(self):
return '%s - %s' % (self.order, self.name)
return '%s - %s - %s' % (self.order, self.topic, self.name)

def active(self):
return self.activation_date <= pytz.utc.localize(datetime.now())
Expand Down
10 changes: 6 additions & 4 deletions challenge/templates/challenge_index.html
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
{% extends 'base.html' %}
{% load bootstrap3 %}
{% load dictionaries %}
{% block head_title %}Challenges{% endblock %}
{% block content %}
<h1 style="text-align: center">Challenges</h1>
<p>Complete all challenges faster than anyone else to win the competition!</p>

{% for phase, group in challenge_groups.items %}
<h2>Phase {{ phase }}</h2>
<h2>{% if phase is not None %}Topic: {{ phase }}{% else %}Challenges{% endif %}</h2>
<div class="list-group">
{% for challenge in group %}
<a {% if challenge.active and player_phase >= challenge.order or request.user.is_staff %}href="{% url 'challenge' challenge.pk %}"{% endif %} class="list-group-item" style="font-size: x-large">
<a {% if challenge.active and player_phase|is_allowed:challenge or request.user.is_staff %}href="{% url 'challenge' challenge.pk %}"{% endif %} class="list-group-item {% if challenge.active and player_phase|is_allowed:challenge or request.user.is_staff %}{% else %}disabled-item{% endif %}" style="font-size: x-large">
<div class="row">
<div class="col-lg-11" style="padding-left: 0px !important;">
Challenge: {{ challenge.name }}<br>
<p style="font-size: small; margin: 0px !important;">{% if finished %}{{ app_name }} has finished{% elif challenge.active %}Active now{% else %}Not active. Starts at <span name="dates">{{ challenge.activation_date|date:"m/d/Y H:i:s T" }}{% endif %}</span></p>
{{ challenge.name }}<br>
<p style="font-size: small; margin: 0px !important;">{% if finished %}{{ app_name }} has finished{% elif challenge.active and player_phase|is_allowed:challenge %}Active now {% elif challenge.active%}Challenge disabled. Finish previous challenges from this topic first.{% else %}Not active. Starts at <span name="dates">{{ challenge.activation_date|date:"m/d/Y H:i:s T" }}{% endif %}</span></p>
</div>
<div class="col-lg-1 text-right" style="padding-right: 0px !important;">
{% if challenge.player_try.0.success %}<span class="badge badge-primary">Done</span>{% endif %}
Expand Down
Empty file.
6 changes: 6 additions & 0 deletions challenge/templatetags/dictionaries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.template.defaulttags import register


@register.filter
def is_allowed(dictionary, challenge):
return dictionary.get(challenge.topic, 1) >= challenge.order
26 changes: 14 additions & 12 deletions challenge/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,30 @@ class HomeView(LoginRequiredMixin, TemplateView):

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
challenges = Challenge.objects.all().prefetch_related(
Prefetch('challengeuser_set', queryset=ChallengeUser.objects.filter(user=self.request.user),
challenges = Challenge.objects.all().order_by('order').prefetch_related(
Prefetch('challengeuser_set', queryset=ChallengeUser.objects.filter(user=self.request.user, success=True),
to_attr='player_try'))
result = {}
player = {}
for challenge in challenges:
aux2 = player.get(challenge.topic, {'order': 1, 'done': 0, 'challenges': 0})
try:
aux2 = player.get(challenge.order, 0) + int(challenge.player_try[0].success)
player[challenge.order] = aux2
aux2['done'] += int(challenge.player_try[-1].success)
if aux2['order'] != challenge.order:
aux2['order'] = challenge.order
aux2['challenges'] = 0
except IndexError:
pass
aux = result.get(challenge.order, [])
if aux2['order'] == challenge.order:
aux2['challenges'] += 1
player[challenge.topic] = aux2
aux = result.get(challenge.topic, [])
aux.append(challenge)
result[challenge.order] = aux
try:
max_challenge = sorted(player.items())[-1]
except IndexError:
max_challenge = (1, 0)
player_phase = max_challenge[0] + int(max_challenge[1] == len(result.get(max_challenge[0], [])))
result[challenge.topic] = aux
player = {topic: item['order'] + int(item['done'] == item['challenges']) for topic, item in player.items()}
context.update({
'challenge_groups': result,
'player_phase': player_phase,
'player_phase': player,
})
return context

Expand Down
2 changes: 1 addition & 1 deletion ranking/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ class RankingView(LoginRequiredMixin, SingleTableView):

def get_queryset(self):
return ChallengeUser.objects.filter(success=True).values('user__username')\
.annotate(count=Count('*'), time=Max('last_try')).order_by('-count', '-time')
.annotate(count=Count('*'), time=Max('last_try')).order_by('-count', 'time')
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ django-bootstrap3==15.0.0
django-tables2==2.4.1
sendgrid==3.6.3
sendgrid-django==4.0.4
psycopg2-binary~=2.8.3
gunicorn==19.6.0
2 changes: 2 additions & 0 deletions thegame/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

MAX_UPLOAD_SIZE = "104857600"

CAS_SERVER_URL = 'https://my.hackupc.com/cas/'
CAS_VERSION = '3'
CAS_APPLY_ATTRIBUTES_TO_USER = True
5 changes: 0 additions & 5 deletions thegame/static/css/custom-bootstrap.css
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,6 @@ th {
border: 1px solid #ddd !important;
}
}
@font-face {
font-family: "Glyphicons Halflings";
src: url("../fonts/glyphicons-halflings-regular.eot");
src: url("../fonts/glyphicons-halflings-regular.eot?#iefix") format("embedded-opentype"), url("../fonts/glyphicons-halflings-regular.woff2") format("woff2"), url("../fonts/glyphicons-halflings-regular.woff") format("woff"), url("../fonts/glyphicons-halflings-regular.ttf") format("truetype"), url("../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular") format("svg");
}
.glyphicon {
position: relative;
top: 1px;
Expand Down
8 changes: 7 additions & 1 deletion thegame/static/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ img {
padding: 0.5em 1em;
text-align: center;
transition: bottom 1s;
background-color:#3f5182;
background-color:#459574;
z-index:1031; /*footer was set to 1030*/
box-shadow: 0px 15px 15px 15px black;
color:white;
Expand Down Expand Up @@ -403,3 +403,9 @@ input:-webkit-autofill
margin-left: 0px;
margin-right: 0px;
}

.list-group-item.disabled-item {
background: #444444;
pointer-events: none;
color: #cccccc
}
Binary file added thegame/static/img/sort_asc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added thegame/static/img/sort_both.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added thegame/static/img/sort_desc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions thegame/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@


<meta name="theme-color" content="#f8f8f8">
<meta name="author" content="{{ h_name }}">
<meta name="description" content="{{ h_description }}">
<meta name="author" content="{{ app_name }}">
<meta name="description" content="{{ app_description }}">

<!--FAVICON -->
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'img/favicon/apple-touch-icon.png' %}">
Expand All @@ -17,8 +17,8 @@
<link rel="manifest" href="{% static 'img/favicon/site.webmanifest' %}">
<link rel="mask-icon" href="{% static 'img/favicon/safari-pinned-tab.svg' %}" color="#5f723f">
<link rel="shortcut icon" href="{% static 'img/favicon/favicon.ico' %}">
<meta name="apple-mobile-web-app-title" content="My HackUPC">
<meta name="application-name" content="My HackUPC">
<meta name="apple-mobile-web-app-title" content="HackUPC - The game">
<meta name="application-name" content="HackUPC - The game">
<meta name="msapplication-TileColor" content="#f8f8f8">
<meta name="msapplication-config" content="{% static 'img/favicon/browserconfig.xml' %}">

Expand Down
1 change: 1 addition & 0 deletions thegame/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ def finished():
def get_substitutions_templates(request):
return {
'app_name': settings.APP_NAME,
'app_description': 'The game is easy! Go and try to solve all challenges!',
'finished': finished(),
}