Добавление поля authors в таблицу событий для соответствия функционалу API ВОЛК. Добавление функции загрузки событий одной категории.
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2025-11-15 20:40:51 +03:00
parent 651aee2b9a
commit 2c84256634
2 changed files with 160 additions and 0 deletions
+4
View File
@@ -126,6 +126,7 @@ def ensure_database_structure():
name VARCHAR(255), name VARCHAR(255),
about VARCHAR(4096), about VARCHAR(4096),
about_social_picture VARCHAR(2048), about_social_picture VARCHAR(2048),
authors VARCHAR(255),
modified DATETIME NULL, modified DATETIME NULL,
added DATETIME NULL, added DATETIME NULL,
tags VARCHAR(255), tags VARCHAR(255),
@@ -224,6 +225,9 @@ def ensure_database_structure():
], ],
'categories': [ 'categories': [
{'column': 'description', 'type': 'TEXT'} {'column': 'description', 'type': 'TEXT'}
],
'events': [
{'column': 'authors', 'type': 'VARCHAR(255)'}
] ]
} }
+156
View File
@@ -13,6 +13,7 @@ load_dotenv()
VOLK_CATEGORY_LIST = os.getenv('VOLK_CATEGORY_LIST') VOLK_CATEGORY_LIST = os.getenv('VOLK_CATEGORY_LIST')
VOLK_CATEGORY_DESC_PREFIX = os.getenv('VOLK_CATEGORY_DESC_PREFIX') 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') VOLK_API_VERSION = os.getenv('VOLK_API_VERSION')
MDB_HOST = os.getenv('MDB_HOST') MDB_HOST = os.getenv('MDB_HOST')
MDB_USER = os.getenv('MDB_USER') MDB_USER = os.getenv('MDB_USER')
@@ -222,6 +223,161 @@ def load_categories():
cursor.close() cursor.close()
connection.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__": if __name__ == "__main__":
load_categories() load_categories()