from flask import Blueprint, abort, request, jsonify import db import lib game = Blueprint("game", __name__) def require_game(game_id): g = db.Game.query.get(game_id) if g is None: abort(404) return g def require_player(game_id): auth = request.headers.get("Authorization", type=str) if auth is None: abort(401) try: pid = int(auth.split(maxsplit=1)[-1]) except ValueError: abort(401) player = db.Player.query.get(pid) if player is None: abort(404) return player @game.route("", methods=["PUT"]) def create_game(): timer = request.json.get("timer", None) if not isinstance(timer, int) or timer <= 0: abort(400) rounds = request.json.get("rounds", None) if not isinstance(rounds, int) or rounds <= 0: abort(400) new_game = db.Game.create(timer, rounds) return jsonify({"gameId": new_game.game_id}) @game.route("/") def game_settings(game_id): g = require_game(game_id) return jsonify(g.to_dict()) @game.route("//linked", methods=["POST"]) def link_game(game_id): g = require_game(game_id) link_id = request.json.get("linkedGame", None) if link_id is None or db.Game.query.get(link_id) is None: abort(401) g.linked_game = link_id return "", 201 @game.route("//join", methods=["POST"]) def join(game_id): name = request.json.get("playerName", None) if name is None: abort(400) g = require_game(game_id) if db.Player.query.filter(db.Player.game_id == game_id, db.Player.player_name == name).first() is not None: abort(409) p = g.join(name) return jsonify({ "playerId": str(p.player_id) }), 201 @game.route("//current") def current_round(game_id): g = require_game(game_id) player = require_player(game_id) cur_rnd = player.get_current_round() if cur_rnd is None: coord = None else: lookup = db.Coordinate.query.get((game_id, cur_rnd)) cur_rnd = str(cur_rnd) if lookup is None: coord = None else: coord = { "lat": lookup.latitude, "lng": lookup.longitude, } return jsonify({ "currentRound": cur_rnd, "coord": coord, "timer": g.timer, }) @game.route("//guesses/", methods=["POST"]) def make_guess(game_id, round_num): player = require_player(game_id) if round_num != player.get_current_round(): abort(409) timed_out = request.json.get("timeout", False) if timed_out: player.add_timeout(round_num) db.session.commit() return jsonify({ "score": 0, "totalScore": player.get_total_score(), "distance": None, }), 201 try: lat = float(request.json.get("lat", None)) lng = float(request.json.get("lng", None)) except ValueError: abort(400) target = db.Coordinate.query.get((game_id, round_num)) if target is None: abort(400) guess_score, distance = lib.score((target.latitude, target.longitude), (lat, lng)) player.add_guess(round_num, lat, lng, guess_score) return jsonify({ "score": guess_score, "totalScore": player.get_total_score(), "distance": distance, }), 201