aboutsummaryrefslogtreecommitdiff
path: root/api/user/games.py
blob: 95bd38ad4ed523999df34d75ce924cb7edee78de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from flask import Blueprint, request
from functools import reduce
from mergedeep import merge
from db import cursor
from auth.login_token import token_login
from ruleset import resolve_ruleset
import json

def game_info(game_id, user_id = None):
    game = cursor.execute("select " + ", ".join([
        "game_id",               # 0
        "parent_game",           # 1
        "moves",                 # 2
        "player_1_id",           # 3
        "player_2_id",           # 4
        "outcome",               # 5
        "created",               # 6
        "started",               # 7
        "duration",              # 8
        "rating_delta_player_1", # 9
        "rating_delta_player_2", # 10
        "ruleset",               # 11
        "status",                # 12
        "private",               # 13
        ]) + " from games where game_id = ?", [game_id]).fetchone()
    is_player_1 = game[4] != user_id
    outcome = "d" if game[5] == "d" else \
        "w" if game[5] == "w" and is_player_1 else "l"
    return {
        "id": game[0],
        "parent": game[1],
        "moves": [int(move) for move in str(game[2]).split(",")],
        "opponent": game[3] if is_player_1 else game[4],
        "outcome": outcome,
        "created": game[6],
        "started": game[7],
        "duration": game[8],
        "rating": game[9] if is_player_1 else game[10],
        "rating_opponent": game[10] if is_player_1 else game[9],
        "ruleset": resolve_ruleset(game[11]),
        "status": game[12],
        "private": bool(game[13]),
    }

def sum_games(user_id): #! SANITIZE USER_ID FIRST
    wld_querys = [' '.join([
        "select count(game_id)",
        "from games",
        "where",
        f"player_{x[0]}_id = \"{user_id}\" and",
        f"outcome = \"{x[1]}\"",
    ]) for x in [(1, "w"), (1, "l"), (2, "w"), (2, "l")]]
    wld_querys.insert(0, ' '.join([
        "select count(game_id)",
        "from games",
        "where",
        f"(player_1_id = \"{user_id}\" or player_2_id = \"{user_id}\") and",
        "outcome = \"d\"",
    ]))

    big_query = "select " + ", ".join([f"({query})" for query in wld_querys])

    results = cursor.execute(big_query).fetchone()

    return {
            "draw": results[0],
            "win": results[1] + results[4],
            "lose": results[2] + results[3],
            "games": reduce(lambda a, b: a + b, results)
    }

def fetch_games(user_id, count):
    game_ids = cursor.execute("select game_id from games where player_1_id = ? or player_2_id = ? order by created desc", [user_id, user_id]).fetchmany(count)
    export = []

    for game_id in game_ids:
        export.append(game_info(game_id[0], user_id))

    return export

games = Blueprint('games', __name__)

@games.route('/games', methods = ['GET', 'POST'])
def index():
    data_string = request.data or "{}"
    data = json.loads(data_string)

    user_id = data.get("id") or ""
    token = request.cookies.get("token") or ""

    if not user_id and \
       not token:
           return "", 400

    if not cursor.execute("select user_id from users where user_id = ?", [user_id]).fetchone(): return "", 403

    if token and not user_id:
        user_id = token_login(token)

    export = {}
    merge(export,
          {"totals": sum_games(user_id)},
          {"games": fetch_games(user_id, 20)})

    return export, 200

dynamic_route = ["/user", games]