Skip to content

Commit

Permalink
Set the top four of the final ranking
Browse files Browse the repository at this point in the history
  • Loading branch information
Osvaldo Matos-Junior committed Jul 13, 2014
1 parent 37014b1 commit 7be8802
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 8 deletions.
32 changes: 30 additions & 2 deletions bolao/admin.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# -*- coding: utf-8 -*-

import flask

from flask import request, redirect, url_for
from flask.ext.admin import BaseView, AdminIndexView, expose
from flask.ext.admin.contrib.sqla import ModelView as SQLAModelView
from flask.ext import login

from wtforms import PasswordField

from bolao.utils import generate_password_hash
from bolao.tasks import update_scores_by_game, update_ranking, update_positions, update_scorer
from bolao.tasks import (update_scores_by_game, update_ranking, update_positions,
update_scorer, update_champions)
from bolao.models import Scorer, Team


Expand Down Expand Up @@ -64,3 +68,27 @@ def on_model_change(self, form, model, is_created):
if not is_created:
update_scorer(model)
update_positions()


class ChampionsView(BaseView):

@expose('/')
def index(self):
teams = Team.query.order_by(Team.name)
first = Team.query.filter_by(position=1).first()
second = Team.query.filter_by(position=2).first()
third = Team.query.filter_by(position=3).first()
fourth = Team.query.filter_by(position=4).first()
return self.render('admin/champions.html', teams=teams, first=first, second=second, third=third, fourth=fourth)

@expose('/save', methods=['POST'])
def save(self):

load = lambda x: Team.query.get(request.form.get(x, -1))
try:
update_champions(load('first'), load('second'), load('third'), load('fourth'))
update_positions()
flask.flash("The champions was updated successfully", category='success')
except AssertionError:
flask.flash("You need to choose all four teams", category='error')
return redirect(url_for('.index'))
3 changes: 2 additions & 1 deletion bolao/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def favicon():

def configure_admin(app):

from .admin import ModelView, IndexView, UserView, ScorerView, GameView
from .admin import ModelView, IndexView, UserView, ScorerView, GameView, ChampionsView
admin = Admin(app, index_view=IndexView())

from .models import User, Scorer, Team, Game
Expand All @@ -137,6 +137,7 @@ def configure_admin(app):
admin.add_view(ScorerView(Scorer, db.session, 'Artilheiros'))
# admin.add_view(ModelView(Team, db.session, u'Seleções'))
admin.add_view(GameView(Game, db.session, 'Jogos'))
admin.add_view(ChampionsView(u"Campeões"))
# admin.add_view(ModelView(BetGame, db.session))
# admin.add_view(ModelView(BetChampions, db.session))
# admin.add_view(ModelView(BetScorer, db.session))
5 changes: 5 additions & 0 deletions bolao/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class Team(db.Model):
id = db.Column(db.Integer, primary_key=True)
alias = db.Column(db.String(3), unique=True)
name = db.Column(db.String(80))
position = db.Column(db.Integer)

def __repr__(self):
return self.name
Expand Down Expand Up @@ -109,6 +110,10 @@ class BetChampions(db.Model):
score = db.Column(db.Integer, default=0)


def __repr__(self):
return "1-{0} 2-{1} 3-{2} 4-{3}".format(self.first, self.second, self.third, self.fourth)


