From 2c84256634e768d29dff4136f77d63f32dd3df12 Mon Sep 17 00:00:00 2001 From: gitadmin Date: Sat, 15 Nov 2025 20:40:51 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=D0=BB=D1=8F=20authors=20?= =?UTF-8?q?=D0=B2=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=D1=83=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B9=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D1=81=D0=BE=D0=BE=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2?= =?UTF-8?q?=D0=B8=D1=8F=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=BE=D0=BD?= =?UTF-8?q?=D0=B0=D0=BB=D1=83=20API=20=D0=92=D0=9E=D0=9B=D0=9A.=20=D0=94?= =?UTF-8?q?=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=84?= =?UTF-8?q?=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20=D0=B7=D0=B0=D0=B3=D1=80?= =?UTF-8?q?=D1=83=D0=B7=D0=BA=D0=B8=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8?= =?UTF-8?q?=D0=B9=20=D0=BE=D0=B4=D0=BD=D0=BE=D0=B9=20=D0=BA=D0=B0=D1=82?= =?UTF-8?q?=D0=B5=D0=B3=D0=BE=D1=80=D0=B8=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ensure_db.py | 4 ++ volk_load.py | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) diff --git a/ensure_db.py b/ensure_db.py index 30c5b53..75f4d3d 100644 --- a/ensure_db.py +++ b/ensure_db.py @@ -126,6 +126,7 @@ def ensure_database_structure(): name VARCHAR(255), about VARCHAR(4096), about_social_picture VARCHAR(2048), + authors VARCHAR(255), modified DATETIME NULL, added DATETIME NULL, tags VARCHAR(255), @@ -224,6 +225,9 @@ def ensure_database_structure(): ], 'categories': [ {'column': 'description', 'type': 'TEXT'} + ], + 'events': [ + {'column': 'authors', 'type': 'VARCHAR(255)'} ] } diff --git a/volk_load.py b/volk_load.py index 0ea7535..0791f63 100644 --- a/volk_load.py +++ b/volk_load.py @@ -13,6 +13,7 @@ load_dotenv() VOLK_CATEGORY_LIST = os.getenv('VOLK_CATEGORY_LIST') VOLK_CATEGORY_DESC_PREFIX = os.getenv('VOLK_CATEGORY_DESC_PREFIX') +VOLK_EVENT_LIST_PREFIX = os.getenv('VOLK_EVENT_LIST_PREFIX') VOLK_API_VERSION = os.getenv('VOLK_API_VERSION') MDB_HOST = os.getenv('MDB_HOST') MDB_USER = os.getenv('MDB_USER') @@ -222,6 +223,161 @@ def load_categories(): cursor.close() connection.close() +def load_events_by_category(category_id): + """Экспортируемая функция для загрузки событий категории из JSON в базу данных""" + inserted_count = 0 + updated_count = 0 + + try: + log_message(f"Начало загрузки событий для категории {category_id}") + + # Проверка наличия URL префикса + if not VOLK_EVENT_LIST_PREFIX: + error_msg = "Переменная окружения VOLK_EVENT_LIST_PREFIX не установлена" + log_message(error_msg, "ERROR") + print(error_msg) + return + + # Проверка наличия category_id + if not category_id: + error_msg = "ID категории не указан" + log_message(error_msg, "ERROR") + print(error_msg) + return + + # Формирование URL для запроса + event_url = VOLK_EVENT_LIST_PREFIX + category_id + log_message(f"Чтение данных из {event_url}") + + # Чтение JSON из URL + with urlopen(event_url) as response: + data = json.loads(response.read().decode()) + + # Проверка версии API + api_version = data.get('api_version') + if api_version != VOLK_API_VERSION: + error_msg = f"Несовпадение версии API: получена версия '{api_version}', ожидается '{VOLK_API_VERSION}'. Обработка остановлена." + log_message(error_msg, "ERROR") + print(error_msg) + return + + log_message(f"Версия API соответствует: {api_version}") + + # Проверка наличия блока data + if 'data' not in data: + error_msg = "В JSON отсутствует блок 'data'" + log_message(error_msg, "ERROR") + print(error_msg) + return + + events_data = data['data'] + log_message(f"Получено {len(events_data)} событий для обработки") + + # Подключение к базе данных + connection = mysql.connector.connect( + host=MDB_HOST, + user=MDB_USER, + password=MDB_PW, + database=MDBASE + ) + + # Установка временной зоны соединения в UTC + cursor_temp = connection.cursor() + cursor_temp.execute("SET time_zone = '+00:00'") + cursor_temp.close() + + cursor = connection.cursor(dictionary=True) + + # Проверка структуры БД + log_message("Проверка структуры базы данных") + ensure_database_structure() + + # Получаем максимальный number для данной категории, чтобы продолжить нумерацию + cursor.execute( + "SELECT MAX(number) as max_number FROM events WHERE unit_name = %s", + (category_id,) + ) + result = cursor.fetchone() + start_number = (result['max_number'] or 0) + 1 + + # Обработка событий + current_number = start_number + for item in events_data: + # Проверка обязательного поля title + if 'title' not in item or not item['title']: + log_message(f"Пропущено событие без title: {item}", "WARNING") + continue + + # Подготовка значений с маппингом полей + name = item.get('title', '') + about = item.get('announce', '') or '' + authors = item.get('authors', '') or '' + about_social_picture = item.get('image', '') or '' + unit_name = category_id + + # Проверка существующей записи по name (title) + cursor.execute( + "SELECT id, name, authors, about, about_social_picture FROM events WHERE name = %s", + (name,) + ) + existing = cursor.fetchone() + + if not existing: + # Вставка новой записи + # Используем 0 для id_event, так как его нет в JSON + cursor.execute( + """INSERT INTO events (id_event, number, unit_name, name, about, about_social_picture, authors) + VALUES (%s, %s, %s, %s, %s, %s, %s)""", + (0, current_number, unit_name, name, about, about_social_picture, authors) + ) + inserted_count += 1 + log_message(f"Добавление: Событие '{name}', номер: {current_number}, категория: {category_id}") + current_number += 1 + else: + # Обновление существующей записи + needs_update = False + update_fields = [] + + if existing['authors'] != authors: + needs_update = True + update_fields.append('authors') + if existing['about'] != about: + needs_update = True + update_fields.append('about') + if existing['about_social_picture'] != about_social_picture: + needs_update = True + update_fields.append('about_social_picture') + + if needs_update: + cursor.execute( + """UPDATE events SET authors = %s, about = %s, about_social_picture = %s + WHERE name = %s""", + (authors, about, about_social_picture, name) + ) + updated_count += 1 + log_message(f"Обновление: Событие '{name}', обновлены поля: {', '.join(update_fields)}") + else: + log_message(f"Событие '{name}' без изменений") + + connection.commit() + + log_message(f"Завершение работы. Добавлено событий: {inserted_count}. Обновлено событий: {updated_count}.") + + except Error as e: + error_msg = f"Ошибка базы данных: {e}" + log_message(error_msg, "ERROR") + print(error_msg) + if 'connection' in locals() and connection.is_connected(): + connection.rollback() + except Exception as e: + error_msg = f"Общая ошибка: {e}" + log_message(error_msg, "ERROR") + print(error_msg) + finally: + if 'connection' in locals() and connection.is_connected(): + cursor.close() + connection.close() + if __name__ == "__main__": load_categories()