diff --git "a/app.py" "b/app.py"
--- "a/app.py"
+++ "b/app.py"
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# --- START OF FILE app.py ---
from flask import Flask, render_template_string, request, redirect, url_for
import json
import os
@@ -28,64 +28,34 @@ def load_data():
data = json.load(file)
logging.info("Данные успешно загружены из JSON")
if not isinstance(data, dict) or 'products' not in data or 'categories' not in data:
- logging.warning("JSON структура некорректна, инициализация пустой структурой.")
- # Handle cases where data is just a list (old format?) or missing keys
- if isinstance(data, list):
- return {'products': data, 'categories': []}
- else:
- return {'products': [], 'categories': []}
- # Ensure categories is a list
- if not isinstance(data.get('categories'), list):
- data['categories'] = []
- # Ensure products is a list
- if not isinstance(data.get('products'), list):
- data['products'] = []
+ return {'products': [], 'categories': [] if not isinstance(data, list) else data}
return data
except FileNotFoundError:
- logging.warning("Локальный файл базы данных не найден после попытки скачивания. Используется пустая база.")
+ logging.warning("Локальный файл базы данных не найден после скачивания.")
return {'products': [], 'categories': []}
except json.JSONDecodeError:
- logging.error("Ошибка: Невозможно декодировать JSON файл. Используется пустая база.")
+ logging.error("Ошибка: Невозможно декодировать JSON файл.")
return {'products': [], 'categories': []}
except RepositoryNotFoundError:
- logging.error("Репозиторий Hugging Face не найден. Создание локальной базы данных.")
- # Create an empty local file if repo not found and local file doesn't exist
- if not os.path.exists(DATA_FILE):
- save_data({'products': [], 'categories': []}) # Save immediately to create the file structure
+ logging.error("Репозиторий не найден. Создание локальной базы данных.")
return {'products': [], 'categories': []}
except Exception as e:
- logging.error(f"Произошла непредвиденная ошибка при загрузке данных: {e}. Используется пустая база.")
+ logging.error(f"Произошла ошибка при загрузке данных: {e}")
return {'products': [], 'categories': []}
def save_data(data):
- # Ensure data integrity before saving
- if not isinstance(data, dict):
- logging.error("Попытка сохранить данные не в формате словаря. Операция отменена.")
- return
- if 'products' not in data or not isinstance(data['products'], list):
- logging.warning("Ключ 'products' отсутствует или не является списком. Инициализация пустым списком.")
- data['products'] = []
- if 'categories' not in data or not isinstance(data['categories'], list):
- logging.warning("Ключ 'categories' отсутствует или не является списком. Инициализация пустым списком.")
- data['categories'] = []
-
try:
with open(DATA_FILE, 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
logging.info("Данные успешно сохранены в JSON")
- # Attempt upload only after successful local save
upload_db_to_hf()
except Exception as e:
- logging.error(f"Ошибка при сохранении данных локально или при загрузке на HF: {e}")
- # Consider if you want to re-raise or just log the error
- # raise # Re-raising might stop the application flow depending on where save_data is called
+ logging.error(f"Ошибка при сохранении данных: {e}")
+ raise
def upload_db_to_hf():
if not HF_TOKEN_WRITE:
- logging.warning("HF_TOKEN (WRITE) не установлен. Загрузка на Hugging Face пропущена.")
- return
- if not os.path.exists(DATA_FILE):
- logging.warning(f"Файл {DATA_FILE} не найден для загрузки на Hugging Face.")
+ logging.warning("HF_TOKEN_WRITE не установлен. Пропуск загрузки на Hugging Face.")
return
try:
api = HfApi()
@@ -99,20 +69,17 @@ def upload_db_to_hf():
)
logging.info("Резервная копия JSON базы успешно загружена на Hugging Face.")
except Exception as e:
- logging.error(f"Ошибка при загрузке резервной копии на Hugging Face: {e}")
+ logging.error(f"Ошибка при загрузке резервной копии: {e}")
def download_db_from_hf():
if not HF_TOKEN_READ:
- logging.warning("HF_TOKEN_READ не установлен. Скачивание из Hugging Face пропущено.")
- # If download is skipped, we should rely on the existing local file or start fresh
- if os.path.exists(DATA_FILE):
- logging.info("Используется существующий локальный файл data.json.")
+ logging.warning("HF_TOKEN_READ не установлен. Пропуск скачивания с Hugging Face.")
+ # If read token is missing, try to use write token if available
+ if HF_TOKEN_WRITE:
+ HF_TOKEN_READ = HF_TOKEN_WRITE
+ logging.info("Используется HF_TOKEN_WRITE для скачивания.")
else:
- logging.warning("Локальный файл data.json не найден, будет создана пустая структура.")
- # Ensure an empty structure is created if the file doesn't exist and download fails/is skipped
- save_data({'products': [], 'categories': []})
- return # Don't raise an error here, allow the app to continue
-
+ raise Exception("Нет доступных токенов для чтения.")
try:
hf_hub_download(
repo_id=REPO_ID,
@@ -120,32 +87,21 @@ def download_db_from_hf():
repo_type="dataset",
token=HF_TOKEN_READ,
local_dir=".",
- local_dir_use_symlinks=False,
- force_download=True # Ensure we get the latest version
+ local_dir_use_symlinks=False
)
logging.info("JSON база успешно скачана из Hugging Face.")
except RepositoryNotFoundError as e:
- logging.error(f"Репозиторий Hugging Face не найден: {e}")
- # Don't raise here, load_data handles this to start with an empty DB
+ logging.error(f"Репозиторий не найден: {e}")
+ raise
except Exception as e:
- # Catch specific hf download errors if possible, otherwise generic Exception
- logging.error(f"Ошибка при скачивании JSON базы из Hugging Face: {e}")
- # Don't raise here, allow load_data to handle fallback
+ logging.error(f"Ошибка при скачивании JSON базы: {e}")
+ raise
def periodic_backup():
while True:
- time.sleep(800) # Sleep first to avoid immediate backup on start
- logging.info("Запуск периодического резервного копирования...")
- # Ensure data is loaded before attempting backup? Or rely on save_data's upload call?
- # Let's rely on save_data triggering uploads after changes.
- # This thread can be simplified or removed if uploads only happen after saves.
- # Keeping it for now as a periodic *check* and potential upload if needed.
- # Maybe load and save here to force consistency?
- try:
- current_data = load_data() # Reload to ensure we have the latest state potentially
- upload_db_to_hf() # Explicitly call upload here
- except Exception as e:
- logging.error(f"Ошибка во время периодического резервного копирования: {e}")
+ time.sleep(800)
+ logging.info("Запуск периодического резервного копирования.")
+ upload_db_to_hf()
@app.route('/')
@@ -160,7 +116,7 @@ def catalog():