updated to silent print

This commit is contained in:
2025-09-24 21:42:22 +03:00
parent b49a22832d
commit 198563aaba
26 changed files with 693 additions and 1520 deletions

View File

@@ -0,0 +1,18 @@
#!/bin/bash
# Cleanup script for Quality Label Printing Service folder
# Run this from the windows_print_service directory (in Git Bash, WSL, or Linux)
# Remove Python-based service and management
rm -f print_service.py
rm -f service_manager.py
# Remove extra documentation (keep only README.md)
rm -f INSTALLATION_GUIDE.md NATIVE_SOLUTION_SUMMARY.md QUICK_SETUP.md QUICK_SETUP_NATIVE.md
# Optionally remove test_service.ps1 if not needed
# rm -f test_service.ps1
# Done
ls -l
echo "Cleanup complete. Only PowerShell service, Chrome extension, and README remain."

View File

@@ -1,361 +0,0 @@
# Quality Recticel Windows Print Service - Installation Guide
## 📋 Overview
The Quality Recticel Windows Print Service enables **silent PDF printing** directly from the web application through a Chrome extension. This system eliminates the need for manual PDF downloads and provides seamless label printing functionality.
## 🏗️ System Architecture
```
Web Application (print_module.html)
Windows Print Service (localhost:8765)
Chrome Extension (Native Messaging)
Windows Print System
```
## 📦 Package Contents
```
windows_print_service/
├── print_service.py # Main Windows service (Flask API)
├── service_manager.py # Service installation & management
├── install_service.bat # Automated installation script
├── chrome_extension/ # Chrome extension files
│ ├── manifest.json # Extension configuration
│ ├── background.js # Service worker
│ ├── content.js # Page integration
│ ├── popup.html # Extension UI
│ ├── popup.js # Extension logic
│ └── icons/ # Extension icons
└── INSTALLATION_GUIDE.md # This documentation
```
## 🔧 Prerequisites
### System Requirements
- **Operating System**: Windows 10/11 (64-bit)
- **Python**: Python 3.8 or higher
- **Browser**: Google Chrome (latest version)
- **Privileges**: Administrator access required for installation
### Python Dependencies
The following packages will be installed automatically:
- `flask` - Web service framework
- `flask-cors` - Cross-origin resource sharing
- `requests` - HTTP client library
- `pywin32` - Windows service integration
## 🚀 Installation Process
### Step 1: Download and Extract Files
1. Download the `windows_print_service` folder to your system
2. Extract to a permanent location (e.g., `C:\QualityRecticel\PrintService\`)
3. **Do not move or delete this folder after installation**
### Step 2: Install Windows Service
#### Method A: Automated Installation (Recommended)
1. **Right-click** on `install_service.bat`
2. Select **"Run as administrator"**
3. Click **"Yes"** when Windows UAC prompt appears
4. Wait for installation to complete
#### Method B: Manual Installation
If the automated script fails, follow these steps:
```bash
# Open Command Prompt as Administrator
cd C:\path\to\windows_print_service
# Install Python dependencies
pip install flask flask-cors requests pywin32
# Install Windows service
python service_manager.py install
# Add firewall exception
netsh advfirewall firewall add rule name="Quality Recticel Print Service" dir=in action=allow protocol=TCP localport=8765
# Create Chrome extension registry entry
reg add "HKEY_CURRENT_USER\Software\Google\Chrome\NativeMessagingHosts\com.qualityrecticel.printservice" /ve /d "%cd%\chrome_extension\manifest.json" /f
```
### Step 3: Install Chrome Extension
1. Open **Google Chrome**
2. Navigate to `chrome://extensions/`
3. Enable **"Developer mode"** (toggle in top-right corner)
4. Click **"Load unpacked"**
5. Select the `chrome_extension` folder
6. Verify the extension appears with a printer icon
### Step 4: Verify Installation
#### Check Windows Service Status
1. Press `Win + R`, type `services.msc`, press Enter
2. Look for **"Quality Recticel Print Service"**
3. Status should show **"Running"**
4. Startup type should be **"Automatic"**
#### Test API Endpoints
Open a web browser and visit:
- **Health Check**: `http://localhost:8765/health`
- **Printer List**: `http://localhost:8765/printers`
Expected response for health check:
```json
{
"status": "healthy",
"service": "Quality Recticel Print Service",
"version": "1.0",
"timestamp": "2025-09-21T10:30:00"
}
```
#### Test Chrome Extension
1. Click the extension icon in Chrome toolbar
2. Verify it shows "Service Status: Connected ✅"
3. Check that printers are listed
4. Try the "Test Print" button
## 🔄 Web Application Integration
The web application automatically detects the Windows service and adapts the user interface:
### Service Available (Green Button)
- Button text: **"🖨️ Print Labels (Silent)"**
- Functionality: Direct printing to default printer
- User experience: Click → Labels print immediately
### Service Unavailable (Blue Button)
- Button text: **"📄 Generate PDF"**
- Functionality: PDF download for manual printing
- User experience: Click → PDF downloads to browser
### Detection Logic
```javascript
// Automatic service detection on page load
const response = await fetch('http://localhost:8765/health');
if (response.ok) {
// Service available - enable silent printing
} else {
// Service unavailable - fallback to PDF download
}
```
## 🛠️ Configuration
### Service Configuration
The service runs with the following default settings:
| Setting | Value | Description |
|---------|-------|-------------|
| **Port** | 8765 | Local API port |
| **Host** | localhost | Service binding |
| **Startup** | Automatic | Starts with Windows |
| **Printer** | Default | Uses system default printer |
| **Copies** | 1 | Default print copies |
### Chrome Extension Permissions
The extension requires these permissions:
- `printing` - Access to printer functionality
- `nativeMessaging` - Communication with Windows service
- `activeTab` - Access to current webpage
- `storage` - Save extension settings
## 🔍 Troubleshooting
### Common Issues
#### 1. Service Not Starting
**Symptoms**: API not accessible at localhost:8765
**Solutions**:
```bash
# Check service status
python -c "from service_manager import service_status; service_status()"
# Restart service manually
python service_manager.py restart
# Check Windows Event Viewer for service errors
```
#### 2. Chrome Extension Not Working
**Symptoms**: Extension shows "Service Status: Disconnected ❌"
**Solutions**:
- Verify Windows service is running
- Check firewall settings (port 8765 must be open)
- Reload the Chrome extension
- Restart Chrome browser
#### 3. Firewall Blocking Connection
**Symptoms**: Service runs but web page can't connect
**Solutions**:
```bash
# Add firewall rule manually
netsh advfirewall firewall add rule name="Quality Recticel Print Service" dir=in action=allow protocol=TCP localport=8765
# Or disable Windows Firewall temporarily to test
```
#### 4. Permission Denied Errors
**Symptoms**: Installation fails with permission errors
**Solutions**:
- Ensure running as Administrator
- Check Windows UAC settings
- Verify Python installation permissions
#### 5. Print Jobs Not Processing
**Symptoms**: API accepts requests but nothing prints
**Solutions**:
- Check default printer configuration
- Verify printer drivers are installed
- Test manual printing from other applications
- Check Windows Print Spooler service
### Log Files
Check these locations for troubleshooting:
| Component | Log Location |
|-----------|--------------|
| **Windows Service** | `print_service.log` (same folder as service) |
| **Chrome Extension** | Chrome DevTools → Extensions → Background page |
| **Windows Event Log** | Event Viewer → Windows Logs → System |
### Diagnostic Commands
```bash
# Check service status
python service_manager.py status
# Test API manually
curl http://localhost:8765/health
# List available printers
curl http://localhost:8765/printers
# Check Windows service
sc query QualityRecticelPrintService
# Check listening ports
netstat -an | findstr :8765
```
## 🔄 Maintenance
### Updating the Service
1. Stop the current service:
```bash
python service_manager.py stop
```
2. Replace service files with new versions
3. Restart the service:
```bash
python service_manager.py start
```
### Uninstalling
#### Remove Chrome Extension
1. Go to `chrome://extensions/`
2. Find "Quality Recticel Print Service"
3. Click "Remove"
#### Remove Windows Service
```bash
# Run as Administrator
python service_manager.py uninstall
```
#### Remove Firewall Rule
```bash
netsh advfirewall firewall delete rule name="Quality Recticel Print Service"
```
## 📞 Support Information
### API Endpoints Reference
| Endpoint | Method | Purpose |
|----------|--------|---------|
| `/health` | GET | Service health check |
| `/printers` | GET | List available printers |
| `/print/pdf` | POST | Print PDF from URL |
| `/print/silent` | POST | Silent print with metadata |
### Request Examples
**Silent Print Request**:
```json
POST /print/silent
{
"pdf_url": "http://localhost:5000/generate_labels_pdf/123",
"printer_name": "default",
"copies": 1,
"silent": true,
"order_id": "123",
"quantity": "10"
}
```
**Expected Response**:
```json
{
"success": true,
"message": "Print job sent successfully",
"job_id": "print_20250921_103000",
"printer": "HP LaserJet Pro",
"timestamp": "2025-09-21T10:30:00"
}
```
## 📚 Technical Details
### Service Architecture
- **Framework**: Flask (Python)
- **Service Type**: Windows Service (pywin32)
- **Communication**: HTTP REST API + Native Messaging
- **Security**: Localhost binding only (127.0.0.1:8765)
### Chrome Extension Architecture
- **Manifest Version**: 3
- **Service Worker**: Handles background print requests
- **Content Script**: Integrates with Quality Recticel web pages
- **Native Messaging**: Communicates with Windows service
### Security Considerations
- Service only accepts local connections (localhost)
- No external network access required
- Chrome extension runs in sandboxed environment
- Windows service runs with system privileges (required for printing)
---
## 📋 Quick Start Checklist
- [ ] Download `windows_print_service` folder
- [ ] Right-click `install_service.bat` → "Run as administrator"
- [ ] Install Chrome extension from `chrome_extension` folder
- [ ] Verify service at `http://localhost:8765/health`
- [ ] Test printing from Quality Recticel web application
**Installation Time**: ~5 minutes
**User Training Required**: Minimal (automatic detection and fallback)
**Maintenance**: Zero (auto-starts with Windows)
For additional support, check the log files and diagnostic commands listed above.

View File

@@ -1,167 +0,0 @@
# Native Windows Print Service - Implementation Summary
## 🎯 Solution Overview
Successfully replaced the Python Flask-based Windows print service with a **native PowerShell implementation** that eliminates all external dependencies while maintaining full functionality.
## 📁 Files Created/Modified
### Core Service Files
-`print_service.ps1` - Complete PowerShell HTTP server with REST API
-`install_native_service.bat` - Native Windows service installer
-`uninstall_service.bat` - Service removal script
### Documentation Updated
-`README.md` - Comprehensive native solution documentation
-`QUICK_SETUP_NATIVE.md` - Fast setup guide for native solution
-`routes.py` - Updated ZIP package to prioritize native files
### Web Integration Updated
-`print_module.html` - Replaced PDF info card with printer dropdown
- ✅ Service detection and printer enumeration integration
- ✅ Enhanced error handling for native service endpoints
## 🚀 Key Advantages
| Feature | Python Flask | Native PowerShell |
|---------|-------------|------------------|
| **Dependencies** | Python + Flask + Requests + pip packages | PowerShell only (built-in) |
| **Installation Time** | 5-10 minutes | 1-2 minutes |
| **Startup Time** | 10-15 seconds | 2-3 seconds |
| **Memory Usage** | 50-100MB | 10-20MB |
| **Disk Space** | 200-500MB | 5-10MB |
| **Security** | External packages | Microsoft-signed only |
| **Enterprise Ready** | Requires IT approval | Uses trusted components |
| **Troubleshooting** | Python debugging | Native Windows tools |
## 🔧 Technical Implementation
### PowerShell HTTP Server
```powershell
# Uses .NET HttpListener for native HTTP serving
$listener = New-Object System.Net.HttpListener
$listener.Prefixes.Add("http://localhost:8765/")
```
### Printer Integration
```powershell
# Native WMI integration for printer enumeration
Get-WmiObject -Class Win32_Printer | Where-Object { $_.Local -eq $true }
```
### PDF Printing
```powershell
# Native file download and print via Windows shell
$webClient = New-Object System.Net.WebClient
Start-Process -FilePath $pdfFile -Verb Print
```
## 📡 API Endpoints (Maintained Compatibility)
All original endpoints preserved:
- `GET /health` - Service health check
- `GET /printers` - List available printers
- `POST /print/pdf` - Print PDF documents
- `POST /print/silent` - Silent PDF printing
## 🔄 Migration Path
### For Existing Users
1. Run `uninstall_service.bat` to remove Python service
2. Run `install_native_service.bat` to install native service
3. No Chrome extension changes needed - same API endpoints
### For New Deployments
1. Download updated service package (includes native solution)
2. Run `install_native_service.bat` as Administrator
3. Install Chrome extension as before
4. Everything works identically to Python version
## 🛡️ Security & Compliance
### Enterprise Benefits
- **No Third-Party Code**: Uses only Microsoft PowerShell and .NET
- **Reduced Attack Surface**: Fewer dependencies = fewer vulnerabilities
- **Audit Friendly**: All code visible and editable
- **Corporate Compliance**: Easier approval through IT security
### Security Features
- Localhost-only binding (127.0.0.1)
- CORS headers for browser security
- Automatic temporary file cleanup
- Service-level isolation
## 📊 Performance Metrics
### Service Startup
- Python Flask: ~12 seconds (package imports, Flask initialization)
- Native PowerShell: ~2 seconds (PowerShell load only)
### Memory Footprint
- Python Flask: ~60MB (Python runtime + packages)
- Native PowerShell: ~15MB (PowerShell host + .NET objects)
### HTTP Response Time
- Both solutions: <50ms for API endpoints (no significant difference)
## 🎉 Deployment Advantages
### IT Department Benefits
1. **Single Installer**: One .bat file installs everything
2. **No Prerequisites**: Works on any Windows machine
3. **Easy Troubleshooting**: Native Windows service tools
4. **Clean Uninstall**: Complete removal with uninstall script
5. **Standard Logging**: Uses Windows event system integration
6. **Group Policy Compatible**: Can be deployed via GPO
### End User Benefits
1. **Faster Installation**: 3 minutes vs 10+ minutes
2. **Better Reliability**: Fewer moving parts to break
3. **Lower Resource Usage**: Less CPU and RAM consumption
4. **Familiar Tools**: Standard Windows service management
## 🔧 Maintenance & Support
### Service Management
```batch
# All standard Windows service commands work
sc start QualityRecticelPrintService
sc stop QualityRecticelPrintService
sc query QualityRecticelPrintService
```
### Log Files
- **Location**: `C:\Program Files\QualityRecticel\PrintService\print_service.log`
- **Format**: Timestamp + message (human readable)
- **Rotation**: Automatic (PowerShell handles)
### Configuration
- **Port**: Editable in print_service.ps1 (default 8765)
- **Logging**: Configurable verbosity levels
- **Service Account**: Standard Windows service account options
## ✅ Success Metrics
### Installation Success Rate
- Target: 95%+ first-time success
- Native solution eliminates dependency conflicts
### Performance Improvement
- 80% faster startup time
- 70% less memory usage
- 95% smaller disk footprint
### Support Ticket Reduction
- Fewer dependency-related issues
- Easier troubleshooting with native tools
- Better compatibility across Windows versions
## 🚀 Next Steps
1. **User Testing**: Deploy to pilot group for validation
2. **Documentation Updates**: Ensure all guides reflect native solution
3. **Package Distribution**: Update download system with native version
4. **Migration Support**: Help existing users transition from Python version
5. **Training Materials**: Create guides for IT support teams
The native PowerShell solution provides all the functionality of the Python version while being significantly more enterprise-friendly, faster, and easier to deploy and maintain.

View File

@@ -1,69 +0,0 @@
# 🚀 Quality Recticel Print Service - Quick Setup
## 📦 What You Get
- **Silent PDF Printing** - No more manual downloads!
- **Automatic Detection** - Smart fallback when service unavailable
- **Zero Configuration** - Works out of the box
## ⚡ 2-Minute Installation
### Step 1: Install Windows Service
1. **Right-click** `install_service.bat`
2. Select **"Run as administrator"**
3. Click **"Yes"** and wait for completion
### Step 2: Install Chrome Extension
1. Open Chrome → `chrome://extensions/`
2. Enable **"Developer mode"**
3. Click **"Load unpacked"** → Select `chrome_extension` folder
### Step 3: Verify Installation
- Visit: `http://localhost:8765/health`
- Should see: `{"status": "healthy"}`
## 🎯 How It Works
| Service Status | Button Appearance | What Happens |
|---------------|-------------------|--------------|
| **Running** ✅ | 🖨️ **Print Labels (Silent)** (Green) | Direct printing |
| **Not Running** ❌ | 📄 **Generate PDF** (Blue) | PDF download |
## ⚠️ Troubleshooting
| Problem | Solution |
|---------|----------|
| **Service won't start** | Run `install_service.bat` as Administrator |
| **Chrome extension not working** | Reload extension in `chrome://extensions/` |
| **Can't connect to localhost:8765** | Check Windows Firewall (port 8765) |
| **Nothing prints** | Verify default printer is set up |
## 🔧 Management Commands
```bash
# Check service status
python service_manager.py status
# Restart service
python service_manager.py restart
# Uninstall service
python service_manager.py uninstall
```
## 📍 Important Notes
-**Auto-starts** with Windows - no manual intervention needed
- 🔒 **Local only** - service only accessible from same computer
- 🖨️ **Uses default printer** - configure your default printer in Windows
- 💾 **Don't move files** after installation - keep folder in same location
## 🆘 Quick Support
**Service API**: `http://localhost:8765`
**Health Check**: `http://localhost:8765/health`
**Printer List**: `http://localhost:8765/printers`
**Log File**: `print_service.log` (same folder as installation)
---
*Installation takes ~5 minutes • Zero maintenance required • Works with existing Quality Recticel web application*

View File

@@ -1,187 +0,0 @@
# Quality Recticel Print Service - Quick Setup Guide (Native)
Get the Windows print service running in under 3 minutes - **Zero Dependencies!**
## What You Need
✅ Windows 10/11 or Windows Server
✅ Administrator access
✅ Chrome browser
✅ Downloaded service package
## Installation Steps
### 1. Install Native Windows Service (1 minute)
```batch
# Extract service package to any folder
# Right-click install_native_service.bat
# Select "Run as administrator"
install_native_service.bat
```
**Expected Output:**
```
✅ Administrator privileges confirmed
✅ Service directory created
✅ Service files copied successfully
✅ Windows service created successfully
✅ Service started successfully
🌐 Service running on http://localhost:8765
```
### 2. Install Chrome Extension (1 minute)
```
1. Open Chrome → More Tools → Extensions
2. Enable "Developer mode" (top right)
3. Click "Load unpacked"
4. Select the chrome_extension folder
5. Extension installed ✅
```
### 3. Test Everything (30 seconds)
**Test Service:**
- Open browser: http://localhost:8765/health
- Should show: `{"status": "healthy", "service": "Quality Recticel Print Service", "platform": "Windows PowerShell"}`
**Test Printing:**
- Go to Quality Recticel web app
- Open a label for printing
- Click print - should print silently ✅
## Native Advantages
🚀 **No Python Required** - Pure PowerShell implementation
**Instant Install** - No package downloads or dependencies
🛡️ **Enterprise Ready** - Uses only Microsoft components
📦 **Tiny Footprint** - Minimal disk and memory usage
🔧 **Easy Deployment** - Single installer, works everywhere
## Troubleshooting
### ❌ Service Won't Install
```batch
# Check if already installed
sc query QualityRecticelPrintService
# If exists, uninstall first
uninstall_service.bat
# Try installation again
install_native_service.bat
```
### ❌ Service Won't Start
```powershell
# Check PowerShell execution policy
Get-ExecutionPolicy
# Should be RemoteSigned or Unrestricted
# Set if needed (as Administrator)
Set-ExecutionPolicy RemoteSigned -Force
# Check the logs
Get-Content "C:\Program Files\QualityRecticel\PrintService\print_service.log" -Tail 20
# Manual start
sc start QualityRecticelPrintService
```
### ❌ Port Already in Use
```cmd
# Check what's using port 8765
netstat -ano | findstr :8765
# Kill process if needed (find PID from above)
taskkill /PID <process_id> /F
```
### ❌ Chrome Extension Issues
1. Check extension is enabled in chrome://extensions/
2. Test service URL directly: http://localhost:8765/health
3. Check browser console (F12) for errors
4. Verify CORS headers are working
### ❌ Printing Doesn't Work
```bash
# Test printer enumeration
curl http://localhost:8765/printers
# Check Windows print spooler
sc query spooler
# Restart print spooler if needed
sc stop spooler && sc start spooler
```
## Quick Commands
**Service Management:**
```batch
sc start QualityRecticelPrintService # Start
sc stop QualityRecticelPrintService # Stop
sc query QualityRecticelPrintService # Status
sc qc QualityRecticelPrintService # Configuration
```
**Test Endpoints:**
```bash
curl http://localhost:8765/health # Health check
curl http://localhost:8765/printers # List printers
```
**Uninstall:**
```batch
uninstall_service.bat # Complete removal
```
**Log Files:**
```
C:\Program Files\QualityRecticel\PrintService\print_service.log
```
## Advanced Configuration
**Custom Port:**
Edit `print_service.ps1` and change:
```powershell
param([int]$Port = 8765) # Change to desired port
```
**Service Account:**
```batch
# Run service as specific user (optional)
sc config QualityRecticelPrintService obj="domain\username" password="password"
```
## Performance Notes
- **Startup**: ~2 seconds (vs 10+ seconds for Python)
- **Memory**: ~15MB RAM (vs 50MB+ for Python/Flask)
- **CPU**: Minimal background usage
- **Dependencies**: Zero external packages
## Need Help?
1. **Check logs first** - PowerShell errors are detailed
2. **Test step by step** - service → health → printers → printing
3. **Verify PowerShell policy** - execution policy must allow scripts
4. **Contact IT support** with specific error messages
## Success Checklist
- [ ] Installer ran without errors
- [ ] Service shows "RUNNING" status: `sc query QualityRecticelPrintService`
- [ ] Health endpoint responds: http://localhost:8765/health
- [ ] Printers endpoint lists devices: http://localhost:8765/printers
- [ ] Chrome extension loaded and enabled
- [ ] Web app can print labels silently
---
**Success**: Native service running + Extension loaded + Silent printing works
📞 **Support**: Contact Quality Recticel IT with log details if issues persist
**Advantages over Python version:**
🚀 No external dependencies | ⚡ Faster startup | 🛡️ Better security | 📦 Smaller footprint

View File

@@ -3,17 +3,25 @@
* Injects print service functionality into web pages
*/
// Only inject on Quality Label Printing domains or localhost
const allowedDomains = [
'localhost',
'127.0.0.1'
];
const currentDomain = window.location.hostname;
if (!allowedDomains.includes(currentDomain)) {
console.log('Quality Label Printing Service: Not injecting on', currentDomain);
// return; // Commented out for development - remove in production
// Inject extension ID into the page as a hidden DOM element for detection
function injectExtensionId() {
try {
const existing = document.getElementById('chrome-extension-id');
if (existing) return; // Already injected
const el = document.createElement('div');
el.id = 'chrome-extension-id';
el.setAttribute('data-extension-id', chrome.runtime.id);
el.style.display = 'none';
document.documentElement.appendChild(el);
// Optionally, also set a global variable
window.CHROME_EXTENSION_ID = chrome.runtime.id;
console.log('Injected extension ID:', chrome.runtime.id);
} catch (e) {
console.warn('Failed to inject extension ID:', e);
}
}
injectExtensionId();
console.log('Quality Label Printing Service: Content script loaded');

View File

@@ -0,0 +1,7 @@
# Placeholder for icon files - in production, add actual PNG icons:
# - icon16.png (16x16 pixels)
# - icon48.png (48x48 pixels)
# - icon128.png (128x128 pixels)
# For now, create simple text-based icons using SVG converted to PNG
# These should be replaced with proper icons later

View File

@@ -0,0 +1,27 @@
# Simple text-based icons for the Chrome extension
# These are placeholder files - replace with actual PNG icons for production
# Create simple SVG icons that can be converted to PNG
ICON_16_SVG = '''
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
<rect width="16" height="16" fill="#007bff"/>
<text x="8" y="12" font-family="Arial" font-size="10" fill="white" text-anchor="middle">🖨</text>
</svg>
'''
ICON_48_SVG = '''
<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg">
<rect width="48" height="48" fill="#007bff" rx="8"/>
<text x="24" y="32" font-family="Arial" font-size="24" fill="white" text-anchor="middle">🖨️</text>
</svg>
'''
ICON_128_SVG = '''
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg">
<rect width="128" height="128" fill="#007bff" rx="16"/>
<text x="64" y="84" font-family="Arial" font-size="48" fill="white" text-anchor="middle">🖨️</text>
</svg>
'''
# For now, create simple text placeholders
# In production, convert these SVGs to PNG files

View File

@@ -0,0 +1,122 @@
#!/usr/bin/env python3
"""
Generate PNG icons for Chrome extension
Creates simple colored squares with printer icons
"""
try:
from PIL import Image, ImageDraw, ImageFont
PIL_AVAILABLE = True
except ImportError:
PIL_AVAILABLE = False
import os
def create_simple_icon(size, filename):
"""Create a simple colored square icon"""
if PIL_AVAILABLE:
# Create image with PIL
img = Image.new('RGBA', (size, size), (0, 123, 255, 255)) # Blue background
draw = ImageDraw.Draw(img)
# Add a white border
border_width = max(1, size // 16)
draw.rectangle([0, 0, size-1, size-1], outline=(255, 255, 255, 255), width=border_width)
# Add text (P for Print)
try:
font_size = size // 2
font = ImageFont.load_default()
text = "P"
bbox = draw.textbbox((0, 0), text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
x = (size - text_width) // 2
y = (size - text_height) // 2
draw.text((x, y), text, fill=(255, 255, 255, 255), font=font)
except:
pass
img.save(filename, 'PNG')
print(f"Created {filename} ({size}x{size})")
else:
# Create a minimal PNG file without PIL
create_minimal_png(size, filename)
def create_minimal_png(size, filename):
"""Create a minimal PNG file without PIL"""
# This creates a very basic PNG file
# Blue square with minimal PNG structure
import struct
import zlib
# PNG signature
png_signature = b'\x89PNG\r\n\x1a\n'
# IHDR chunk
width = height = size
bit_depth = 8
color_type = 2 # RGB
compression = 0
filter_method = 0
interlace = 0
ihdr_data = struct.pack('>IIBBBBB', width, height, bit_depth, color_type, compression, filter_method, interlace)
ihdr_crc = zlib.crc32(b'IHDR' + ihdr_data) & 0xffffffff
ihdr_chunk = struct.pack('>I', len(ihdr_data)) + b'IHDR' + ihdr_data + struct.pack('>I', ihdr_crc)
# IDAT chunk (blue pixels)
pixels = []
for y in range(height):
row = [0] # Filter byte
for x in range(width):
# Blue color RGB(0, 123, 255)
row.extend([0, 123, 255])
pixels.extend(row)
pixel_data = bytes(pixels)
compressed_data = zlib.compress(pixel_data)
idat_crc = zlib.crc32(b'IDAT' + compressed_data) & 0xffffffff
idat_chunk = struct.pack('>I', len(compressed_data)) + b'IDAT' + compressed_data + struct.pack('>I', idat_crc)
# IEND chunk
iend_crc = zlib.crc32(b'IEND') & 0xffffffff
iend_chunk = struct.pack('>I', 0) + b'IEND' + struct.pack('>I', iend_crc)
# Write PNG file
with open(filename, 'wb') as f:
f.write(png_signature)
f.write(ihdr_chunk)
f.write(idat_chunk)
f.write(iend_chunk)
print(f"Created minimal {filename} ({size}x{size})")
def main():
# Create icons directory if it doesn't exist
icons_dir = "/home/ske087/quality_recticel/windows_print_service/chrome_extension/icons"
print("Creating Chrome extension icons...")
print(f"PIL available: {PIL_AVAILABLE}")
# Create required icon sizes
sizes = [16, 32, 48, 128]
for size in sizes:
filename = os.path.join(icons_dir, f"icon{size}.png")
create_simple_icon(size, filename)
print("✅ All icons created successfully!")
print("\nIcons created:")
for size in sizes:
filename = f"icon{size}.png"
filepath = os.path.join(icons_dir, filename)
if os.path.exists(filepath):
file_size = os.path.getsize(filepath)
print(f"{filename} ({size}x{size}px, {file_size} bytes)")
else:
print(f"{filename} - FAILED")
if __name__ == "__main__":
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 B

View File

@@ -0,0 +1,4 @@
# Placeholder for 128x128 icon
# This is a text file placeholder
# Replace with actual icon128.png file
🖨️

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

View File

@@ -0,0 +1,4 @@
# Placeholder for 16x16 icon
# This is a text file placeholder
# Replace with actual icon16.png file
🖨️

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

View File

@@ -0,0 +1,4 @@
# Placeholder for 48x48 icon
# This is a text file placeholder
# Replace with actual icon48.png file
🖨️

View File

@@ -1,374 +0,0 @@
"""
Quality Recticel Windows Print Service
=====================================
A local Windows service that provides a REST API for silent printing
through Chrome extension integration.
Features:
- Local HTTP API server (localhost:8765)
- Chrome extension native messaging
- Silent PDF printing
- Windows service management
- Security and error handling
Installation:
1. Run install_service.bat as Administrator
2. Install Chrome extension
3. Configure web application to use localhost:8765
Author: Quality Recticel Development Team
Version: 1.0.0
"""
import sys
import os
import json
import logging
import threading
from datetime import datetime
from pathlib import Path
# Add current directory to path for imports
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from flask import Flask, request, jsonify, send_file
from flask_cors import CORS
import requests
import subprocess
import tempfile
import uuid
import time
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('print_service.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
class WindowsPrintService:
"""Main Windows Print Service class"""
def __init__(self, port=8765):
self.port = port
self.app = Flask(__name__)
CORS(self.app) # Enable CORS for web page communication
self.setup_routes()
self.chrome_extension_id = None
self.service_status = "starting"
def setup_routes(self):
"""Set up Flask routes for the API"""
@self.app.route('/health', methods=['GET'])
def health_check():
"""Health check endpoint"""
return jsonify({
'status': 'healthy',
'service': 'Quality Recticel Print Service',
'version': '1.0.0',
'timestamp': datetime.now().isoformat(),
'chrome_extension_connected': self.is_chrome_extension_available()
})
@self.app.route('/print/pdf', methods=['POST'])
def print_pdf():
"""Print PDF endpoint"""
try:
data = request.get_json()
# Validate required fields
required_fields = ['pdf_url', 'printer_name']
for field in required_fields:
if field not in data:
return jsonify({
'error': f'Missing required field: {field}',
'success': False
}), 400
# Execute print job
result = self.execute_print_job(data)
if result['success']:
return jsonify(result), 200
else:
return jsonify(result), 500
except Exception as e:
logger.error(f"Print PDF error: {e}")
return jsonify({
'error': str(e),
'success': False
}), 500
@self.app.route('/print/silent', methods=['POST'])
def silent_print():
"""Silent print endpoint using Chrome extension"""
try:
data = request.get_json()
# Validate required fields
if 'pdf_data' not in data and 'pdf_url' not in data:
return jsonify({
'error': 'Either pdf_data or pdf_url is required',
'success': False
}), 400
# Send to Chrome extension for silent printing
result = self.send_to_chrome_extension(data)
if result['success']:
return jsonify(result), 200
else:
return jsonify(result), 500
except Exception as e:
logger.error(f"Silent print error: {e}")
return jsonify({
'error': str(e),
'success': False
}), 500
@self.app.route('/printers', methods=['GET'])
def get_printers():
"""Get available printers"""
try:
printers = self.get_available_printers()
return jsonify({
'printers': printers,
'success': True
})
except Exception as e:
logger.error(f"Get printers error: {e}")
return jsonify({
'error': str(e),
'success': False
}), 500
@self.app.route('/extension/status', methods=['GET'])
def extension_status():
"""Check Chrome extension status"""
return jsonify({
'extension_available': self.is_chrome_extension_available(),
'success': True
})
def execute_print_job(self, print_data):
"""Execute a print job"""
try:
pdf_url = print_data.get('pdf_url')
printer_name = print_data.get('printer_name', 'default')
copies = print_data.get('copies', 1)
logger.info(f"Executing print job: {pdf_url} -> {printer_name}")
# Download PDF if URL provided
if pdf_url:
pdf_content = self.download_pdf(pdf_url)
else:
pdf_content = print_data.get('pdf_data')
if not pdf_content:
return {
'success': False,
'error': 'No PDF content available'
}
# Save PDF to temporary file
temp_pdf = self.save_temp_pdf(pdf_content)
# Print using system command
print_result = self.print_pdf_file(temp_pdf, printer_name, copies)
# Cleanup
os.unlink(temp_pdf)
return {
'success': print_result,
'message': 'Print job completed' if print_result else 'Print job failed',
'job_id': str(uuid.uuid4())
}
except Exception as e:
logger.error(f"Execute print job error: {e}")
return {
'success': False,
'error': str(e)
}
def send_to_chrome_extension(self, print_data):
"""Send print command to Chrome extension"""
try:
# Prepare message for Chrome extension
message = {
'action': 'silent_print',
'data': print_data,
'timestamp': datetime.now().isoformat(),
'job_id': str(uuid.uuid4())
}
# Try to communicate with Chrome extension via native messaging
result = self.send_native_message(message)
if result:
return {
'success': True,
'message': 'Print command sent to Chrome extension',
'job_id': message['job_id']
}
else:
# Fallback to direct printing
logger.warning("Chrome extension not available, falling back to direct printing")
return self.execute_print_job(print_data)
except Exception as e:
logger.error(f"Send to Chrome extension error: {e}")
return {
'success': False,
'error': str(e)
}
def send_native_message(self, message):
"""Send native message to Chrome extension"""
try:
# This would be implemented based on Chrome's native messaging protocol
# For now, we'll simulate the communication
# In a real implementation, this would:
# 1. Find Chrome extension by ID
# 2. Send message via stdin/stdout pipe
# 3. Wait for response
logger.info(f"Sending native message to Chrome extension: {message}")
# Simulate successful communication
return True
except Exception as e:
logger.error(f"Native messaging error: {e}")
return False
def download_pdf(self, url):
"""Download PDF from URL"""
try:
response = requests.get(url, timeout=30)
response.raise_for_status()
return response.content
except Exception as e:
logger.error(f"PDF download error: {e}")
raise
def save_temp_pdf(self, pdf_content):
"""Save PDF content to temporary file"""
temp_file = tempfile.mktemp(suffix='.pdf')
with open(temp_file, 'wb') as f:
if isinstance(pdf_content, str):
# Base64 encoded content
import base64
pdf_content = base64.b64decode(pdf_content)
f.write(pdf_content)
return temp_file
def print_pdf_file(self, pdf_path, printer_name, copies=1):
"""Print PDF file using system command"""
try:
# Windows printing command
if printer_name == 'default':
cmd = f'powershell -Command "Start-Process -FilePath \\"{pdf_path}\\" -ArgumentList \\"/p\\" -Wait"'
else:
cmd = f'powershell -Command "Start-Process -FilePath \\"{pdf_path}\\" -ArgumentList \\"/p /h /{printer_name}\\" -Wait"'
logger.info(f"Executing print command: {cmd}")
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode == 0:
logger.info("Print command executed successfully")
return True
else:
logger.error(f"Print command failed: {result.stderr}")
return False
except Exception as e:
logger.error(f"Print PDF file error: {e}")
return False
def get_available_printers(self):
"""Get list of available printers"""
try:
# Windows command to get printers
cmd = 'powershell -Command "Get-Printer | Select-Object Name, DriverName, PortName | ConvertTo-Json"'
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode == 0:
printers_data = json.loads(result.stdout)
# Ensure it's a list
if isinstance(printers_data, dict):
printers_data = [printers_data]
printers = []
for printer in printers_data:
printers.append({
'name': printer.get('Name', ''),
'driver': printer.get('DriverName', ''),
'port': printer.get('PortName', ''),
'is_default': False # Could be enhanced to detect default printer
})
return printers
else:
logger.error(f"Failed to get printers: {result.stderr}")
return []
except Exception as e:
logger.error(f"Get available printers error: {e}")
return []
def is_chrome_extension_available(self):
"""Check if Chrome extension is available"""
# This would check for Chrome extension via native messaging
# For now, we'll return a simulated status
return True
def run_service(self):
"""Run the Flask service"""
try:
self.service_status = "running"
logger.info(f"Starting Quality Recticel Print Service on port {self.port}")
self.app.run(
host='localhost',
port=self.port,
debug=False,
threaded=True
)
except Exception as e:
logger.error(f"Service run error: {e}")
self.service_status = "error"
finally:
self.service_status = "stopped"
def main():
"""Main entry point"""
print("Quality Recticel Windows Print Service")
print("=====================================")
service = WindowsPrintService()
try:
service.run_service()
except KeyboardInterrupt:
logger.info("Service stopped by user")
except Exception as e:
logger.error(f"Service error: {e}")
if __name__ == "__main__":
main()

View File

@@ -1,143 +0,0 @@
"""
Windows Service Installation and Management
==========================================
This module handles Windows service installation, configuration, and management
for the Quality Recticel Print Service.
"""
import os
import sys
import time
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
from pathlib import Path
class QualityRecticelPrintService(win32serviceutil.ServiceFramework):
"""Windows Service wrapper for the print service"""
_svc_name_ = "QualityRecticelPrintService"
_svc_display_name_ = "Quality Recticel Print Service"
_svc_description_ = "Local API service for silent PDF printing via Chrome extension"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
self.is_alive = True
def SvcStop(self):
"""Stop the service"""
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
self.is_alive = False
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, '')
)
def SvcDoRun(self):
"""Run the service"""
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, '')
)
# Import and run the print service
try:
from print_service import WindowsPrintService
service = WindowsPrintService(port=8765)
# Run service in a separate thread
import threading
service_thread = threading.Thread(target=service.run_service)
service_thread.daemon = True
service_thread.start()
# Wait for stop event
win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)
except Exception as e:
servicemanager.LogErrorMsg(f"Service error: {e}")
def install_service():
"""Install the Windows service"""
try:
# Install the service with automatic startup
win32serviceutil.InstallService(
QualityRecticelPrintService._svc_reg_class_,
QualityRecticelPrintService._svc_name_,
QualityRecticelPrintService._svc_display_name_,
description=QualityRecticelPrintService._svc_description_,
startType=win32service.SERVICE_AUTO_START # Auto-start on system boot
)
print(f"✅ Service '{QualityRecticelPrintService._svc_display_name_}' installed successfully")
print(f"🔄 Service configured for AUTOMATIC startup on system restart")
# Start the service
win32serviceutil.StartService(QualityRecticelPrintService._svc_name_)
print(f"✅ Service started successfully")
return True
except Exception as e:
print(f"❌ Service installation failed: {e}")
return False
def uninstall_service():
"""Uninstall the Windows service"""
try:
# Stop the service first
try:
win32serviceutil.StopService(QualityRecticelPrintService._svc_name_)
print(f"✅ Service stopped")
except:
pass # Service might not be running
# Remove the service
win32serviceutil.RemoveService(QualityRecticelPrintService._svc_name_)
print(f"✅ Service '{QualityRecticelPrintService._svc_display_name_}' uninstalled successfully")
return True
except Exception as e:
print(f"❌ Service uninstallation failed: {e}")
return False
def service_status():
"""Get service status"""
try:
status = win32serviceutil.QueryServiceStatus(QualityRecticelPrintService._svc_name_)
status_names = {
win32service.SERVICE_STOPPED: "Stopped",
win32service.SERVICE_START_PENDING: "Start Pending",
win32service.SERVICE_STOP_PENDING: "Stop Pending",
win32service.SERVICE_RUNNING: "Running",
win32service.SERVICE_CONTINUE_PENDING: "Continue Pending",
win32service.SERVICE_PAUSE_PENDING: "Pause Pending",
win32service.SERVICE_PAUSED: "Paused"
}
current_status = status_names.get(status[1], "Unknown")
print(f"Service Status: {current_status}")
return status[1]
except Exception as e:
print(f"❌ Failed to get service status: {e}")
return None
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(QualityRecticelPrintService)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(QualityRecticelPrintService)