Files
2025-05-26 07:45:27 -05:00

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();