Добавление поля authors в таблицу событий для соответствия функционалу API ВОЛК. Добавление функции загрузки событий одной категории.
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
@@ -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
@@ -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()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user