Files
test-loderweb/services/processor.py
2026-02-12 01:41:09 +05:00

205 lines
11 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Модуль для обработки файлов и управления циклом загрузок
"""
import logging
import time
from pathlib import Path
from services.file_finder import FileFinderService
from services.browser_service import BrowserService
class FileProcessorService:
"""Сервис для обработки файлов и управления процессом загрузок"""
def __init__(self, directory_path, url, download_dir, firefox_path=None):
"""
Инициализирует процессор файлов.
Args:
directory_path (str): Путь к директории с .xlsx файлами
url (str): URL страницы для загрузки файлов
download_dir (str): Путь для загрузок
firefox_path (str): Путь к Firefox (опционально)
"""
self.directory_path = directory_path
self.url = url
self.download_dir = download_dir
self.firefox_path = firefox_path
self.file_finder = FileFinderService()
self.browser = None
self.processed_files = 0
self.failed_files = []
logging.info("=" * 70)
logging.info("🚀 ИНИЦИАЛИЗАЦИЯ ПРОЦЕССОРА ФАЙЛОВ")
logging.info("=" * 70)
def start_processing(self, upload_button_texts=None, process_button_texts=None, selected_tab=None):
"""
Запускает процесс поиска и загрузки файлов.
Args:
upload_button_texts (list): Варианты текста кнопки загрузки файла
process_button_texts (list): Варианты текста кнопки обработки
selected_tab (str): Название вкладки на странице для выбора
Returns:
dict: Результаты обработки
"""
if upload_button_texts is None:
upload_button_texts = ["Загрузить файл", "Выбрать файл", "Добавить файл"]
if process_button_texts is None:
process_button_texts = ["Загрузить", "Обработать", "Преобразовать", "Изменить", "Конвертировать"]
results = {
"total_files": 0,
"processed_files": 0,
"failed_files": [],
"errors": []
}
try:
# Шаг 1: Поиск файлов
logging.info("\n📂 ШАГ 1: ПОИСК ФАЙЛОВ")
logging.info("-" * 70)
xlsx_files = self.file_finder.find_xlsx_files(self.directory_path, recursive=True)
results["total_files"] = len(xlsx_files)
if not xlsx_files:
logging.error("❌ Файлы не найдены. Процесс прерван.")
results["errors"].append("Файлы .xlsx не найдены в указанной директории")
return results
# Шаг 2: Инициализация браузера
logging.info("\n🌐 ШАГ 2: ИНИЦИАЛИЗАЦИЯ БРАУЗЕРА")
logging.info("-" * 70)
self.browser = BrowserService(self.download_dir, self.firefox_path)
self.browser.open_page(self.url)
self.browser.wait_page_load(5)
# ПЕРВЫЙ ПРОГОН НАСТРОЙКИ: Если выбрана вкладка, пробуем её активировать на главной странице сразу
if selected_tab:
logging.info(f"🔍 [Pre-Check] Пробую найти вкладку '{selected_tab}' на стартовой странице...")
# Попытка найти вкладку с увеличенным таймаутом для первого раза
if self.browser.select_tab_by_multiple_methods(selected_tab, timeout=10):
logging.info(f"✅ [Pre-Check] Вкладка '{selected_tab}' найдена на старте.")
else:
logging.info(f"⚠️ [Pre-Check] Вкладка '{selected_tab}' пока не найдена (возможно появится после авторизации/загрузки).")
# Шаг 3: Обработка каждого файла
logging.info("\n📋 ШАГ 3: ОБРАБОТКА ФАЙЛОВ")
logging.info("-" * 70)
for idx, file_path in enumerate(xlsx_files, 1):
# Задержка 5 сек перед следующим файлом (кроме первого)
if idx > 1:
logging.info(f"\n⏳ Задержка 5 сек перед следующим файлом...")
time.sleep(5)
logging.info(f"\n📄 Файл {idx}/{len(xlsx_files)}: {file_path.name}")
logging.info("=" * 70)
try:
# Открываем новую вкладку для КАЖДОГО файла (включая первый)
logging.info(f" Открываю новую вкладку в браузере для файла...")
if not self.browser.open_new_tab(self.url):
logging.warning(f"⚠️ Не удалось открыть новую вкладку")
self.browser.wait_page_load(3)
# Выбор вкладки на странице (если указана)
if selected_tab:
logging.info(f"🔍 Выбираю вкладку на странице: '{selected_tab}'")
if self.browser.select_tab_by_multiple_methods(selected_tab, timeout=15):
logging.info(f"✅ Вкладка '{selected_tab}' успешно выбрана")
self.browser.wait_page_load(2)
else:
logging.warning(f"⚠️ Не удалось выбрать вкладку '{selected_tab}'")
# Поиск и клик по кнопке загрузки
upload_button_found = False
for btn_text in upload_button_texts:
if self.browser.click_button_by_text(btn_text):
upload_button_found = True
break
if not upload_button_found:
logging.warning(f"⚠️ Не найдена кнопка загрузки файла")
self.failed_files.append({
"file": file_path.name,
"reason": "Кнопка загрузки не найдена"
})
results["failed_files"].append(file_path.name)
continue
# Загрузка файла
self.browser.wait_page_load(1)
upload_success = self.browser.upload_file(str(file_path))
if not upload_success:
logging.warning(f"⚠️ Ошибка при загрузке файла")
self.failed_files.append({
"file": file_path.name,
"reason": "Ошибка при загрузке файла"
})
results["failed_files"].append(file_path.name)
continue
# Поиск и клик по кнопке обработки
self.browser.wait_page_load(2)
process_button_found = False
for btn_text in process_button_texts:
if self.browser.click_button_by_text(btn_text):
process_button_found = True
break
if not process_button_found:
logging.warning(f"⚠️ Не найдена кнопка обработки")
# Это не критичная ошибка, файл уже загружен
# Ожидание обработки
self.browser.wait_page_load(3)
self.processed_files += 1
results["processed_files"] += 1
logging.info(f"✅ Файл обработан успешно")
# Закрываем вкладку после обработки (если это не первый файл)
if idx > 1:
logging.info(f" Закрываю вкладку после обработки...")
self.browser.close_current_tab()
except Exception as e:
logging.error(f"❌ Ошибка при обработке файла: {e}")
self.failed_files.append({
"file": file_path.name,
"reason": str(e)
})
results["failed_files"].append(file_path.name)
# Итоговый отчет
logging.info("\n" + "=" * 70)
logging.info("📊 ИТОГОВЫЙ ОТЧЕТ")
logging.info("=" * 70)
logging.info(f"Всего файлов: {results['total_files']}")
logging.info(f"Обработано успешно: {results['processed_files']}")
logging.info(f"Ошибок: {len(results['failed_files'])}")
if results["failed_files"]:
logging.warning("\n❌ Файлы с ошибками:")
for file_info in self.failed_files:
logging.warning(f" - {file_info['file']}: {file_info['reason']}")
logging.info("\n✅ ОБРАБОТКА ЗАВЕРШЕНА")
logging.info("=" * 70)
return results
except Exception as e:
logging.error(f"❌ Критическая ошибка: {e}")
results["errors"].append(str(e))
return results
finally:
if self.browser:
self.browser.close()