first commit
This commit is contained in:
+280
@@ -0,0 +1,280 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.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
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# 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__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be added to the global gitignore or merged into this project gitignore.
|
||||
# For PyCharm Community Edition, use 'PyCharm CE' instead of 'PyCharm'.
|
||||
.idea/
|
||||
|
||||
# VSCode
|
||||
.vscode/
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# Windows
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# Linux
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
# Project specific
|
||||
# ComfyUI installations (if any get created locally)
|
||||
ComfyUI/
|
||||
comfy/
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
logs/
|
||||
|
||||
# Configuration files that might contain sensitive info
|
||||
config.json
|
||||
*.ini
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
temp/
|
||||
tmp/
|
||||
|
||||
# Archive files (shouldn't be committed)
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
*.7z
|
||||
|
||||
# Backup files
|
||||
*.bak
|
||||
*.backup
|
||||
*~
|
||||
|
||||
# Editor swap files
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# GTK/GLib cache and temporary files
|
||||
.cache/
|
||||
gschemas.compiled
|
||||
|
||||
# Application specific temporary files
|
||||
comfyui_*.pid
|
||||
launcher_*.lock
|
||||
@@ -0,0 +1,60 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to ComfyUI Launcher will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.0.0] - 2025-09-29
|
||||
|
||||
### Added
|
||||
- Initial release of ComfyUI Launcher
|
||||
- GTK4 based modern interface with libadwaita
|
||||
- Full conda environment detection and management
|
||||
- Automatic ComfyUI installation via comfy-cli
|
||||
- Real-time process monitoring (checks every 3 seconds)
|
||||
- Start/stop controls for ComfyUI
|
||||
- Real-time log viewing with timestamps
|
||||
- Status indicators with visual feedback
|
||||
- Cross-platform support (Linux distributions)
|
||||
- System dependency detection and installation guidance
|
||||
- Desktop integration file
|
||||
- Comprehensive documentation in English and Italian
|
||||
- Automated installation script for Fedora and Debian-based systems
|
||||
|
||||
### Features
|
||||
- **Environment Management**: Automatic detection of conda environments
|
||||
- **Process Control**: Start, stop, and monitor ComfyUI processes
|
||||
- **Real-time Monitoring**: Continuous status checking via port 8188 and process detection
|
||||
- **Installation Assistant**: One-click installation of ComfyUI and dependencies
|
||||
- **Log Viewer**: Real-time output display with monospace font
|
||||
- **Modern UI**: GTK4 interface with proper dark/light theme support
|
||||
- **Cross-distribution Support**: Works on Fedora, Ubuntu, Debian, and other Linux distributions
|
||||
|
||||
### System Requirements
|
||||
- Python 3.9 or higher
|
||||
- GTK4 and libadwaita
|
||||
- Conda or Miniconda
|
||||
- Cairo, GObject Introspection development libraries
|
||||
|
||||
### Known Issues
|
||||
- Font fallback may not work properly on systems without monospace fonts
|
||||
- Some older GTK themes may not display correctly with libadwaita
|
||||
|
||||
### Documentation
|
||||
- Complete installation guide for Debian and Fedora
|
||||
- Troubleshooting section for common issues
|
||||
- Development setup instructions
|
||||
- Contributing guidelines
|
||||
|
||||
### Files Added
|
||||
- `main.py` - Main application code
|
||||
- `requirements.txt` - Python dependencies
|
||||
- `install.sh` - Automated installation script
|
||||
- `README_EN.md` - English documentation
|
||||
- `README.md` - Italian documentation
|
||||
- `style.css` - Custom GTK styles
|
||||
- `pyproject.toml` - Project configuration
|
||||
- `.gitignore` - Git ignore rules
|
||||
- `LICENSE` - MIT license
|
||||
- `CHANGELOG.md` - This changelog
|
||||
@@ -0,0 +1,41 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 ComfyUI Launcher Team
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Copyright (c) 2025 [Il tuo nome]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,124 @@
|
||||
# ComfyUI Launcher
|
||||
|
||||
Un launcher GTK4 moderno per ComfyUI con supporto completo per ambienti conda.
|
||||
|
||||
## Caratteristiche
|
||||
|
||||
- 🚀 **Gestione Ambienti Conda**: Selezione facile degli ambienti conda disponibili
|
||||
- 🔧 **Installazione Automatica**: Installa ComfyUI e comfy-cli con un click
|
||||
- 📊 **Monitoraggio in Tempo Reale**: Controlla continuamente se ComfyUI è in esecuzione
|
||||
- 🎮 **Controlli Intuitivi**: Avvia e ferma ComfyUI facilmente
|
||||
- 📝 **Log in Tempo Reale**: Visualizza l'output di ComfyUI direttamente nel launcher
|
||||
- 🎨 **Interfaccia Moderna**: Basata su GTK4 e libadwaita
|
||||
|
||||
## Prerequisiti
|
||||
|
||||
- Python 3.9 o superiore
|
||||
- conda o miniconda installato
|
||||
- GTK4 e libadwaita
|
||||
- Librerie di sviluppo (cairo-devel, gobject-introspection-devel, ecc.)
|
||||
|
||||
## Installazione Dipendenze Sistema
|
||||
|
||||
### Fedora/RHEL:
|
||||
```bash
|
||||
sudo dnf install cairo-devel gobject-introspection-devel gtk3-devel pkg-config python3-devel
|
||||
```
|
||||
|
||||
### Ubuntu/Debian:
|
||||
```bash
|
||||
sudo apt install libcairo2-dev libgirepository1.0-dev libgtk-3-dev pkg-config python3-dev
|
||||
```
|
||||
|
||||
## Installazione
|
||||
|
||||
1. Clona il repository:
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd gtk-app
|
||||
```
|
||||
|
||||
2. Crea e attiva l'ambiente virtuale:
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
3. Installa le dipendenze Python:
|
||||
```bash
|
||||
pip install pygobject
|
||||
```
|
||||
|
||||
## Utilizzo
|
||||
|
||||
1. Avvia il launcher:
|
||||
```bash
|
||||
python main.py
|
||||
```
|
||||
|
||||
2. Seleziona un ambiente conda dalla lista dropdown
|
||||
|
||||
3. Se ComfyUI non è installato nell'ambiente, clicca "Installa ComfyUI"
|
||||
|
||||
4. Una volta installato, usa "Avvia ComfyUI" per lanciare ComfyUI
|
||||
|
||||
5. Il launcher monitorerà automaticamente lo stato di ComfyUI
|
||||
|
||||
## Funzionalità Dettagliate
|
||||
|
||||
### Gestione Ambienti Conda
|
||||
- Lista automatica di tutti gli ambienti conda disponibili
|
||||
- Supporto per l'ambiente base
|
||||
- Pulsante di aggiornamento per ricaricare la lista
|
||||
|
||||
### Monitoraggio Stato
|
||||
- Controllo ogni 3 secondi se ComfyUI è in esecuzione
|
||||
- Indicatore visivo dello stato (icona e colore)
|
||||
- Rilevamento tramite porta 8188 e processi attivi
|
||||
|
||||
### Controlli
|
||||
- **Avvia ComfyUI**: Lancia ComfyUI nell'ambiente selezionato
|
||||
- **Ferma ComfyUI**: Termina gracefully il processo ComfyUI
|
||||
- **Installa ComfyUI**: Installa comfy-cli e ComfyUI nell'ambiente
|
||||
|
||||
### Log
|
||||
- Output in tempo reale di ComfyUI
|
||||
- Timestamp per ogni messaggio
|
||||
- Font monospace per miglior leggibilità
|
||||
|
||||
## File di Configurazione
|
||||
|
||||
- `main.py`: Applicazione principale
|
||||
- `style.css`: Stili personalizzati (opzionale)
|
||||
- `comfyui-launcher.desktop`: File desktop per integrazione sistema
|
||||
|
||||
## Problemi Comuni
|
||||
|
||||
### Conda non trovato
|
||||
Assicurati che conda sia nel PATH:
|
||||
```bash
|
||||
export PATH="$HOME/miniconda3/bin:$PATH"
|
||||
```
|
||||
|
||||
### Errori di permessi
|
||||
Su alcuni sistemi potrebbe essere necessario rendere eseguibile lo script:
|
||||
```bash
|
||||
chmod +x main.py
|
||||
```
|
||||
|
||||
### ComfyUI non si avvia
|
||||
- Verifica che l'ambiente conda abbia Python 3.9+
|
||||
- Controlla che comfy-cli sia installato correttamente
|
||||
- Verifica i log per eventuali errori specifici
|
||||
|
||||
## Contribuire
|
||||
|
||||
Contributi sono benvenuti! Per favore:
|
||||
1. Fai un fork del repository
|
||||
2. Crea un branch per la tua feature
|
||||
3. Committa le modifiche
|
||||
4. Apri una Pull Request
|
||||
|
||||
## Licenza
|
||||
|
||||
MIT License - vedi il file LICENSE per dettagli.
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
# ComfyUI Launcher
|
||||
|
||||
A modern GTK4 launcher for ComfyUI with full conda environment support.
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- 🚀 **Conda Environment Management**: Easy selection of available conda environments
|
||||
- 🔧 **Automatic Installation**: Install ComfyUI and comfy-cli with one click
|
||||
- 📊 **Real-time Monitoring**: Continuously monitors if ComfyUI is running
|
||||
- 🎮 **Intuitive Controls**: Start and stop ComfyUI easily
|
||||
- 📝 **Real-time Logs**: View ComfyUI output directly in the launcher
|
||||
- 🎨 **Modern Interface**: Built with GTK4 and libadwaita
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Python 3.9 or higher
|
||||
- conda or miniconda installed
|
||||
- GTK4 and libadwaita
|
||||
- Development libraries (cairo-devel, gobject-introspection-devel, etc.)
|
||||
|
||||
## System Dependencies Installation
|
||||
|
||||
### Fedora/RHEL/CentOS/Rocky Linux
|
||||
|
||||
```bash
|
||||
# Install system dependencies
|
||||
sudo dnf install cairo-devel gobject-introspection-devel gtk4-devel pkg-config python3-devel
|
||||
|
||||
# Install conda if not already installed
|
||||
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
|
||||
bash Miniconda3-latest-Linux-x86_64.sh
|
||||
```
|
||||
|
||||
### Debian/Ubuntu
|
||||
|
||||
```bash
|
||||
# Update package list
|
||||
sudo apt update
|
||||
|
||||
# Install system dependencies
|
||||
sudo apt install libcairo2-dev libgirepository1.0-dev libgtk-4-dev pkg-config python3-dev python3-venv
|
||||
|
||||
# Install conda if not already installed
|
||||
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
|
||||
bash Miniconda3-latest-Linux-x86_64.sh
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
1. **Clone the repository:**
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd gtk-app
|
||||
```
|
||||
|
||||
2. **Create and activate virtual environment:**
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
3. **Install Python dependencies:**
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Quick Start
|
||||
|
||||
1. **Launch the application:**
|
||||
```bash
|
||||
python main.py
|
||||
```
|
||||
or use the provided script:
|
||||
```bash
|
||||
./run.sh
|
||||
```
|
||||
|
||||
2. **Select a conda environment** from the dropdown list
|
||||
|
||||
3. **Install ComfyUI** (if not already installed) by clicking "Install ComfyUI"
|
||||
|
||||
4. **Start ComfyUI** by clicking "Start ComfyUI"
|
||||
|
||||
5. The launcher will **automatically monitor** ComfyUI status
|
||||
|
||||
### Detailed Workflow
|
||||
|
||||
1. **Environment Selection**
|
||||
- The launcher automatically detects all available conda environments
|
||||
- Select your preferred environment from the dropdown
|
||||
- Click "Refresh Environment List" to reload environments
|
||||
|
||||
2. **ComfyUI Installation**
|
||||
- If ComfyUI is not installed in the selected environment, click "Install ComfyUI"
|
||||
- This will install both `comfy-cli` and ComfyUI automatically
|
||||
- Installation progress is shown in the log window
|
||||
|
||||
3. **Running ComfyUI**
|
||||
- Click "Start ComfyUI" to launch ComfyUI in the selected environment
|
||||
- Real-time output appears in the log window
|
||||
- The status indicator shows when ComfyUI is running
|
||||
|
||||
4. **Monitoring**
|
||||
- The launcher checks every 3 seconds if ComfyUI is running
|
||||
- Status is indicated by both text and visual indicators
|
||||
- Automatic detection works even if ComfyUI was started outside the launcher
|
||||
|
||||
## Features Detail
|
||||
|
||||
### Environment Management
|
||||
- Automatic detection of all conda environments
|
||||
- Support for conda base environment
|
||||
- Refresh button to reload environment list
|
||||
- Clear indication of selected environment
|
||||
|
||||
### Status Monitoring
|
||||
- Checks every 3 seconds if ComfyUI is running
|
||||
- Visual status indicator (icon and color)
|
||||
- Detection via port 8188 and active processes
|
||||
- Works even with externally started ComfyUI instances
|
||||
|
||||
### Controls
|
||||
- **Start ComfyUI**: Launch ComfyUI in selected environment
|
||||
- **Stop ComfyUI**: Gracefully terminate ComfyUI process
|
||||
- **Install ComfyUI**: Install comfy-cli and ComfyUI in environment
|
||||
- **Refresh Environments**: Reload conda environment list
|
||||
|
||||
### Logging
|
||||
- Real-time output from ComfyUI
|
||||
- Timestamp for each message
|
||||
- Monospace font for better readability
|
||||
- Automatic scrolling to latest messages
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
gtk-app/
|
||||
├── main.py # Main application
|
||||
├── requirements.txt # Python dependencies
|
||||
├── style.css # Custom styles (optional)
|
||||
├── comfyui-launcher.desktop # Desktop integration file
|
||||
├── run.sh # Launch script
|
||||
├── README.md # This file
|
||||
├── .gitignore # Git ignore rules
|
||||
└── .venv/ # Virtual environment (created after setup)
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Conda not found
|
||||
Make sure conda is in your PATH:
|
||||
```bash
|
||||
export PATH="$HOME/miniconda3/bin:$PATH"
|
||||
# Add to ~/.bashrc or ~/.zshrc for persistence
|
||||
echo 'export PATH="$HOME/miniconda3/bin:$PATH"' >> ~/.bashrc
|
||||
```
|
||||
|
||||
### Permission errors
|
||||
Make the script executable:
|
||||
```bash
|
||||
chmod +x main.py
|
||||
chmod +x run.sh
|
||||
```
|
||||
|
||||
### ComfyUI won't start
|
||||
- Verify the conda environment has Python 3.9+
|
||||
- Check that comfy-cli is properly installed
|
||||
- Review logs for specific error messages
|
||||
- Ensure sufficient disk space and memory
|
||||
|
||||
### GTK/PyGObject errors
|
||||
Make sure all system dependencies are installed:
|
||||
```bash
|
||||
# Fedora/RHEL
|
||||
sudo dnf install gtk4-devel python3-gobject
|
||||
|
||||
# Debian/Ubuntu
|
||||
sudo apt install libgtk-4-dev python3-gi
|
||||
```
|
||||
|
||||
### Missing fonts
|
||||
The launcher uses monospace fonts for logs. If fonts appear wrong:
|
||||
```bash
|
||||
# Install additional fonts (optional)
|
||||
sudo dnf install jetbrains-mono-fonts # Fedora
|
||||
sudo apt install fonts-jetbrains-mono # Ubuntu
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
### Setting up development environment
|
||||
|
||||
1. Fork the repository
|
||||
2. Clone your fork
|
||||
3. Install development dependencies:
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
4. Make your changes
|
||||
5. Test thoroughly
|
||||
6. Submit a pull request
|
||||
|
||||
### Code Style
|
||||
- Follow PEP 8 for Python code
|
||||
- Use meaningful variable names
|
||||
- Add comments for complex logic
|
||||
- Keep functions focused and small
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please:
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Add tests if applicable
|
||||
5. Update documentation
|
||||
6. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
MIT License - see the LICENSE file for details.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
- [ComfyUI](https://github.com/comfyanonymous/ComfyUI) - The amazing stable diffusion GUI
|
||||
- [comfy-cli](https://github.com/Comfy-Org/comfy-cli) - Command line tool for ComfyUI
|
||||
- [GTK](https://gtk.org/) - The GUI toolkit
|
||||
- [PyGObject](https://pygobject.readthedocs.io/) - Python bindings for GTK
|
||||
|
||||
## Support
|
||||
|
||||
If you encounter issues:
|
||||
|
||||
1. Check the troubleshooting section above
|
||||
2. Search existing GitHub issues
|
||||
3. Create a new issue with:
|
||||
- Your operating system and version
|
||||
- Python version
|
||||
- Complete error messages
|
||||
- Steps to reproduce the problem
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"_comment": "ComfyUI Launcher Configuration Template",
|
||||
"_instructions": "Copy this file to ~/.config/comfyui-launcher/config.json to customize settings",
|
||||
|
||||
"launcher": {
|
||||
"window": {
|
||||
"width": 900,
|
||||
"height": 700,
|
||||
"remember_size": true,
|
||||
"remember_position": true
|
||||
},
|
||||
"monitoring": {
|
||||
"check_interval_seconds": 3,
|
||||
"port_to_check": 8188,
|
||||
"process_patterns": [
|
||||
"comfy.*launch",
|
||||
"python.*main.py.*comfyui"
|
||||
]
|
||||
},
|
||||
"logging": {
|
||||
"max_log_lines": 1000,
|
||||
"auto_scroll": true,
|
||||
"timestamp_format": "%H:%M:%S",
|
||||
"font_family": "JetBrains Mono, Fira Code, Source Code Pro, monospace",
|
||||
"font_size": "10pt"
|
||||
},
|
||||
"conda": {
|
||||
"auto_refresh_on_startup": true,
|
||||
"preferred_environments": [],
|
||||
"exclude_environments": []
|
||||
},
|
||||
"comfyui": {
|
||||
"default_args": [],
|
||||
"auto_start_browser": false,
|
||||
"startup_timeout_seconds": 60,
|
||||
"shutdown_timeout_seconds": 10
|
||||
}
|
||||
},
|
||||
"paths": {
|
||||
"conda_executable": "conda",
|
||||
"comfy_executable": "comfy",
|
||||
"default_comfyui_directory": "~/comfy/ComfyUI"
|
||||
},
|
||||
"ui": {
|
||||
"theme": "auto",
|
||||
"use_dark_theme": null,
|
||||
"accent_color": "#3584e4",
|
||||
"show_tooltips": true,
|
||||
"animations_enabled": true
|
||||
},
|
||||
"advanced": {
|
||||
"debug_mode": false,
|
||||
"verbose_logging": false,
|
||||
"check_for_updates": true,
|
||||
"telemetry_enabled": false
|
||||
}
|
||||
}
|
||||
Executable
+207
@@ -0,0 +1,207 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ComfyUI Launcher Installation Script
|
||||
# This script automates the installation process for different Linux distributions
|
||||
|
||||
set -e # Exit on any error
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to print colored output
|
||||
print_status() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Detect Linux distribution
|
||||
detect_distro() {
|
||||
if [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
DISTRO=$ID
|
||||
VERSION=$VERSION_ID
|
||||
else
|
||||
print_error "Cannot detect Linux distribution"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Install system dependencies based on distribution
|
||||
install_system_deps() {
|
||||
print_status "Installing system dependencies for $DISTRO..."
|
||||
|
||||
case $DISTRO in
|
||||
"fedora"|"rhel"|"centos"|"rocky")
|
||||
sudo dnf install -y cairo-devel gobject-introspection-devel gtk4-devel pkg-config python3-devel python3-pip
|
||||
;;
|
||||
"ubuntu"|"debian")
|
||||
sudo apt update
|
||||
sudo apt install -y libcairo2-dev libgirepository1.0-dev libgtk-4-dev pkg-config python3-dev python3-pip python3-venv
|
||||
;;
|
||||
"arch"|"manjaro")
|
||||
sudo pacman -S --needed cairo gobject-introspection gtk4 pkgconf python python-pip
|
||||
;;
|
||||
*)
|
||||
print_warning "Unsupported distribution: $DISTRO"
|
||||
print_warning "Please install the following packages manually:"
|
||||
print_warning "- Cairo development libraries"
|
||||
print_warning "- GObject Introspection development libraries"
|
||||
print_warning "- GTK4 development libraries"
|
||||
print_warning "- pkg-config"
|
||||
print_warning "- Python 3.9+ development headers"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Check if conda is installed
|
||||
check_conda() {
|
||||
if command -v conda &> /dev/null; then
|
||||
print_success "Conda found: $(conda --version)"
|
||||
return 0
|
||||
else
|
||||
print_warning "Conda not found"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Install conda if not present
|
||||
install_conda() {
|
||||
print_status "Installing Miniconda..."
|
||||
|
||||
# Detect architecture
|
||||
ARCH=$(uname -m)
|
||||
if [ "$ARCH" = "x86_64" ]; then
|
||||
CONDA_URL="https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh"
|
||||
elif [ "$ARCH" = "aarch64" ]; then
|
||||
CONDA_URL="https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh"
|
||||
else
|
||||
print_error "Unsupported architecture: $ARCH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Download and install conda
|
||||
wget "$CONDA_URL" -O miniconda.sh
|
||||
bash miniconda.sh -b -p "$HOME/miniconda3"
|
||||
rm miniconda.sh
|
||||
|
||||
# Add conda to PATH
|
||||
echo 'export PATH="$HOME/miniconda3/bin:$PATH"' >> ~/.bashrc
|
||||
export PATH="$HOME/miniconda3/bin:$PATH"
|
||||
|
||||
# Initialize conda
|
||||
conda init bash
|
||||
|
||||
print_success "Miniconda installed successfully"
|
||||
print_warning "Please restart your terminal or run: source ~/.bashrc"
|
||||
}
|
||||
|
||||
# Setup Python virtual environment
|
||||
setup_venv() {
|
||||
print_status "Setting up Python virtual environment..."
|
||||
|
||||
if [ ! -d ".venv" ]; then
|
||||
python3 -m venv .venv
|
||||
print_success "Virtual environment created"
|
||||
else
|
||||
print_status "Virtual environment already exists"
|
||||
fi
|
||||
|
||||
# Activate virtual environment
|
||||
source .venv/bin/activate
|
||||
|
||||
# Upgrade pip
|
||||
pip install --upgrade pip
|
||||
|
||||
# Install requirements
|
||||
if [ -f "requirements.txt" ]; then
|
||||
print_status "Installing Python dependencies..."
|
||||
pip install -r requirements.txt
|
||||
print_success "Python dependencies installed"
|
||||
else
|
||||
print_warning "requirements.txt not found, installing basic dependencies..."
|
||||
pip install PyGObject
|
||||
fi
|
||||
}
|
||||
|
||||
# Make scripts executable
|
||||
make_executable() {
|
||||
print_status "Making scripts executable..."
|
||||
chmod +x main.py 2>/dev/null || true
|
||||
chmod +x run.sh 2>/dev/null || true
|
||||
print_success "Scripts are now executable"
|
||||
}
|
||||
|
||||
# Create desktop entry (optional)
|
||||
create_desktop_entry() {
|
||||
if [ -f "comfyui-launcher.desktop" ]; then
|
||||
read -p "Install desktop entry? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
DESKTOP_FILE="$HOME/.local/share/applications/comfyui-launcher.desktop"
|
||||
mkdir -p "$(dirname "$DESKTOP_FILE")"
|
||||
|
||||
# Update paths in desktop file
|
||||
CURRENT_DIR=$(pwd)
|
||||
sed "s|/home/enne2/Development/gtk-app|$CURRENT_DIR|g" comfyui-launcher.desktop > "$DESKTOP_FILE"
|
||||
|
||||
print_success "Desktop entry installed to $DESKTOP_FILE"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Main installation function
|
||||
main() {
|
||||
print_status "ComfyUI Launcher Installation Script"
|
||||
print_status "======================================"
|
||||
|
||||
# Detect distribution
|
||||
detect_distro
|
||||
print_status "Detected distribution: $DISTRO $VERSION"
|
||||
|
||||
# Install system dependencies
|
||||
install_system_deps
|
||||
|
||||
# Check for conda
|
||||
if ! check_conda; then
|
||||
read -p "Install Miniconda? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
install_conda
|
||||
else
|
||||
print_warning "Conda not installed. You'll need to install it manually for full functionality."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Setup Python environment
|
||||
setup_venv
|
||||
|
||||
# Make scripts executable
|
||||
make_executable
|
||||
|
||||
# Optional desktop entry
|
||||
create_desktop_entry
|
||||
|
||||
print_success "Installation completed!"
|
||||
print_status "To run the launcher:"
|
||||
print_status " ./run.sh"
|
||||
print_status "or:"
|
||||
print_status " source .venv/bin/activate && python main.py"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
@@ -0,0 +1,501 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import gi
|
||||
gi.require_version('Gtk', '4.0')
|
||||
gi.require_version('Adw', '1')
|
||||
|
||||
from gi.repository import Gtk, Adw, Gio, GLib
|
||||
import sys
|
||||
import subprocess
|
||||
import json
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
import re
|
||||
|
||||
class ComfyUILauncher(Gtk.ApplicationWindow):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Configurazione finestra principale
|
||||
self.set_title("ComfyUI Launcher")
|
||||
self.set_default_size(900, 700)
|
||||
|
||||
# Variabili di stato
|
||||
self.comfyui_process = None
|
||||
self.is_running = False
|
||||
self.selected_conda_env = None
|
||||
self.conda_envs = []
|
||||
self.status_check_timeout = None
|
||||
|
||||
# Crea il layout principale
|
||||
self.setup_ui()
|
||||
|
||||
# Inizializza il controllo degli ambienti conda
|
||||
self.load_conda_environments()
|
||||
|
||||
# Avvia il monitoraggio dello stato
|
||||
self.start_status_monitoring()
|
||||
|
||||
def setup_ui(self):
|
||||
# Header bar
|
||||
header = Gtk.HeaderBar()
|
||||
header.set_title_widget(Gtk.Label(label="ComfyUI Launcher"))
|
||||
self.set_titlebar(header)
|
||||
|
||||
# Menu button
|
||||
menu_button = Gtk.MenuButton()
|
||||
menu_button.set_icon_name("open-menu-symbolic")
|
||||
header.pack_end(menu_button)
|
||||
|
||||
# Main content area
|
||||
main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)
|
||||
main_box.set_margin_top(12)
|
||||
main_box.set_margin_bottom(12)
|
||||
main_box.set_margin_start(12)
|
||||
main_box.set_margin_end(12)
|
||||
|
||||
# Title
|
||||
title_label = Gtk.Label()
|
||||
title_label.set_markup("<span size='x-large'><b>ComfyUI Launcher</b></span>")
|
||||
title_label.set_margin_bottom(12)
|
||||
main_box.append(title_label)
|
||||
|
||||
# Status section
|
||||
status_frame = Gtk.Frame()
|
||||
status_frame.set_label("Stato ComfyUI")
|
||||
status_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12)
|
||||
status_box.set_margin_top(12)
|
||||
status_box.set_margin_bottom(12)
|
||||
status_box.set_margin_start(12)
|
||||
status_box.set_margin_end(12)
|
||||
|
||||
self.status_indicator = Gtk.Image()
|
||||
self.status_indicator.set_from_icon_name("media-playback-stop-symbolic")
|
||||
self.status_indicator.set_icon_size(Gtk.IconSize.LARGE)
|
||||
status_box.append(self.status_indicator)
|
||||
|
||||
self.status_label = Gtk.Label(label="ComfyUI non in esecuzione")
|
||||
self.status_label.set_hexpand(True)
|
||||
self.status_label.set_halign(Gtk.Align.START)
|
||||
status_box.append(self.status_label)
|
||||
|
||||
status_frame.set_child(status_box)
|
||||
main_box.append(status_frame)
|
||||
|
||||
# Environment selection
|
||||
env_frame = Gtk.Frame()
|
||||
env_frame.set_label("Selezione Ambiente Conda")
|
||||
env_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
|
||||
env_box.set_margin_top(12)
|
||||
env_box.set_margin_bottom(12)
|
||||
env_box.set_margin_start(12)
|
||||
env_box.set_margin_end(12)
|
||||
|
||||
# Dropdown per ambienti conda
|
||||
self.env_dropdown = Gtk.DropDown()
|
||||
self.env_dropdown.set_enable_search(True)
|
||||
self.env_dropdown.connect("notify::selected-item", self.on_env_selected)
|
||||
env_box.append(self.env_dropdown)
|
||||
|
||||
# Refresh button
|
||||
refresh_button = Gtk.Button(label="Aggiorna Lista Ambienti")
|
||||
refresh_button.connect("clicked", self.on_refresh_envs)
|
||||
env_box.append(refresh_button)
|
||||
|
||||
env_frame.set_child(env_box)
|
||||
main_box.append(env_frame)
|
||||
|
||||
# Control buttons
|
||||
control_frame = Gtk.Frame()
|
||||
control_frame.set_label("Controlli")
|
||||
control_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12)
|
||||
control_box.set_margin_top(12)
|
||||
control_box.set_margin_bottom(12)
|
||||
control_box.set_margin_start(12)
|
||||
control_box.set_margin_end(12)
|
||||
control_box.set_homogeneous(True)
|
||||
|
||||
self.start_button = Gtk.Button(label="Avvia ComfyUI")
|
||||
self.start_button.add_css_class("suggested-action")
|
||||
self.start_button.connect("clicked", self.on_start_comfyui)
|
||||
self.start_button.set_sensitive(False)
|
||||
control_box.append(self.start_button)
|
||||
|
||||
self.stop_button = Gtk.Button(label="Ferma ComfyUI")
|
||||
self.stop_button.add_css_class("destructive-action")
|
||||
self.stop_button.connect("clicked", self.on_stop_comfyui)
|
||||
self.stop_button.set_sensitive(False)
|
||||
control_box.append(self.stop_button)
|
||||
|
||||
self.install_button = Gtk.Button(label="Installa ComfyUI")
|
||||
self.install_button.connect("clicked", self.on_install_comfyui)
|
||||
control_box.append(self.install_button)
|
||||
|
||||
control_frame.set_child(control_box)
|
||||
main_box.append(control_frame)
|
||||
|
||||
# Log section
|
||||
log_frame = Gtk.Frame()
|
||||
log_frame.set_label("Log")
|
||||
log_frame.set_vexpand(True)
|
||||
|
||||
scrolled = Gtk.ScrolledWindow()
|
||||
scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
||||
scrolled.set_vexpand(True)
|
||||
|
||||
self.log_view = Gtk.TextView()
|
||||
self.log_view.set_editable(False)
|
||||
self.log_view.set_monospace(True)
|
||||
self.log_buffer = self.log_view.get_buffer()
|
||||
scrolled.set_child(self.log_view)
|
||||
|
||||
log_frame.set_child(scrolled)
|
||||
main_box.append(log_frame)
|
||||
|
||||
self.set_child(main_box)
|
||||
|
||||
# Setup menu
|
||||
self.setup_menu(menu_button)
|
||||
|
||||
def setup_menu(self, menu_button):
|
||||
menu = Gio.Menu()
|
||||
menu.append("Apri Cartella ComfyUI", "app.open_folder")
|
||||
menu.append("About", "app.about")
|
||||
menu.append("Quit", "app.quit")
|
||||
menu_button.set_menu_model(menu)
|
||||
|
||||
def log_message(self, message):
|
||||
"""Aggiunge un messaggio al log"""
|
||||
def update_log():
|
||||
current_text = self.log_buffer.get_text(
|
||||
self.log_buffer.get_start_iter(),
|
||||
self.log_buffer.get_end_iter(),
|
||||
False
|
||||
)
|
||||
timestamp = time.strftime("%H:%M:%S")
|
||||
new_text = f"{current_text}[{timestamp}] {message}\n" if current_text else f"[{timestamp}] {message}\n"
|
||||
self.log_buffer.set_text(new_text)
|
||||
|
||||
# Scorri alla fine
|
||||
mark = self.log_buffer.get_insert()
|
||||
self.log_view.scroll_mark_onscreen(mark)
|
||||
|
||||
GLib.idle_add(update_log)
|
||||
|
||||
def load_conda_environments(self):
|
||||
"""Carica la lista degli ambienti conda disponibili"""
|
||||
def load_envs():
|
||||
try:
|
||||
# Prova a ottenere la lista degli ambienti conda
|
||||
result = subprocess.run(['conda', 'env', 'list', '--json'],
|
||||
capture_output=True, text=True, timeout=30)
|
||||
if result.returncode == 0:
|
||||
env_data = json.loads(result.stdout)
|
||||
envs = []
|
||||
for env_path in env_data['envs']:
|
||||
env_name = os.path.basename(env_path)
|
||||
if env_name == env_path: # È il path base, usa 'base'
|
||||
env_name = 'base'
|
||||
envs.append((env_name, env_path))
|
||||
|
||||
def update_ui():
|
||||
self.conda_envs = envs
|
||||
string_list = Gtk.StringList()
|
||||
for name, path in envs:
|
||||
string_list.append(f"{name} ({path})")
|
||||
self.env_dropdown.set_model(string_list)
|
||||
if envs:
|
||||
self.env_dropdown.set_selected(0)
|
||||
self.log_message(f"Trovati {len(envs)} ambienti conda")
|
||||
|
||||
GLib.idle_add(update_ui)
|
||||
else:
|
||||
GLib.idle_add(lambda: self.log_message(f"Errore nel caricare ambienti conda: {result.stderr}"))
|
||||
except subprocess.TimeoutExpired:
|
||||
GLib.idle_add(lambda: self.log_message("Timeout nel caricamento ambienti conda"))
|
||||
except FileNotFoundError:
|
||||
GLib.idle_add(lambda: self.log_message("Conda non trovato. Assicurati che conda sia installato e nel PATH"))
|
||||
except Exception as e:
|
||||
GLib.idle_add(lambda: self.log_message(f"Errore imprevisto: {str(e)}"))
|
||||
|
||||
# Esegui in un thread separato per non bloccare l'UI
|
||||
threading.Thread(target=load_envs, daemon=True).start()
|
||||
|
||||
def on_env_selected(self, dropdown, param):
|
||||
"""Gestisce la selezione di un ambiente conda"""
|
||||
selected_idx = dropdown.get_selected()
|
||||
if selected_idx != Gtk.INVALID_LIST_POSITION and self.conda_envs:
|
||||
env_name, env_path = self.conda_envs[selected_idx]
|
||||
self.selected_conda_env = (env_name, env_path)
|
||||
self.log_message(f"Selezionato ambiente: {env_name}")
|
||||
self.update_button_states()
|
||||
|
||||
def on_refresh_envs(self, button):
|
||||
"""Aggiorna la lista degli ambienti conda"""
|
||||
self.log_message("Aggiornamento lista ambienti...")
|
||||
self.load_conda_environments()
|
||||
|
||||
def update_button_states(self):
|
||||
"""Aggiorna lo stato dei pulsanti in base allo stato corrente"""
|
||||
has_env = self.selected_conda_env is not None
|
||||
self.start_button.set_sensitive(has_env and not self.is_running)
|
||||
self.stop_button.set_sensitive(self.is_running)
|
||||
self.install_button.set_sensitive(has_env)
|
||||
|
||||
def check_comfyui_running(self):
|
||||
"""Controlla se ComfyUI è in esecuzione"""
|
||||
try:
|
||||
# Controlla se il processo ComfyUI è ancora vivo
|
||||
if self.comfyui_process and self.comfyui_process.poll() is None:
|
||||
return True
|
||||
|
||||
# Controlla se c'è un processo ComfyUI in esecuzione (porta 8188)
|
||||
try:
|
||||
result = subprocess.run(['ss', '-tulpn'], capture_output=True, text=True, timeout=5)
|
||||
if ':8188' in result.stdout:
|
||||
return True
|
||||
except:
|
||||
# Fallback con netstat se ss non è disponibile
|
||||
try:
|
||||
result = subprocess.run(['netstat', '-tulpn'], capture_output=True, text=True, timeout=5)
|
||||
if ':8188' in result.stdout:
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
|
||||
# Controlla processi con nome 'comfy' o 'python' che potrebbero essere ComfyUI
|
||||
try:
|
||||
result = subprocess.run(['pgrep', '-f', 'comfy.*launch'], capture_output=True, text=True, timeout=5)
|
||||
if result.returncode == 0 and result.stdout.strip():
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
|
||||
return False
|
||||
except Exception as e:
|
||||
self.log_message(f"Errore nel controllo stato: {str(e)}")
|
||||
return False
|
||||
|
||||
def update_status_ui(self):
|
||||
"""Aggiorna l'interfaccia utente con lo stato corrente"""
|
||||
if self.is_running:
|
||||
self.status_indicator.set_from_icon_name("media-playback-start-symbolic")
|
||||
self.status_indicator.add_css_class("success")
|
||||
self.status_label.set_text("ComfyUI in esecuzione")
|
||||
else:
|
||||
self.status_indicator.set_from_icon_name("media-playback-stop-symbolic")
|
||||
self.status_indicator.remove_css_class("success")
|
||||
self.status_label.set_text("ComfyUI non in esecuzione")
|
||||
|
||||
self.update_button_states()
|
||||
|
||||
def start_status_monitoring(self):
|
||||
"""Avvia il monitoraggio periodico dello stato"""
|
||||
def monitor():
|
||||
was_running = self.is_running
|
||||
self.is_running = self.check_comfyui_running()
|
||||
|
||||
if was_running != self.is_running:
|
||||
if self.is_running:
|
||||
self.log_message("ComfyUI rilevato in esecuzione")
|
||||
else:
|
||||
self.log_message("ComfyUI non più in esecuzione")
|
||||
GLib.idle_add(self.update_status_ui)
|
||||
|
||||
return True # Continua il monitoring
|
||||
|
||||
# Controlla ogni 3 secondi
|
||||
self.status_check_timeout = GLib.timeout_add(3000, monitor)
|
||||
|
||||
def on_start_comfyui(self, button):
|
||||
"""Avvia ComfyUI"""
|
||||
if not self.selected_conda_env:
|
||||
self.log_message("Nessun ambiente conda selezionato")
|
||||
return
|
||||
|
||||
env_name, env_path = self.selected_conda_env
|
||||
self.log_message(f"Avvio ComfyUI nell'ambiente {env_name}...")
|
||||
|
||||
def start_comfy():
|
||||
try:
|
||||
# Comando per attivare l'ambiente conda e avviare comfyui
|
||||
if env_name == 'base':
|
||||
cmd = ['conda', 'run', '-n', 'base', 'comfy', 'launch']
|
||||
else:
|
||||
cmd = ['conda', 'run', '-n', env_name, 'comfy', 'launch']
|
||||
|
||||
self.comfyui_process = subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
text=True,
|
||||
bufsize=1,
|
||||
universal_newlines=True
|
||||
)
|
||||
|
||||
GLib.idle_add(lambda: self.log_message("Processo ComfyUI avviato"))
|
||||
|
||||
# Leggi l'output in tempo reale
|
||||
for line in iter(self.comfyui_process.stdout.readline, ''):
|
||||
if line:
|
||||
GLib.idle_add(lambda l=line.strip(): self.log_message(f"ComfyUI: {l}"))
|
||||
|
||||
except Exception as e:
|
||||
GLib.idle_add(lambda: self.log_message(f"Errore nell'avvio: {str(e)}"))
|
||||
|
||||
threading.Thread(target=start_comfy, daemon=True).start()
|
||||
|
||||
def on_stop_comfyui(self, button):
|
||||
"""Ferma ComfyUI"""
|
||||
self.log_message("Fermando ComfyUI...")
|
||||
|
||||
if self.comfyui_process:
|
||||
try:
|
||||
self.comfyui_process.terminate()
|
||||
# Aspetta un po' per la terminazione graceful
|
||||
try:
|
||||
self.comfyui_process.wait(timeout=5)
|
||||
except subprocess.TimeoutExpired:
|
||||
# Forza la terminazione
|
||||
self.comfyui_process.kill()
|
||||
self.comfyui_process = None
|
||||
self.log_message("Processo ComfyUI terminato")
|
||||
except Exception as e:
|
||||
self.log_message(f"Errore nella terminazione: {str(e)}")
|
||||
else:
|
||||
# Prova a killare qualsiasi processo sulla porta 8188
|
||||
try:
|
||||
subprocess.run(['pkill', '-f', 'comfy'], timeout=5)
|
||||
self.log_message("Terminati processi ComfyUI")
|
||||
except:
|
||||
self.log_message("Nessun processo ComfyUI trovato da terminare")
|
||||
|
||||
def on_install_comfyui(self, button):
|
||||
"""Installa ComfyUI nell'ambiente selezionato"""
|
||||
if not self.selected_conda_env:
|
||||
self.log_message("Nessun ambiente conda selezionato")
|
||||
return
|
||||
|
||||
env_name, env_path = self.selected_conda_env
|
||||
self.log_message(f"Installazione ComfyUI nell'ambiente {env_name}...")
|
||||
|
||||
def install_comfy():
|
||||
try:
|
||||
# Prima installa comfy-cli
|
||||
cmd1 = ['conda', 'run', '-n', env_name, 'pip', 'install', 'comfy-cli']
|
||||
result1 = subprocess.run(cmd1, capture_output=True, text=True, timeout=300)
|
||||
|
||||
if result1.returncode == 0:
|
||||
GLib.idle_add(lambda: self.log_message("comfy-cli installato con successo"))
|
||||
|
||||
# Poi installa ComfyUI
|
||||
cmd2 = ['conda', 'run', '-n', env_name, 'comfy', 'install']
|
||||
result2 = subprocess.run(cmd2, capture_output=True, text=True, timeout=600)
|
||||
|
||||
if result2.returncode == 0:
|
||||
GLib.idle_add(lambda: self.log_message("ComfyUI installato con successo!"))
|
||||
else:
|
||||
GLib.idle_add(lambda: self.log_message(f"Errore installazione ComfyUI: {result2.stderr}"))
|
||||
else:
|
||||
GLib.idle_add(lambda: self.log_message(f"Errore installazione comfy-cli: {result1.stderr}"))
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
GLib.idle_add(lambda: self.log_message("Timeout durante l'installazione"))
|
||||
except Exception as e:
|
||||
GLib.idle_add(lambda: self.log_message(f"Errore durante l'installazione: {str(e)}"))
|
||||
|
||||
threading.Thread(target=install_comfy, daemon=True).start()
|
||||
|
||||
class ComfyUIApp(Adw.Application):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.connect('activate', self.on_activate)
|
||||
|
||||
# Configura il style manager per gestire correttamente i temi
|
||||
self.setup_style_manager()
|
||||
|
||||
# Aggiungi azioni per il menu
|
||||
self.setup_actions()
|
||||
|
||||
def setup_style_manager(self):
|
||||
"""Configura il gestore dello stile per evitare warning"""
|
||||
style_manager = Adw.StyleManager.get_default()
|
||||
style_manager.set_color_scheme(Adw.ColorScheme.DEFAULT)
|
||||
|
||||
def setup_actions(self):
|
||||
# Azione About
|
||||
about_action = Gio.SimpleAction.new("about", None)
|
||||
about_action.connect("activate", self.on_about_action)
|
||||
self.add_action(about_action)
|
||||
|
||||
# Azione Quit
|
||||
quit_action = Gio.SimpleAction.new("quit", None)
|
||||
quit_action.connect("activate", self.on_quit_action)
|
||||
self.add_action(quit_action)
|
||||
|
||||
# Azione Open Folder
|
||||
open_folder_action = Gio.SimpleAction.new("open_folder", None)
|
||||
open_folder_action.connect("activate", self.on_open_folder_action)
|
||||
self.add_action(open_folder_action)
|
||||
|
||||
# Shortcut per quit
|
||||
self.set_accels_for_action("app.quit", ["<primary>q"])
|
||||
|
||||
def on_activate(self, app):
|
||||
print("Avvio ComfyUI Launcher...")
|
||||
# Crea la finestra principale
|
||||
self.win = ComfyUILauncher(application=app)
|
||||
print("Finestra launcher creata")
|
||||
self.win.present()
|
||||
print("Launcher presentato")
|
||||
|
||||
def on_about_action(self, action, param):
|
||||
# Mostra dialog About
|
||||
about = Adw.AboutWindow(
|
||||
transient_for=self.win,
|
||||
application_name="ComfyUI Launcher",
|
||||
application_icon="application-x-executable",
|
||||
developer_name="ComfyUI Launcher",
|
||||
version="1.0.0",
|
||||
developers=["ComfyUI Launcher Team"],
|
||||
copyright="© 2025 ComfyUI Launcher",
|
||||
comments="Un launcher GTK per ComfyUI con supporto conda"
|
||||
)
|
||||
about.present()
|
||||
|
||||
def on_open_folder_action(self, action, param):
|
||||
"""Apre la cartella ComfyUI"""
|
||||
try:
|
||||
# Prova ad aprire la cartella di default di ComfyUI
|
||||
home_dir = os.path.expanduser("~")
|
||||
comfy_dir = os.path.join(home_dir, "comfy", "ComfyUI")
|
||||
if os.path.exists(comfy_dir):
|
||||
subprocess.run(['xdg-open', comfy_dir])
|
||||
else:
|
||||
self.win.log_message("Cartella ComfyUI non trovata")
|
||||
except Exception as e:
|
||||
self.win.log_message(f"Errore nell'apertura cartella: {str(e)}")
|
||||
|
||||
def on_quit_action(self, action, param):
|
||||
# Ferma ComfyUI se in esecuzione prima di chiudere
|
||||
if hasattr(self, 'win') and self.win.comfyui_process:
|
||||
self.win.on_stop_comfyui(None)
|
||||
self.quit()
|
||||
|
||||
def main():
|
||||
print("Avvio del ComfyUI Launcher...")
|
||||
try:
|
||||
app = ComfyUIApp(application_id="com.example.ComfyUILauncher")
|
||||
print("Applicazione launcher creata, avvio in corso...")
|
||||
exit_code = app.run(sys.argv)
|
||||
print(f"Launcher terminato con codice: {exit_code}")
|
||||
return exit_code
|
||||
except Exception as e:
|
||||
print(f"Errore durante l'esecuzione del launcher: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,84 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=61.0", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "comfyui-launcher"
|
||||
version = "1.0.0"
|
||||
description = "A modern GTK4 launcher for ComfyUI with conda environment support"
|
||||
readme = "README_EN.md"
|
||||
license = {text = "MIT"}
|
||||
authors = [
|
||||
{name = "ComfyUI Launcher Team"},
|
||||
]
|
||||
maintainers = [
|
||||
{name = "ComfyUI Launcher Team"},
|
||||
]
|
||||
keywords = ["comfyui", "launcher", "gtk4", "conda", "ai", "stable-diffusion"]
|
||||
classifiers = [
|
||||
"Development Status :: 4 - Beta",
|
||||
"Intended Audience :: End Users/Desktop",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: POSIX :: Linux",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Topic :: Multimedia :: Graphics",
|
||||
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
||||
"Environment :: X11 Applications :: GTK",
|
||||
]
|
||||
requires-python = ">=3.9"
|
||||
dependencies = [
|
||||
"PyGObject>=3.42.0",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
monitoring = ["psutil>=5.9.0"]
|
||||
dev = [
|
||||
"black",
|
||||
"flake8",
|
||||
"mypy",
|
||||
"pytest",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/your-username/comfyui-launcher"
|
||||
Repository = "https://github.com/your-username/comfyui-launcher"
|
||||
Issues = "https://github.com/your-username/comfyui-launcher/issues"
|
||||
Documentation = "https://github.com/your-username/comfyui-launcher/blob/main/README_EN.md"
|
||||
|
||||
[project.scripts]
|
||||
comfyui-launcher = "main:main"
|
||||
|
||||
[tool.setuptools]
|
||||
py-modules = ["main"]
|
||||
|
||||
[tool.black]
|
||||
line-length = 88
|
||||
target-version = ['py39']
|
||||
include = '\.pyi?$'
|
||||
extend-exclude = '''
|
||||
/(
|
||||
# directories
|
||||
\.eggs
|
||||
| \.git
|
||||
| \.hg
|
||||
| \.mypy_cache
|
||||
| \.tox
|
||||
| \.venv
|
||||
| build
|
||||
| dist
|
||||
)/
|
||||
'''
|
||||
|
||||
[tool.flake8]
|
||||
max-line-length = 88
|
||||
extend-ignore = ["E203", "W503"]
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.9"
|
||||
warn_return_any = true
|
||||
warn_unused_configs = true
|
||||
disallow_untyped_defs = true
|
||||
@@ -0,0 +1,26 @@
|
||||
# ComfyUI Launcher Requirements
|
||||
# Python dependencies for the GTK4 ComfyUI launcher
|
||||
|
||||
# Core GTK bindings
|
||||
PyGObject>=3.42.0
|
||||
|
||||
# System monitoring (optional, fallback to system commands if not available)
|
||||
psutil>=5.9.0
|
||||
|
||||
# Note: Additional system dependencies required:
|
||||
# - GTK4 development libraries
|
||||
# - Cairo development libraries
|
||||
# - GObject Introspection development libraries
|
||||
# - pkg-config
|
||||
# - Python development headers
|
||||
#
|
||||
# Install system dependencies first:
|
||||
#
|
||||
# Fedora/RHEL/CentOS:
|
||||
# sudo dnf install cairo-devel gobject-introspection-devel gtk4-devel pkg-config python3-devel
|
||||
#
|
||||
# Debian/Ubuntu:
|
||||
# sudo apt install libcairo2-dev libgirepository1.0-dev libgtk-4-dev pkg-config python3-dev
|
||||
#
|
||||
# Arch Linux:
|
||||
# sudo pacman -S cairo gobject-introspection gtk4 pkgconf python
|
||||
@@ -0,0 +1,35 @@
|
||||
/* Stili per il ComfyUI Launcher */
|
||||
|
||||
.status-running {
|
||||
color: #26a269;
|
||||
}
|
||||
|
||||
.status-stopped {
|
||||
color: #c01c28;
|
||||
}
|
||||
|
||||
.log-view {
|
||||
font-family: "JetBrains Mono", "Fira Code", "Source Code Pro", monospace;
|
||||
font-size: 10pt;
|
||||
background-color: #1e1e1e;
|
||||
color: #d4d4d4;
|
||||
}
|
||||
|
||||
.environment-frame {
|
||||
border: 1px solid #3584e4;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.control-button {
|
||||
margin: 6px;
|
||||
padding: 12px 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.install-button {
|
||||
background: linear-gradient(to bottom, #62a0ea, #3584e4);
|
||||
}
|
||||
|
||||
.install-button:hover {
|
||||
background: linear-gradient(to bottom, #74b0fa, #4894f4);
|
||||
}
|
||||
Reference in New Issue
Block a user