HES-Selenium/app.js

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;