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: 'UDISBRM@CLARO.COM.CO', 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: 'UDISBRM@CLARO.COM.CO', 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();