CHAIRS mapping was {1:A, 2:B, 3:C} but the API's country field has
1=C and 3=A. Fixed the mapping in backend and both frontends, added a
startup migration to swap A↔C columns in existing DB data, corrected
multiIf SQL queries that hardcoded the wrong winner→column mapping,
and moved _save_round() to the ENDED status block so hot/cold stats
reflect the latest round immediately.
64 lines
1.7 KiB
Python
64 lines
1.7 KiB
Python
"""
|
|
Entry point — starts all async tasks concurrently:
|
|
1. StreamKar WebSocket client (anonymous, captures user bets)
|
|
2. Game state HTTP poller (authenticated, captures full game state)
|
|
3. aiohttp web server (serves dashboard, pushes events to browsers)
|
|
"""
|
|
|
|
import asyncio
|
|
import logging
|
|
import signal
|
|
|
|
from .server import WebServer
|
|
from .streamkar_ws import StreamKarWSClient
|
|
from .game_poller import GamePoller
|
|
from . import db
|
|
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s [%(name)s] %(levelname)s: %(message)s",
|
|
datefmt="%H:%M:%S",
|
|
)
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
async def main():
|
|
server = WebServer()
|
|
ws_client = StreamKarWSClient(broadcast_fn=server.broadcast)
|
|
poller = GamePoller(broadcast_fn=server.broadcast, push_refresh_fn=server.push_refresh)
|
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
def shutdown():
|
|
log.info("Shutting down...")
|
|
ws_client.stop()
|
|
poller.stop()
|
|
for task in asyncio.all_tasks(loop):
|
|
task.cancel()
|
|
|
|
for sig in (signal.SIGINT, signal.SIGTERM):
|
|
loop.add_signal_handler(sig, shutdown)
|
|
|
|
log.info("Starting Teen Patti Live Monitor")
|
|
await loop.run_in_executor(None, db.run_migrations)
|
|
log.info("Dashboard: http://localhost:8765")
|
|
|
|
tasks = [
|
|
asyncio.create_task(server.run(), name="web_server"),
|
|
asyncio.create_task(poller.run(), name="game_poller"),
|
|
asyncio.create_task(ws_client.run(), name="ws_client"),
|
|
]
|
|
|
|
try:
|
|
await asyncio.gather(*tasks)
|
|
except asyncio.CancelledError:
|
|
pass
|
|
except Exception as e:
|
|
log.error("Fatal: %s", e)
|
|
finally:
|
|
log.info("Stopped.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|