diff --git a/simple-crawler/smart-cloner.js b/simple-crawler/smart-cloner.js index 816fc08..a077a7e 100644 --- a/simple-crawler/smart-cloner.js +++ b/simple-crawler/smart-cloner.js @@ -71,7 +71,7 @@ class SmartCloner { } } - async cloneSite(url, maxPages = 20) { + async cloneSite(url, maxPages = 20, customFolderName = null) { console.log(`\n🚀 INICIANDO DEEP SMART CLONE: ${url}`); console.log(`📂 Limite de páginas: ${maxPages}\n`); @@ -82,7 +82,8 @@ class SmartCloner { const urlObj = new URL(url); const siteName = this.sanitizeFilename(urlObj.hostname); const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); - const siteDir = path.join(this.baseOutputDir, `${siteName}_${timestamp}`); + const finalFolderName = customFolderName ? this.sanitizeFilename(customFolderName) : `${siteName}_${timestamp}`; + const siteDir = path.join(this.baseOutputDir, finalFolderName); this.ensureDirectoryExists(siteDir); browser = await chromium.launch({ @@ -368,10 +369,12 @@ if (require.main === module) { const args = process.argv.slice(2); const urlArg = args.find(arg => arg.startsWith('--url=')); const url = urlArg ? urlArg.split('=')[1] : args[0]; + const folderArg = args.find(arg => arg.startsWith('--folderName=')); + const folderName = folderArg ? folderArg.split('=')[1] : null; if (url) { const cloner = new SmartCloner(); - cloner.cloneSite(url).then(res => { + cloner.cloneSite(url, 20, folderName).then(res => { console.log(JSON.stringify(res, null, 2)); process.exit(res.success ? 0 : 1); }); diff --git a/simple-crawler/wget-cloner.js b/simple-crawler/wget-cloner.js index e5953b2..81c8531 100644 --- a/simple-crawler/wget-cloner.js +++ b/simple-crawler/wget-cloner.js @@ -65,7 +65,7 @@ class WgetCloner { } } - async cloneWebsite(url) { + async cloneWebsite(url, customFolderName = null) { console.log(`\n${'='.repeat(60)}`); console.log(`🚀 CLONAGEM PROFISSIONAL COM WGET`); console.log(`${'='.repeat(60)}`); @@ -98,7 +98,8 @@ class WgetCloner { const urlObj = new URL(url); const siteName = this.sanitizeFilename(urlObj.hostname); const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); - const siteDir = path.join(this.baseOutputDir, `${siteName}_${timestamp}`); + const finalFolderName = customFolderName ? this.sanitizeFilename(customFolderName) : `${siteName}_${timestamp}`; + const siteDir = path.join(this.baseOutputDir, finalFolderName); this.ensureDirectoryExists(siteDir); console.log(`📁 Salvando em: ${siteDir}\n`); @@ -328,13 +329,13 @@ class WgetCloner { // API app.post('/wget-clone', async (req, res) => { try { - const { url } = req.body; + const { url, folderName } = req.body; if (!url) { return res.status(400).json({ error: 'URL obrigatória' }); } const cloner = new WgetCloner(); - const result = await cloner.cloneWebsite(url); + const result = await cloner.cloneWebsite(url, folderName); res.json({ success: true, data: result }); } catch (error) { diff --git a/update.sh b/update.sh index 4411ab5..d3f0582 100644 --- a/update.sh +++ b/update.sh @@ -17,4 +17,8 @@ git commit -m "$COMMIT_MESSAGE" || echo "Nenhuma mudança para comitar." # Se não houver origin ou for local, ele ignora falhas suavemente. git push origin main || git push || echo "Aviso: Push falhou ou repositório não tem remoto configurado." -echo "Atualização concluída!" +echo "Acionando o deploy no Coolify..." +curl -X POST -s -H "Authorization: Bearer 12|wbepNILQe24LAOjfEUmMROgU93F6uG1zuwPLwrRi786bca03" "http://localhost:8000/api/v1/deploy?uuid=at22zt4l2pv5at9cfkl2feh7" +echo "" + +echo "Atualização e Deploy concluídos!" diff --git a/web-interface/public/app-new.js b/web-interface/public/app-new.js index 3ff4601..5041e09 100644 --- a/web-interface/public/app-new.js +++ b/web-interface/public/app-new.js @@ -59,7 +59,8 @@ function navigateToPage(page) { 'dashboard': 'Dashboard', 'new-clone': 'Nova Clonagem', 'history': 'Histórico', - 'settings': 'Configurações' + 'settings': 'Configurações', + 'optimized-pages': 'Páginas Otimizadas (AI)' }; document.getElementById('pageTitle').textContent = titles[page] || page; @@ -70,6 +71,8 @@ function navigateToPage(page) { loadDashboard(); } else if (page === 'history') { loadHistory(); + } else if (page === 'optimized-pages') { + loadOptimizedPages(); } } @@ -206,6 +209,7 @@ async function handleCloneSubmit(e) { const includeCSSEl = document.getElementById('includeCSS'); const includeJSEl = document.getElementById('includeJS'); const convertLinksEl = document.getElementById('convertLinks'); + const customFolderEl = document.getElementById('customFolder'); if (!cloneUrlEl || !depthLevelEl || !includeImagesEl || !includeCSSEl || !includeJSEl || !convertLinksEl) { console.error('Form elements not found'); @@ -219,6 +223,7 @@ async function handleCloneSubmit(e) { const includeCSS = includeCSSEl.checked; const includeJS = includeJSEl.checked; const convertLinks = convertLinksEl.checked; + const folderName = customFolderEl ? customFolderEl.value.trim() : ''; const cloneMethod = 'wget'; if (!url) { @@ -240,6 +245,7 @@ async function handleCloneSubmit(e) { includeCSS, includeJS, convertLinks, + folderName, method: cloneMethod }); } @@ -306,7 +312,8 @@ async function startCloning(url, options) { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url, - outputDir: settings.outputDir + outputDir: settings.outputDir, + folderName: options.folderName }) }); } else { @@ -317,7 +324,8 @@ async function startCloning(url, options) { body: JSON.stringify({ url, depth: options.depth, - outputDir: settings.outputDir + outputDir: settings.outputDir, + folderName: options.folderName }) }); } @@ -709,3 +717,61 @@ function formatRelativeTime(dateString) { if (minutes > 0) return minutes === 1 ? 'Há 1 minuto' : `Há ${minutes} minutos`; return 'Agora mesmo'; } + +// Optimized Pages +async function loadOptimizedPages() { + const listEl = document.getElementById('optimizedList'); + if (!listEl) return; + + listEl.innerHTML = ` +
Otimizada pela IA • ${page.directory}
+Use o Agente Designer para otimizar suas clonagens.
+${e.message}
+