mirror of
				https://github.com/simon987/bingo.git
				synced 2025-10-30 17:06:52 +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