376 lines
12 KiB
JavaScript
376 lines
12 KiB
JavaScript
const { BrowserWindow, app, ipcMain, dialog } = require("electron");
|
|
const pie = require("puppeteer-in-electron");
|
|
const puppeteer = require("puppeteer");
|
|
const AdmZip = require('adm-zip');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { v4: uuidv4 } = require('uuid');
|
|
const os = require('os');
|
|
const Client = require("ssh2-sftp-client");
|
|
const sftp = new Client();
|
|
|
|
// Add this function to handle credentials
|
|
function handleCredentials() {
|
|
const credentialsPath = 'C:/ddbb/credenciales.json';
|
|
|
|
try {
|
|
if (!fs.existsSync('C:/ddbb')) {
|
|
fs.mkdirSync('C:/ddbb', { recursive: true });
|
|
}
|
|
|
|
if (fs.existsSync(credentialsPath)) {
|
|
const fileContent = fs.readFileSync(credentialsPath, 'utf8');
|
|
const credentials = JSON.parse(fileContent);
|
|
return credentials;
|
|
} else {
|
|
const defaultCredentials = {
|
|
sftp: {
|
|
host: "10.130.20.3",
|
|
port: 22,
|
|
username: "tarsclsharep",
|
|
password: "bD7*oWPahJ4)"
|
|
},
|
|
sharepoint: {
|
|
url: 'https://claromovilco.sharepoint.com/_layouts/15/sharepoint.aspx',
|
|
email: '[email protected]',
|
|
password: 'QwSqTlSK8%'
|
|
}
|
|
};
|
|
|
|
fs.writeFileSync(credentialsPath, JSON.stringify(defaultCredentials, null, 2));
|
|
return defaultCredentials;
|
|
}
|
|
} catch (error) {
|
|
console.error('Error handling credentials:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Get credentials and configure CONFIG
|
|
const credentials = handleCredentials();
|
|
|
|
// Configuración
|
|
const CONFIG = {
|
|
sftp: credentials?.sftp || {
|
|
host: "10.130.20.3",
|
|
port: 22,
|
|
username: "tarsclsharep",
|
|
password: "bD7*oWPahJ4)"
|
|
},
|
|
sharepoint: credentials?.sharepoint || {
|
|
url: 'https://claromovilco.sharepoint.com',
|
|
email: '[email protected]',
|
|
password: 'TittqbAP5rlnR8PQnYLe'
|
|
},
|
|
downloads: {
|
|
folder: path.join(os.homedir(), 'Downloads'),
|
|
filePrefix: 'OneDrive'
|
|
}
|
|
};
|
|
|
|
let window;
|
|
|
|
// Funciones auxiliares
|
|
async function delay(ms) {
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
}
|
|
|
|
// Función auxiliar para enviar logs
|
|
function sendLog(message) {
|
|
if (window) {
|
|
window.webContents.send('log_message', message);
|
|
}
|
|
console.log(message);
|
|
}
|
|
|
|
async function handleSftpConnection(folderToUpload, ftpUrl, downloadUrl) {
|
|
sendLog(`URL: ${downloadUrl} >>> Carpeta a subir: ${folderToUpload}`);
|
|
sendLog(`URL: ${downloadUrl} >>> Iniciando conexión SFTP...`);
|
|
const sftp = new Client();
|
|
try {
|
|
await sftp.connect(CONFIG.sftp);
|
|
sendLog(`URL: ${downloadUrl} >>> Conectado exitosamente al servidor SFTP`);
|
|
|
|
sendLog(`URL: ${downloadUrl} >>> Iniciando subida de archivos...`);
|
|
const filesToUpload = fs.readdirSync(folderToUpload);
|
|
|
|
// Get current date in format DDMMYY
|
|
const today = new Date();
|
|
// Add timezone offset to ensure we get the correct local date
|
|
today.setMinutes(today.getMinutes() + today.getTimezoneOffset());
|
|
|
|
const datePrefix = today.getDate().toString().padStart(2, '0') +
|
|
(today.getMonth() + 1).toString().padStart(2, '0') +
|
|
today.getFullYear().toString().slice(-2);
|
|
|
|
// Log the date being used for debugging
|
|
sendLog(`URL: ${downloadUrl} >>> Buscando archivos con fecha: ${datePrefix}`);
|
|
|
|
// Filter files that start with today's date
|
|
const todayFiles = filesToUpload.filter(file => file.startsWith(datePrefix));
|
|
|
|
if (todayFiles.length === 0) {
|
|
sendLog(`URL: ${downloadUrl} >>> No se encontraron archivos con la fecha actual (${datePrefix})`);
|
|
return;
|
|
}
|
|
|
|
for (let i = 0; i < todayFiles.length; i++) {
|
|
const localFile = path.join(folderToUpload, todayFiles[i]);
|
|
await sftp.put(localFile, ftpUrl + todayFiles[i]);
|
|
sendLog(`URL: ${downloadUrl} >>> Archivo ${i + 1} de ${todayFiles.length} subido exitosamente`);
|
|
}
|
|
sendLog(`URL: ${downloadUrl} >>> Todos los archivos del día ${datePrefix} subidos exitosamente`);
|
|
} catch (error) {
|
|
sendLog(`URL: ${downloadUrl} >>> Error en la conexión SFTP: ${error}`);
|
|
} finally {
|
|
await sftp.end();
|
|
sendLog(`URL: ${downloadUrl} >>> Conexión SFTP cerrada`);
|
|
}
|
|
}
|
|
|
|
async function loginToSharepoint(page) {
|
|
sendLog('>>> Iniciando proceso de login en SharePoint...');
|
|
await page.goto(CONFIG.sharepoint.url);
|
|
sendLog('>>> Ingresando email...');
|
|
await page.waitForSelector('input[type="email"]');
|
|
await page.type('input[type="email"]', CONFIG.sharepoint.email);
|
|
await page.click('input[type="submit"]');
|
|
|
|
sendLog('>>> Ingresando contraseña...');
|
|
await page.waitForSelector('input[type="password"]');
|
|
await page.type('input[type="password"]', CONFIG.sharepoint.password);
|
|
await delay(1000);
|
|
await page.click('input[type="submit"]');
|
|
await delay(1000);
|
|
// await page.locator('#idBtn_Back').click();
|
|
sendLog('>>> Login completado exitosamente');
|
|
}
|
|
|
|
async function handleFileDownload(downloadFolder, downloadUrl) {
|
|
sendLog(`URL: ${downloadUrl} >>> Iniciando búsqueda de archivo descargado en: ${downloadFolder}`);
|
|
let newFile = null;
|
|
let extractFolder = null;
|
|
const now = new Date();
|
|
|
|
for (let i = 0; i < 120; i++) {
|
|
sendLog(`URL: ${downloadUrl} >>> Intento ${i + 1} de 120...`);
|
|
const files = fs.readdirSync(downloadFolder);
|
|
sendLog(`URL: ${downloadUrl} >>> Archivos encontrados en carpeta: ${files.length}`);
|
|
|
|
const recentFiles = files.filter(file => {
|
|
const filePath = path.join(downloadFolder, file);
|
|
const fileStat = fs.statSync(filePath);
|
|
const isValid = fileStat.isFile() &&
|
|
file.startsWith(CONFIG.downloads.filePrefix) &&
|
|
fileStat.mtime > now &&
|
|
file.endsWith('.zip');
|
|
|
|
if (isValid) {
|
|
sendLog(`URL: ${downloadUrl} >>> Archivo válido encontrado: ${file} (Modificado: ${fileStat.mtime.toISOString()})`);
|
|
}
|
|
return isValid;
|
|
});
|
|
|
|
if (recentFiles.length > 0) {
|
|
newFile = recentFiles[0];
|
|
const filePath = path.join(downloadFolder, newFile);
|
|
extractFolder = path.join(downloadFolder, 'extracted_' + newFile.replace('.zip', ''));
|
|
|
|
sendLog(`URL: ${downloadUrl} >>> Archivo encontrado: ${newFile}`);
|
|
sendLog(`URL: ${downloadUrl} >>> Ruta completa: ${filePath}`);
|
|
sendLog(`URL: ${downloadUrl} >>> Iniciando descompresión en: ${extractFolder}`);
|
|
|
|
const zip = new AdmZip(filePath);
|
|
zip.extractAllTo(extractFolder, true);
|
|
|
|
// Contar archivos extraídos
|
|
const extractedFiles = fs.readdirSync(extractFolder);
|
|
sendLog(`URL: ${downloadUrl} >>> Descompresión completada. ${extractedFiles.length} archivos extraídos:`);
|
|
extractedFiles.forEach(file => {
|
|
sendLog(`URL: ${downloadUrl} >>> - ${file}`);
|
|
});
|
|
|
|
break;
|
|
}
|
|
await delay(1000);
|
|
}
|
|
|
|
if (!newFile) {
|
|
sendLog(`URL: ${downloadUrl} >>> No se encontró ningún archivo nuevo después de 120 segundos.`);
|
|
return null;
|
|
}
|
|
return extractFolder;
|
|
}
|
|
|
|
async function processUrl(downloadUrl, ftpUrl) {
|
|
const sendLogWithUrl = (message) => {
|
|
sendLog(`URL: ${downloadUrl} ${message}`);
|
|
};
|
|
|
|
let browser = null;
|
|
let tempDownloadPath = null;
|
|
|
|
try {
|
|
// Crear carpeta temporal única para este proceso
|
|
const processId = uuidv4();
|
|
tempDownloadPath = path.join(CONFIG.downloads.folder, `temp_${processId}`);
|
|
fs.mkdirSync(tempDownloadPath, { recursive: true });
|
|
|
|
sendLogWithUrl('>>> Iniciando proceso...');
|
|
sendLogWithUrl(`>>> Carpeta temporal creada: ${tempDownloadPath}`);
|
|
sendLogWithUrl(`>>> Contenido inicial de la carpeta: ${fs.readdirSync(tempDownloadPath).length} archivos`);
|
|
|
|
browser = await puppeteer.launch({
|
|
headless: false,
|
|
executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
|
|
defaultViewport: null,
|
|
args: ['--start-maximized']
|
|
});
|
|
|
|
const page = await browser.newPage();
|
|
|
|
// Configurar descarga para esta página específica
|
|
const client = await page.createCDPSession();
|
|
await client.send('Page.setDownloadBehavior', {
|
|
behavior: 'allow',
|
|
downloadPath: tempDownloadPath
|
|
});
|
|
|
|
await loginToSharepoint(page);
|
|
await delay(120000);
|
|
await delay(4000);
|
|
|
|
sendLogWithUrl(`>>> Navegando a: ${downloadUrl}`);
|
|
await page.goto(downloadUrl);
|
|
await delay(12000);
|
|
|
|
sendLogWithUrl('>>> Interactuando con la interfaz...');
|
|
await page.waitForSelector('.text_a4f5cb66');
|
|
await page.locator('::-p-text(Todos los documentos)').click();
|
|
await page.locator('::-p-text(Mosaicos)').click();
|
|
await delay(1000);
|
|
await page.locator('::-p-text(Todos los documentos)').click();
|
|
await delay(2000);
|
|
|
|
sendLogWithUrl('>>> Seleccionando elementos...');
|
|
await page.locator('.ms-Check').click();
|
|
await delay(500);
|
|
await page.keyboard.down('Control');
|
|
await page.keyboard.press('a');
|
|
await page.keyboard.up('Control');
|
|
|
|
await delay(2000);
|
|
|
|
sendLogWithUrl('>>> Iniciando descarga...');
|
|
await page.locator('[title="Más comandos"]').click();
|
|
await delay(1000);
|
|
await page.locator('::-p-text(Descargar)').click();
|
|
|
|
// Verificar contenido de la carpeta antes de buscar la descarga
|
|
sendLogWithUrl(`>>> Contenido de la carpeta antes de la descarga: ${fs.readdirSync(tempDownloadPath).length} archivos`);
|
|
await delay(1000);
|
|
|
|
const extractFolder = await handleFileDownload(tempDownloadPath, downloadUrl);
|
|
if (!extractFolder) {
|
|
throw new Error('No se pudo encontrar o procesar el archivo descargado');
|
|
}
|
|
|
|
await delay(1000);
|
|
await handleSftpConnection(extractFolder, ftpUrl, downloadUrl);
|
|
|
|
if (browser) {
|
|
await browser.close();
|
|
}
|
|
|
|
// Limpiar archivos temporales
|
|
try {
|
|
fs.rmSync(tempDownloadPath, { recursive: true, force: true });
|
|
sendLogWithUrl('>>> Archivos temporales eliminados');
|
|
} catch (cleanupError) {
|
|
sendLogWithUrl(`>>> Advertencia: No se pudieron eliminar los archivos temporales: ${cleanupError}`);
|
|
}
|
|
|
|
dialog.showMessageBox({
|
|
type: 'info',
|
|
title: 'Proceso completado',
|
|
message: `Proceso completado exitosamente para ${downloadUrl}`
|
|
});
|
|
|
|
sendLogWithUrl(`>>> Proceso completado para: ${downloadUrl}`);
|
|
} catch (error) {
|
|
sendLogWithUrl(`>>> Error en el proceso: ${error}`);
|
|
if (browser) {
|
|
await browser.close();
|
|
}
|
|
// Intentar limpiar archivos temporales en caso de error
|
|
if (tempDownloadPath && fs.existsSync(tempDownloadPath)) {
|
|
try {
|
|
fs.rmSync(tempDownloadPath, { recursive: true, force: true });
|
|
sendLogWithUrl('>>> Archivos temporales eliminados después del error');
|
|
} catch (cleanupError) {
|
|
sendLogWithUrl(`>>> Advertencia: No se pudieron eliminar los archivos temporales: ${cleanupError}`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ipcMain.on('url_process', async (event, urls) => {
|
|
try {
|
|
// Procesar todas las URLs en paralelo
|
|
const promises = urls.map(url => processUrl(url.downloadUrl, url.ftpUrl));
|
|
await Promise.all(promises);
|
|
|
|
sendLog('>>> Todos los procesos han sido completados');
|
|
} catch (error) {
|
|
sendLog('>>> Error general en el proceso: ' + error);
|
|
}
|
|
});
|
|
|
|
// Modificar la inicialización
|
|
const main = async () => {
|
|
await pie.initialize(app);
|
|
};
|
|
|
|
// Esperar a que la app esté lista
|
|
app.whenReady().then(async () => {
|
|
window = new BrowserWindow({
|
|
width: 800,
|
|
height: 600,
|
|
webPreferences: {
|
|
contextIsolation: false,
|
|
nodeIntegration: true
|
|
}
|
|
});
|
|
|
|
await window.maximize();
|
|
await window.removeMenu();
|
|
await window.loadFile('index.html');
|
|
});
|
|
|
|
// Manejar el cierre de la aplicación
|
|
app.on('window-all-closed', () => {
|
|
if (process.platform !== 'darwin') {
|
|
app.quit();
|
|
}
|
|
});
|
|
|
|
app.on('activate', async () => {
|
|
if (BrowserWindow.getAllWindows().length === 0) {
|
|
window = new BrowserWindow({
|
|
width: 800,
|
|
height: 600,
|
|
webPreferences: {
|
|
contextIsolation: false,
|
|
nodeIntegration: true
|
|
}
|
|
});
|
|
|
|
await window.maximize();
|
|
await window.removeMenu();
|
|
await window.loadFile('index.html');
|
|
}
|
|
});
|
|
|
|
main();
|
|
|