179 lines
5.4 KiB
JavaScript
179 lines
5.4 KiB
JavaScript
const express = require('express');
|
|
const { exec } = require('child_process');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const csv = require('csv-parser');
|
|
const http = require('http');
|
|
const socketIoServer = require('socket.io');
|
|
const chokidar = require('chokidar');
|
|
const socketIoClient = require('socket.io-client');
|
|
|
|
const app = express();
|
|
const server = http.createServer(app);
|
|
const ioServer = socketIoServer(server); // Server-side socket.io instance
|
|
const socketClient = socketIoClient('http://localhost:5000'); // Client-side socket.io connection to Python
|
|
|
|
app.use(express.json());
|
|
app.use(express.urlencoded({ extended: true }));
|
|
app.use(express.static(path.join(__dirname, 'public')));
|
|
|
|
// Define file paths
|
|
const processingLogPath = "/Users/macos/Documents/SINDIGILIVE/CLIENTS/ICON+/Project-HES/Update_DCU/processing_log.txt";
|
|
const updatedLogPath = "/Users/macos/Documents/SINDIGILIVE/CLIENTS/ICON+/Project-HES/Update_DCU/update_log.csv";
|
|
|
|
// Clear specified files when the app starts
|
|
function clearLogs() {
|
|
[processingLogPath, updatedLogPath].forEach((filePath) => {
|
|
fs.writeFile(filePath, '', (err) => {
|
|
if (err) {
|
|
console.error(`Error clearing file ${filePath}:`, err);
|
|
} else {
|
|
console.log(`File cleared: ${filePath}`);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// Call clearLogs on startup
|
|
clearLogs();
|
|
|
|
// Stream log data in real-time to WebSocket clients
|
|
function streamLogToClients(socket) {
|
|
// Send the entire log file content when a client connects
|
|
fs.readFile(processingLogPath, 'utf8', (err, data) => {
|
|
if (!err && data) {
|
|
socket.emit('logUpdate', data);
|
|
}
|
|
});
|
|
|
|
// Watch for changes to the log file
|
|
fs.watch(processingLogPath, { encoding: 'utf8' }, (eventType) => {
|
|
if (eventType === 'change') {
|
|
fs.readFile(processingLogPath, 'utf8', (err, data) => {
|
|
if (!err && data) {
|
|
// Send updated log content to the client
|
|
socket.emit('logUpdate', data);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
// Clean up on disconnect
|
|
socket.on('disconnect', () => {
|
|
console.log('Client disconnected');
|
|
});
|
|
}
|
|
|
|
// Function for streaming log real-time to table
|
|
function streamUpdatedLogToClients(socket) {
|
|
// Read and send initial data from CSV to client on first connection
|
|
sendUpdatedLogData(socket);
|
|
|
|
// Watch for changes in the CSV file
|
|
const watcher = chokidar.watch(updatedLogPath, { ignoreInitial: true });
|
|
|
|
watcher.on('change', () => {
|
|
sendUpdatedLogData(socket);
|
|
});
|
|
|
|
socket.on('disconnect', () => {
|
|
watcher.close();
|
|
console.log('Stopped watching updated log file');
|
|
});
|
|
}
|
|
|
|
// Function to read and send data from CSV to client
|
|
function sendUpdatedLogData(socket) {
|
|
const rows = [];
|
|
fs.createReadStream(updatedLogPath)
|
|
.pipe(csv())
|
|
.on('data', (row) => {
|
|
rows.push(row);
|
|
})
|
|
.on('end', () => {
|
|
console.log('Updated data sent to client:', rows);
|
|
socket.emit('tableUpdate', rows); // Emit data to the client
|
|
})
|
|
.on('error', (err) => {
|
|
console.error('Error reading CSV file:', err);
|
|
});
|
|
}
|
|
|
|
// Count number of DCU entries
|
|
app.post('/count-ips', (req, res) => {
|
|
const ipList = req.body.ipList || '';
|
|
const sanitizedList = ipList.replace(/\r\n/g, '\n'); // Normalize line endings
|
|
const ips = sanitizedList.split(/[\n,]+/).map(ip => ip.trim()).filter(ip => ip !== '');
|
|
res.json({ total: ips.length });
|
|
});
|
|
|
|
// Variabel global untuk menyimpan proses yang sedang berjalan
|
|
let currentProcess = null;
|
|
|
|
app.post('/run-script', (req, res) => {
|
|
const ipList = req.body.ipList;
|
|
const venvPath = path.join(__dirname, 'bin/activate');
|
|
const pythonScriptPath = path.join(__dirname, 'update_dcu_by_nodejs.py');
|
|
const ipArgs = ipList.join(' ');
|
|
const command = `source ${venvPath} && python ${pythonScriptPath} ${ipArgs}`;
|
|
|
|
// Jalankan perintah Python dan simpan proses ke `currentProcess`
|
|
currentProcess = exec(command, (error, stdout, stderr) => {
|
|
currentProcess = null; // Reset `currentProcess` setelah selesai
|
|
|
|
if (error) {
|
|
console.error(`Error: ${error.message}`);
|
|
return res.status(500).send(`Error: ${error.message}`);
|
|
}
|
|
if (stderr) {
|
|
console.error(`Stderr: ${stderr}`);
|
|
return res.status(500).send(`Stderr: ${stderr}`);
|
|
}
|
|
|
|
const processedData = [];
|
|
|
|
fs.createReadStream(updatedLogPath)
|
|
.pipe(csv())
|
|
.on('data', (row) => {
|
|
if (row['Update Status'] === 'Success') {
|
|
processedData.push(row);
|
|
}
|
|
})
|
|
.on('end', () => {
|
|
res.json({ processedData, totalProcessed: processedData.length });
|
|
});
|
|
});
|
|
});
|
|
|
|
// Endpoint untuk menghentikan proses yang sedang berjalan
|
|
app.post('/stop-script', (req, res) => {
|
|
console.log("Stop script endpoint hit");
|
|
|
|
// Emit the 'stop_tunnel' event to Python
|
|
socketClient.emit("stop_tunnel");
|
|
|
|
// Optionally, handle the response from Python
|
|
socketClient.once("tunnel_status", (data) => {
|
|
console.log("Tunnel status:", data.status); // Logs 'terminated' or 'not_active' status
|
|
res.send({status: data.status});
|
|
});
|
|
});
|
|
|
|
// WebSocket connection event for clients connecting to this server
|
|
ioServer.on('connection', (socket) => {
|
|
console.log('Client connected to WebSocket');
|
|
|
|
// Stream log text
|
|
streamLogToClients(socket);
|
|
|
|
// Stream updated log CSV
|
|
streamUpdatedLogToClients(socket);
|
|
});
|
|
|
|
const PORT = process.env.PORT || 3000;
|
|
server.listen(PORT, () => {
|
|
console.log(`Server running on port ${PORT}`);
|
|
});
|
|
|
|
module.exports = app;
|