/
tsps
/
core
Обзор
Документация
Войти
/
tsps
/
core
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
scripts/auto_load_daily.py
174 строки
7 KB
Василий Петров
Багфикс: отмена загрузки в выходной
07 мар 2026, 21:42
07 мар 2026, 21:42
f5d1d25
Код
Авторство
О чём код?
""" Скрипт ежедневной автоматической загрузки документов. Находит судей с auto_load_enabled=True и создает задачи на загрузку документов за вчера Запуск: python scripts/auto_load_daily.py """ import sys import time import random from datetime import date, timedelta from typing import List # Добавляем корень проекта в PYTHONPATH import os sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from sqlalchemy.orm import Session from app.database import SessionLocal from app.models.judge import Judge from app.models.document_import_job import DocumentImportJob from app.models.admin import Admin from app.models.document_type import DocumentType from app.services.case_loader_client import notify_case_loader import logging # Настройка логирования logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s" ) logger = logging.getLogger(__name__) def get_system_bot(db: Session) -> Admin: """Получает системного бота. Если не найден — падает с ошибкой""" bot = Admin.get_system_bot(db) if not bot: raise RuntimeError("Системный бот не найден в БД. Создайте его перед запуском скрипта") return bot def get_target_date() -> str: """ Вычисляет дату для выгрузки документов. Чтобы документ появился, должен пройти целый рабочий день Логика: - Понедельник - берём пятницу (3 дня назад) - Выходные - возвращаем None (скрипт должен остановиться) - Остальные дни - вчера (1 день назад) Возвращает дату в формате YYYY-MM-DD или None, если сегодня выходной """ today = date.today() weekday = today.weekday() # 0=Пн, 1=Вт... if weekday == 0: # Понедельник target = today - timedelta(days=3) # Берем пятницу logger.info(f"Сегодня понедельник. Выгружаем документы за пятницу ({target.isoformat()}).") return target.isoformat() elif weekday >= 5: # Суббота (5) или Воскресенье (6) logger.info(f"Сегодня выходной день ({weekday}). Пропускаем выгрузку.") return None else: # Вт-Пт target = today - timedelta(days=1) logger.info(f"Выгружаем документы за вчера ({target.isoformat()}).") return target.isoformat() def get_active_judges(db: Session) -> List[Judge]: """Выбирает всех судей с включенной автозагрузкой.""" return db.query(Judge).filter(Judge.auto_load_enabled == True).all() def create_import_job(db: Session, admin_id: int, judge: Judge, doc_type_id: int, date_from: str, date_to: str) -> DocumentImportJob: """Создает задачу импорта для конкретного судьи и типа документа.""" # court_id берем из текущего места работы судьи if not judge.current_court_id: logger.warning(f"У судьи {judge.id} ({judge.last_name}) не указан current_court_id. Пропускаем создание задач для этого судьи.") return None search_params = { "judge_id": judge.id, "court_id": judge.current_court_id, "document_type_id": doc_type_id, "date_from": date_from, "date_to": date_to, } job = DocumentImportJob( admin_id=admin_id, status="created", search_params=search_params, result_summary=None, error_message=None ) db.add(job) db.commit() db.refresh(job) return job def main(): logger.info("=== Запуск скрипта автозагрузки документов ===") db = SessionLocal() try: # Получаем системного бота system_bot = get_system_bot(db) logger.info(f"Используем системного админа: {system_bot.email} (ID={system_bot.id})") target_date = get_target_date() if not target_date: logger.info("=== Завершено (выходной день) ===") return # Выходим из скрипта, ничего не делаем logger.info(f"Дата для выгрузки: {target_date}") judges = get_active_judges(db) logger.info(f"Найдено судей с автозагрузкой: {len(judges)}") if not judges: logger.info("Нет активных судей. Завершение.") return # Получаем нужные типы документов target_types = ["Решение", "Постановление", "Определение"] doc_types = db.query(DocumentType).filter( DocumentType.name.in_(target_types) ).all() if not doc_types: logger.error("В БД нет нужных типов документов (document_type). Невозможно создать задачи") return success_count = 0 fail_count = 0 # Цикл по судьям for judge in judges: if not judge.current_court_id: logger.warning(f"Пропуск судьи {judge.id}: не назначен суд (current_court_id is NULL)") continue # Цикл по типам документов (создаем отдельную задачу на каждый тип) for doc_type in doc_types: try: job = create_import_job( db=db, admin_id=system_bot.id, judge=judge, doc_type_id=doc_type.id, date_from=target_date, date_to=target_date ) if job: logger.info(f"Создана задача ID={job.id} | Судья: {judge.id} | Тип: {doc_type.name}") notify_case_loader(job.id) success_count += 1 # Пауза для предотвращения перегрузки case_loader - скрипт фоновый так что нам не критично если "размажется" по времени sleep_time = random.uniform(15, 30) time.sleep(sleep_time) except Exception as e: logger.exception(f"Ошибка при создании задачи для судьи {judge.id} (тип {doc_type.id}): {e}") fail_count += 1 # Не прерываем цикл, пытаемся создать остальные задачи logger.info(f"=== Завершено. Создано задач: {success_count}, Ошибок: {fail_count} ===") except Exception as e: logger.exception(f"Критическая ошибка выполнения скрипта: {e}") sys.exit(1) finally: db.close() if __name__ == "__main__": main()