mirror of
https://github.com/dredx/prole.git
synced 2026-09-24 16:24:32 +00:00
Major feature additions and infrastructure improvements for the Prole Database Installer, enabling command-line operation and packaged binary distribution. ## Ncurses Terminal Interface - Add installer/ncurses_ui.py: UI primitives (CursesWindow, TerminalConsole, NavFooter, InputField, Checkbox) - Add installer/ncurses_installer.py: Complete terminal UI with all 11 screens - Implement same screen flow as GUI (welcome, deps, network scan, env setup, kerberos, password, build, cluster, scripts, deploy, installer creation) - Add keyboard navigation (arrows, hjkl, vim-style) - Support both GUI and ncurses modes in single binary ## Automatic Display Detection - Add has_display() function to detect GUI availability - Auto-select GUI if display available, ncurses otherwise - Add --gui and --no-gui command-line flags - Fallback to ncurses on GUI failure ## Build System and Packaging - Add Makefile with targets: build, package, clean, test, install - Add scripts/generate_spec.py: PyInstaller spec generator - Add installer.spec: PyInstaller configuration - Automatic PNG to ICNS icon conversion - Create self-contained macOS .app bundle with embedded icon - Support both Intel (x86_64) and Apple Silicon (arm64) ## Embedded Resources - Add get_resource_path() helper for PyInstaller compatibility - Embed all images (proleIcon.png, proleLogo.png, proleLogoSepia.png) - Embed prole-net/prole-scan binary (6.8 MB universal binary) - Embed prole-app/dist/Prole Tools.app (12 MB app bundle) - Embed prole-db/ Docker build context ## Writable Directory Fixes - Create ~/.prole/build/prole-db/ for Docker builds (fixes read-only _MEIPASS) - Create ~/.prole/scan/ for network scan output (fixes API call failures) - Copy build context to writable location before Docker operations - Run prole-scan from writable working directory ## Documentation - docs/build-system.md: Complete build system guide - docs/ncurses-installer.md: Ncurses interface documentation - docs/RELEASE-NOTES.md: Feature overview and release notes - docs/IMAGE-RESOURCES.md: Image resource management - docs/EMBEDDED-RESOURCES.md: Binary and app bundle embedding - docs/DOCKER-BUILD-FIX.md: Docker build hang solution - docs/PROLE-HOME-DIRECTORY.md: ~/.prole directory structure - BUILD.md: Quick build reference ## Key Changes install.py: - Add get_resource_path() for embedded resource resolution - Update image paths to use get_resource_path() - Update Docker build to use ~/.prole/build/prole-db/ - Update network scan to use ~/.prole/scan/ - Add display detection and mode selection - Add --gui and --no-gui argument parsing ## Testing All features tested and verified: - Ncurses interface navigation - Display auto-detection - Resource path resolution - Docker build from package - Network scan from package - Icon conversion and embedding Package size: ~50-100 MB (includes Python runtime, all resources) Disk usage: ~/.prole/ uses ~2-6 MB 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
262 lines
6.7 KiB
Markdown
262 lines
6.7 KiB
Markdown
# Image Resource Management
|
|
|
|
## Overview
|
|
|
|
The Prole Database Installer includes multiple image assets that need to work both when running from source and when packaged as a standalone binary. This document explains how image resources are managed.
|
|
|
|
## Image Assets
|
|
|
|
The following images are included in the installer:
|
|
|
|
### Primary Assets
|
|
- **proleIcon.png** (1,494,782 bytes) - Application icon
|
|
- **proleLogo.png** (2,190,703 bytes) - Main Prole logo
|
|
- **proleLogoSepia.png** (2,657,956 bytes) - Sepia-toned background logo
|
|
- **proleLogoBlueprint.png** (3,107,147 bytes) - Blueprint style logo
|
|
- **proleIconblueprint.png** (1,570,109 bytes) - Blueprint style icon
|
|
|
|
### Supplementary Assets
|
|
- **prole-type.gif** (599 bytes) - Small typing animation
|
|
|
|
## Resource Path Resolution
|
|
|
|
### The Challenge
|
|
|
|
When packaging Python applications with PyInstaller, resource files need to be found in two different scenarios:
|
|
1. **Development**: Running from source, files are in `PROJECT_ROOT/img/`
|
|
2. **Production**: Running from bundle, files are in PyInstaller's temporary extraction directory
|
|
|
|
### The Solution
|
|
|
|
The `get_resource_path()` function automatically resolves paths correctly in both scenarios:
|
|
|
|
```python
|
|
def get_resource_path(relative_path):
|
|
"""Get absolute path to resource, works for dev and for PyInstaller."""
|
|
try:
|
|
# PyInstaller creates a temp folder and stores path in _MEIPASS
|
|
base_path = Path(sys._MEIPASS)
|
|
except AttributeError:
|
|
# Running from source
|
|
base_path = PROJECT_ROOT
|
|
|
|
return base_path / relative_path
|
|
```
|
|
|
|
### Usage
|
|
|
|
All image loading code uses this function:
|
|
|
|
```python
|
|
# Instead of:
|
|
bg_path = Path('img/proleLogoSepia.png')
|
|
|
|
# Use:
|
|
bg_path = get_resource_path('img/proleLogoSepia.png')
|
|
```
|
|
|
|
## Implementation Details
|
|
|
|
### Modified Code Locations
|
|
|
|
The following locations in `install.py` were updated to use `get_resource_path()`:
|
|
|
|
1. **Background logo loading** (line ~191)
|
|
```python
|
|
bg_path = get_resource_path('img/proleLogoSepia.png')
|
|
```
|
|
|
|
2. **Application icon candidates** (line ~406)
|
|
```python
|
|
img_candidates = [
|
|
get_resource_path('img/proleIcon.png'),
|
|
get_resource_path('img/prole-type.png'),
|
|
get_resource_path('img/prole-type.gif'),
|
|
get_resource_path('img/Prole.png'),
|
|
get_resource_path('img/proleLogoSepia.png'),
|
|
]
|
|
```
|
|
|
|
3. **DMG background image** (line ~3820)
|
|
```python
|
|
bg_img = get_resource_path('img/proleLogoSepia.png')
|
|
```
|
|
|
|
### PyInstaller Configuration
|
|
|
|
The `installer.spec` file includes the entire `img/` directory in the bundle:
|
|
|
|
```python
|
|
datas = [
|
|
('installer', 'installer'),
|
|
('conf', 'conf'),
|
|
('etc', 'etc'),
|
|
('img', 'img'), # All images included
|
|
('docs', 'docs'),
|
|
]
|
|
```
|
|
|
|
This ensures all images are:
|
|
1. Copied into the PyInstaller bundle
|
|
2. Extracted to the temporary directory at runtime
|
|
3. Accessible via `sys._MEIPASS / 'img' / filename`
|
|
|
|
## Testing
|
|
|
|
### Verify Resource Paths
|
|
|
|
Run the test script:
|
|
|
|
```bash
|
|
python3 test_resource_paths.py
|
|
```
|
|
|
|
This tests:
|
|
- Path resolution from source
|
|
- Path resolution simulating PyInstaller environment
|
|
- Existence of all image files
|
|
|
|
Expected output:
|
|
```
|
|
✓ App icon
|
|
✓ Background logo (sepia)
|
|
✓ Main logo
|
|
✓ Blueprint logo
|
|
✓ Blueprint icon
|
|
|
|
✓ All tests passed!
|
|
Images will be correctly included in PyInstaller build.
|
|
```
|
|
|
|
### Manual Testing
|
|
|
|
From source:
|
|
```bash
|
|
python3 install.py --gui
|
|
# Check that logo appears in background
|
|
```
|
|
|
|
From built binary:
|
|
```bash
|
|
make package
|
|
./dist/Prole\ Installer.app/Contents/MacOS/prole-installer --gui
|
|
# Check that logo appears in background
|
|
```
|
|
|
|
## Icon Formats
|
|
|
|
### PNG (Source)
|
|
- Format: PNG with transparency
|
|
- Resolution: 1024x1024 recommended
|
|
- Location: `img/proleIcon.png`
|
|
|
|
### ICNS (macOS Bundle)
|
|
- Generated by build system from PNG
|
|
- Contains multiple resolutions (16x16 through 1024x1024)
|
|
- Location: `build/prole.icns` (intermediate), embedded in `.app` bundle
|
|
- Generated by: `make build/prole.icns`
|
|
|
|
The build system automatically converts PNG to ICNS using macOS tools:
|
|
```bash
|
|
sips -z 512 512 img/proleIcon.png --out build/icon.iconset/icon_512x512.png
|
|
iconutil -c icns build/icon.iconset -o build/prole.icns
|
|
```
|
|
|
|
## Background Image Usage
|
|
|
|
The GUI installer uses `proleLogoSepia.png` as a subtle background:
|
|
|
|
1. **Loading**: Image loaded via PIL (Pillow)
|
|
2. **Processing**:
|
|
- Converted to RGBA
|
|
- Blended with white background at 15% opacity
|
|
- Creates subtle watermark effect
|
|
3. **Rendering**:
|
|
- Scaled to fill canvas
|
|
- Maintains aspect ratio
|
|
- Centered on canvas
|
|
|
|
Code snippet:
|
|
```python
|
|
bg_path = get_resource_path('img/proleLogoSepia.png')
|
|
if bg_path.exists():
|
|
original = Image.open(str(bg_path)).convert('RGBA')
|
|
white_bg = Image.new('RGBA', original.size, (255, 255, 255, 255))
|
|
self._bg_pil = Image.blend(white_bg, original, 0.15)
|
|
```
|
|
|
|
## Adding New Images
|
|
|
|
To add new image resources:
|
|
|
|
1. **Add image file** to `img/` directory
|
|
2. **Update code** to use `get_resource_path()`:
|
|
```python
|
|
new_img = get_resource_path('img/new_image.png')
|
|
```
|
|
3. **No spec changes needed** - entire `img/` directory is already included
|
|
4. **Test** with `python3 test_resource_paths.py`
|
|
|
|
## Troubleshooting
|
|
|
|
### Image Not Found in Built Binary
|
|
|
|
**Symptom:** Image loads from source but not from built `.app`
|
|
|
|
**Cause:** Path hardcoded instead of using `get_resource_path()`
|
|
|
|
**Solution:**
|
|
```python
|
|
# Wrong:
|
|
img_path = PROJECT_ROOT / 'img' / 'logo.png'
|
|
|
|
# Correct:
|
|
img_path = get_resource_path('img/logo.png')
|
|
```
|
|
|
|
### Image Not Showing in GUI
|
|
|
|
**Cause:** File doesn't exist or wrong path
|
|
|
|
**Solution:** Check with test script:
|
|
```bash
|
|
python3 test_resource_paths.py
|
|
```
|
|
|
|
### Build Size Too Large
|
|
|
|
**Cause:** Large images included in bundle
|
|
|
|
**Solution:**
|
|
- Optimize PNG files: `pngcrush`, `optipng`, etc.
|
|
- Consider JPEG for photos (PNG for logos/icons)
|
|
- Remove unused images from `img/` directory
|
|
|
|
## Performance Considerations
|
|
|
|
### Startup Time
|
|
|
|
PyInstaller extracts bundled resources to a temporary directory on each launch:
|
|
- **Small images** (< 100 KB): Negligible impact
|
|
- **Large images** (> 1 MB): 100-200ms extraction time
|
|
- **Total time**: ~1-2 seconds for all resources
|
|
|
|
### Memory Usage
|
|
|
|
Images are loaded into memory when displayed:
|
|
- **proleLogoSepia.png**: ~2.6 MB on disk, ~10 MB in memory (RGBA)
|
|
- **Scaled versions**: Additional memory for display size
|
|
|
|
### Optimization
|
|
|
|
For production, consider:
|
|
1. Compress images before including
|
|
2. Use lazy loading (load only when needed)
|
|
3. Cache scaled versions instead of re-scaling
|
|
|
|
## References
|
|
|
|
- [PyInstaller Data Files](https://pyinstaller.org/en/stable/spec-files.html#adding-data-files)
|
|
- [Pillow (PIL) Documentation](https://pillow.readthedocs.io/)
|
|
- [macOS Icon Creation](https://developer.apple.com/design/human-interface-guidelines/app-icons)
|