This repository has been archived on 2026-05-25. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
github_pulse/application/app.py
T

188 lines
6.1 KiB
Python

"""
GitHub Pulse
Main application entry point
This application provides GitHub automation workflows with AI assistance.
"""
import sys
import flet as ft
# Compatibility fix for Flet 0.28+ (Icons vs icons, Colors vs colors)
ft.icons = ft.Icons
ft.colors = ft.Colors
# Import our modular components
try:
from app_components.config_manager import ConfigManager
from app_components.ai_manager import AIManager
from app_components.github_api import GitHubAPI
from app_components.main_gui import MainGUI
except ImportError as e:
print(f"Error importing application components: {e}")
print("Make sure all files are present in the app_components folder")
sys.exit(1)
class GitHubAutomationApp:
"""Main application class that orchestrates all components"""
def __init__(self, page: ft.Page):
"""Initialize the application"""
self.page = page
# Configure page
self.page.title = "GitHub Pulse"
self.page.theme_mode = ft.ThemeMode.DARK
self.page.padding = 0
# Set window size
self.page.window_width = 1400
self.page.window_height = 1000
self.page.window_min_width = 1200
self.page.window_min_height = 800
# Material Design 3 theme
self.page.theme = ft.Theme(
color_scheme_seed="blue",
use_material3=True,
)
# Initialize core managers
self.config_manager = ConfigManager()
self.ai_manager = AIManager()
# Load configuration
self.config = self.config_manager.load_configuration()
# Initialize dry run state
dry_run_config = self.config.get('DRY_RUN', 'false')
self.dry_run_enabled = str(dry_run_config).lower() in ('true', '1', 'yes', 'on')
# Register listener for live settings updates
self.config_manager.register_listener(self._on_setting_changed)
# Initialize main GUI
self.main_gui = MainGUI(
page=self.page,
config_manager=self.config_manager,
ai_manager=self.ai_manager,
app=self
)
# Build UI
self.page.add(self.main_gui.build())
# Check AI provider setup after a short delay
self.page.run_task(self._check_ai_provider_setup_async)
async def _check_ai_provider_setup_async(self):
"""Check and setup AI providers after GUI initialization"""
try:
# Wait a bit for GUI to fully load
import asyncio
await asyncio.sleep(0.5)
ai_provider = self.config.get('AI_PROVIDER', '').strip().lower()
if not ai_provider or ai_provider in ['none', '']:
return # No AI provider selected
if ai_provider not in ['chatgpt', 'claude', 'anthropic', 'github-copilot', 'copilot', 'github_copilot']:
return # Unknown provider
# Check if modules are available and offer installation if needed
await self.ai_manager.check_and_install_ai_modules_async(ai_provider, self.page)
except Exception as e:
print(f"Error checking AI provider setup: {e}")
def get_config(self):
"""Get current configuration"""
return self.config.copy()
def update_config(self, new_config):
"""Update configuration"""
self.config.update(new_config)
self.config_manager.config = self.config.copy()
def save_config(self, config_values):
"""Save configuration"""
success = self.config_manager.save_configuration(config_values)
if success:
self.config = self.config_manager.get_config()
# Update dry run state
dry_run_config = self.config.get('DRY_RUN', 'false')
self.dry_run_enabled = str(dry_run_config).lower() in ('true', '1', 'yes', 'on')
return success
def create_github_api(self, token=None, dry_run=None):
"""Create a GitHub API instance"""
if token is None:
token = self.config.get('GITHUB_PAT', '')
if dry_run is None:
dry_run = self.dry_run_enabled
logger = self.main_gui.logger if hasattr(self.main_gui, 'logger') else None
return GitHubAPI(token, logger, dry_run)
def _on_setting_changed(self, key: str, value: any):
"""
Handle settings changes with live updates (no restart needed!)
Args:
key: Setting key that changed
value: New value
"""
print(f"⚡ Setting changed: {key} = {value}")
# Theme changes - apply immediately
if key == 'THEME_MODE':
if value == 'dark':
self.page.theme_mode = ft.ThemeMode.DARK
elif value == 'light':
self.page.theme_mode = ft.ThemeMode.LIGHT
self.page.update()
print(f"✓ Theme updated to {value}")
# Dry run mode changes
elif key == 'DRY_RUN':
self.dry_run_enabled = str(value).lower() in ('true', '1', 'yes', 'on')
print(f"✓ Dry run mode: {self.dry_run_enabled}")
# GitHub token changes - reinitialize API
elif key == 'GITHUB_PAT':
if hasattr(self, 'main_gui') and self.main_gui:
print("✓ GitHub token updated - API will be reinitialized on next use")
# AI provider changes
elif key == 'AI_PROVIDER':
print(f"✓ AI provider changed to: {value}")
# AI manager will use new provider on next request
# Update internal config
self.config[key] = value
async def main(page: ft.Page):
"""Main entry point for Flet application"""
try:
app = GitHubAutomationApp(page)
except Exception as e:
# Show error as a simple text on the page since dialog can't open before page init
print(f"Failed to start application: {e}")
import traceback
traceback.print_exc()
# Add error message to page
error_text = ft.Text(
f"Application Error:\n\n{str(e)}\n\nPlease check the console for details.",
color="red",
size=16,
)
page.add(error_text)
if __name__ == "__main__":
# Run the Flet app
ft.app(target=main)