Merge branch 'dev' of https://github.com/sorrelbri/browser-go-api into dev
This commit is contained in:
commit
b0e4d2aa99
10 changed files with 103 additions and 36 deletions
|
@ -9,18 +9,31 @@ import os
|
||||||
import json
|
import json
|
||||||
from websockets.roomSocket import new_game_notice, join_game_notice
|
from websockets.roomSocket import new_game_notice, join_game_notice
|
||||||
|
|
||||||
|
from marshmallow import pprint
|
||||||
|
|
||||||
api_games = Blueprint('api_games', __name__, url_prefix='/api/games')
|
api_games = Blueprint('api_games', __name__, url_prefix='/api/games')
|
||||||
|
|
||||||
@api_games.route('/<game_id>', methods=['GET'])
|
@api_games.route('/<game_id>', methods=['GET'])
|
||||||
def get_room(game_id):
|
def get_room(game_id):
|
||||||
print(game_id)
|
print(game_id)
|
||||||
game = Game.query.filter_by(id=game_id).first()
|
game = Game.query.filter_by(id=game_id).first()
|
||||||
response = game_schema.dumps(game)
|
|
||||||
# TODO create decorator that returns user from header
|
# TODO create decorator that returns user from header
|
||||||
auth_header = request.headers.get('Authorization')
|
auth_header = request.headers.get('Authorization')
|
||||||
user = jwt.decode(auth_header.split(" ")[1], os.environ.get('SECRET_KEY'))['user']
|
user = jwt.decode(auth_header.split(" ")[1], os.environ.get('SECRET_KEY'))['user']
|
||||||
print(user)
|
user = json.loads(user)
|
||||||
join_game_notice(game_id, user)
|
# add user to game if open position available
|
||||||
|
if user and not game.player_black and game.player_white != user['id']:
|
||||||
|
game.player_black = user['id']
|
||||||
|
db.session.add(game)
|
||||||
|
db.session.commit()
|
||||||
|
print(game.player_black)
|
||||||
|
join_game_notice(game)
|
||||||
|
response = {'game': game_schema.dumps(game)}
|
||||||
|
if game.player_black:
|
||||||
|
response['black'] = user_schema.dumps(User.query.filter_by(id=game.player_black).first())
|
||||||
|
else:
|
||||||
|
response['black'] = ''
|
||||||
|
response['white'] = user_schema.dumps(User.query.filter_by(id=game.player_white).first())
|
||||||
return jsonify(response)
|
return jsonify(response)
|
||||||
|
|
||||||
@api_games.route('/', methods=['POST'])
|
@api_games.route('/', methods=['POST'])
|
||||||
|
|
3
app.py
3
app.py
|
@ -17,7 +17,8 @@ app.config.from_object(os.getenv('CONFIGURATION_OBJECT'))
|
||||||
|
|
||||||
# ! Environment Variable
|
# ! Environment Variable
|
||||||
# TODO export ALLOWED_ORIGIN= whatever the react server is
|
# TODO export ALLOWED_ORIGIN= whatever the react server is
|
||||||
socketio = SocketIO(app, cors_allowed_origins=os.getenv('ALLOWED_ORIGIN'))
|
# TODO cors_allowed_origins=os.getenv('ALLOWED_ORIGIN')
|
||||||
|
socketio = SocketIO(app, cors_allowed_origins=['http://localhost:3000', 'http://localhost:3001'])
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
CORS(app, resources={
|
CORS(app, resources={
|
||||||
|
|
|
@ -8,19 +8,21 @@ from database import db
|
||||||
from app import create_app
|
from app import create_app
|
||||||
app = create_app()
|
app = create_app()
|
||||||
|
|
||||||
|
|
||||||
migrate = Migrate(app, db)
|
migrate = Migrate(app, db)
|
||||||
manager = Manager(app)
|
manager = Manager(app)
|
||||||
|
|
||||||
|
# migrations
|
||||||
|
manager.add_command('db', MigrateCommand)
|
||||||
|
|
||||||
from models.Game import Game
|
from models.Game import Game
|
||||||
from models.GameRoom import GameRoom
|
from models.GameRoom import GameRoom
|
||||||
from models.Message import Message
|
from models.Message import Message
|
||||||
from models.Move import Move
|
from models.Move import Move
|
||||||
from models.User import User
|
from models.User import User
|
||||||
|
|
||||||
# migrations
|
|
||||||
manager.add_command('db', MigrateCommand)
|
|
||||||
|
|
||||||
|
|
||||||
|
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://localhost/browser-go'
|
||||||
@manager.command
|
@manager.command
|
||||||
def test():
|
def test():
|
||||||
"""Runs the unit tests without test coverage."""
|
"""Runs the unit tests without test coverage."""
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
"""empty message
|
"""empty message
|
||||||
|
|
||||||
Revision ID: 45f01fb15e26
|
Revision ID: 77a6ccbab312
|
||||||
Revises:
|
Revises:
|
||||||
Create Date: 2019-10-10 17:50:40.846864
|
Create Date: 2019-10-12 19:28:48.173762
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
|
@ -10,7 +10,7 @@ import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '45f01fb15e26'
|
revision = '77a6ccbab312'
|
||||||
down_revision = None
|
down_revision = None
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
|
@ -1,7 +1,7 @@
|
||||||
from app import db, ma
|
from app import db, ma
|
||||||
from marshmallow import fields
|
from marshmallow import fields, Schema, pre_dump
|
||||||
import enum
|
import enum
|
||||||
from models.User import user_schema
|
from models.User import UserSchema, user_schema, User
|
||||||
|
|
||||||
# ! Games >-< Users join table
|
# ! Games >-< Users join table
|
||||||
games_users = db.Table('games_users',
|
games_users = db.Table('games_users',
|
||||||
|
@ -55,9 +55,9 @@ class Game(db.Model):
|
||||||
overtime_length = db.Column(db.Integer) # seconds
|
overtime_length = db.Column(db.Integer) # seconds
|
||||||
|
|
||||||
# foreign keys
|
# foreign keys
|
||||||
game_room = db.Column(db.Integer, db.ForeignKey("game_rooms.id"))
|
game_room = db.Column(db.ForeignKey("game_rooms.id"))
|
||||||
player_black = db.Column(db.Integer, db.ForeignKey("users.id"))
|
player_black = db.Column(db.ForeignKey("users.id"))
|
||||||
player_white = db.Column(db.Integer, db.ForeignKey("users.id"))
|
player_white = db.Column(db.ForeignKey("users.id"))
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, name, description, board_size, game_room, player_white,
|
self, name, description, board_size, game_room, player_white,
|
||||||
|
@ -73,13 +73,17 @@ class Game(db.Model):
|
||||||
self.main_time = main_time
|
self.main_time = main_time
|
||||||
self.overtime = overtime
|
self.overtime = overtime
|
||||||
|
|
||||||
class GameSchema(ma.ModelSchema):
|
class GameSchema(ma.Schema):
|
||||||
id = fields.Int()
|
id = fields.Int()
|
||||||
name = fields.Str()
|
name = fields.Str()
|
||||||
description = fields.Str()
|
description = fields.Str()
|
||||||
board_size = fields.Int()
|
board_size = fields.Int()
|
||||||
player = fields.Nested(user_schema)
|
|
||||||
game_room = fields.Int()
|
game_room = fields.Int()
|
||||||
|
# TODO change players to fields.Nested(UserSchema)
|
||||||
|
# TODO when you figure out why it's not working
|
||||||
|
player_black = fields.Int()
|
||||||
|
player_white = fields.Int()
|
||||||
|
|
||||||
|
|
||||||
game_schema = GameSchema()
|
game_schema = GameSchema()
|
||||||
games_schema = GameSchema(many=True)
|
games_schema = GameSchema(many=True)
|
|
@ -15,7 +15,7 @@ class Message(db.Model):
|
||||||
content = db.Column(db.String(200), nullable=False)
|
content = db.Column(db.String(200), nullable=False)
|
||||||
|
|
||||||
# foreign key
|
# foreign key
|
||||||
move = db.Column(db.Integer, db.ForeignKey("moves.id"), nullable=False)
|
move = db.Column(db.ForeignKey("moves.id"), nullable=False)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
|
@ -19,14 +19,26 @@ class Move(db.Model):
|
||||||
is_main = db.Column(db.Boolean, nullable=False, default=True)
|
is_main = db.Column(db.Boolean, nullable=False, default=True)
|
||||||
|
|
||||||
# foreign keys
|
# foreign keys
|
||||||
game = db.Column(db.Integer, db.ForeignKey("games.id"), nullable=False)
|
game = db.Column(db.ForeignKey("games.id"), nullable=False)
|
||||||
preceding_move = db.Column(db.Integer, db.ForeignKey("moves.id"))
|
preceding_move = db.Column(db.Integer, db.ForeignKey("moves.id"))
|
||||||
|
|
||||||
succeeding_moves = db.relationship(
|
|
||||||
'Move',
|
|
||||||
lazy='subquery',
|
|
||||||
backref=db.backref('moves', lazy=True)
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, game_id, player, x_point, y_point, move_number, is_pass=True, is_main=True, preceding_move=None):
|
||||||
pass
|
self.game = game_id
|
||||||
|
if player == 'black':
|
||||||
|
self.player = 'BLACK'
|
||||||
|
else:
|
||||||
|
self.player = 'WHITE'
|
||||||
|
self.x_point = x_point
|
||||||
|
self.y_point = y_point
|
||||||
|
self.move_number = move_number
|
||||||
|
self.is_pass = is_pass
|
||||||
|
self.is_main = is_main
|
||||||
|
self.preceding_move = preceding_move
|
||||||
|
|
||||||
|
Move.succeeding_moves = db.relationship(
|
||||||
|
'Move',
|
||||||
|
lazy='subquery',
|
||||||
|
backref=db.backref('moves', lazy=True),
|
||||||
|
remote_side=Move.id
|
||||||
|
)
|
|
@ -1,5 +1,5 @@
|
||||||
from database import db, ma
|
from database import db, ma
|
||||||
from marshmallow import fields
|
from marshmallow import fields, Schema
|
||||||
from app import bcrypt
|
from app import bcrypt
|
||||||
from configuration import config
|
from configuration import config
|
||||||
import datetime
|
import datetime
|
||||||
|
@ -63,7 +63,7 @@ class User(db.Model):
|
||||||
rank_certainty = db.Column(db.Boolean, nullable=False, default=False)
|
rank_certainty = db.Column(db.Boolean, nullable=False, default=False)
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, username, email, password, rank=Ranks.K1, admin=False):
|
def __init__(self, username, email, password, rank=Ranks.UR, admin=False):
|
||||||
self.username = username
|
self.username = username
|
||||||
self.email = email
|
self.email = email
|
||||||
self.password = bcrypt.generate_password_hash(
|
self.password = bcrypt.generate_password_hash(
|
||||||
|
@ -107,7 +107,7 @@ class User(db.Model):
|
||||||
except jwt.InvalidTokenError:
|
except jwt.InvalidTokenError:
|
||||||
return 'Invalid token. Please log in again.'
|
return 'Invalid token. Please log in again.'
|
||||||
|
|
||||||
class UserSchema(ma.ModelSchema):
|
class UserSchema(Schema):
|
||||||
id = fields.Int()
|
id = fields.Int()
|
||||||
username = fields.Str()
|
username = fields.Str()
|
||||||
email = fields.Str()
|
email = fields.Str()
|
||||||
|
@ -116,6 +116,8 @@ class UserSchema(ma.ModelSchema):
|
||||||
rank_certainty = fields.Bool()
|
rank_certainty = fields.Bool()
|
||||||
elo = fields.Int()
|
elo = fields.Int()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
register=True
|
||||||
|
|
||||||
user_schema = UserSchema()
|
user_schema = UserSchema()
|
||||||
users_schema = UserSchema(many=True)
|
users_schema = UserSchema(many=True)
|
|
@ -15,13 +15,14 @@ Flask-SocketIO==4.2.1
|
||||||
Flask-SQLAlchemy==2.4.1
|
Flask-SQLAlchemy==2.4.1
|
||||||
Flask-Testing==0.7.1
|
Flask-Testing==0.7.1
|
||||||
greenlet==0.4.15
|
greenlet==0.4.15
|
||||||
|
gunicorn==19.9.0
|
||||||
isort==4.3.21
|
isort==4.3.21
|
||||||
itsdangerous==1.1.0
|
itsdangerous==1.1.0
|
||||||
Jinja2==2.10.1
|
Jinja2==2.10.1
|
||||||
lazy-object-proxy==1.4.2
|
lazy-object-proxy==1.4.2
|
||||||
Mako==1.1.0
|
Mako==1.1.0
|
||||||
MarkupSafe==1.1.1
|
MarkupSafe==1.1.1
|
||||||
marshmallow==3.2.0
|
marshmallow==3.2.1
|
||||||
marshmallow-sqlalchemy==0.19.0
|
marshmallow-sqlalchemy==0.19.0
|
||||||
mccabe==0.6.1
|
mccabe==0.6.1
|
||||||
monotonic==1.5
|
monotonic==1.5
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
from app import socketio
|
from app import socketio
|
||||||
from flask_socketio import send, emit, join_room, leave_room
|
from flask_socketio import send, emit, join_room, leave_room
|
||||||
import json
|
import json
|
||||||
|
from models.Game import Game
|
||||||
|
from models.User import User, user_schema
|
||||||
|
from models.Move import Move
|
||||||
|
from database import db
|
||||||
|
|
||||||
|
|
||||||
def join_room_notice(room):
|
def join_room_notice(room):
|
||||||
@socketio.on('join room', namespace=f'/{room}')
|
@socketio.on('join room', namespace=f'/{room}')
|
||||||
|
@ -16,9 +21,36 @@ def new_game_notice(room, game):
|
||||||
def new_room_notice(room):
|
def new_room_notice(room):
|
||||||
socketio.emit('new room', room, broadcast=True)
|
socketio.emit('new room', room, broadcast=True)
|
||||||
|
|
||||||
def join_game_notice(game_id, user):
|
def join_game_notice(game):
|
||||||
@socketio.on('join game')
|
print('join game')
|
||||||
def return_join_game_notice(data):
|
print(game)
|
||||||
game = data['game']
|
black = user_schema.dumps(User.query.filter_by(id=game.player_black).first())
|
||||||
join_room(game)
|
white = user_schema.dumps(User.query.filter_by(id=game.player_white).first())
|
||||||
emit('join game', data, room=f'game')
|
room_id = game.game_room
|
||||||
|
game_id = game.id
|
||||||
|
print(black)
|
||||||
|
@socketio.on('join game', namespace=f'/{room_id}')
|
||||||
|
def handle_join_game(data):
|
||||||
|
print('emit join game')
|
||||||
|
join_room(game_id)
|
||||||
|
emit('join game', {'black': black, 'white': white}, broadcast=True)
|
||||||
|
|
||||||
|
@socketio.on('add move', namespace=f'/{room_id}')
|
||||||
|
def handle_new_move(data):
|
||||||
|
game_id = data['game']
|
||||||
|
player = data['move']['player']
|
||||||
|
x_point = data['move']['x_point']
|
||||||
|
y_point = data['move']['y_point']
|
||||||
|
move_number = data['move_number']
|
||||||
|
try:
|
||||||
|
move = Move(
|
||||||
|
game_id=game_id,
|
||||||
|
player=player,
|
||||||
|
x_point=x_point,
|
||||||
|
y_point=y_point,
|
||||||
|
move_number=move_number
|
||||||
|
)
|
||||||
|
db.session.add(move)
|
||||||
|
db.session.commit()
|
||||||
|
except Exception as e:
|
||||||
|
emit('move rejected', e)
|
Loading…
Reference in a new issue