2025-07-05 06:02:21 +05:30

111 lines
4.0 KiB
Python

# --- Standard Library Imports ---
import sys
import os
import time
import traceback
# --- PyQt5 Imports ---
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5.QtCore import QCoreApplication
# --- Local Application Imports ---
from src.ui.main_window import DownloaderApp
from src.ui.dialogs.TourDialog import TourDialog
from src.config.constants import CONFIG_ORGANIZATION_NAME, CONFIG_APP_NAME_MAIN
# --- Define APP_BASE_DIR globally and make available early ---
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
APP_BASE_DIR = sys._MEIPASS
else:
APP_BASE_DIR = os.path.abspath(os.path.dirname(__file__))
# Optional: Set a global variable or pass it into modules if needed
# Or re-export it via constants.py for cleaner imports
def handle_uncaught_exception(exc_type, exc_value, exc_traceback):
"""
Handles uncaught exceptions by logging them to a file for easier debugging,
especially for bundled applications.
"""
# Use APP_BASE_DIR to determine logging location
log_dir = os.path.join(APP_BASE_DIR, "logs")
log_file_path = os.path.join(log_dir, "uncaught_exceptions.log")
try:
os.makedirs(os.path.dirname(log_file_path), exist_ok=True)
with open(log_file_path, "a", encoding="utf-8") as f:
f.write(f"Timestamp: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
traceback.print_exception(exc_type, exc_value, exc_traceback, file=f)
f.write("-" * 80 + "\n\n")
except Exception as log_ex:
# Fallback to stderr if logging to file fails
print(f"CRITICAL: Failed to write to uncaught_exceptions.log: {log_ex}", file=sys.stderr)
traceback.print_exception(exc_type, exc_value, exc_traceback, file=sys.stderr)
# Also call the default excepthook
sys.__excepthook__(exc_type, exc_value, exc_traceback)
def main():
"""Main entry point for the Kemono Downloader application."""
# Set up global exception handling
sys.excepthook = handle_uncaught_exception
try:
# Set up application metadata for QSettings
QCoreApplication.setOrganizationName(CONFIG_ORGANIZATION_NAME)
QCoreApplication.setApplicationName(CONFIG_APP_NAME_MAIN)
qt_app = QApplication(sys.argv)
# Create the main application window
downloader_app_instance = DownloaderApp()
# --- Window Sizing and Positioning ---
primary_screen = QApplication.primaryScreen()
if not primary_screen:
downloader_app_instance.resize(1024, 768)
else:
available_geo = primary_screen.availableGeometry()
screen_width = available_geo.width()
screen_height = available_geo.height()
min_app_width, min_app_height = 960, 680
desired_width_ratio, desired_height_ratio = 0.80, 0.85
app_width = max(min_app_width, int(screen_width * desired_width_ratio))
app_height = max(min_app_height, int(screen_height * desired_height_ratio))
app_width = min(app_width, screen_width)
app_height = min(app_height, screen_height)
downloader_app_instance.resize(app_width, app_height)
# Show and center the main window
downloader_app_instance.show()
if hasattr(downloader_app_instance, '_center_on_screen'):
downloader_app_instance._center_on_screen()
# --- First-Run Welcome Tour ---
if TourDialog.should_show_tour():
tour_dialog = TourDialog(parent_app=downloader_app_instance)
tour_dialog.exec_()
# --- Start Application ---
exit_code = qt_app.exec_()
print(f"Application finished with exit code: {exit_code}")
sys.exit(exit_code)
except SystemExit:
pass
except Exception as e:
print("--- CRITICAL APPLICATION STARTUP ERROR ---")
print(f"An unhandled exception occurred during application startup: {e}")
traceback.print_exc()
print("--- END CRITICAL ERROR ---")
if __name__ == '__main__':
main()