From 2b6c20bc3a2d1736234479e55a169d52809fc48f Mon Sep 17 00:00:00 2001
From: Derek Schmidt <skehmatics@gmail.com>
Date: Wed, 9 Dec 2020 21:32:58 -0700
Subject: [PATCH] Define keybinds in processes rather than pygame app, minor
 cleanup

---
 chats/ChatProcess.py |  6 ++++++
 chats/FakeChat.py    |  7 ++++++-
 chats/YoutubeLive.py | 36 +++++++++++++++++++++---------------
 ui/App.py            | 25 +++++++++++--------------
 4 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/chats/ChatProcess.py b/chats/ChatProcess.py
index 39eafc8..5901f83 100644
--- a/chats/ChatProcess.py
+++ b/chats/ChatProcess.py
@@ -8,9 +8,11 @@ import time
 class GracefulShutdownException(Exception):
     pass
 
+
 class LIFECYCLE_MESSAGES(Enum):
     SHUTDOWN = auto()
 
+
 class ChatProcess(Process, ABC):
     def __init__(self, event_poll_frequency):
         super().__init__()
@@ -22,6 +24,10 @@ class ChatProcess(Process, ABC):
         self._state = None
         self._next_state = None
 
+    @abstractmethod
+    def keybinds(self):
+        return []
+
     @abstractmethod
     def loop(self, next_state):
         pass
diff --git a/chats/FakeChat.py b/chats/FakeChat.py
index 7fb6365..083030b 100644
--- a/chats/FakeChat.py
+++ b/chats/FakeChat.py
@@ -1,4 +1,3 @@
-import time
 import random
 from enum import Enum, auto
 
@@ -23,6 +22,12 @@ class FakeChat(ChatProcess):
         self._max_messages_per_chunk = 1
         self._max_delay = 10
 
+    @property
+    def keybinds(self):
+        return {
+            ord('f'): {'type': CONTROL_MESSAGES.START_STOP}
+        }
+
     def process_messages(self, message_type, args, next_state):
         if message_type == CONTROL_MESSAGES.START_STOP:
             running = not self.state == STATES.RUNNING
diff --git a/chats/YoutubeLive.py b/chats/YoutubeLive.py
index 88ecb72..e9c4bae 100644
--- a/chats/YoutubeLive.py
+++ b/chats/YoutubeLive.py
@@ -39,22 +39,10 @@ class YoutubeLiveProcess(ChatProcess):
         self._live_chat_id = None
         self._page_token = None
 
-    @classmethod
-    def normalize_message(cls, message):
-        if message['authorDetails']['isChatOwner']:
-            author_type = AUTHOR_TYPES.OWNER
-        elif message['authorDetails']['isChatModerator']:
-            author_type = AUTHOR_TYPES.MODERATOR
-        elif message['authorDetails']['isChatSponsor']:
-            author_type = AUTHOR_TYPES.PATRON
-        else:
-            author_type = AUTHOR_TYPES.USER
-
+    @property
+    def keybinds(self):
         return {
-            'text': message['snippet']['displayMessage'],
-            'author_name': message['authorDetails']['displayName'],
-            'author_id': message['authorDetails']['channelId'],
-            'author_type': author_type,
+            ord('r'): {'type': CONTROL_MESSAGES.RESTART}
         }
 
     def loop(self, next_state):
@@ -156,6 +144,24 @@ class YoutubeLiveProcess(ChatProcess):
                 })
                 return None, None
 
+    @classmethod
+    def normalize_message(cls, message):
+        if message['authorDetails']['isChatOwner']:
+            author_type = AUTHOR_TYPES.OWNER
+        elif message['authorDetails']['isChatModerator']:
+            author_type = AUTHOR_TYPES.MODERATOR
+        elif message['authorDetails']['isChatSponsor']:
+            author_type = AUTHOR_TYPES.PATRON
+        else:
+            author_type = AUTHOR_TYPES.USER
+
+        return {
+            'text': message['snippet']['displayMessage'],
+            'author_name': message['authorDetails']['displayName'],
+            'author_id': message['authorDetails']['channelId'],
+            'author_type': author_type,
+        }
+
     def request_oauth_consent(self):
         params = {
             'client_id': self._client_secrets['client_id'],
diff --git a/ui/App.py b/ui/App.py
index ca9e15e..7965871 100644
--- a/ui/App.py
+++ b/ui/App.py
@@ -13,17 +13,17 @@ from chats import FakeChat, YoutubeLive
 class App(Process):
     def __init__(self, chat_processes):
         super().__init__()
-        self._running = False
-        self._display_surf = None
-        self._title = 'Chat monitor'
+        self._chat_processes = chat_processes
 
-        self._chat_processes = {proc.__class__: proc for proc in chat_processes}
-        self._log_scroll = 0
+        self.size = self.width, self.height = 500, 1200
+        self._title = 'Chat monitor'
         self._scroll_speed = 20
         self._max_fps = 60
 
         self.chat_log = deque(maxlen=100)
-        self.size = self.width, self.height = 500, 1200
+        self._log_scroll = 0
+        self._running = False
+        self._display_surf = None
 
     @property
     def deamon(self):
@@ -38,14 +38,11 @@ class App(Process):
     def on_event(self, event):
         if event.type == pygame.QUIT:
             self._running = False
-        elif event.type == pygame.KEYDOWN and event.key == ord('r'):
-            self._chat_processes[YoutubeLive.YoutubeLiveProcess].control_pipe.send(
-                {'type': YoutubeLive.CONTROL_MESSAGES.RESTART}
-            )
-        elif event.type == pygame.KEYDOWN and event.key == ord('f'):
-            self._chat_processes[FakeChat.FakeChat].control_pipe.send(
-                {'type': FakeChat.CONTROL_MESSAGES.START_STOP}
-            )
+        elif event.type == pygame.KEYDOWN:
+            for process in self._chat_processes:
+                bound_action = process.keybinds.get(event.key)
+                if bound_action is not None:
+                    process.control_pipe.send(bound_action)
 
     def tick(self, dt):
         for message in self.chat_log: