mirror of
https://github.com/simon987/bingo.git
synced 2025-04-19 08:26:43 +00:00
wip
This commit is contained in:
commit
20abc7e978
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.idea/
|
||||||
|
__pychache__
|
||||||
|
*.pyc
|
101
app.py
Normal file
101
app.py
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
from threading import Lock
|
||||||
|
|
||||||
|
from flask import Flask, request, session
|
||||||
|
from flask_socketio import Namespace, join_room, leave_room, SocketIO, emit, rooms, close_room, disconnect
|
||||||
|
|
||||||
|
from common import config
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.config['SECRET_KEY'] = 'secret!'
|
||||||
|
|
||||||
|
# TODO: test mode mode "threading", "eventlet" or "gevent"
|
||||||
|
socketio = SocketIO(app, async_mode=None)
|
||||||
|
|
||||||
|
# TODO: wth is that?!
|
||||||
|
thread = None
|
||||||
|
thread_lock = Lock()
|
||||||
|
|
||||||
|
@app.route("/")
|
||||||
|
def page_index():
|
||||||
|
return "Hello, world"
|
||||||
|
|
||||||
|
|
||||||
|
def background_thread():
|
||||||
|
"""Example of how to send server generated events to clients."""
|
||||||
|
count = 0
|
||||||
|
while True:
|
||||||
|
socketio.sleep(10)
|
||||||
|
count += 1
|
||||||
|
socketio.emit('my_response',
|
||||||
|
{'data': 'Server generated event', 'count': count},
|
||||||
|
namespace='/test')
|
||||||
|
|
||||||
|
|
||||||
|
# When class-based namespaces are used, any events received by the server are dispatched to a method named as the
|
||||||
|
# event name with the on_ prefix. For example, event my_event will be handled by a method named on_my_event
|
||||||
|
|
||||||
|
class BingoNamespace(Namespace):
|
||||||
|
|
||||||
|
def on_my_event(self, message):
|
||||||
|
session['receive_count'] = session.get('receive_count', 0) + 1
|
||||||
|
emit('my_response',
|
||||||
|
{'data': message['data'], 'count': session['receive_count']})
|
||||||
|
|
||||||
|
def on_my_broadcast_event(self, message):
|
||||||
|
session['receive_count'] = session.get('receive_count', 0) + 1
|
||||||
|
emit('my_response',
|
||||||
|
{'data': message['data'], 'count': session['receive_count']},
|
||||||
|
broadcast=True)
|
||||||
|
|
||||||
|
def on_join(self, message):
|
||||||
|
join_room(message['room'])
|
||||||
|
session['receive_count'] = session.get('receive_count', 0) + 1
|
||||||
|
emit('my_response',
|
||||||
|
{'data': 'In rooms: ' + ', '.join(rooms()),
|
||||||
|
'count': session['receive_count']})
|
||||||
|
|
||||||
|
def on_leave(self, message):
|
||||||
|
leave_room(message['room'])
|
||||||
|
session['receive_count'] = session.get('receive_count', 0) + 1
|
||||||
|
emit('my_response',
|
||||||
|
{'data': 'In rooms: ' + ', '.join(rooms()),
|
||||||
|
'count': session['receive_count']})
|
||||||
|
|
||||||
|
def on_close_room(self, message):
|
||||||
|
session['receive_count'] = session.get('receive_count', 0) + 1
|
||||||
|
emit('my_response', {'data': 'Room ' + message['room'] + ' is closing.',
|
||||||
|
'count': session['receive_count']},
|
||||||
|
room=message['room'])
|
||||||
|
close_room(message['room'])
|
||||||
|
|
||||||
|
def on_my_room_event(self, message):
|
||||||
|
session['receive_count'] = session.get('receive_count', 0) + 1
|
||||||
|
emit('my_response',
|
||||||
|
{'data': message['data'], 'count': session['receive_count']},
|
||||||
|
room=message['room'])
|
||||||
|
|
||||||
|
def on_disconnect_request(self):
|
||||||
|
session['receive_count'] = session.get('receive_count', 0) + 1
|
||||||
|
emit('my_response',
|
||||||
|
{'data': 'Disconnected!', 'count': session['receive_count']})
|
||||||
|
disconnect()
|
||||||
|
|
||||||
|
def on_my_ping(self):
|
||||||
|
emit('my_pong')
|
||||||
|
|
||||||
|
def on_connect(self):
|
||||||
|
global thread
|
||||||
|
with thread_lock:
|
||||||
|
if thread is None:
|
||||||
|
thread = socketio.start_background_task(background_thread)
|
||||||
|
emit('my_response', {'data': 'Connected', 'count': 0})
|
||||||
|
|
||||||
|
def on_disconnect(self):
|
||||||
|
print('Client disconnected', request.sid)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
socketio.run(
|
||||||
|
app=app,
|
||||||
|
port=config["API_PORT"],
|
||||||
|
host=config["API_HOST"],
|
||||||
|
)
|
9
bingo.iml
Normal file
9
bingo.iml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
7
common.py
Normal file
7
common.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
config = {
|
||||||
|
"API_PORT": 3000,
|
||||||
|
"API_HOST": "0.0.0.0",
|
||||||
|
"REDIS_HOST": "localhost",
|
||||||
|
"REDIS_PORT": 6379,
|
||||||
|
}
|
||||||
|
|
90
models.py
Normal file
90
models.py
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
|
import redis
|
||||||
|
import json
|
||||||
|
from common import config
|
||||||
|
|
||||||
|
|
||||||
|
class BingoCell:
|
||||||
|
|
||||||
|
def __init__(self, text, checked=False, free=False):
|
||||||
|
self.text = text
|
||||||
|
self.free = free
|
||||||
|
self.checked = checked
|
||||||
|
|
||||||
|
def serialize(self):
|
||||||
|
return self.__dict__
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def deserialize(j):
|
||||||
|
return BingoCell(
|
||||||
|
text=j["text"],
|
||||||
|
free=bool(j["free"]),
|
||||||
|
checked=bool(j["checked"])
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Row:
|
||||||
|
|
||||||
|
|
||||||
|
class BingoCard:
|
||||||
|
def __init__(self, size, cells=None, oid=None):
|
||||||
|
if cells is None:
|
||||||
|
self.cells = []
|
||||||
|
else:
|
||||||
|
self.cells = cells
|
||||||
|
if oid is None:
|
||||||
|
self.oid = uuid4().hex
|
||||||
|
else:
|
||||||
|
self.oid = oid
|
||||||
|
self.size = size
|
||||||
|
|
||||||
|
def serialize(self):
|
||||||
|
return {
|
||||||
|
"oid": self.oid,
|
||||||
|
"cells": [c.serialize() for c in self.cells]
|
||||||
|
}
|
||||||
|
|
||||||
|
def __getitem__(self, col):
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def deserialize(text):
|
||||||
|
j = json.loads(text)
|
||||||
|
return BingoCard(cells=[
|
||||||
|
BingoCell.deserialize(c) for c in j["cells"]
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
class DB:
|
||||||
|
|
||||||
|
_prefix = "bingo:"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._rdb = redis.Redis(
|
||||||
|
host=config["REDIS_HOST"],
|
||||||
|
port=config["REDIS_PORT"]
|
||||||
|
)
|
||||||
|
|
||||||
|
def flush(self):
|
||||||
|
self._rdb.delete(self._rdb.keys(DB._prefix + "*"))
|
||||||
|
|
||||||
|
def _get(self, name):
|
||||||
|
return self._rdb.get(DB._prefix + name)
|
||||||
|
|
||||||
|
def _set(self, name, value):
|
||||||
|
return self._rdb.set(DB._prefix + name, value)
|
||||||
|
|
||||||
|
def get_card(self, oid):
|
||||||
|
return BingoCard.deserialize(self._get(oid))
|
||||||
|
|
||||||
|
def save_card(self, card):
|
||||||
|
self._set(card.oid, card.serialize())
|
||||||
|
|
||||||
|
|
||||||
|
c = BingoCard(
|
||||||
|
size=4,
|
||||||
|
cells=[
|
||||||
|
BingoCell("test")
|
||||||
|
])
|
||||||
|
print(c.serialize())
|
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
flask
|
||||||
|
flask-socketio
|
||||||
|
redis
|
13
web/index.html
Normal file
13
web/index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Test</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user