Skip to content

Commit

Permalink
Create game function; use jinja2 templates for html
Browse files Browse the repository at this point in the history
  • Loading branch information
alrusdi committed Apr 25, 2023
1 parent c94ec55 commit 81aa6ac
Show file tree
Hide file tree
Showing 22 changed files with 1,034 additions and 96 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ You will need a python3.10+
3. Hit `uvicorn main:app --reload`
4. ...
5. Profit

26 changes: 26 additions & 0 deletions client/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,29 @@
background-color: black;
color: #666;
}

.new-game-players {
margin: 25px 135px;
}

.new-game-players span {
font-size: 20px !important;
line-height: 18px !important;
}

.alert .card-content span {
font-weight: bold;
font-size: 1.1em;
margin-right:4px;
}

.alert .card-content .material-icons {
font-size: 1.5em;
position: relative;
top: 5px;
margin-right: 0.5em;
}

#game-results dt {
font-weight: bold;
}
16 changes: 8 additions & 8 deletions client/app.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
var ws = null;

const POSSIBLE_PLAYERS = [
{'id': '09eabde7-3a21-43f6-b197-c75452e7c214', 'name': 'Саша', 'points': 0, 'current_break': 0, 'max_break': 0},
{'id': '1d5dd8e0-b411-43ac-a872-25747fce3c12', 'name': 'Сергей', 'points': 0, 'current_break': 0, 'max_break': 0},
{'id': '578137b1-b118-4a9d-85b0-b5a108b5e333', 'name': 'Гузель', 'points': 0, 'current_break': 0, 'max_break': 0},
]