class BetScorer(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
Expand Down
38 changes: 37 additions & 1 deletion bolao/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
from sqlalchemy.orm.session import make_transient

from bolao.database import db
from bolao.models import Scorer, BetGame, BetScorer, User
from bolao.models import User, Team, Scorer, BetGame, BetScorer, BetChampions

EXACT_RESULT = 18
RESULT_AND_A_SCORE = 12
ONLY_RESULT = 9
ONLY_ONE_SCORE = 3
SCORER_POINTS = 20
EXACT_CHAMPIONS = 10
CHAMPIONS_POINTS = 5


def update_scorer(scorer):
Expand Down Expand Up @@ -41,6 +43,40 @@ def update_scorer(scorer):
db.session.commit()


def update_champions(first, second, third, fourth):

assert None not in (first, second, third, fourth)

# reset all
BetChampions.query.update({'score': 0})
Team.query.update({'position': 0})

first.position = 1
second.position = 2
third.position = 3
fourth.position = 4

rank = (first.id, second.id, third.id, fourth.id)
bets = BetChampions.query.filter(or_(
BetChampions.first_id.in_(rank),
BetChampions.second_id.in_(rank),
BetChampions.third_id.in_(rank),
BetChampions.fourth_id.in_(rank))).all()

def update_pos(arg):
bet_team, team = arg[0], arg[1]
if bet_team.id in rank:
return EXACT_CHAMPIONS if bet_team == team else CHAMPIONS_POINTS
return 0

def update_all(bet):
bet.score = sum(map(update_pos, [(bet.first, first), (bet.second, second), (bet.third, third), (bet.fourth, fourth)]))
update_total_score(bet.user, bet_champions=bet)

map(update_all, bets)
db.session.commit()


def update_total_score(user, bet_scorer=None, bet_champions=None):
user.score_total = user.score_games
bet_scorer = bet_scorer or user.bet_scorer
Expand Down
60 changes: 60 additions & 0 deletions bolao/templates/admin/champions.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{% extends 'admin/master.html' %}

{% block head %}
{{super()}}
<style>
.champions_content {
width: 500px;
}

.flag {
margin: -5px 12px 0;
}

.table > tbody > tr > th {
border-top: none;
text-align: center;
}
</style>
{% endblock %}

{% block body %}
<h4>Quais seleções foram as quatro primeiras colocadas da Copa do Mundo 2014?</h4>
<div class="champions_content">
<form action="{{url_for('.save')}}" method="post">
<table class="table">
<tr>
<th>&nbsp;</th>
<th>1&ordm;</th>
<th>2&ordm;</th>
<th>3&ordm;</th>
<th>4&ordm;</th>
</tr>
{% for team in teams %}
<tr>
<td><img class="flag" src="{{url_for('static', filename='images/flags/%s.png'%team.alias)}}" width="30" height="30" alt="{{team.name}}" />{{team.name}} ({{team.alias}})</td>
<td><input type="radio" name="first" value="{{team.id}}" {{'checked="checked"' if team == first}}/>
<td><input type="radio" name="second" value="{{team.id}}" {{'checked="checked"' if team == second}}/>
<td><input type="radio" name="third" value="{{team.id}}" {{'checked="checked"' if team == third}}/>
<td><input type="radio" name="fourth" value="{{team.id}}" {{'checked="checked"' if team == fourth}}/>
</tr>
{% endfor %}
</table>
<button type="submit" class="btn btn-default pull-right">Salvar</button>
</form>
</div>
{% endblock %}

{% block tail_js %}
{{super()}}
<script>
$(function(){
$('input:radio').on('click', function() {
$(this).closest('tr').find('input:radio').each(function() {
this.checked = false;
});
this.checked = true;
});
});
</script>
{% endblock %}
12 changes: 10 additions & 2 deletions bolao/templates/profile_champions.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

{% macro row_champion(team, position, pts=0) %}
{% macro row_champion(team, position) %}
<tr>
<td>
<strong>{{position}}&ordm;</strong>
Expand All @@ -9,7 +9,11 @@
&nbsp;&nbsp;<small>Não escolhido</small>
{% endif %}
</td>
<td>{{pts}}</td>
{% if team.position %}
<td>{{10 if team.position == position else 5}}</td>
{% else %}
<td>0</td>
{% endif %}
</tr>
{% endmacro %}

Expand All @@ -25,6 +29,10 @@
{{row_champion(bet.second, 2)}}
{{row_champion(bet.third, 3)}}
{{row_champion(bet.fourth, 4)}}
<tr class="total">
<td>Total ({{((100*bet.score)/(40))|round(2)}}%)</td>
<td>{{bet.score}}</td>
</tr>
</table>
{% if profile.id == current_user.id and now() < config.BOLAO_BET_CHAMPIONS_LIMIT %}
<a href="{{url_for('.bet_champions', edit='edit')}}" class="btn btn-default btn-xs btn-block">Editar</a>
Expand Down
103 changes: 101 additions & 2 deletions tests/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

from flask.ext.testing import TestCase

from bolao.models import Team, User, Game, Scorer, BetScorer, BetGame
from bolao.models import Team, User, Game, Scorer, BetScorer, BetGame, BetChampions
from bolao.main import app_factory
from bolao.tasks import (update_scores_by_game, update_ranking, update_ranking_criterias,
update_scorer)
update_scorer, update_champions)
from bolao.database import db


