updated download
This commit is contained in:
@@ -1278,6 +1278,378 @@ Ready to use immediately after installation!"""
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
@bp.route('/create_zero_dependency_service_package', methods=['POST'])
|
||||
def create_zero_dependency_service_package():
|
||||
"""Create and serve ZIP package with embedded Python - ZERO external dependencies"""
|
||||
import os
|
||||
import tempfile
|
||||
import zipfile
|
||||
import urllib.request
|
||||
import subprocess
|
||||
from flask import current_app, jsonify
|
||||
|
||||
try:
|
||||
print("🚀 Creating Zero-Dependency Service Package...")
|
||||
|
||||
# Path to the windows_print_service directory
|
||||
service_dir = os.path.join(os.path.dirname(os.path.dirname(current_app.root_path)), 'windows_print_service')
|
||||
print(f"Looking for service files in: {service_dir}")
|
||||
|
||||
if not os.path.exists(service_dir):
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': f'Windows service directory not found: {service_dir}'
|
||||
}), 500
|
||||
|
||||
# Create static directory if it doesn't exist
|
||||
static_dir = os.path.join(current_app.root_path, 'static')
|
||||
os.makedirs(static_dir, exist_ok=True)
|
||||
|
||||
zip_filename = 'QualityPrintService_ZERO_DEPENDENCIES.zip'
|
||||
zip_path = os.path.join(static_dir, zip_filename)
|
||||
|
||||
# Python embeddable version details
|
||||
PYTHON_VERSION = "3.11.9"
|
||||
PYTHON_DOWNLOAD_URL = f"https://www.python.org/ftp/python/{PYTHON_VERSION}/python-{PYTHON_VERSION}-embed-amd64.zip"
|
||||
PYTHON_DIR_NAME = "python_embedded"
|
||||
|
||||
print(f"📥 Will download Python {PYTHON_VERSION} embedded...")
|
||||
|
||||
# Create the complete zero-dependency package
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
print(f"🔧 Using temporary directory: {temp_dir}")
|
||||
|
||||
# Download Python embedded
|
||||
python_zip_path = os.path.join(temp_dir, "python-embed.zip")
|
||||
python_extract_dir = os.path.join(temp_dir, PYTHON_DIR_NAME)
|
||||
|
||||
try:
|
||||
print(f"📥 Downloading Python embedded from: {PYTHON_DOWNLOAD_URL}")
|
||||
urllib.request.urlretrieve(PYTHON_DOWNLOAD_URL, python_zip_path)
|
||||
print(f"✅ Downloaded Python to: {python_zip_path}")
|
||||
|
||||
# Extract Python
|
||||
os.makedirs(python_extract_dir, exist_ok=True)
|
||||
with zipfile.ZipFile(python_zip_path, 'r') as zip_ref:
|
||||
zip_ref.extractall(python_extract_dir)
|
||||
print(f"✅ Extracted Python to: {python_extract_dir}")
|
||||
|
||||
# Enable site-packages by modifying pth file
|
||||
pth_files = [f for f in os.listdir(python_extract_dir) if f.endswith('._pth')]
|
||||
if pth_files:
|
||||
pth_file = os.path.join(python_extract_dir, pth_files[0])
|
||||
with open(pth_file, 'a') as f:
|
||||
f.write('\nimport site\n')
|
||||
print("✅ Enabled site-packages in embedded Python")
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': f'Failed to download Python embedded: {str(e)}'
|
||||
}), 500
|
||||
|
||||
# Create the complete package ZIP
|
||||
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
||||
files_added = 0
|
||||
|
||||
# Add Python embedded distribution
|
||||
print("📁 Adding Python embedded distribution...")
|
||||
for root, dirs, files in os.walk(python_extract_dir):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
arcname = os.path.join(PYTHON_DIR_NAME, os.path.relpath(file_path, python_extract_dir))
|
||||
zipf.write(file_path, arcname)
|
||||
files_added += 1
|
||||
if files_added % 10 == 0: # Progress indicator
|
||||
print(f" 📄 Added {files_added} Python files...")
|
||||
|
||||
# Add service files
|
||||
print("📁 Adding service files...")
|
||||
service_files = [
|
||||
"print_service_complete.py",
|
||||
"install_service_complete.bat",
|
||||
"uninstall_service_complete.bat",
|
||||
"INSTALLATION_COMPLETE.md",
|
||||
"PACKAGE_SUMMARY.md",
|
||||
"README_COMPLETE.md"
|
||||
]
|
||||
|
||||
for file_name in service_files:
|
||||
file_path = os.path.join(service_dir, file_name)
|
||||
if os.path.exists(file_path):
|
||||
zipf.write(file_path, file_name)
|
||||
files_added += 1
|
||||
print(f" ✅ Added: {file_name}")
|
||||
|
||||
# Add Chrome extension
|
||||
chrome_ext_dir = os.path.join(service_dir, "chrome_extension")
|
||||
if os.path.exists(chrome_ext_dir):
|
||||
print("📁 Adding Chrome extension...")
|
||||
for root, dirs, files in os.walk(chrome_ext_dir):
|
||||
for file in files:
|
||||
if not file.startswith('.'):
|
||||
file_path = os.path.join(root, file)
|
||||
arcname = os.path.relpath(file_path, service_dir)
|
||||
zipf.write(file_path, arcname)
|
||||
files_added += 1
|
||||
|
||||
# Create updated zero-dependency installer
|
||||
installer_content = f'''@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
echo ========================================
|
||||
echo Quality Label Print Service Installer
|
||||
echo ZERO DEPENDENCIES - COMPLETE PACKAGE
|
||||
echo ========================================
|
||||
echo.
|
||||
echo This package includes EVERYTHING needed:
|
||||
echo ✅ Embedded Python {PYTHON_VERSION}
|
||||
echo ✅ Complete Print Service
|
||||
echo ✅ Windows Service Installer
|
||||
echo ✅ Chrome Extension
|
||||
echo ✅ Auto-recovery System
|
||||
echo.
|
||||
|
||||
REM Check for administrator privileges
|
||||
net session >nul 2>&1
|
||||
if %errorLevel% neq 0 (
|
||||
echo ❌ ERROR: Administrator privileges required
|
||||
echo Please right-click this file and select "Run as administrator"
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo [1/7] Administrator privileges confirmed ✅
|
||||
echo.
|
||||
|
||||
REM Set variables
|
||||
set CURRENT_DIR=%~dp0
|
||||
set SERVICE_NAME=QualityPrintService
|
||||
set SERVICE_DISPLAY_NAME=Quality Label Print Service
|
||||
set INSTALL_DIR=C:\\QualityPrintService
|
||||
set PYTHON_EXE=%INSTALL_DIR%\\{PYTHON_DIR_NAME}\\python.exe
|
||||
set PYTHON_SCRIPT=%INSTALL_DIR%\\print_service_complete.py
|
||||
set LOG_DIR=%USERPROFILE%\\PrintService\\logs
|
||||
|
||||
echo [2/7] Using embedded Python distribution ✅
|
||||
echo Python location: %PYTHON_EXE%
|
||||
echo.
|
||||
|
||||
REM Stop existing service if running
|
||||
echo [3/7] Stopping existing service (if any)...
|
||||
sc query "%SERVICE_NAME%" >nul 2>&1
|
||||
if %errorLevel% equ 0 (
|
||||
echo Stopping existing service...
|
||||
net stop "%SERVICE_NAME%" >nul 2>&1
|
||||
sc delete "%SERVICE_NAME%" >nul 2>&1
|
||||
timeout /t 2 >nul
|
||||
)
|
||||
echo Service cleanup completed ✅
|
||||
echo.
|
||||
|
||||
REM Create installation directory
|
||||
echo [4/7] Creating installation directory...
|
||||
if exist "%INSTALL_DIR%" (
|
||||
echo Removing old installation...
|
||||
rmdir /s /q "%INSTALL_DIR%" >nul 2>&1
|
||||
)
|
||||
mkdir "%INSTALL_DIR%" >nul 2>&1
|
||||
echo Installation directory: %INSTALL_DIR% ✅
|
||||
echo.
|
||||
|
||||
REM Copy all files to installation directory
|
||||
echo [5/7] Installing service files...
|
||||
echo Copying embedded Python...
|
||||
xcopy "%CURRENT_DIR%{PYTHON_DIR_NAME}" "%INSTALL_DIR%\\{PYTHON_DIR_NAME}\\" /E /I /Y >nul
|
||||
echo Copying service script...
|
||||
copy "%CURRENT_DIR%print_service_complete.py" "%INSTALL_DIR%\\" >nul
|
||||
echo Service files installed ✅
|
||||
echo.
|
||||
|
||||
REM Create log directory
|
||||
echo [6/7] Setting up logging...
|
||||
mkdir "%LOG_DIR%" >nul 2>&1
|
||||
echo Log directory: %LOG_DIR% ✅
|
||||
echo.
|
||||
|
||||
REM Install and start Windows service
|
||||
echo [7/7] Installing Windows service...
|
||||
sc create "%SERVICE_NAME%" binPath= "\\"%PYTHON_EXE%\\" \\"%PYTHON_SCRIPT%\\"" DisplayName= "%SERVICE_DISPLAY_NAME%" start= auto
|
||||
if %errorLevel% neq 0 (
|
||||
echo ❌ Failed to create Windows service
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM Configure service recovery
|
||||
sc failure "%SERVICE_NAME%" reset= 60 actions= restart/10000/restart/30000/restart/60000
|
||||
sc config "%SERVICE_NAME%" depend= ""
|
||||
|
||||
REM Start the service
|
||||
echo Starting service...
|
||||
net start "%SERVICE_NAME%"
|
||||
if %errorLevel% neq 0 (
|
||||
echo ⚠️ Service created but failed to start immediately
|
||||
echo This is normal - the service will start automatically on reboot
|
||||
) else (
|
||||
echo Service started successfully ✅
|
||||
)
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo INSTALLATION COMPLETED! 🎉
|
||||
echo ========================================
|
||||
echo.
|
||||
echo ✅ Python embedded distribution installed
|
||||
echo ✅ Windows Print Service installed and configured
|
||||
echo ✅ Auto-recovery enabled (restarts on failure)
|
||||
echo ✅ Service will start automatically on boot
|
||||
echo.
|
||||
echo 🌐 Service URL: http://localhost:8765
|
||||
echo 📊 Health check: http://localhost:8765/health
|
||||
echo 📁 Logs location: %LOG_DIR%
|
||||
echo.
|
||||
echo 📋 NEXT STEPS:
|
||||
echo 1. Install Chrome extension from 'chrome_extension' folder
|
||||
echo 2. Test service: http://localhost:8765/health
|
||||
echo 3. Configure web application to use service
|
||||
echo.
|
||||
echo Press any key to test service connection...
|
||||
pause >nul
|
||||
|
||||
REM Test service
|
||||
echo Testing service connection...
|
||||
timeout /t 3 >nul
|
||||
curl -s http://localhost:8765/health >nul 2>&1
|
||||
if %errorLevel% equ 0 (
|
||||
echo ✅ Service is responding correctly!
|
||||
) else (
|
||||
echo ⚠️ Service test failed - may need a moment to start
|
||||
echo Check logs in: %LOG_DIR%
|
||||
)
|
||||
|
||||
echo.
|
||||
echo Installation complete! Service is ready to use.
|
||||
pause
|
||||
'''
|
||||
|
||||
zipf.writestr("INSTALL_ZERO_DEPENDENCIES.bat", installer_content)
|
||||
files_added += 1
|
||||
|
||||
# Add comprehensive README
|
||||
readme_content = f'''# Quality Print Service - ZERO DEPENDENCIES Package
|
||||
|
||||
## 🎯 COMPLETE SELF-CONTAINED INSTALLATION
|
||||
|
||||
This package contains EVERYTHING needed to run the Quality Print Service:
|
||||
|
||||
### ✅ What's Included:
|
||||
- **Embedded Python {PYTHON_VERSION}** - No system Python required!
|
||||
- **Complete Print Service** - Zero external dependencies
|
||||
- **Windows Service Installer** - Automatic installation and recovery
|
||||
- **Chrome Extension** - Web browser integration
|
||||
- **Comprehensive Documentation** - Installation and usage guides
|
||||
|
||||
### 🚀 INSTALLATION (5 Minutes):
|
||||
|
||||
#### Requirements:
|
||||
- Windows 10/11 or Windows Server 2016+
|
||||
- Administrator privileges (for service installation)
|
||||
- Google Chrome browser
|
||||
|
||||
#### Step 1: Extract Package
|
||||
- Extract this ZIP file to any location (Desktop, Downloads, etc.)
|
||||
- No permanent location needed - installer copies files automatically
|
||||
|
||||
#### Step 2: Install Service
|
||||
- Right-click `INSTALL_ZERO_DEPENDENCIES.bat`
|
||||
- Select "Run as administrator"
|
||||
- Follow the installation prompts
|
||||
|
||||
#### Step 3: Install Chrome Extension
|
||||
- Open Chrome browser
|
||||
- Navigate to `chrome://extensions/`
|
||||
- Enable "Developer mode" (toggle in top-right)
|
||||
- Click "Load unpacked"
|
||||
- Select the `chrome_extension` folder from extracted package
|
||||
|
||||
#### Step 4: Test Installation
|
||||
- Visit: http://localhost:8765/health
|
||||
- Should return: {{"status": "healthy", "service": "Windows Print Service"}}
|
||||
|
||||
### 🔧 Technical Details:
|
||||
|
||||
**Service Architecture:**
|
||||
```
|
||||
Quality Web App → Chrome Extension → Windows Service → Printer
|
||||
```
|
||||
|
||||
**Printing Methods (automatic fallback):**
|
||||
1. Adobe Reader (silent printing)
|
||||
2. SumatraPDF (if Adobe unavailable)
|
||||
3. PowerShell Print-Document
|
||||
4. Microsoft Edge (fallback)
|
||||
5. Windows default printer
|
||||
|
||||
**Service Management:**
|
||||
- Automatic startup on Windows boot
|
||||
- Auto-recovery on failure (3 restart attempts)
|
||||
- Comprehensive logging in: `%USERPROFILE%\\PrintService\\logs\\`
|
||||
|
||||
**Network Configuration:**
|
||||
- Service runs on: http://localhost:8765
|
||||
- Chrome extension communicates via this local endpoint
|
||||
- No external network access required
|
||||
|
||||
### 📦 Package Size: ~15MB (includes full Python runtime)
|
||||
### ⏱️ Installation Time: ~5 minutes
|
||||
### 🔧 Maintenance Required: Zero (auto-starts with Windows)
|
||||
|
||||
Ready to use immediately after installation!
|
||||
'''
|
||||
|
||||
zipf.writestr("README_ZERO_DEPENDENCIES.md", readme_content)
|
||||
files_added += 1
|
||||
|
||||
# Verify ZIP was created successfully
|
||||
if os.path.exists(zip_path):
|
||||
zip_size = os.path.getsize(zip_path)
|
||||
print(f"✅ Zero-dependency package created: {zip_path}")
|
||||
print(f"📄 Total files: {files_added}")
|
||||
print(f"📏 Size: {zip_size / 1024 / 1024:.1f} MB")
|
||||
|
||||
if zip_size > 0:
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'download_url': f'/static/{zip_filename}',
|
||||
'files_included': files_added,
|
||||
'zip_size': zip_size,
|
||||
'package_type': 'Zero Dependencies - Complete Package',
|
||||
'python_version': PYTHON_VERSION,
|
||||
'dependencies': 'None - Everything included!',
|
||||
'estimated_size_mb': round(zip_size / 1024 / 1024, 1)
|
||||
})
|
||||
else:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'ZIP file was created but is empty'
|
||||
}), 500
|
||||
else:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Failed to create zero-dependency ZIP file'
|
||||
}), 500
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error creating zero-dependency service package: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
@bp.route('/test_extension_files')
|
||||
def test_extension_files():
|
||||
"""Test route to check extension files"""
|
||||
|
||||
Reference in New Issue
Block a user