const express = require('express'); const { spawn } = require('child_process'); const path = require('path'); const fs = require('fs'); const app = express(); const port = process.env.PORT || 3006; // LOGGING SETUP const LOG_DIR = '/app/Log_from_docker'; if (!fs.existsSync(LOG_DIR)) { try { fs.mkdirSync(LOG_DIR, { recursive: true }); } catch (e) { console.error("Could not create Log directory:", e); } } const LOG_FILE = path.join(LOG_DIR, 'content_node_server.log'); function log(message, level = 'INFO') { const timestamp = new Date().toISOString(); const logLine = `[${timestamp}] [${level}] ${message}\n`; // Console output if (level === 'ERROR') console.error(logLine); else console.log(logLine); // File output try { fs.appendFileSync(LOG_FILE, logLine); } catch (e) { console.error("Failed to write to log file:", e); } } app.use(express.json({ limit: '50mb' })); // INITIALIZE DATABASE ON START const dbScript = path.join(__dirname, 'content_db_manager.py'); log(`Initializing database via ${dbScript}...`); const dbInit = spawn('python3', [dbScript]); dbInit.stdout.on('data', (data) => log(`DB Init Output: ${data}`)); dbInit.stderr.on('data', (data) => log(`DB Init Error: ${data}`, 'ERROR')); dbInit.on('close', (code) => log(`DB Init finished with code ${code}`)); // Helper to run python commands function runPython(mode, payload) { return new Promise((resolve, reject) => { const payloadFile = path.join(__dirname, `payload_${Date.now()}.json`); try { fs.writeFileSync(payloadFile, JSON.stringify(payload)); log(`Created payload file: ${payloadFile} for mode: ${mode}`); } catch (e) { log(`Failed to write payload file: ${e.message}`, 'ERROR'); return reject(e); } const scriptPath = path.join(__dirname, 'content_orchestrator.py'); log(`Spawning Python: python3 ${scriptPath} --mode ${mode} --payload_file ${payloadFile}`); const pythonProcess = spawn('python3', [ scriptPath, '--mode', mode, '--payload_file', payloadFile ]); let stdout = ''; let stderr = ''; pythonProcess.stdout.on('data', (data) => { stdout += data.toString(); }); pythonProcess.stderr.on('data', (data) => { stderr += data.toString(); }); pythonProcess.on('close', (code) => { // Cleanup payload file if (fs.existsSync(payloadFile)) { try { fs.unlinkSync(payloadFile); } catch(e) { log(`Warning: Could not delete payload file: ${e.message}`, 'WARN'); } } if (code !== 0) { log(`Python script exited with code ${code}. Stderr: ${stderr}`, 'ERROR'); return reject(stderr || "Unknown Python Error"); } // Log stderr anyway as it might contain debug info (Python logging often goes to stderr) if (stderr) { log(`Python Stderr (Debug): ${stderr}`); } try { log(`Python Stdout received (${stdout.length} bytes). Parsing JSON...`); const parsed = JSON.parse(stdout); resolve(parsed); } catch (e) { log(`Failed to parse JSON output: ${stdout.substring(0, 200)}...`, 'ERROR'); reject("Failed to parse Python output: " + stdout); } }); }); } app.post('/api/:mode', async (req, res) => { const mode = req.params.mode; log(`Incoming POST request for mode: ${mode}`); try { const result = await runPython(mode, req.body); log(`Request for ${mode} completed successfully.`); res.json(result); } catch (error) { log(`Request for ${mode} failed: ${error}`, 'ERROR'); res.status(500).json({ error: error.toString() }); } }); // Serve static assets if (fs.existsSync(path.join(__dirname, 'dist'))) { app.use(express.static(path.join(__dirname, 'dist'))); app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'dist', 'index.html')); }); } app.listen(port, () => { log(`Content Engine Server running on port ${port}`); });