Files
eboek.info-scraper/gui_main.py
Louis Mylle ea4cab15c3 feat: Add installation scripts for Windows and Unix-based systems
- Created `install_and_run.bat` for Windows installation and setup.
- Created `install_and_run.sh` for Unix-based systems installation and setup.
- Removed `main.py` as it is no longer needed.
- Updated `requirements.txt` to specify package versions and added PyQt5.
- Deleted `start.bat` as it is redundant.
- Added unit tests for core functionality and scraping modes.
- Implemented input validation utilities in `utils/validators.py`.
- Added support for dual scraping modes in the scraper.
2026-01-10 14:45:00 +01:00

221 lines
7.0 KiB
Python

#!/usr/bin/env python3
"""
EBoek.info Scraper GUI Application
Main entry point for the PyQt5 GUI version of the EBoek.info scraper.
"""
import sys
import os
import traceback
import warnings
from pathlib import Path
# Suppress urllib3 OpenSSL warnings on macOS
warnings.filterwarnings("ignore", message="urllib3 v2 only supports OpenSSL 1.1.1+")
warnings.filterwarnings("ignore", category=UserWarning, module="urllib3")
# Ensure we can import PyQt5
try:
from PyQt5.QtWidgets import QApplication, QMessageBox
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
except ImportError as e:
print("Error: PyQt5 is not installed.")
print("Please run: pip install PyQt5")
print(f"Import error: {e}")
sys.exit(1)
# Add the project root to Python path
project_root = Path(__file__).parent
sys.path.insert(0, str(project_root))
# Import our GUI components
try:
from gui.main_window import MainWindow
from core.credentials import CredentialManager
except ImportError as e:
print(f"Error importing application modules: {e}")
print("Please ensure all required files are present.")
traceback.print_exc()
sys.exit(1)
class EBoekScraperApp(QApplication):
"""
Main application class for the EBoek.info Scraper GUI.
"""
def __init__(self, argv):
super().__init__(argv)
self.setApplicationName("EBoek.info Scraper")
self.setApplicationVersion("2.0")
self.setOrganizationName("EBoek Scraper")
# Set application icon if available
self.set_application_icon()
# Handle exceptions
sys.excepthook = self.handle_exception
self.main_window = None
def set_application_icon(self):
"""Set the application icon if available."""
# You can add an icon file here if desired
# icon_path = project_root / "resources" / "icon.png"
# if icon_path.exists():
# self.setWindowIcon(QIcon(str(icon_path)))
pass
def handle_exception(self, exc_type, exc_value, exc_traceback):
"""Handle uncaught exceptions."""
if issubclass(exc_type, KeyboardInterrupt):
# Allow Ctrl+C to exit gracefully
sys.__excepthook__(exc_type, exc_value, exc_traceback)
return
# Log the exception
error_msg = "".join(traceback.format_exception(exc_type, exc_value, exc_traceback))
print("Uncaught exception:")
print(error_msg)
# Show error dialog to user
if self.main_window:
try:
QMessageBox.critical(
self.main_window,
"Unexpected Error",
f"An unexpected error occurred:\n\n{str(exc_value)}\n\n"
f"The application may need to be restarted.\n\n"
f"Error type: {exc_type.__name__}"
)
except:
# If we can't show the dialog, just print
print("Could not display error dialog")
def initialize(self):
"""Initialize the application."""
try:
# Check system requirements
self.check_requirements()
# Create and show main window
self.main_window = MainWindow()
self.main_window.show()
return True
except Exception as e:
print(f"Error initializing application: {e}")
traceback.print_exc()
# Try to show error dialog
try:
msg = QMessageBox()
msg.setIcon(QMessageBox.Critical)
msg.setWindowTitle("Initialization Error")
msg.setText(f"Could not initialize the application:\n\n{str(e)}")
msg.setDetailedText(traceback.format_exc())
msg.exec_()
except:
print("Could not display initialization error dialog")
return False
def check_requirements(self):
"""Check system requirements and dependencies."""
errors = []
# Check Python version
if sys.version_info < (3, 6):
errors.append(f"Python 3.6+ required (found {sys.version_info.major}.{sys.version_info.minor})")
# Check required modules
required_modules = ['selenium', 'urllib3']
missing_modules = []
for module in required_modules:
try:
__import__(module)
except ImportError:
missing_modules.append(module)
if missing_modules:
errors.append(f"Missing required modules: {', '.join(missing_modules)}")
# Check Chrome/Chromium availability (basic check)
chrome_paths = [
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", # macOS
"/usr/bin/google-chrome", # Linux
"/usr/bin/chromium-browser", # Linux (Chromium)
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe", # Windows
"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe", # Windows 32-bit
]
chrome_found = any(Path(path).exists() for path in chrome_paths)
if not chrome_found:
# This is a warning, not an error
print("Warning: Chrome browser not detected in standard locations.")
print("Make sure Google Chrome is installed for the scraper to work.")
if errors:
error_text = "System requirement errors:\n\n" + "\n".join(f"{error}" for error in errors)
error_text += "\n\nPlease install missing requirements and try again."
raise RuntimeError(error_text)
def show_startup_error(title, message):
"""Show a startup error dialog without a main window."""
app = QApplication.instance()
if not app:
app = QApplication(sys.argv)
msg = QMessageBox()
msg.setIcon(QMessageBox.Critical)
msg.setWindowTitle(title)
msg.setText(message)
msg.exec_()
def main():
"""Main entry point for the GUI application."""
# Set up high DPI support
if hasattr(Qt, 'AA_EnableHighDpiScaling'):
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
if hasattr(Qt, 'AA_UseHighDpiPixmaps'):
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
# Create the application
try:
app = EBoekScraperApp(sys.argv)
# Initialize and run
if app.initialize():
# Run the application
sys.exit(app.exec_())
else:
print("Application initialization failed")
sys.exit(1)
except Exception as e:
print(f"Fatal error starting application: {e}")
traceback.print_exc()
# Try to show error dialog
try:
show_startup_error(
"Startup Error",
f"Could not start the EBoek.info Scraper:\n\n{str(e)}\n\n"
f"Please check the installation and try again."
)
except:
print("Could not display startup error dialog")
sys.exit(1)
if __name__ == "__main__":
main()