/** * Scraping Control Panel for Legal Dashboard * Manages web scraping operations, real-time monitoring, and results display */ class ScrapingControlPanel { constructor() { this.baseEndpoint = '/api/scraping'; this.currentJob = null; this.isRunning = false; this.statusInterval = null; this.logs = []; this.initializeEventListeners(); this.loadScrapingStatus(); } initializeEventListeners() { // Start scraping button const startBtn = document.getElementById('startScrapingBtn'); if (startBtn) { startBtn.addEventListener('click', () => this.startScraping()); } // Stop scraping button const stopBtn = document.getElementById('stopScrapingBtn'); if (stopBtn) { stopBtn.addEventListener('click', () => this.stopScraping()); } // Refresh results button const refreshBtn = document.getElementById('refreshResultsBtn'); if (refreshBtn) { refreshBtn.addEventListener('click', () => this.loadScrapingResults()); } // Clear logs button const clearLogsBtn = document.getElementById('clearLogsBtn'); if (clearLogsBtn) { clearLogsBtn.addEventListener('click', () => this.clearLogs()); } } async startScraping() { if (this.isRunning) { this.showToast('اسکرپینگ در حال انجام است', 'warning'); return; } const scrapingConfig = this.getScrapingConfig(); if (!scrapingConfig.url) { this.showToast('لطفاً URL را وارد کنید', 'error'); return; } try { this.isRunning = true; this.updateStartButton(true); this.addLog('شروع اسکرپینگ...', 'info'); const response = await fetchWithErrorHandling(`${this.baseEndpoint}/start`, { method: 'POST', body: JSON.stringify(scrapingConfig) }); this.currentJob = response.job_id; this.showToast('اسکرپینگ شروع شد', 'success'); this.addLog(`شغل اسکرپینگ ایجاد شد: ${this.currentJob}`, 'success'); // Start monitoring this.startStatusMonitoring(); } catch (error) { this.showToast(`خطا در شروع اسکرپینگ: ${error.message}`, 'error'); this.addLog(`خطا در شروع اسکرپینگ: ${error.message}`, 'error'); this.isRunning = false; this.updateStartButton(false); } } async stopScraping() { if (!this.isRunning) { this.showToast('هیچ اسکرپینگی در حال انجام نیست', 'warning'); return; } try { const response = await fetchWithErrorHandling(`${this.baseEndpoint}/stop`, { method: 'POST', body: JSON.stringify({ job_id: this.currentJob }) }); this.showToast('اسکرپینگ متوقف شد', 'success'); this.addLog('اسکرپینگ متوقف شد', 'info'); this.isRunning = false; this.currentJob = null; this.updateStartButton(false); this.stopStatusMonitoring(); } catch (error) { this.showToast(`خطا در توقف اسکرپینگ: ${error.message}`, 'error'); this.addLog(`خطا در توقف اسکرپینگ: ${error.message}`, 'error'); } } async loadScrapingStatus() { try { const response = await fetchWithErrorHandling(`${this.baseEndpoint}/status`); this.updateStatusDisplay(response); } catch (error) { console.error('Failed to load scraping status:', error); } } async loadScrapingResults() { try { const response = await fetchWithErrorHandling(`${this.baseEndpoint}/results`); this.renderResults(response); } catch (error) { console.error('Failed to load scraping results:', error); this.showToast('خطا در بارگذاری نتایج', 'error'); } } async loadScrapingStatistics() { try { const response = await fetchWithErrorHandling(`${this.baseEndpoint}/statistics`); this.renderStatistics(response); } catch (error) { console.error('Failed to load scraping statistics:', error); } } startStatusMonitoring() { this.statusInterval = setInterval(async () => { if (this.isRunning) { await this.updateScrapingStatus(); } }, 5000); // Update every 5 seconds } stopStatusMonitoring() { if (this.statusInterval) { clearInterval(this.statusInterval); this.statusInterval = null; } } async updateScrapingStatus() { try { const response = await fetchWithErrorHandling(`${this.baseEndpoint}/status`); this.updateStatusDisplay(response); // Check if scraping is complete if (response.status === 'completed' || response.status === 'failed') { this.isRunning = false; this.currentJob = null; this.updateStartButton(false); this.stopStatusMonitoring(); if (response.status === 'completed') { this.addLog('اسکرپینگ تکمیل شد', 'success'); this.loadScrapingResults(); } else { this.addLog('اسکرپینگ با خطا مواجه شد', 'error'); } } } catch (error) { console.error('Failed to update scraping status:', error); } } updateStatusDisplay(status) { const statusElement = document.getElementById('scrapingStatus'); const progressElement = document.getElementById('scrapingProgress'); const statsElement = document.getElementById('scrapingStats'); if (statusElement) { statusElement.textContent = this.getStatusText(status.status); statusElement.className = `status-indicator ${this.getStatusClass(status.status)}`; } if (progressElement && status.progress) { progressElement.style.width = `${status.progress}%`; progressElement.textContent = `${status.progress}%`; } if (statsElement) { statsElement.innerHTML = `
هیچ نتیجهای یافت نشد
'; return; } const resultsHTML = results.items.map(item => `${item.description || 'توضیحات موجود نیست'}