Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

work in progress

  • Loading branch information...
commit 1fdb862b7167adcf6e8c777cf3b7244b937feb2d 1 parent 4a5d687
@depesz authored
View
130 kanasta.py
@@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
from flask import Flask, g, render_template, flash, session, request, redirect, url_for
+from functools import wraps
import crypt
import psycopg2
import psycopg2.extras
@@ -22,6 +23,15 @@
app.config.from_object(__name__)
app.config.from_envvar('KANASTARC', silent=True)
+def login_required(f):
+ @wraps(f)
+ def decorated_function(*args, **kwargs):
+ if session.has_key( 'username' ):
+ return f(*args, **kwargs)
+ flash('NOT_LOGGED')
+ return redirect( url_for( 'index' ) )
+ return decorated_function
+
def get_db_connection():
conn_details = dict()
@@ -30,19 +40,33 @@ def get_db_connection():
return psycopg2.connect( connection_factory = psycopg2.extras.DictConnection, **conn_details )
+
@app.before_request
def before_request():
g.db = get_db_connection()
+
@app.teardown_request
def teardown_request(exception):
if hasattr(g, 'db'):
g.db.close()
+
@app.route('/main')
+@login_required
def main():
return render_template( 'main.html' )
+
+@app.route('/logout')
+def logout():
+ for key in ( 'username', 'is_admin' ):
+ if session.has_key( key ):
+ session.pop( key )
+ flash('LOGGED_OUT')
+ return redirect(url_for('index'))
+
+
@app.route('/login', methods=['POST'])
def login():
cur = g.db.cursor()
@@ -61,9 +85,115 @@ def login():
session['admin'] = user_data['is_admin']
return redirect(url_for('main'))
+
@app.route('/')
def index():
+ if session.has_key("username"):
+ return redirect( url_for('main') )
+
return render_template('index.html' )
+
+@app.route('/new_game', methods=['POST', 'GET'])
+def new_game():
+ if request.method == 'POST' and new_game_validate():
+ cur = g.db.cursor()
+ cur.execute( """
+ INSERT INTO games
+ (started, pair1_player1, pair1_player2, pair2_player1, pair2_player2, first_dealing, second_dealing)
+ VALUES
+ ( now(), least( %(p1_p1)s, %(p1_p2)s ), greatest( %(p1_p1)s, %(p1_p2)s ), least( %(p2_p1)s, %(p2_p2)s ), greatest( %(p2_p1)s, %(p2_p2)s ), %(deal_1)s, %(deal_2)s)
+ RETURNING id""", {
+ 'p1_p1': request.form['pair1_player1'],
+ 'p1_p2': request.form['pair1_player2'],
+ 'p2_p1': request.form['pair2_player1'],
+ 'p2_p2': request.form['pair2_player2'],
+ 'deal_1': request.form['first_dealing'],
+ 'deal_2': request.form['second_dealing']
+ }
+ )
+ res = cur.fetchone()
+ cur.close()
+ g.db.commit()
+ return redirect( url_for( 'game', game_id=res['id'] ) )
+
+ cur = g.db.cursor()
+ cur.execute( "SELECT username FROM users order by username" )
+ users_rs = cur.fetchall()
+ cur.close()
+ users = map( lambda r: r["username"], users_rs )
+
+ return render_template('new_game.html', users = users )
+
+
+def new_game_validate():
+ for key in ( 'pair1_player1', 'pair1_player2', 'pair2_player1', 'pair2_player2', 'first_dealing', 'second_dealing' ):
+ if request.form.has_key( key ) and request.form[ key ]:
+ continue
+ g.errors=['MISSING_DATA']
+ return False
+
+ seen=dict()
+ for key in ( 'pair1_player1', 'pair1_player2', 'pair2_player1', 'pair2_player2' ):
+ if seen.has_key( request.form[ key ] ):
+ g.errors=['DUPLICATE_DATA']
+ return False
+ seen[key] = 1;
+
+ if request.form['first_dealing'] == request.form['second_dealing']:
+ g.errors=['DUPLICATE_DATA']
+ return False
+
+ first_dealing_pair = 2
+ second_dealing_pair = 2
+ if request.form['first_dealing'] in ( request.form['pair1_player1'], request.form['pair1_player2'] ):
+ first_dealing_pair = 1
+ if request.form['second_dealing'] in ( request.form['pair1_player1'], request.form['pair1_player2'] ):
+ second_dealing_pair = 1
+
+ if first_dealing_pair == second_dealing_pair:
+ g.errors=[ 'BAD_DEALING' ]
+ return False
+
+ return True
+
+
+@app.route('/game/<int:game_id>')
+def game( game_id ):
+ cur = g.db.cursor()
+ cur.execute( "SELECT * FROM games WHERE id = %s", ( game_id, ) )
+ game = cur.fetchone()
+ cur.execute( "select *, sum(pair1_score) over (order by deal_no) as pair1_sum, sum(pair2_score) over (order by deal_no) as pair2_sum from deals where game_id = 26 order by deal_no", ( game_id, ) )
+ deals = cur.fetchall()
+ cur.close()
+
+ pair1=set( [ game[ 'pair1_player1' ], game[ 'pair1_player2' ] ] )
+ pair2=set( [ game[ 'pair2_player1' ], game[ 'pair2_player2' ] ] )
+ dealing_order=[]
+ dealing_order.append( game[ 'first_dealing' ] )
+ dealing_order.append( game[ 'second_dealing' ] )
+
+ if game[ 'first_dealing' ] in pair1:
+ pair1.remove( game[ 'first_dealing' ])
+ pair2.remove( game[ 'second_dealing' ])
+ dealing_order.extend( pair1 )
+ dealing_order.extend( pair2 )
+ else:
+ pair2.remove( game[ 'first_dealing' ])
+ pair1.remove( game[ 'second_dealing' ])
+ dealing_order.extend( pair2 )
+ dealing_order.extend( pair1 )
+
+ return render_template('game.html', game = game, deals = deals, dealing_order = dealing_order )
+
+@app.route("/games")
+def games():
+ pass
+
+
+@app.route('/game_stats')
+def game_stats():
+ pass
+
if __name__ == '__main__':
app.run()
View
0  static/style.css
No changes.
View
108 templates/game.html
@@ -0,0 +1,108 @@
+{% extends "layout_logged.html" %}
+{% block content %}
+
+{% macro initial_meld( s ) %}
+{% if s < 0 %}
+15
+{% elif s < 2500 %}
+50
+{% elif s < 5000 %}
+90
+{% elif s < 10000 %}
+120
+{% elif s < 10000 %}
+120
+{% else %}
+150
+{% endif %}
+{% endmacro %}
+
+<h1>Gra zaczęta {{ game.started.strftime('%Y-%m-%d') }}</h1>
+
+<table border="1">
+ <thead>
+ <tr>
+ <th rowspan="2">#</th>
+ <th colspan="2">Rozdanie:</th>
+ <th colspan="2">Wynik:</th>
+ <th rowspan="2">Rozdaje:</th>
+ </tr>
+ <tr>
+ <th>{{ game.pair1_player1 }} + {{ game.pair1_player2 }}</th>
+ <th>{{ game.pair2_player1 }} + {{ game.pair2_player2 }}</th>
+ <th>{{ game.pair1_player1 }} + {{ game.pair1_player2 }}</th>
+ <th>{{ game.pair2_player1 }} + {{ game.pair2_player2 }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for d in deals %}
+ <tr>
+ <td>{{ d.deal_no }}</td>
+ <td>{{ d.pair1_score }}</td>
+ <td>{{ d.pair2_score }}</td>
+ <td>{{ d.pair1_sum }}</td>
+ <td>{{ d.pair2_sum }}</td>
+ <td>{{ dealing_order[ ( d.deal_no - 1 )% 4 ] }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
+
+<h1>Nowe rozdanie</h1>
+
+<h2>Rozdający: {{ dealing_order[ deals[-1].deal_no % 4 ] }} </h2>
+
+<h2>Para {{ game.pair1_player1 }} + {{ game.pair1_player2 }}</h2>
+<ul>
+ <li>Wynik: {{ game.pair1_score }}</li>
+ <li>Wyjście z {{ initial_meld( game.pair1_score ) }}</li>
+</ul>
+
+<h2>{{ game.pair2_player1 }} + {{ game.pair2_player2 }}</h2>
+<ul>
+ <li>Wynik: {{ game.pair2_score }}</li>
+ <li>Wyjście z {{ initial_meld( game.pair2_score ) }}</li>
+</ul>
+
+<h2>Wyniki częściowe:</h2>
+
+<form action="{{ url_for( 'game', game_id = game.id ) }}" method="post">
+ <table border="1">
+ <thead>
+ <tr>
+ <th></th>
+ <th>{{ game.pair1_player1 }}</th>
+ <th>{{ game.pair1_player2 }}</th>
+ <th>{{ game.pair2_player1 }}</th>
+ <th>{{ game.pair2_player2 }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>Ręka</th>
+ <td><input type="text" name="p1p1_hand" value="0"/></td>
+ <td><input type="text" name="p1p2_hand" value="0"/></td>
+ <td><input type="text" name="p2p1_hand" value="0"/></td>
+ <td><input type="text" name="p2p2_hand" value="0"/></td>
+ </tr>
+ <tr>
+ <th>Stół</th>
+ <td><input type="text" name="p1p1_table" value="0"/></td>
+ <td><input type="text" name="p1p2_table" value="0"/></td>
+ <td><input type="text" name="p2p1_table" value="0"/></td>
+ <td><input type="text" name="p2p2_table" value="0"/></td>
+ </tr>
+ <tr>
+ <th>Skończenie</th>
+ <td><input type="text" name="p1p1_finish" value="0"/></td>
+ <td><input type="text" name="p1p2_finish" value="0"/></td>
+ <td><input type="text" name="p2p1_finish" value="0"/></td>
+ <td><input type="text" name="p2p2_finish" value="0"/></td>
+ </tr>
+ </tbody>
+ </table>
+ <input type="submit" name="submit" value="Zapisz wynik tego rozdania"/>
+</form>
+
+{% endblock %}
+<!-- vim: set ft=htmldjango: -->
View
13 templates/layout.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!DOCTYPE html 'PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>kanasta.depesz.com</title>
@@ -6,6 +6,9 @@
</head>
<body>
<h1>kanasta.depesz.com</h1>
+ {% if session.username %}
+ <a href="{{ url_for( "logout" ) }}">Logout from <i>{{ session.username }}</i></a>
+ {% endif %}
{% set fl = get_flashed_messages() %}
{% if fl %}
<h2>messages:</h2>
@@ -15,6 +18,14 @@
{% endfor %}
</ul>
{% endif %}
+ {% if g.errors %}
+ <h2>errors:</h2>
+ <ul>
+ {% for e in g.errors %}
+ <li>{{ e }}</li>
+ {% endfor %}
+ </ul>
+ {% endif %}
<hr/>
{% block body %}{% endblock %}
</body>
View
11 templates/layout_logged.html
@@ -0,0 +1,11 @@
+{% extends "layout.html" %}
+{% block body %}
+<h1>menu:</h1>
+<ul>
+ <li><a href="{{ url_for("new_game") }}">Nowa gra</a></li>
+ <li><a href="{{ url_for("games") }}">Lista gier</a></li>
+ <li><a href="{{ url_for("game_stats") }}">Statystyki</a></li>
+</ul>
+{% block content %}{% endblock %}
+{% endblock %}
+<!-- vim: set ft=htmldjango: -->
View
6 templates/main.html
@@ -1,5 +1,5 @@
-{% extends "layout.html" %}
-{% block body %}
- main, you're logged as {{ session.username }}
+{% extends "layout_logged.html" %}
+{% block content %}
+HA
{% endblock %}
<!-- vim: set ft=htmldjango: -->
View
34 templates/new_game.html
@@ -0,0 +1,34 @@
+{% extends "layout_logged.html" %}
+{% block content %}
+
+{% macro user_select( name, label ) %}
+<label for="{{ name}}">Gracz 1</label>
+<select name="{{ name }}">
+ {% for i in users %}
+ <option {% if request.form[ name ] == i %}selected="1"{% endif %}>{{ i }}</option>
+ {% endfor %}
+</select>
+{% endmacro %}
+
+<form action="{{ url_for('new_game') }}" method="post">
+<h1>Gracze:</h1>
+<h2>Para1:</h2>
+<ul>
+ <li>{{ user_select( "pair1_player1", "Gracz 1" ) }}</li>
+ <li>{{ user_select( "pair1_player2", "Gracz 2" ) }}</li>
+</ul>
+<h2>Para2:</h2>
+<ul>
+ <li>{{ user_select( "pair2_player1", "Gracz 1" ) }}</li>
+ <li>{{ user_select( "pair2_player2", "Gracz 2" ) }}</li>
+</ul>
+<h2>Rozdający</h2>
+<ul>
+ <li>{{ user_select( "first_dealing", "Pierwsza/y" ) }}</li>
+ <li>{{ user_select( "second_dealing", "Druga/y" ) }}</li>
+</ul>
+<input type="submit" name="submit" value="Zacznij grę"/>
+</form>
+
+{% endblock %}
+<!-- vim: set ft=htmldjango: -->
Please sign in to comment.
Something went wrong with that request. Please try again.