commit
1574f2853d
11 changed files with 1662 additions and 0 deletions
@ -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. |
||||
@ -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 |
||||
} |
||||
} |
||||
@ -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); |
||||
} |
||||
Loading…
Reference in new issue