Skip to content

Commit

Permalink
Async logger and app teardown (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
WolfwithSword authored Jan 8, 2025
1 parent 23477ef commit 10aac7a
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 16 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,11 @@ jobs:
- name: Build with pyinstaller
if: true && !startsWith(github.ref, 'refs/tags/')
# --noconsole # TODO: update code to log to file if frozen, impl rolling logs in local directory
run: pyinstaller --icon=images/logo.ico --onefile --collect-binaries python312.dll --hidden-import=aiosqlite --hidden-import=pyttsx4.drivers --hidden-import=pyttsx4.drivers.sapi5 --distpath dist/twitchchatdnd/${{ matrix.os }}-${{env.REF_NAME}}/ --name=twitchchatdnd-nightly src/main.py
run: pyinstaller --icon=images/logo.ico --noconsole --onefile --collect-binaries python312.dll --hidden-import=aiosqlite --hidden-import=pyttsx4.drivers --hidden-import=pyttsx4.drivers.sapi5 --distpath dist/twitchchatdnd/${{ matrix.os }}-${{env.REF_NAME}}/ --name=twitchchatdnd-nightly src/main.py

- name: Release Build with pyinstaller
if: startsWith(github.ref, 'refs/tags/')
# --noconsole
run: pyinstaller --icon=images/logo.ico --onefile --collect-binaries python312.dll --hidden-import=aiosqlite --hidden-import=pyttsx4.drivers --hidden-import=pyttsx4.drivers.sapi5 --distpath dist/twitchchatdnd/${{ matrix.os }}-${{env.REF_NAME}}/ --name=twitchchatdnd src/main.py
run: pyinstaller --icon=images/logo.ico --noconsole --onefile --collect-binaries python312.dll --hidden-import=aiosqlite --hidden-import=pyttsx4.drivers --hidden-import=pyttsx4.drivers.sapi5 --distpath dist/twitchchatdnd/${{ matrix.os }}-${{env.REF_NAME}}/ --name=twitchchatdnd src/main.py

- name: Copy Resources
run: |
Expand Down
66 changes: 60 additions & 6 deletions src/custom_logger/logger.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,67 @@
import logging
import os
import sys
import asyncio
from logging.handlers import RotatingFileHandler, QueueHandler, QueueListener
from queue import Queue

class CustomHandler(logging.StreamHandler):
_format = "%(asctime)s [%(threadName)s] [%(name)s] [%(module)s] [%(levelname)s] - %(message)s"

class CustomStreamHandler(logging.StreamHandler):
def __init__(self):
logging.StreamHandler.__init__(self)
formatter = logging.Formatter('%(asctime)s [%(threadName)s] [%(name)s] [%(module)s] [%(levelname)s] - %(message)s')
super().__init__()
formatter = logging.Formatter(_format)
self.setFormatter(formatter)

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG) # TODO: Env var
logger.addHandler(CustomHandler())
class CustomFileHandler(RotatingFileHandler):
def __init__(self, log_file):
super().__init__(
log_file,
maxBytes=10 * 1024 * 1024, # 10 MB
backupCount=5,
encoding='utf-8'
)
formatter = logging.Formatter(_format)
self.setFormatter(formatter)

class CustomLogger:
def __init__(self, name):
self.logger = logging.getLogger(name)
debug_mode = os.environ['TCDND_DEBUG_MODE'] == '1'
self.logger.setLevel(logging.DEBUG if debug_mode else logging.INFO) # TODO env var

self.log_queue = Queue()

is_frozen = getattr(sys, 'frozen', False)

if is_frozen:
# if getattr(sys, '_MEIPASS', False):
# base_path = sys._MEIPASS
# else:
base_path = os.path.dirname(sys.executable)
log_folder = os.path.join(base_path, 'logs')
else:
log_folder = os.path.join(os.getcwd(), 'logs')

os.makedirs(log_folder, exist_ok=True)
log_file = os.path.join(log_folder, 'app.log')

if is_frozen:
file_handler = CustomFileHandler(log_file)
handlers = [file_handler]
else:
stream_handler = CustomStreamHandler()
handlers = [stream_handler]

self.listener = QueueListener(self.log_queue, *handlers, respect_handler_level=True)
self.listener.start()

queue_handler = QueueHandler(self.log_queue)
self.logger.addHandler(queue_handler)

self.logger.propagate = False

def shutdown(self):
self.listener.stop()

logger = CustomLogger("ChatDND").logger
24 changes: 18 additions & 6 deletions src/main.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import os
import os, sys

import asyncio
import threading
import time
import argparse

def parse_args():
parser = argparse.ArgumentParser(description="Run the application.")
parser.add_argument('--debug', action='store_true', help="Enable debug logging level.")
return parser.parse_args()

args = parse_args()
os.environ['TCDND_DEBUG_MODE'] = '1' if args.debug else '0'

from twitch.utils import TwitchUtils
from twitch.chat import ChatController
Expand All @@ -14,11 +23,10 @@

from _version import __version__

from custom_logger.logger import logger
from chatdnd import SessionManager

from chatdnd.events.ui_events import ui_settings_twitch_auth_update_event, ui_settings_twitch_channel_update_event

from custom_logger.logger import logger
from db import initialize_database

cwd = os.getcwd()
Expand All @@ -35,6 +43,7 @@

server = ServerApp(config)

APP_RUNNING = True

async def run_twitch():

Expand All @@ -60,7 +69,7 @@ async def try_setup():
success = await try_setup()
await asyncio.sleep(1)
try:
while True:
while APP_RUNNING:
await asyncio.sleep(0.5)
except (KeyboardInterrupt, Exception):
pass
Expand Down Expand Up @@ -97,7 +106,7 @@ async def try_channel():
success = await try_channel()
await asyncio.sleep(1)
try:
while True:
while APP_RUNNING:
await asyncio.sleep(0.5)
except (KeyboardInterrupt, Exception):
pass
Expand All @@ -114,9 +123,12 @@ async def run_server():

async def run_ui():
app = DesktopApp(session_mgr, chat, config, twitch_utils)
while True:
while app.running:
await asyncio.sleep(0.05)
app.update()
APP_RUNNING = False
await asyncio.sleep(2)
sys.exit(0)
# app.mainloop()

async def run_all():
Expand Down
8 changes: 8 additions & 0 deletions src/ui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class DesktopApp(ctk.CTk):

def __init__(self, session_mgr: SessionManager, chat_ctrl: ChatController, config: Config, twitch_utils: TwitchUtils):
super().__init__()
self.running = True
self.protocol("WM_DELETE_WINDOW", self.on_close)

self.resizable(False, False)
self.config:Config = config
self.twitch_utils = twitch_utils
Expand Down Expand Up @@ -54,3 +57,8 @@ def _setup_tabs(self):
def button_callback(self):
logger.info("Test")

def on_close(self):
logger.info("Shutting down...")
self.running = False
self.destroy()

0 comments on commit 10aac7a

Please sign in to comment.