Files
quality_recticel/windows_print_service/chrome_extension/background.js
2025-09-22 20:34:15 +03:00

299 lines
8.7 KiB
JavaScript

/**
* Quality Label Printing Service - Background Script
* Handles communication between web pages and Windows print service
*/
// Configuration
const PRINT_SERVICE_URL = 'http://localhost:8765';
const SERVICE_CHECK_INTERVAL = 30000; // 30 seconds
// Service status
let serviceStatus = {
available: false,
lastCheck: null,
printers: []
};
// Initialize extension
chrome.runtime.onInstalled.addListener(() => {
console.log('Quality Label Printing Service extension installed');
checkServiceStatus();
// Set up periodic service check
setInterval(checkServiceStatus, SERVICE_CHECK_INTERVAL);
});
// Handle messages from content scripts or web pages
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log('Background script received message:', message);
switch (message.action) {
case 'print_pdf':
handlePrintPDF(message.data).then(sendResponse);
return true; // Keep message channel open for async response
case 'silent_print':
handleSilentPrint(message.data).then(sendResponse);
return true;
case 'get_printers':
handleGetPrinters().then(sendResponse);
return true;
case 'check_service':
checkServiceStatus().then(sendResponse);
return true;
default:
sendResponse({ error: 'Unknown action', success: false });
}
});
// Handle external messages from web pages
chrome.runtime.onMessageExternal.addListener((message, sender, sendResponse) => {
console.log('External message received:', message, 'from:', sender);
// Verify sender origin for security
const allowedOrigins = [
'http://localhost:5000',
'http://localhost:8000',
'http://127.0.0.1:5000',
'http://127.0.0.1:8000'
];
if (!allowedOrigins.includes(sender.origin)) {
sendResponse({ error: 'Unauthorized origin', success: false });
return;
}
// Handle the message
switch (message.action) {
case 'print_pdf':
case 'silent_print':
handleSilentPrint(message.data).then(sendResponse);
return true;
case 'get_printers':
handleGetPrinters().then(sendResponse);
return true;
case 'ping':
sendResponse({
success: true,
service_available: serviceStatus.available,
extension_version: chrome.runtime.getManifest().version
});
break;
default:
sendResponse({ error: 'Unknown action', success: false });
}
});
/**
* Check if the Windows print service is available
*/
async function checkServiceStatus() {
try {
const response = await fetch(`${PRINT_SERVICE_URL}/health`, {
method: 'GET',
timeout: 5000
});
if (response.ok) {
const data = await response.json();
serviceStatus.available = true;
serviceStatus.lastCheck = new Date();
console.log('Print service is available:', data);
// Update extension badge
chrome.action.setBadgeText({ text: '✓' });
chrome.action.setBadgeBackgroundColor({ color: '#28a745' });
return { success: true, status: data };
} else {
throw new Error(`Service returned status ${response.status}`);
}
} catch (error) {
console.warn('Print service not available:', error);
serviceStatus.available = false;
serviceStatus.lastCheck = new Date();
// Update extension badge
chrome.action.setBadgeText({ text: '✗' });
chrome.action.setBadgeBackgroundColor({ color: '#dc3545' });
return { success: false, error: error.message };
}
}
/**
* Handle PDF printing request
*/
async function handlePrintPDF(printData) {
try {
if (!serviceStatus.available) {
await checkServiceStatus();
if (!serviceStatus.available) {
throw new Error('Print service is not available');
}
}
const response = await fetch(`${PRINT_SERVICE_URL}/print/pdf`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(printData)
});
const result = await response.json();
if (response.ok) {
console.log('Print job completed:', result);
// Show notification
chrome.notifications.create({
type: 'basic',
iconUrl: 'icons/icon48.png',
title: 'Quality Label Printing Service',
message: 'PDF printed successfully'
});
return { success: true, result };
} else {
throw new Error(result.error || 'Print job failed');
}
} catch (error) {
console.error('Print PDF error:', error);
// Show error notification
chrome.notifications.create({
type: 'basic',
iconUrl: 'icons/icon48.png',
title: 'Quality Label Printing Service',
message: `Print failed: ${error.message}`
});
return { success: false, error: error.message };
}
}
/**
* Handle silent printing request
*/
async function handleSilentPrint(printData) {
try {
if (!serviceStatus.available) {
await checkServiceStatus();
if (!serviceStatus.available) {
// Try direct browser printing as fallback
return await handleDirectPrint(printData);
}
}
const response = await fetch(`${PRINT_SERVICE_URL}/print/silent`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(printData)
});
const result = await response.json();
if (response.ok) {
console.log('Silent print completed:', result);
return { success: true, result };
} else {
throw new Error(result.error || 'Silent print failed');
}
} catch (error) {
console.error('Silent print error:', error);
// Fallback to direct printing
return await handleDirectPrint(printData);
}
}
/**
* Handle direct browser printing (fallback)
*/
async function handleDirectPrint(printData) {
try {
// Create hidden iframe for printing
const printFrame = document.createElement('iframe');
printFrame.style.display = 'none';
printFrame.src = printData.pdf_url || 'data:application/pdf;base64,' + printData.pdf_data;
document.body.appendChild(printFrame);
// Wait for load and print
return new Promise((resolve) => {
printFrame.onload = () => {
setTimeout(() => {
printFrame.contentWindow.print();
document.body.removeChild(printFrame);
resolve({ success: true, method: 'browser_fallback' });
}, 1000);
};
});
} catch (error) {
console.error('Direct print error:', error);
return { success: false, error: error.message };
}
}
/**
* Get available printers
*/
async function handleGetPrinters() {
try {
if (!serviceStatus.available) {
await checkServiceStatus();
if (!serviceStatus.available) {
return {
success: false,
error: 'Print service not available',
printers: []
};
}
}
const response = await fetch(`${PRINT_SERVICE_URL}/printers`, {
method: 'GET'
});
const result = await response.json();
if (response.ok) {
serviceStatus.printers = result.printers || [];
return { success: true, printers: result.printers };
} else {
throw new Error(result.error || 'Failed to get printers');
}
} catch (error) {
console.error('Get printers error:', error);
return { success: false, error: error.message, printers: [] };
}
}
// Export for testing
if (typeof module !== 'undefined' && module.exports) {
module.exports = {
checkServiceStatus,
handlePrintPDF,
handleSilentPrint,
handleGetPrinters
};
}