diff --git a/Dockerfile b/Dockerfile index fae3228a..d7c77a5d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,15 @@ -FROM alpine +FROM python:3 ADD entrypoint.sh /entrypoint.sh +ADD requirements.txt requirements.txt RUN \ chmod +x /entrypoint.sh && \ - apk add --update --no-cache python py-pip gettext && \ - pip install --upgrade pip && \ - pip install Django>=1.9 gunicorn && \ - rm -rf /var/cache/apk/* + apt-get update && \ + apt-get install -y --no-install-recommends gettext && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +RUN pip install -r requirements.txt ENTRYPOINT ["/entrypoint.sh"] diff --git a/entrypoint.sh b/entrypoint.sh index 17aac170..a9073ddd 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,9 +1,9 @@ -#!bin/sh +#!bin/bash cd /ipt_connect -if [ "$DEV" == "true" ]; then +if [ "$DEV" = "true" ]; then python manage.py runserver 0.0.0.0:8000 exit 1 fi -gunicorn --workers=${WORKERS} --bind=unix:/ipt_connect/ipt_connect.sock ipt_connect.wsgi \ No newline at end of file +gunicorn --workers=${WORKERS} --bind=unix:/ipt_connect/ipt_connect.sock ipt_connect.wsgi diff --git a/ipt_connect/IPTdev/admin.py b/ipt_connect/IPTdev/admin.py index fe91d200..ae69a02f 100644 --- a/ipt_connect/IPTdev/admin.py +++ b/ipt_connect/IPTdev/admin.py @@ -2,8 +2,8 @@ from django.contrib import admin from solo.admin import SingletonModelAdmin -from model_SupplementaryMaterial import * -from models import * +from .model_SupplementaryMaterial import * +from .models import * # from config.models import SiteConfiguration diff --git a/ipt_connect/IPTdev/cache_per_user.py b/ipt_connect/IPTdev/cache_per_user.py index 40e03c68..257eb755 100644 --- a/ipt_connect/IPTdev/cache_per_user.py +++ b/ipt_connect/IPTdev/cache_per_user.py @@ -33,7 +33,7 @@ def apply_cache(request, *args, **kwargs): # No caching for authorized users: # they have to see the results of their edits immideately! - can_cache = request.user.is_anonymous() and request.method == 'GET' + can_cache = request.user.is_anonymous and request.method == 'GET' # Gera a chave do cache if prefix: @@ -47,7 +47,7 @@ def apply_cache(request, *args, **kwargs): response = None if not response: - print 'Not in cache: %s' % (CACHE_KEY) + print('Not in cache: %s' % (CACHE_KEY)) response = function(request, *args, **kwargs) if can_cache: cache.set(CACHE_KEY, response, ttl) diff --git a/ipt_connect/IPTdev/forms.py b/ipt_connect/IPTdev/forms.py index c8bf34f6..93249b81 100644 --- a/ipt_connect/IPTdev/forms.py +++ b/ipt_connect/IPTdev/forms.py @@ -1,8 +1,8 @@ from django import forms from django.http import JsonResponse -from django.utils.encoding import smart_unicode +from django.utils.encoding import smart_str -from models import Participant +from .models import Participant # class RegisterForm(forms.ModelForm): @@ -31,7 +31,7 @@ def member_for_team(request): if request.GET and "team_id" in request.GET: objs = Participant.objects.filter(team=request.GET["team_id"]) for o in objs: - res.append({"id": o.id, "name": smart_unicode(o)}) + res.append({"id": o.id, "name": smart_str(o)}) # return HttpResponse(json.dumps(res), content_type="application/json") return JsonResponse({"res": res}) diff --git a/ipt_connect/IPTdev/func_mean.py b/ipt_connect/IPTdev/func_mean.py index 87052525..0fd76464 100644 --- a/ipt_connect/IPTdev/func_mean.py +++ b/ipt_connect/IPTdev/func_mean.py @@ -18,7 +18,7 @@ def ipt_mean(vec): # There was an unsuccessful attempt to refactor it. # The code should be refactored and tested. - nhigh = nreject / 2 + nhigh = nreject // 2 nlow = nreject - nhigh if nhigh == 0: diff --git a/ipt_connect/IPTdev/model_SupplementaryMaterial.py b/ipt_connect/IPTdev/model_SupplementaryMaterial.py index 5dd3ef19..8a0f9bbf 100644 --- a/ipt_connect/IPTdev/model_SupplementaryMaterial.py +++ b/ipt_connect/IPTdev/model_SupplementaryMaterial.py @@ -2,11 +2,11 @@ from django.db import models -import models as ipt_connect_models +from . import models as ipt_connect_models class SupplementaryMaterial(models.Model): - team = models.ForeignKey(ipt_connect_models.Team, null=True) - problem = models.ForeignKey(ipt_connect_models.Problem) + team = models.ForeignKey(ipt_connect_models.Team, null=True, on_delete=models.CASCADE) + problem = models.ForeignKey(ipt_connect_models.Problem, on_delete=models.CASCADE) name = models.CharField(max_length=500) link = models.CharField(max_length=5000) diff --git a/ipt_connect/IPTdev/models.py b/ipt_connect/IPTdev/models.py index 54b92814..0fc55c97 100644 --- a/ipt_connect/IPTdev/models.py +++ b/ipt_connect/IPTdev/models.py @@ -1,7 +1,6 @@ # coding: utf8 import os import time -from string import replace from uuid import uuid4 from django.contrib.auth.models import User @@ -16,9 +15,9 @@ from django.utils.encoding import iri_to_uri from solo.models import SingletonModel -import func_mean as means -import parameters as params -from func_bonus import distribute_bonus_points +from . import func_mean as means +from . import parameters as params +from .func_bonus import distribute_bonus_points # Useful static variables selective_fights = [i + 1 for i in range(params.npf)] @@ -120,7 +119,7 @@ class Participant(models.Model): passport_number = models.CharField(blank=True, max_length=50) birthdate = models.DateField(default='1900-01-31', verbose_name='Birthdate') # photo = models.ImageField(upload_to=UploadToPathAndRename(params.instance_name+'/id_photo'),help_text="Please use a clear ID photo. This will be used for badges and transportation cards.", null=True) - team = models.ForeignKey('Team', null=True, verbose_name='Team') + team = models.ForeignKey('Team', null=True, verbose_name='Team', on_delete=models.CASCADE) role = models.CharField( max_length=20, choices=ROLE_CHOICES, @@ -166,7 +165,7 @@ def fullname(self): """ return self.name + ' ' + self.surname - def __unicode__(self): + def __str__(self): """ :return: return the full name of the participant """ @@ -252,7 +251,7 @@ class Problem(models.Model): mean_score_of_opponents = models.FloatField(default=0.0, editable=False) mean_score_of_reviewers = models.FloatField(default=0.0, editable=False) - def __unicode__(self): + def __str__(self): return self.name def status(self, verbose=True, meangradesonly=False): @@ -392,7 +391,7 @@ class Team(models.Model): nrounds_as_opp = models.IntegerField(default=0, editable=False) nrounds_as_rev = models.IntegerField(default=0, editable=False) - def __unicode__(self): + def __str__(self): return self.name @@ -601,7 +600,7 @@ class Room(models.Model): name = models.CharField(max_length=50) link = models.CharField(max_length=2083, blank=True, default='') - def __unicode__(self): + def __str__(self): return self.name @property @@ -625,7 +624,7 @@ def fullname(self): """ return self.name + ' ' + self.surname - def __unicode__(self): + def __str__(self): return self.fullname() email = models.EmailField( @@ -639,7 +638,7 @@ def __unicode__(self): verbose_name='Affiliation to display', help_text='Will be used for export (badges and web).', ) - team = models.ForeignKey('Team', null=True, blank=True) + team = models.ForeignKey('Team', null=True, blank=True, on_delete=models.CASCADE) # TODO: unhardcode PF number! pf1 = models.BooleanField(default=False, verbose_name='PF 1') pf2 = models.BooleanField(default=False, verbose_name='PF 2') @@ -666,29 +665,29 @@ class Round(models.Model): ), default=None, ) - room = models.ForeignKey(Room) + room = models.ForeignKey(Room, on_delete=models.CASCADE) reporter_team = models.ForeignKey( - Team, related_name='reporterteam', blank=True, null=True + Team, related_name='reporterteam', blank=True, null=True, on_delete=models.CASCADE ) opponent_team = models.ForeignKey( - Team, related_name='opponentteam', blank=True, null=True + Team, related_name='opponentteam', blank=True, null=True, on_delete=models.CASCADE ) reviewer_team = models.ForeignKey( - Team, related_name='reviewerteam', blank=True, null=True + Team, related_name='reviewerteam', blank=True, null=True, on_delete=models.CASCADE ) reporter = models.ForeignKey( - Participant, related_name='reporter_name_1', blank=True, null=True + Participant, related_name='reporter_name_1', blank=True, null=True, on_delete=models.CASCADE ) reporter_2 = models.ForeignKey( - Participant, related_name='reporter_name_2', blank=True, null=True + Participant, related_name='reporter_name_2', blank=True, null=True, on_delete=models.CASCADE ) opponent = models.ForeignKey( - Participant, related_name='opponent_name', blank=True, null=True + Participant, related_name='opponent_name', blank=True, null=True, on_delete=models.CASCADE ) reviewer = models.ForeignKey( - Participant, related_name='reviewer_name', blank=True, null=True + Participant, related_name='reviewer_name', blank=True, null=True, on_delete=models.CASCADE ) - problem_presented = models.ForeignKey(Problem, blank=True, null=True) + problem_presented = models.ForeignKey(Problem, blank=True, null=True, on_delete=models.CASCADE) submitted_date = models.DateTimeField(default=timezone.now, blank=True, null=True) score_reporter = models.FloatField(default=0.0, editable=False) @@ -705,7 +704,7 @@ class Round(models.Model): default=0.0, editable=params.manual_bonus_points ) - def __unicode__(self): + def __str__(self): try: fight_name = params.fights['names'][self.pf_number - 1] except: @@ -844,8 +843,8 @@ class Meta: class JuryGrade(models.Model): - round = models.ForeignKey(Round, null=True) - jury = models.ForeignKey(Jury) + round = models.ForeignKey(Round, null=True, on_delete=models.CASCADE) + jury = models.ForeignKey(Jury, on_delete=models.CASCADE) grade_reporter = models.IntegerField(choices=grade_choices, default=None) @@ -853,7 +852,7 @@ class JuryGrade(models.Model): grade_reviewer = models.IntegerField(choices=grade_choices, default=None) - def __unicode__(self): + def __str__(self): return "Grade of %s" % self.jury.name def info(self): @@ -881,36 +880,36 @@ def info(self): class TacticalRejection(models.Model): - round = models.ForeignKey(Round, null=True) - problem = models.ForeignKey(Problem) + round = models.ForeignKey(Round, null=True, on_delete=models.CASCADE) + problem = models.ForeignKey(Problem, on_delete=models.CASCADE) extra_free = models.BooleanField( default=False, verbose_name='Extra free rejection', editable=params.enable_extra_free_tactical_rejections, ) - def __unicode__(self): + def __str__(self): return "Problem rejected : %s" % self.problem.pk class EternalRejection(models.Model): - round = models.ForeignKey(Round, null=True) - problem = models.ForeignKey(Problem) + round = models.ForeignKey(Round, null=True, on_delete=models.CASCADE) + problem = models.ForeignKey(Problem, on_delete=models.CASCADE) extra_free = models.BooleanField( default=False, verbose_name='Extra free rejection', editable=params.enable_extra_free_eternal_rejections, ) - def __unicode__(self): + def __str__(self): return "Problem rejected : %s" % self.problem.pk class AprioriRejection(models.Model): - team = models.ForeignKey(Team, null=True) - problem = models.ForeignKey(Problem) + team = models.ForeignKey(Team, null=True, on_delete=models.CASCADE) + problem = models.ForeignKey(Problem, on_delete=models.CASCADE) - def __unicode__(self): + def __str__(self): # TODO: also print the Team return "Problem rejected : %s" % self.problem.pk @@ -962,7 +961,7 @@ class SiteConfiguration(SingletonModel): image_URL = models.URLField(default="http://i.imgur.com/QH8aoXL.gif") image_repeat_count = models.IntegerField(default=6) - def __unicode__(self): + def __str__(self): return u"Site Configuration" class Meta: diff --git a/ipt_connect/IPTdev/parameters.py b/ipt_connect/IPTdev/parameters.py index ff51b39b..41126c78 100644 --- a/ipt_connect/IPTdev/parameters.py +++ b/ipt_connect/IPTdev/parameters.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from get_script_dir import get_script_dir +from .get_script_dir import get_script_dir # Here we get the name of the folder in which THIS FILE is located. # It is probably NOT the current working directory. diff --git a/ipt_connect/IPTdev/tactics.py b/ipt_connect/IPTdev/tactics.py index 76e1c799..1c633aba 100644 --- a/ipt_connect/IPTdev/tactics.py +++ b/ipt_connect/IPTdev/tactics.py @@ -1,4 +1,4 @@ -from views import * +from .views import * def build_tactics_for_two_teams(reporter_team, opponent_team, current_round=None): @@ -51,14 +51,14 @@ def build_tactics_for_two_teams(reporter_team, opponent_team, current_round=None # Will be filled later # TODO: is it possible to cast a lambda here? ), - 'apriori_rejected_by_reporter': map( + 'apriori_rejected_by_reporter': list(map( lambda rejection: None, list(apri_rej.filter(team=reporter_team)), - ), - 'eternally_rejected_by_reporter': map( + )), + 'eternally_rejected_by_reporter': list(map( lambda rejection: rejection.round, list(eter_rej.filter(round__reporter_team=reporter_team)), - ), + )), 'reported_by_reporter': list(atrounds.filter(reporter_team=reporter_team)), 'opposed_by_opponent': list(atrounds.filter(opponent_team=opponent_team)), 'reported_by_opponent': list(atrounds.filter(reporter_team=opponent_team)), @@ -66,11 +66,11 @@ def build_tactics_for_two_teams(reporter_team, opponent_team, current_round=None # If the opponent tried to challenge for a problem and received a rejection, # it is likely that the opponent will try to challenge for the same problem again. # This knowledge is obviously valuable for the reporter ;-) - 'tried_by_opponent': map( + 'tried_by_opponent': list(map( lambda rejection: rejection.round, list(tact_rej.filter(round__opponent_team=opponent_team)) + list(eter_rej.filter(round__opponent_team=opponent_team)), - ), + )), # The same thing for reviewing 'reviewed_by_opponent': list(atrounds.filter(reviewer_team=opponent_team)), # reporter's oppositions... @@ -78,11 +78,11 @@ def build_tactics_for_two_teams(reporter_team, opponent_team, current_round=None # ... and for reporter's reviews - no idea what for 'reviewed_by_reporter': list(atrounds.filter(reviewer_team=reporter_team)), # Crazyness must go on! - 'tried_by_reporter': map( + 'tried_by_reporter': list(map( lambda rejection: rejection.round, list(tact_rej.filter(round__opponent_team=reporter_team)) + list(eter_rej.filter(round__opponent_team=reporter_team)), - ), + )), } for round in previous_rounds: @@ -197,7 +197,7 @@ class TacticsForm(forms.Form): try: # This fails if no teams are registered (which is essentially for a new tournament) all_teams = Team.objects.all() - team_choices = map(lambda team: (team.pk, team), all_teams) + team_choices = [(team.pk, team) for team in all_teams] reporter_team = forms.ChoiceField(label='Reporter team', choices=team_choices) opponent_team = forms.ChoiceField(label='Opponent team', choices=team_choices) except: diff --git a/ipt_connect/IPTdev/templates/IPTdev/bebacksoon.html b/ipt_connect/IPTdev/templates/IPTdev/bebacksoon.html index 6118cd72..dd868e11 100644 --- a/ipt_connect/IPTdev/templates/IPTdev/bebacksoon.html +++ b/ipt_connect/IPTdev/templates/IPTdev/bebacksoon.html @@ -1,5 +1,5 @@ {% extends params.instance_name|add:'/head.html' %} -{% load staticfiles %} +{% load static %} {% load i18n %} {% load solo_tags %} diff --git a/ipt_connect/IPTdev/templates/IPTdev/head.html b/ipt_connect/IPTdev/templates/IPTdev/head.html index ce303ad8..ef1fce30 100644 --- a/ipt_connect/IPTdev/templates/IPTdev/head.html +++ b/ipt_connect/IPTdev/templates/IPTdev/head.html @@ -1,5 +1,5 @@ {% load i18n %} -{% load staticfiles %} +{% load static %}
diff --git a/ipt_connect/IPTdev/urls.py b/ipt_connect/IPTdev/urls.py index 2f75d384..4b3ba342 100644 --- a/ipt_connect/IPTdev/urls.py +++ b/ipt_connect/IPTdev/urls.py @@ -1,52 +1,52 @@ # coding: utf8 -from django.conf.urls import url +from django.urls import re_path -import parameters -from forms import member_for_team -from tactics import * +from . import parameters +from .forms import member_for_team +from .tactics import * app_name = parameters.instance_name urlpatterns = [ - url(r"^$", tournament_overview), - url(r"^tournament$", tournament_overview, name="tournament_overview"), - url(r"^participants$", participants_overview, name="participants_overview"), - url( + re_path(r"^$", tournament_overview), + re_path(r"^tournament$", tournament_overview, name="tournament_overview"), + re_path(r"^participants$", participants_overview, name="participants_overview"), + re_path( r"^participants/(?P