let statusCheckInterval; function startStatusCheck() { // Очищаем предыдущий интервал, если он существует if (statusCheckInterval) { clearInterval(statusCheckInterval); } // Проверяем статус каждые 500мс statusCheckInterval = setInterval(checkStatus, 500); // Сразу делаем первую проверку checkStatus(); } function checkStatus() { fetch('/status') .then(response => response.json()) .then(data => { const status = document.getElementById('status'); const button = document.getElementById('parseButton'); if (data.is_running) { let statusHtml = `
Парсинг запущено для категорії: ${data.current_category}
`;
if (data.total_products > 0) {
statusHtml += `
Товар ${data.current_product} із ${data.total_products}
Прогрес: ${data.progress}%
`;
} else {
statusHtml += `Отримання інформації про кількість товарів...`;
}
statusHtml += `
Помилка: ${data.error}
`; } else if (data.total_products > 0) { status.innerHTML = `
Парсинг завершено
Всього оброблено товарів: ${data.total_products}
Помилка: ${error.message}
`; button.disabled = false; }); } function stopStatusCheck() { if (statusCheckInterval) { clearInterval(statusCheckInterval); statusCheckInterval = null; } } function deleteFile(filename, type) { if (confirm('Ви впевнені, що хочете видалити цей файл?')) { fetch(`/delete/${filename}`, { method: 'POST' }) .then(response => response.json()) .then(data => { if (data.error) { alert(data.error); } else { // Удаляем файл из списка const fileItem = document.querySelector(`a[href*="${filename}"]`).closest('li'); fileItem.remove(); // Обновляем соответствующий select в зависимости от типа файла if (type === 'parsed') { const fileSelect = document.getElementById('file-select'); const optionToRemove = Array.from(fileSelect.options).find(opt => opt.value === filename); if (optionToRemove) { optionToRemove.remove(); } } else if (type === 'translated') { const ymlFileSelect = document.getElementById('yml-file-select'); const optionToRemove = Array.from(ymlFileSelect.options).find(opt => opt.value === filename); if (optionToRemove) { optionToRemove.remove(); } } } }) .catch(error => { console.error('Error:', error); alert('Помилка при видаленні файлу'); }); } } function openTab(tabName) { // Приховуємо всі вкладки const tabContents = document.getElementsByClassName('tab-content'); for (let content of tabContents) { content.classList.remove('active'); } // Деактивуємо всі кнопки const tabButtons = document.getElementsByClassName('tab-button'); for (let button of tabButtons) { button.classList.remove('active'); } // Показуємо вибрану вкладку document.getElementById(tabName).classList.add('active'); // Активуємо потрібну кнопку event.currentTarget.classList.add('active'); } function startTranslation() { const fileSelect = document.getElementById('file-select'); const button = document.getElementById('translateButton'); const status = document.getElementById('translation-status'); if (!fileSelect.value) { status.innerHTML = 'Будь ласка, виберіть файл для обробки
'; return; } button.disabled = true; status.innerHTML = 'Починаємо переклад...
'; fetch('/translate', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: `filename=${encodeURIComponent(fileSelect.value)}` }) .then(response => response.json()) .then(data => { if (data.error) { status.innerHTML = `${data.error}
`; button.disabled = false; } else { checkTranslationStatus(); } }); } function checkTranslationStatus() { fetch('/translation-status') .then(response => response.json()) .then(data => { const status = document.getElementById('translation-status'); const button = document.getElementById('translateButton'); if (data.is_running) { if (data.total_items > 0) { const percent = Math.round((data.processed_items / data.total_items) * 100); status.innerHTML = `
Переклад в процесі...
Оброблено: ${data.processed_items} з ${data.total_items}
Прогрес: ${percent}%
Підготовка до перекладу...
'; } setTimeout(checkTranslationStatus, 1000); } else { if (data.error) { status.innerHTML = `Помилка: ${data.error}
`; } else if (data.total_items > 0) { status.innerHTML = `
Переклад завершено
Всього оброблено товарів: ${data.total_items}
Помилка: ${error.message}
`; document.getElementById('translateButton').disabled = false; }); } function generateFullYML() { if (!confirm("Згенерувати загальний YML-файл для всіх категорій?")) return; fetch('/generate-full-yml', { method: 'POST' }) .then(response => response.json()) .then(data => { if (data.success) { alert("Повний YML успішно згенеровано"); updateFilesList('yml', 'generator'); } else { alert("Помилка: " + (data.error || "Невідома помилка")); } }); } function updateItemsLimit(value) { fetch('/update-settings', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ items_limit: parseInt(value) }) }) .then(response => response.json()) .then(data => { if (data.error) { alert(data.error); } }); } function addCategory() { const categoryName = document.getElementById('category-name').value; const portalId = document.getElementById('portal-id').value; const categoryUrl = document.getElementById('category-url').value; if (!categoryName || !categoryUrl) { alert('Будь ласка, заповніть назву і URL категорії'); return; } fetch('/add-category', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ name: categoryName, portal_id: portalId, url: categoryUrl }) }) .then(response => response.json()) .then(data => { if (data.error) { alert(data.error); } else { const newId = data.id; document.getElementById('category-name').value = ''; document.getElementById('portal-id').value = ''; document.getElementById('category-url').value = ''; const categoriesList = document.getElementById('categories-list'); const li = document.createElement('li'); li.title = categoryUrl; li.innerHTML = ` ${newId} - ${categoryName} ${portalId ? `(portal_id: ${portalId})` : ''} `; categoriesList.appendChild(li); const ymlSelect = document.getElementById('yml-category-select'); const option = document.createElement('option'); option.value = newId; option.text = categoryName; ymlSelect.appendChild(option); } }); } function deleteCategory(categoryId) { if (confirm('Ви впевнені, що хочете видалити цю категорію?')) { fetch('/delete-category', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ id: categoryId }) }) .then(response => response.json()) .then(data => { if (data.error) { alert(data.error); } else { // Удаляем категорию из списка const categoryItems = document.querySelectorAll('#categories-list li'); categoryItems.forEach(item => { if (item.querySelector('span').textContent.startsWith(categoryId + ' -')) { item.remove(); } }); // Удаляем опцию из select в генераторе YML const ymlSelect = document.getElementById('yml-category-select'); const option = Array.from(ymlSelect.options).find(opt => opt.value === categoryId); if (option) option.remove(); } }); } } function generateYML() { console.log('generateYML called'); // Отладка const categoryId = document.getElementById('yml-category-select').value; const fileSelect = document.getElementById('yml-file-select'); console.log('Selected category:', categoryId); // Отладка console.log('Selected file:', fileSelect.value); // Отладка const button = document.getElementById('generateButton'); const status = document.getElementById('yml-status'); if (!categoryId || !fileSelect.value) { status.innerHTML = 'Будь ласка, виберіть категорію та файл
'; return; } button.disabled = true; status.innerHTML = 'Генерація YML...
'; fetch('/generate-yml', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ filename: fileSelect.value, category_id: categoryId }) }) .then(response => response.json()) .then(data => { if (data.error) { status.innerHTML = `${data.error}
`; } else { status.innerHTML = 'YML файл успішно згенеровано
'; updateFilesList('yml', 'generator', null); } button.disabled = false; }) .catch(error => { status.innerHTML = `Помилка: ${error.message}
`; button.disabled = false; }); } // Добавляем вспомогательную функцию для поиска по тексту jQuery.expr[':'].contains = function (a, i, m) { return jQuery(a).text().toUpperCase() .indexOf(m[3].toUpperCase()) >= 0; }; function updateFilesList(fileType, containerId, selectId = null) { fetch(`/get-files/${fileType}`) .then(response => response.json()) .then(files => { // Обновляем список файлов const filesList = document.querySelector(`#${containerId} .files ul`); filesList.innerHTML = files.map(file => `Будь ласка, введіть URL
'; return; } button.disabled = true; status.innerHTML = 'Починаємо парсинг...
'; fetch('/parse', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: `url=${encodeURIComponent(url)}` }) .then(response => response.json()) .then(data => { if (data.error) { status.innerHTML = `${data.error}
`; button.disabled = false; } else { checkParsingStatus(); } }) .catch(error => { status.innerHTML = `Помилка: ${error.message}
`; button.disabled = false; }); } function checkParsingStatus() { fetch('/status') .then(response => response.json()) .then(data => { const status = document.getElementById('status'); const button = document.getElementById('parseButton'); if (data.is_running) { if (data.total_items > 0) { const percent = Math.round((data.processed_items / data.total_items) * 100); status.innerHTML = `
Парсинг в процесі...
Оброблено: ${data.processed_items} з ${data.total_items}
Прогрес: ${percent}%
Отримання інформації про товари...
'; } setTimeout(checkParsingStatus, 1000); } else { if (data.error) { status.innerHTML = `Помилка: ${data.error}
`; } else { status.innerHTML = `
Парсинг завершено
Всього оброблено товарів: ${data.total_items}
Помилка: ${error.message}
`; document.getElementById('parseButton').disabled = false; }); } function refreshOldestCategory() { fetch('/manual-refresh-all', { method: 'POST' }) }