Expand Down Expand Up @@ -456,3 +456,102 @@ def test_no_changes(self):
update_scorer(self.fred)
self.assertEqual(20, bet.score)
self.assertEqual(20, self.user.score_total)


class UpdateChampionsTest(TestCase):

def create_app(self):
app = app_factory('Testing')
return app

def setUp(self):
db.create_all()

user = User(name="Test", email="[email protected]", active=True)
db.session.add(user)

bra = Team(name='Brasil', alias='BRA')
arg = Team(name='Argentina', alias='ARG')
uru = Team(name='Uruguai', alias='URU')
ale = Team(name='Alemanha', alias='ALE')
usa = Team(name='Estados Unidos', alias='USA')
db.session.add(bra)
db.session.add(arg)
db.session.add(uru)
db.session.add(ale)
db.session.add(usa)

db.session.commit()

self.user = user
self.bra = bra
self.arg = arg
self.uru = uru
self.ale = ale
self.usa = usa

def tearDown(self):
db.session.remove()
db.drop_all()

def test_exact_positions(self):

bet = BetChampions(first=self.bra, second=self.arg, third=self.ale, fourth=self.uru, user=self.user)
db.session.add(bet)
db.session.commit()

update_champions(self.bra, self.arg, self.ale, self.uru)

self.assertEqual(40, bet.score)
self.assertEqual(40, self.user.score_total)

def test_only_positions(self):

bet = BetChampions(first=self.bra, second=self.arg, third=self.ale, fourth=self.uru, user=self.user)
db.session.add(bet)
db.session.commit()

update_champions(self.uru, self.ale, self.arg, self.bra)

self.assertEqual(20, bet.score)
self.assertEqual(20, self.user.score_total)

def test_mixed_positions(self):

bet = BetChampions(first=self.ale, second=self.arg, third=self.bra, fourth=self.uru, user=self.user)
db.session.add(bet)
db.session.commit()

update_champions(self.bra, self.usa, self.arg, self.uru)

self.assertEqual(20, bet.score)
self.assertEqual(20, self.user.score_total)

def test_any_position(self):

t1 = Team(name="T1", alias="T1")
t2 = Team(name="T2", alias="T2")
t3 = Team(name="T3", alias="T3")
t4 = Team(name="T4", alias="T4")

db.session.add(t1)
db.session.add(t2)
db.session.add(t3)
db.session.add(t4)

bet = BetChampions(first=self.bra, second=self.arg, third=self.ale, fourth=self.uru, user=self.user)
db.session.add(bet)
db.session.commit()

update_champions(t1, t2, t3, t4)

self.assertEqual(0, bet.score)


def test_raises_with_none(self):
bet = BetChampions(first=self.bra, second=self.arg, third=self.ale, fourth=self.uru, user=self.user)
db.session.add(bet)
db.session.commit()

self.assertRaises(AssertionError, update_champions, None, None, None, None)

0 comments on commit 7be8802

Please sign in to comment.