safetyMaster / create_improved_mac_app.py
mrvero's picture
Upload folder using huggingface_hub
0469d65 verified
#!/usr/bin/env python3
"""
Create an improved Mac App Bundle for SafetyMaster Pro
with better cross-Mac compatibility
"""
import os
import shutil
import stat
import plistlib
from pathlib import Path
def create_improved_mac_app():
"""Create an improved Mac app bundle with better compatibility."""
app_name = "SafetyMaster Pro"
app_dir = f"{app_name}.app"
# Remove existing app if it exists
if os.path.exists(app_dir):
shutil.rmtree(app_dir)
# Create app bundle structure
contents_dir = os.path.join(app_dir, "Contents")
macos_dir = os.path.join(contents_dir, "MacOS")
resources_dir = os.path.join(contents_dir, "Resources")
os.makedirs(macos_dir, exist_ok=True)
os.makedirs(resources_dir, exist_ok=True)
# Copy all necessary files to Resources
files_to_copy = [
'web_interface.py',
'safety_detector.py',
'camera_manager.py',
'config.py',
'requirements.txt',
'ppe_yolov8_model_0.pt',
'ppe_model.pt',
'yolov8n.pt'
]
for file in files_to_copy:
if os.path.exists(file):
shutil.copy2(file, resources_dir)
print(f"Copied {file}")
# Copy templates directory
if os.path.exists('templates'):
shutil.copytree('templates', os.path.join(resources_dir, 'templates'))
print("Copied templates directory")
# Create improved executable script
executable_script = '''#!/bin/bash
# SafetyMaster Pro - Improved Mac App Bundle Launcher
# Compatible with Intel and Apple Silicon Macs
# Get the app bundle directory - Fixed path resolution
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
APP_DIR="$( cd "$SCRIPT_DIR/../.." && pwd )"
RESOURCES_DIR="$APP_DIR/Contents/Resources"
# Function to show error dialog
show_error() {
osascript -e "display dialog \\"$1\\" with title \\"SafetyMaster Pro - Error\\" buttons {\\"OK\\"} default button \\"OK\\" with icon caution"
}
# Function to show info dialog
show_info() {
osascript -e "display dialog \\"$1\\" with title \\"SafetyMaster Pro\\" buttons {\\"OK\\"} default button \\"OK\\" with icon note"
}
# Check if resources directory exists
if [[ ! -d "$RESOURCES_DIR" ]]; then
show_error "Resources directory not found at: $RESOURCES_DIR
This might be due to:
- Incomplete app bundle
- Incorrect installation
- File permissions
Please re-download SafetyMaster Pro."
exit 1
fi
# Change to resources directory
cd "$RESOURCES_DIR" || {
show_error "Failed to access application resources at: $RESOURCES_DIR
Please check file permissions and try again."
exit 1
}
# Detect Python installation with multiple fallbacks
PYTHON_CMD=""
# Check for various Python installations in order of preference
for cmd in python3.11 python3.10 python3.9 python3.8 python3 python; do
if command -v "$cmd" &> /dev/null; then
# Verify it's Python 3.8+
version=$("$cmd" -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')" 2>/dev/null || echo "0.0")
if [[ $(echo "$version >= 3.8" | bc -l 2>/dev/null || echo "0") == "1" ]]; then
PYTHON_CMD="$cmd"
break
fi
fi
done
# If no suitable Python found, provide installation guidance
if [[ -z "$PYTHON_CMD" ]]; then
show_error "Python 3.8+ is required but not found.
Installation options:
1. Official Python (Recommended):
Download from: https://www.python.org/downloads/macos/
2. Homebrew (if installed):
brew install python3
3. Xcode Command Line Tools:
xcode-select --install
After installation, restart this application."
exit 1
fi
echo "Using Python: $PYTHON_CMD"
# Check if we're in a virtual environment, if not try to create one
if [[ -z "$VIRTUAL_ENV" ]]; then
VENV_DIR="$HOME/.safetymaster_venv"
if [[ ! -d "$VENV_DIR" ]]; then
echo "Creating virtual environment..."
"$PYTHON_CMD" -m venv "$VENV_DIR" || {
echo "Warning: Could not create virtual environment, using system Python"
}
fi
if [[ -d "$VENV_DIR" ]]; then
source "$VENV_DIR/bin/activate"
PYTHON_CMD="python"
fi
fi
# Install/upgrade dependencies with better error handling
echo "Installing dependencies..."
"$PYTHON_CMD" -m pip install --upgrade pip setuptools wheel > /dev/null 2>&1 || true
# Install requirements with fallback options
if ! "$PYTHON_CMD" -m pip install -r requirements.txt > /dev/null 2>&1; then
echo "Trying alternative installation method..."
if ! "$PYTHON_CMD" -m pip install --user -r requirements.txt > /dev/null 2>&1; then
show_error "Failed to install required dependencies.
Please try installing manually:
1. Open Terminal
2. Run: pip3 install opencv-python ultralytics flask flask-socketio torch torchvision
Then restart SafetyMaster Pro."
exit 1
fi
fi
# Check for camera permissions (macOS 10.14+)
if [[ $(sw_vers -productVersion | cut -d. -f1) -ge 10 ]] && [[ $(sw_vers -productVersion | cut -d. -f2) -ge 14 ]]; then
# Request camera permission by attempting to access camera
"$PYTHON_CMD" -c "
import cv2
import sys
try:
cap = cv2.VideoCapture(0)
if cap.isOpened():
cap.release()
print('Camera access OK')
else:
print('Camera access denied or no camera found')
sys.exit(1)
except Exception as e:
print(f'Camera test failed: {e}')
sys.exit(1)
" > /dev/null 2>&1 || {
show_error "Camera access is required for SafetyMaster Pro.
Please:
1. Go to System Preferences > Security & Privacy > Camera
2. Enable camera access for SafetyMaster Pro
3. Restart the application
If you don't see SafetyMaster Pro in the list, try running it once more."
exit 1
}
# Start the application in background
echo "Starting SafetyMaster Pro..."
"$PYTHON_CMD" web_interface.py > /dev/null 2>&1 &
APP_PID=$!
# Wait for server to start
sleep 5
# Check if the application started successfully
if ! kill -0 $APP_PID 2>/dev/null; then
show_error "Failed to start SafetyMaster Pro.
This might be due to:
- Missing dependencies
- Camera access issues
- Port 8080 already in use
Check the Terminal for error messages."
exit 1
fi
# Open browser
open http://localhost:8080 || {
echo "Could not open browser automatically"
}
# Show success message with more information
show_info "SafetyMaster Pro is running!
🌐 Web Interface: http://localhost:8080
πŸ“Ή Make sure your camera is connected
πŸ›‘ To stop: Close this dialog and quit the app
The application will continue running until you quit it."
# Wait for the Python process to finish
wait $APP_PID
'''
# Write the executable script
executable_path = os.path.join(macos_dir, "SafetyMasterPro")
with open(executable_path, 'w') as f:
f.write(executable_script)
# Make executable
os.chmod(executable_path, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
# Create improved Info.plist
plist_data = {
'CFBundleExecutable': 'SafetyMasterPro',
'CFBundleIdentifier': 'com.safetymaster.pro',
'CFBundleName': 'SafetyMaster Pro',
'CFBundleDisplayName': 'SafetyMaster Pro',
'CFBundleVersion': '1.0.1',
'CFBundleShortVersionString': '1.0.1',
'CFBundlePackageType': 'APPL',
'CFBundleSignature': 'SMPR',
'LSMinimumSystemVersion': '10.14', # macOS Mojave minimum for camera permissions
'LSRequiresNativeExecution': True, # Ensure it runs natively on Apple Silicon
'NSCameraUsageDescription': 'SafetyMaster Pro needs camera access to detect safety equipment and monitor workplace compliance in real-time.',
'NSMicrophoneUsageDescription': 'SafetyMaster Pro may use microphone for enhanced safety monitoring features.',
'NSHighResolutionCapable': True,
'LSApplicationCategoryType': 'public.app-category.business',
'NSRequiresAquaSystemAppearance': False, # Support dark mode
'LSMultipleInstancesProhibited': True, # Prevent multiple instances
'NSSupportsAutomaticGraphicsSwitching': True, # Support GPU switching
'LSArchitecturePriority': ['arm64', 'x86_64'], # Prefer Apple Silicon, fallback to Intel
'NSAppTransportSecurity': {
'NSAllowsLocalNetworking': True, # Allow localhost connections
'NSExceptionDomains': {
'localhost': {
'NSExceptionAllowsInsecureHTTPLoads': True
}
}
}
}
# Write Info.plist
plist_path = os.path.join(contents_dir, "Info.plist")
with open(plist_path, 'wb') as f:
plistlib.dump(plist_data, f)
# Create a README for distribution
readme_content = '''# SafetyMaster Pro - Mac Distribution
## System Requirements
- macOS 10.14 (Mojave) or later
- Python 3.8 or later (will be installed automatically if missing)
- Camera/webcam connected
- At least 2GB RAM
- 1GB free disk space
## Installation Instructions
### Method 1: Double-Click (Easiest)
1. Double-click "SafetyMaster Pro.app"
2. If prompted about security, go to System Preferences > Security & Privacy and click "Open Anyway"
3. Grant camera permissions when requested
4. The app will open in your web browser
### Method 2: Right-Click Open (If security blocked)
1. Right-click "SafetyMaster Pro.app"
2. Select "Open" from the context menu
3. Click "Open" in the security dialog
4. Grant camera permissions when requested
## First Run Setup
1. The app will automatically install Python dependencies
2. Grant camera access when prompted
3. The web interface will open at http://localhost:8080
4. Click "Start Monitoring" to begin safety detection
## Troubleshooting
### "App can't be opened because it is from an unidentified developer"
- Right-click the app and select "Open"
- Or go to System Preferences > Security & Privacy > General and click "Open Anyway"
### Python Not Found
- Install Python from https://www.python.org/downloads/macos/
- Or install Homebrew and run: brew install python3
### Camera Access Denied
- Go to System Preferences > Security & Privacy > Camera
- Enable camera access for SafetyMaster Pro
### Port Already in Use
- Make sure no other SafetyMaster Pro instances are running
- Or restart your Mac to free up the port
## Features
- Real-time PPE detection (hard hats, safety vests, masks)
- Web-based dashboard with statistics
- Violation tracking and alerts
- High-performance AI processing (30+ FPS)
- Cross-platform compatibility
## Support
For issues or questions, check the included documentation or visit the project repository.
'''
readme_path = os.path.join(resources_dir, "README.txt")
with open(readme_path, 'w') as f:
f.write(readme_content)
print(f"\nβœ… Improved Mac app bundle created: {app_dir}")
print(f"πŸ“ Size: {get_directory_size(app_dir):.1f} MB")
print(f"πŸ”§ Features:")
print(f" - Better Python detection (supports multiple versions)")
print(f" - Virtual environment support")
print(f" - Enhanced error handling and user guidance")
print(f" - Apple Silicon + Intel compatibility")
print(f" - Improved security permissions")
print(f" - Better camera access handling")
print(f"\nπŸ“‹ Distribution ready - users can:")
print(f" 1. Double-click to run")
print(f" 2. No manual Python setup required")
print(f" 3. Automatic dependency installation")
print(f" 4. Clear error messages with solutions")
def get_directory_size(path):
"""Calculate directory size in MB."""
total_size = 0
for dirpath, dirnames, filenames in os.walk(path):
for filename in filenames:
filepath = os.path.join(dirpath, filename)
if os.path.exists(filepath):
total_size += os.path.getsize(filepath)
return total_size / (1024 * 1024)
if __name__ == "__main__":
create_improved_mac_app()