Making enhancements to make building and packaging the application possible

This commit is contained in:
b-tsammmons
2025-11-13 11:32:28 -10:00
parent 2accd790a8
commit 9968233dee
28 changed files with 110 additions and 183 deletions
+10 -62
View File
@@ -1,6 +1,6 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[codz]
*.py[cod]
*$py.class
# C extensions
@@ -46,7 +46,7 @@ htmlcov/
nosetests.xml
coverage.xml
*.cover
*.py.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
@@ -94,35 +94,20 @@ ipython_config.py
# install all needed dependencies.
#Pipfile.lock
# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
#uv.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
#poetry.toml
*.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
#pdm.lock
#pdm.toml
.pdm-python
.pdm-build/
# pixi
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
#pixi.lock
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
# in the .venv directory. It is recommended not to include this directory in version control.
.pixi
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
@@ -136,7 +121,6 @@ celerybeat.pid
# Environments
.env
.envrc
.venv
env/
venv/
@@ -175,45 +159,9 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# Abstra
# Abstra is an AI-powered process automation framework.
# Ignore directories containing user credentials, local state, and settings.
# Learn more at https://abstra.io/docs
.abstra/
# Visual Studio Code
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# you could uncomment the following to ignore the entire vscode folder
# .vscode/
# Ruff stuff:
.ruff_cache/
# PyPI configuration file
.pypirc
# Cursor
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
# refer to https://docs.cursor.com/context/ignore-files
.cursorignore
.cursorindexingignore
# Marimo
marimo/_static/
marimo/_lsp/
__marimo__/
# AI Files
.claude/
# Settings files
config.json
# Flet
storage/
# Build
build/
# FVM Version Cache
.fvm/
pyproject.toml
+4 -2
View File
@@ -15,7 +15,7 @@
```bash
git clone https://github.com/TySP-Dev/github_pulse.git
cd github_pulse/GitHub_Pulse
cd github_pulse/src
```
## Python Virtual Environment
@@ -59,9 +59,11 @@ export PATH="$PATH":"$HOME/.pub-cache/bin"
```bash
# Set ICU data file path (Windows example)
$env:FLUTTER_ICU_DATA_FILE="C:\Users\micro\fvm\versions\3.29.0\bin\cache\artifacts\engine\windows-x64\icudtl.dat"
$env:FLUTTER_ICU_DATA_FILE="C:\path\to\flutter\bin\cache\artifacts\engine\windows-x64\icudtl.dat"
```
# Example path $env:FLUTTER_ICU_DATA_FILE="C:\Users\<username>\flutter\bin\cache\artifacts\engine\windows-x64\icudtl.dat"
```bash
# Install Flutter version 3.29.0
fvm install 3.29.0
-9
View File
@@ -1,9 +0,0 @@
# Core dependencies
requests>=2.31.0
keyring>=24.0.0 # Secure credential storage
# UI Framework
flet>=0.28.0
# Git operations (required for AI functionality)
GitPython>=3.1.40
+8 -5
View File
@@ -1,4 +1,4 @@
# ![GitHub Pulse Logo](GitHub_Pulse/app_components/assets/pulse_logo_white_no_bkg_github.png)
# ![GitHub Pulse Logo](src/app_components/assets/pulse_logo_white_no_bkg_github.png)
A Python-based GUI application for GitHub automation workflows and AI assisted workflows.
@@ -6,19 +6,22 @@ A Python-based GUI application for GitHub automation workflows and AI assisted w
> This project is currently in active development. Features and functionality may change frequently. Bug reports and contributions are welcome and encouraged!
> Please be aware that some features may be incomplete or unstable.
![GitHub Pulse img](GitHub_Pulse/app_components/assets/github_pulse_img.png)
![GitHub Pulse img](src/app_components/assets/github_pulse_img.png)
## Pulse Workflow
![Pulse Workflow img](GitHub_Pulse/app_components/assets/flow-diagram.png)
![Pulse Workflow img](src/app_components/assets/flow-diagram.png)
## Project Structure
```text
github_pulse/
├── GitHub_Pulse/ # Main application directory
├── src/ # Main application directory
│ ├── app.py # Application entry point
│ ├── requirements.txt # Python dependencies
│ ├── assets # Images for build
│ │ ├── icon.png # Application icon
│ │ └── splash_android.png # Splash screen image
│ └── app_components/ # Application modules
│ ├── assets/ # Images and assets
│ │ ├── flow-diagram.png # Workflow diagram
@@ -55,7 +58,7 @@ github_pulse/
1. **Clone the repository**
```bash
git clone https://github.com/TySP-Dev/github_pulse.git
cd github_pulse/GitHub_Pulse
cd github_pulse/src
```
2. **Create and activate virtual environment**
+6 -3
View File
@@ -18,7 +18,7 @@ A Python-based GUI application for GitHub automation workflows.
```bash
git clone https://github.com/TySP-Dev/github_pulse.git
cd github_pulse/GitHub_Pulse
cd github_pulse/src
```
2. **Create Virtual Environment** (Recommended)
@@ -44,7 +44,7 @@ A Python-based GUI application for GitHub automation workflows.
4. **Run the Application**
```bash
python app.py
python main.py
```
> [!NOTE]
@@ -79,9 +79,12 @@ The project is organized as follows:
```text
github_pulse/
├── GitHub_Pulse/ # Main application directory
├── src/ # Main application directory
│ ├── app.py # Application entry point
│ ├── requirements.txt # Python dependencies
│ ├── assets # Images for build
│ │ ├── icon.png # Application icon
│ │ └── splash_android.png # Splash screen image
│ └── app_components/ # Application modules
│ ├── assets/ # Images and assets
│ │ ├── flow-diagram.png # Workflow diagram
+46
View File
@@ -0,0 +1,46 @@
[project]
name = "GitHub Pulse"
version = "0.0.1"
description = "A Python-based GUI application for GitHub automation workflows and AI assisted workflows."
readme = "README.md"
requires-python = ">=3.9"
authors = [
{ name = "Flet developer", email = "you@example.com" }
]
dependencies = [
"flet==0.28.3",
"requests>=2.32.5",
"keyring>=25.6.0",
"GitPython>=3.1.45",
"openai>=2.8.0",
"anthropic>=0.72.1"
]
[tool.flet]
# org name in reverse domain name notation, e.g. "com.mycompany".
# Combined with project.name to build bundle ID for iOS and Android apps
org = "com.mycompany"
# project display name that is used as an app title on Android and iOS home screens,
# shown in window titles and about app dialogs on desktop.
product = "GitHub Pulse"
# company name to display in about app dialogs
company = "Flet"
# copyright text to display in about app dialogs
copyright = "Copyright (C) 2025 by Flet"
[tool.flet.app]
path = "src"
[tool.uv]
dev-dependencies = [
"flet[all]==0.28.3",
]
[tool.poetry]
package-mode = false
[tool.poetry.group.dev.dependencies]
flet = {extras = ["all"], version = "0.28.3"}
@@ -10,10 +10,8 @@ import subprocess
import sys
import tempfile
import time
import tkinter as tk
from abc import ABC, abstractmethod
from pathlib import Path
from tkinter import messagebox
from typing import List, Tuple, Optional
@@ -2761,10 +2759,6 @@ def get_detailed_python_environment_info() -> dict:
def install_ai_packages_enhanced(packages: List[str], parent_window=None) -> bool:
"""Enhanced AI provider package installation with better error handling
Args:
packages: List of package names to install
parent_window: Parent tkinter window for dialog (optional)
Returns:
bool: True if installation successful or user declined, False if failed
@@ -2801,102 +2795,11 @@ def install_ai_packages_enhanced(packages: List[str], parent_window=None) -> boo
f"{venv_info}\n\n"
f"Would you like to install them now?\n\n"
f"This will run: pip install {' '.join(packages)}")
# Show confirmation dialog
try:
import tkinter as tk
from tkinter import messagebox
# If we have a parent window, use it; otherwise create a temporary root
if parent_window:
result = messagebox.askyesno("Install AI Packages", message, parent=parent_window)
else:
# Create temporary root window for the dialog
temp_root = tk.Tk()
temp_root.withdraw() # Hide the temporary window
result = messagebox.askyesno("Install AI Packages", message)
temp_root.destroy()
if not result:
print("User declined to install AI packages")
return True # User declined, but this isn't a failure
except Exception as e:
print(f"Could not show dialog, proceeding with installation: {e}")
# If dialog fails, ask in console
response = input(f"Install AI packages ({package_list})? [y/N]: ").lower()
if response not in ['y', 'yes']:
return True
# Install packages
try:
if in_venv:
print(f"Installing packages to virtual environment: {package_list}")
else:
print(f"Installing packages system-wide: {package_list}")
for package in packages:
print(f"Installing {package}...")
# Build pip command
pip_cmd = [sys.executable, '-m', 'pip', 'install', package]
# First attempt: Direct installation
result = subprocess.run(pip_cmd, capture_output=True, text=True, timeout=300)
# If direct install fails and we're not in venv, try with --user flag
if result.returncode != 0 and not in_venv:
print(f" Direct installation failed, trying with --user flag...")
pip_cmd_user = [sys.executable, '-m', 'pip', 'install', '--user', package]
result = subprocess.run(pip_cmd_user, capture_output=True, text=True, timeout=300)
if result.returncode == 0:
print(f"✅ Successfully installed {package} (user-local)")
continue
if result.returncode != 0:
print(f"❌ Failed to install {package}:")
print(f"Error: {result.stderr}")
# Show more helpful error message
if "permission" in result.stderr.lower() or "access" in result.stderr.lower():
print(" This appears to be a permissions issue.")
if not in_venv:
print(" Consider:")
print(" 1. Running as administrator")
print(" 2. Using a virtual environment")
print(" 3. Installing with --user flag")
return False
else:
install_type = "to virtual environment" if in_venv else "system-wide"
print(f"✅ Successfully installed {package} ({install_type})")
success_msg = "✅ AI packages installed successfully!"
if in_venv:
success_msg += f" (installed to virtual environment)"
else:
success_msg += f" (installed system-wide)"
print(success_msg)
print("Please restart the application to use the new AI features.")
return True
except subprocess.TimeoutExpired:
print("❌ Installation timed out")
return False
except Exception as e:
print(f"❌ Error installing packages: {e}")
return False
def validate_ai_provider_setup(config: dict, parent_window=None) -> bool:
"""Validate AI provider setup and offer to install missing modules
Args:
config: Configuration dictionary
parent_window: Parent tkinter window for dialogs
Returns:
bool: True if setup is valid or user handled the issue
"""

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

@@ -44,14 +44,18 @@ class SettingsDialog:
dialog = self._create_dialog()
print(f"Dialog created: {dialog}")
# IMPORTANT: Set the reference before opening
if self.dialog_ref.current is None:
print("dialog_ref.current is None, setting it now")
self.dialog_ref.current = dialog
# Always set the dialog ref to the current dialog instance
print("Setting dialog_ref.current to new dialog instance")
self.dialog_ref.current = dialog
# Use Flet 0.28+ API: page.open() instead of page.dialog
print("Opening dialog with page.open()...")
self.page.open(dialog)
# Ensure UI updates immediately (useful when console is not visible)
try:
self.page.update()
except Exception:
pass
print("page.open() completed")
# Start async initialization

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

+14
View File
@@ -0,0 +1,14 @@
{
"GITHUB_REPO": "",
"FORKED_REPO": "",
"LOCAL_REPO_PATH": "",
"AI_PROVIDER": "none",
"DRY_RUN": "false",
"DEFAULT_BRANCH": "main",
"THEME_MODE": "dark",
"AUTO_REFRESH": "true",
"REFRESH_INTERVAL": "300",
"OLLAMA_URL": "",
"OLLAMA_MODEL": "",
"CUSTOM_INSTRUCTIONS": ""
}
+13
View File
@@ -0,0 +1,13 @@
# Core dependencies
requests>=2.32.5
keyring>=25.6.0 # Secure credential storage
# UI Framework
flet>=0.28.3
# Git operations (required for AI functionality)
GitPython>=3.1.45
# AI Providers
openai>=2.8.0
anthropic>=0.72.1