-
Notifications
You must be signed in to change notification settings - Fork 54
/
Copy pathlive_show.py
124 lines (97 loc) · 4.24 KB
/
live_show.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import json
import logging
from typing import Dict
import aiohttp
import colorama
from anyascii import anyascii
from hackq_trivia.config import config
from hackq_trivia.question_handler import QuestionHandler
class LiveShow:
async def __aenter__(self):
self.question_handler = QuestionHandler()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.question_handler.close()
def __init__(self, headers):
self.headers = headers
self.show_question_summary = config.getboolean("LIVE", "ShowQuestionSummary")
self.show_chat = config.getboolean("LIVE", "ShowChat")
self.block_chat = False # Block chat while question is active
self.logger = logging.getLogger(__name__)
self.logger.info("LiveShow initialized.")
async def connect(self, uri: str) -> None:
session = aiohttp.ClientSession()
rejoin = True
while rejoin:
async with session.ws_connect(uri, headers=self.headers, heartbeat=5) as ws:
async for msg in ws:
# suppress incorrect type warning for msg in PyCharm
if msg.type != aiohttp.WSMsgType.TEXT: # noqa
continue
message = json.loads(msg.data) # noqa
await self.handle_msg(message)
rejoin = self.should_rejoin(message)
if rejoin:
break
self.logger.info("Disconnected.")
@staticmethod
def should_rejoin(message: Dict) -> bool:
if message["type"] != "broadcastEnded":
return False
return (
message.get("reason", "")
== "You are no longer in the game. Please join again."
)
async def handle_msg(self, message: Dict) -> None:
self.logger.debug(message)
if "error" in message and message["error"] == "Auth not valid":
raise ConnectionRefusedError(
"User ID/Bearer invalid. Please check your settings.ini."
)
message_type = message["type"]
if message_type == "broadcastEnded":
if "reason" in message:
reason = message["reason"]
self.logger.info(f"Disconnected: {reason}")
else:
self.logger.info("Disconnected.")
elif message_type == "interaction" and self.show_chat and not self.block_chat:
self.logger.info(
f'{message["metadata"]["username"]}: {message["metadata"]["message"]}'
)
elif message_type == "question":
question = anyascii(message["question"])
choices = [anyascii(choice["text"]) for choice in message["answers"]]
self.logger.info("\n" * 5)
self.logger.info(
f'Question {message["questionNumber"]} out of {message["questionCount"]}'
)
self.logger.info(question, extra={"pre": colorama.Fore.BLUE})
self.logger.info(
f'Choices: {", ".join(choices)}', extra={"pre": colorama.Fore.BLUE}
)
await self.question_handler.answer_question(question, choices)
self.block_chat = True
elif message_type == "questionSummary" and self.show_question_summary:
question = anyascii(message["question"])
self.logger.info(
f"Question summary: {question}", extra={"pre": colorama.Fore.BLUE}
)
for answer in message["answerCounts"]:
ans_str = anyascii(answer["answer"])
self.logger.info(
f'{ans_str}:{answer["count"]}:{answer["correct"]}',
extra={
"pre": colorama.Fore.GREEN
if answer["correct"]
else colorama.Fore.RED
},
)
self.logger.info(f'{message["advancingPlayersCount"]} players advancing')
self.logger.info(
f'{message["eliminatedPlayersCount"]} players eliminated\n'
)
elif message_type == "questionClosed" and self.block_chat:
self.block_chat = False
if self.show_chat:
self.logger.info("\n" * 5)