function sendMessage(msg) {
const data = {
"message_type": msg.messageType,
Expand All @@ -21,18 +15,24 @@ function sendMessage(msg) {
}

const SnookerScoreKeeper = {
delimiters: ["[[", "]]"],
mounted () {
M.AutoInit()
M.Sidenav.init(document.querySelectorAll('.sidenav'), {});
},
created() {
const app = this;
const host = window.location.host.toString();
ws = new WebSocket(`ws://${host}/ws/${this.clientId}`);
const protocol = window.location.protocol == 'https:' ? 'wss': 'ws'
ws = new WebSocket(`${protocol}://${host}/ws/${this.clientId}`);

ws.onmessage = (event) => {
var results = JSON.parse(event.data)
if (results.status != 'players') {
console.log(results.message);
return
}
players_data_map = results.message
console.log('GOT DATA', players_data_map);
for (player of app.players) {
pdata = players_data_map[player.id]
if (pdata) {
Expand Down
5 changes: 5 additions & 0 deletions client/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const POSSIBLE_PLAYERS = [
{'id': '09eabde7-3a21-43f6-b197-c75452e7c214', 'name': 'Саша', 'points': 0, 'current_break': 0, 'max_break': 0},
{'id': '1d5dd8e0-b411-43ac-a872-25747fce3c12', 'name': 'Сергей', 'points': 0, 'current_break': 0, 'max_break': 0},
{'id': '578137b1-b118-4a9d-85b0-b5a108b5e333', 'name': 'Гузель', 'points': 0, 'current_break': 0, 'max_break': 0},
]
64 changes: 0 additions & 64 deletions client/index.html

This file was deleted.

56 changes: 56 additions & 0 deletions client/new_game.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const SnookerScoreKeeperNewGameForm = {
delimiters: ["[[", "]]"],
mounted () {
M.AutoInit()
const modals = document.querySelectorAll('.modal');
M.Modal.init(modals, {});
},
created() {
const app = this;
},
data() {
return {
selectedPlayers: [],
errorMessage: ''
}
},
methods: {
sendForm() {
const app = this
this.errorMessage = ''
if (this.selectedPlayers.length < 2) {
this.errorMessage = 'нужно выбрать хотя бы двух игроков'
return
}

const playerIndices = [];
for (var idx in POSSIBLE_PLAYERS) {
player = POSSIBLE_PLAYERS[idx]
if (this.selectedPlayers.includes(player.id)) {
playerIndices.push(String(idx))
}
}
const pset = playerIndices.join('');

const fetch_options = {
method: "POST",
cache: "no-cache",
headers: {
"Content-Type": "application/json",
}
}

fetch('/create-new-game/', fetch_options)
.then(response => response.json())
.then(result => {
window.location.href = `/play/?gid=${result.game_id}&pset=${pset}`
})
.catch((error) => {
app.errorMessage = 'не удалось создать игру'
console.log(error)
});
}
}
}

Vue.createApp(SnookerScoreKeeperNewGameForm).mount('#new-game-form')
53 changes: 38 additions & 15 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,47 @@
import json
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi import FastAPI, HTTPException, Request, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse
from server.game import GameManager
from server.game_results import GameResultsManager
from server.models.game_event import GameEventTypeEnum
from server.models.game_request import GameEventRequest

from server.ws_connection_manager import WsConnectionManager
from fastapi.encoders import jsonable_encoder
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

app = FastAPI()
templtes = templates = Jinja2Templates(directory="server/templates")
manager = WsConnectionManager()
game_manager = GameManager()
game_results_manager = GameResultsManager()


app.mount("/static", StaticFiles(directory="client"), name="static")

@app.get("/")
async def main_page():
with open('client/index.html', encoding='utf8') as f:
html = f.read()
return HTMLResponse(html)
@app.get("/play/", response_class=HTMLResponse)
async def main_page(request: Request):
return templates.TemplateResponse("play.jinja2", {"request": request})

@app.post('/create-new-game/')
async def create_game_handler():
@app.get("/new-game/", response_class=HTMLResponse)
def new_game_page(request: Request):
return templates.TemplateResponse("new_game.jinja2", {"request": request})

@app.get("/game-results/{game_id}/", response_class=HTMLResponse)
async def game_results_page(request: Request, game_id:str):
game_results = await game_results_manager.get_game_results(game_id=game_id)
if not game_results and game_manager.is_game_exists(game_id=game_id):
game = await game_manager.get_game(game_id=game_id)
if game:
await game_manager.finalize_game(game, game_results_manager)

if not game_results:
raise HTTPException(status_code=404, detail="Item not found")
return templates.TemplateResponse("game_results.jinja2", {"request": request, "game_results": game_results})

@app.post("/create-new-game/")
async def create_game_handler(request: Request):
new_game = await game_manager.create_new_game()
return {"status": "Ok", "game_id": new_game.id}

Expand All @@ -38,20 +56,24 @@ async def websocket_endpoint(websocket: WebSocket, client_id: int):
players_data = {}
if event.game_id:
game = await game_manager.get_game(event.game_id)
if game:
if game and not game.is_finished:
await game_manager.push_game_event(game, event)
players_data = game.calc_players()
await manager.broadcast(
_to_message(jsonable_encoder(players_data), status='players'),
current_websocket=websocket,
)

await manager.broadcast(_to_message(jsonable_encoder(players_data)), current_websocket=websocket)
await manager.broadcast(_to_message("Game not found", status='fail'))
except WebSocketDisconnect:
manager.disconnect(websocket)
await manager.broadcast(_to_message(f"Client #{client_id} left the chat"))
await manager.broadcast(_to_message(f"Client #{client_id} left the chat", status='info'))
except KeyboardInterrupt:
raise
except:
import traceback
print(traceback.format_exc())
await manager.broadcast(_to_message("Server error"))
await manager.broadcast(_to_message("Server error", status='fail'))


def parse_ws_request(data: str) -> GameEventRequest:
Expand All @@ -68,7 +90,8 @@ def parse_ws_request(data: str) -> GameEventRequest:
value_string='Unable to parse input json'
)

def _to_message(data):
def _to_message(data, status: str='ok'):
return json.dumps({
'message': data
})
'status': status,
'message': data,
})
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ dataclasses-json==0.5.7
fastapi==0.95.1
uvicorn==0.21.1
websockets==11.0.2
Jinja2==3.1.2
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"game_id": "113d99eb-7775-4062-9693-53780f130ef3",
"game_date": 1682317664.058284,
"player_stats": [
{
"id": "09eabde7-3a21-43f6-b197-c75452e7c214",
"name": "Саша",
"points": 53,
"max_break": 0,
"current_break": 0,
"fouls": 0
},
{
"id": "578137b1-b118-4a9d-85b0-b5a108b5e333",
"name": "Гузель",
"points": 20,
"max_break": 0,
"current_break": 0,
"fouls": 0
}
]
}
Loading

0 comments on commit 81aa6ac

Please sign in to comment.