/** * 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 }; }