Initial
This commit is contained in:
+34
@@ -0,0 +1,34 @@
|
|||||||
|
# Directorios y archivos generados automáticamente
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
|
||||||
|
# Archivos de construcción
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
out/
|
||||||
|
|
||||||
|
# Archivos de configuración locales (pueden variar según tus herramientas)
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Dependencias locales (puedes ajustar esta lista según tus necesidades)
|
||||||
|
# /node_modules/
|
||||||
|
|
||||||
|
# Logs y archivos temporales
|
||||||
|
*.log
|
||||||
|
*.tmp
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
# Archivos de usuario y configuración específica de IDE
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
|
# Dependencias globales de Yarn (opcional; úsalo si lo necesitas)
|
||||||
|
# /.yarn/
|
||||||
+305
@@ -0,0 +1,305 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Sistema de descarga automatizado</title>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--primary-color: #1DA1F2;
|
||||||
|
--background-color: #15202B;
|
||||||
|
--card-background: #192734;
|
||||||
|
--text-color: #FFFFFF;
|
||||||
|
--border-color: #38444D;
|
||||||
|
--success-color: #17BF63;
|
||||||
|
--error-color: #E0245E;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Inter', sans-serif;
|
||||||
|
background-color: var(--background-color);
|
||||||
|
color: var(--text-color);
|
||||||
|
margin: 0;
|
||||||
|
padding: 20px;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 15px 0;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-container {
|
||||||
|
background: var(--card-background);
|
||||||
|
border-radius: 15px;
|
||||||
|
padding: 20px;
|
||||||
|
position: relative;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-container:hover {
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-title {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-url {
|
||||||
|
background: transparent;
|
||||||
|
color: var(--error-color);
|
||||||
|
border: none;
|
||||||
|
font-size: 1.2em;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-url:hover {
|
||||||
|
background: rgba(224, 36, 94, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-inputs {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
background: var(--background-color);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
color: var(--text-color);
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 25px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-container {
|
||||||
|
margin-top: 15px;
|
||||||
|
background: var(--background-color);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 10px;
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: auto;
|
||||||
|
font-size: 0.9em;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-message {
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-message:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 12px 24px;
|
||||||
|
border-radius: 25px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-url {
|
||||||
|
background: var(--success-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-indicator {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-pending {
|
||||||
|
background-color: #FFD700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-success {
|
||||||
|
background-color: var(--success-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-error {
|
||||||
|
background-color: var(--error-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scrollbar personalizado */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: var(--background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--border-color);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--primary-color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<h1>Sistema de descarga automatizado</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="url-list" id="urlList">
|
||||||
|
<div class="url-container">
|
||||||
|
<div class="url-header">
|
||||||
|
<span class="url-title">Proceso #1</span>
|
||||||
|
<button class="remove-url" onclick="removeUrl(this)">×</button>
|
||||||
|
</div>
|
||||||
|
<div class="url-inputs">
|
||||||
|
<input type="text" class="downloadUrl" placeholder="URL de Descarga" required>
|
||||||
|
<input type="text" class="ftpUrl" placeholder="Ruta FTP" required>
|
||||||
|
</div>
|
||||||
|
<div class="log-container"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="actions">
|
||||||
|
<button class="add-url" onclick="addNewUrl()">Nueva URL</button>
|
||||||
|
<button id="url_send">Procesar URLs</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const { ipcRenderer } = require('electron');
|
||||||
|
let processCount = 1;
|
||||||
|
|
||||||
|
function addNewUrl() {
|
||||||
|
processCount++;
|
||||||
|
const urlList = document.getElementById('urlList');
|
||||||
|
const newUrl = document.createElement('div');
|
||||||
|
newUrl.className = 'url-container';
|
||||||
|
newUrl.innerHTML = `
|
||||||
|
<div class="url-header">
|
||||||
|
<span class="url-title">Proceso #${processCount}</span>
|
||||||
|
<button class="remove-url" onclick="removeUrl(this)">×</button>
|
||||||
|
</div>
|
||||||
|
<div class="url-inputs">
|
||||||
|
<input type="text" class="downloadUrl" placeholder="URL de Descarga" required>
|
||||||
|
<input type="text" class="ftpUrl" placeholder="Ruta FTP" required>
|
||||||
|
</div>
|
||||||
|
<div class="log-container"></div>
|
||||||
|
`;
|
||||||
|
urlList.appendChild(newUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeUrl(button) {
|
||||||
|
const container = button.closest('.url-container');
|
||||||
|
if (document.getElementsByClassName('url-container').length > 1) {
|
||||||
|
container.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('url_send').addEventListener('click', () => {
|
||||||
|
const urls = [];
|
||||||
|
const containers = document.getElementsByClassName('url-container');
|
||||||
|
|
||||||
|
Array.from(containers).forEach((container, index) => {
|
||||||
|
const downloadUrl = container.querySelector('.downloadUrl').value;
|
||||||
|
const ftpUrl = container.querySelector('.ftpUrl').value;
|
||||||
|
|
||||||
|
if (downloadUrl && ftpUrl) {
|
||||||
|
urls.push({
|
||||||
|
downloadUrl,
|
||||||
|
ftpUrl,
|
||||||
|
containerId: index
|
||||||
|
});
|
||||||
|
// Limpiar logs anteriores
|
||||||
|
container.querySelector('.log-container').innerHTML = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (urls.length > 0) {
|
||||||
|
ipcRenderer.send('url_process', urls);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcRenderer.on('log_message', (event, message) => {
|
||||||
|
const containers = document.getElementsByClassName('url-container');
|
||||||
|
const urlPattern = /URL: (.*?)(?=\s|$)/;
|
||||||
|
const match = message.match(urlPattern);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
const url = match[1];
|
||||||
|
// Encontrar el contenedor correspondiente
|
||||||
|
Array.from(containers).forEach(container => {
|
||||||
|
if (container.querySelector('.downloadUrl').value === url) {
|
||||||
|
const logContainer = container.querySelector('.log-container');
|
||||||
|
const logElement = document.createElement('div');
|
||||||
|
logElement.className = 'log-message';
|
||||||
|
// Eliminar la URL del mensaje para los logs
|
||||||
|
const cleanMessage = message.replace(urlPattern, '').trim();
|
||||||
|
logElement.textContent = cleanMessage;
|
||||||
|
logContainer.appendChild(logElement);
|
||||||
|
logContainer.scrollTop = logContainer.scrollHeight;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,375 @@
|
|||||||
|
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();
|
||||||
|
|
||||||
Generated
+5177
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "descargas-bbdd",
|
||||||
|
"version": "0.0.6",
|
||||||
|
"main": "main.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "electron .",
|
||||||
|
"build": "electron-builder"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"adm-zip": "^0.5.16",
|
||||||
|
"basic-ftp": "^5.0.5",
|
||||||
|
"extract-zip": "^2.0.1",
|
||||||
|
"puppeteer": "^22.15.0",
|
||||||
|
"puppeteer-core": "^21.11.0",
|
||||||
|
"puppeteer-in-electron": "^3.0.5",
|
||||||
|
"ssh2-sftp-client": "^11.0.0",
|
||||||
|
"uuid": "^11.0.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"electron": "^20.0.0",
|
||||||
|
"electron-builder": "^24.9.1"
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"appId": "com.downloads.id",
|
||||||
|
"productName": "Descargas BBDD",
|
||||||
|
"win": {
|
||||||
|
"target": "nsis",
|
||||||
|
"icon": "icono.ico"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
const puppeteer = require("puppeteer");
|
||||||
|
// Or import puppeteer from 'puppeteer-core';
|
||||||
|
const main = async () => {
|
||||||
|
// Launch the browser and open a new blank page
|
||||||
|
const browser = await puppeteer.launch({
|
||||||
|
headless: false
|
||||||
|
});
|
||||||
|
const page = await browser.newPage();
|
||||||
|
|
||||||
|
// Navigate the page to a URL.
|
||||||
|
await page.goto('https://claromovilco.sharepoint.com/sites/01Facturacion2/Documentos%20compartidos/Forms/AllItems.aspx?ga=1&id=%2Fsites%2F01Facturacion2%2FDocumentos%20compartidos%2FGestión%20Campañas%20Outbound%2F02%2E%20BRM%2F01%2E%20Campaña%20Tercer%20Anillo%20BRM%2FCampaña%20Tercer%20Anillo%20BRM%20Archivo');
|
||||||
|
|
||||||
|
await page.waitForSelector('input[type="email"]');
|
||||||
|
await page.type('input[type="email"]', '[email protected]');
|
||||||
|
await page.click('input[type="submit"]');
|
||||||
|
await page.waitForSelector('input[type="password"]');
|
||||||
|
await page.type('input[type="password"]', 'TittqbAP5rlnR8PQnYLe');
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
await page.click('input[type="submit"]');
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
await page.locator('#idBtn_Back').click();
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 4000));
|
||||||
|
console.log('ya');
|
||||||
|
|
||||||
|
}
|
||||||
|
main();
|
||||||
Reference in New Issue
Block a user