Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -51,7 +51,7 @@ def save_data(data):
|
|
| 51 |
try:
|
| 52 |
with open(DATA_FILE, 'w', encoding='utf-8') as f:
|
| 53 |
json.dump(data, f, ensure_ascii=False, indent=4)
|
| 54 |
-
upload_db_to_hf()
|
| 55 |
except Exception as e:
|
| 56 |
logger.error(f"Ошибка при сохранении данных: {e}")
|
| 57 |
|
|
@@ -85,6 +85,17 @@ def download_db_from_hf():
|
|
| 85 |
logger.error(f"Ошибка при скачивании: {e}")
|
| 86 |
raise
|
| 87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
# Загрузка данных
|
| 89 |
data = load_data()
|
| 90 |
|
|
@@ -121,7 +132,6 @@ async def show_categories(message: types.Message):
|
|
| 121 |
return
|
| 122 |
await message.answer("Выберите категорию:", reply_markup=get_category_keyboard())
|
| 123 |
|
| 124 |
-
# Оптимизированный вывод товаров
|
| 125 |
@dp.callback_query(F.data.startswith("cat_"))
|
| 126 |
async def show_products_in_category(callback_query: types.CallbackQuery):
|
| 127 |
try:
|
|
@@ -133,7 +143,6 @@ async def show_products_in_category(callback_query: types.CallbackQuery):
|
|
| 133 |
await bot.answer_callback_query(callback_query.id)
|
| 134 |
return
|
| 135 |
|
| 136 |
-
# Отправка товаров пачками асинхронно
|
| 137 |
async def send_product_batch(products_batch):
|
| 138 |
for product in products_batch:
|
| 139 |
photo_url = f"https://huggingface.co/datasets/{REPO_ID}/resolve/main/photos/{product['photo']}" if product.get('photo') else None
|
|
@@ -147,12 +156,11 @@ async def show_products_in_category(callback_query: types.CallbackQuery):
|
|
| 147 |
logger.error(f"Ошибка при отправке: {e}")
|
| 148 |
await bot.send_message(callback_query.from_user.id, caption, reply_markup=get_product_keyboard(product['id']))
|
| 149 |
|
| 150 |
-
# Разбиваем на пачки по 5 товаров
|
| 151 |
batch_size = 5
|
| 152 |
for i in range(0, len(products_in_cat), batch_size):
|
| 153 |
batch = products_in_cat[i:i + batch_size]
|
| 154 |
await send_product_batch(batch)
|
| 155 |
-
await asyncio.sleep(0.1)
|
| 156 |
|
| 157 |
await bot.answer_callback_query(callback_query.id)
|
| 158 |
except Exception as e:
|
|
@@ -236,7 +244,7 @@ async def show_orders(message: types.Message):
|
|
| 236 |
response += f"\nИтого: {total} сом\nДата: {order['date']}"
|
| 237 |
await message.answer(response)
|
| 238 |
|
| 239 |
-
# Админ-панель
|
| 240 |
admin_html = """
|
| 241 |
<!DOCTYPE html>
|
| 242 |
<html>
|
|
@@ -387,7 +395,6 @@ admin_html = """
|
|
| 387 |
</div>
|
| 388 |
</div>
|
| 389 |
<script>
|
| 390 |
-
// Автоматическое обновление через Server-Sent Events
|
| 391 |
const eventSource = new EventSource('/updates');
|
| 392 |
eventSource.onmessage = function(event) {
|
| 393 |
if (event.data === 'update') {
|
|
@@ -414,7 +421,6 @@ admin_html = """
|
|
| 414 |
</html>
|
| 415 |
"""
|
| 416 |
|
| 417 |
-
# Глобальная переменная для отслеживания обновлений
|
| 418 |
update_event = threading.Event()
|
| 419 |
|
| 420 |
@app.route('/')
|
|
@@ -460,7 +466,7 @@ def add_product():
|
|
| 460 |
'photo': photo_filename
|
| 461 |
})
|
| 462 |
save_data(data)
|
| 463 |
-
update_event.set()
|
| 464 |
return redirect("/")
|
| 465 |
except Exception as e:
|
| 466 |
logger.error(f"Ошибка при добавлении товара: {e}")
|
|
@@ -526,6 +532,10 @@ if __name__ == '__main__':
|
|
| 526 |
flask_thread = threading.Thread(target=run_flask, daemon=True)
|
| 527 |
flask_thread.start()
|
| 528 |
logger.info("Flask запущен")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 529 |
try:
|
| 530 |
asyncio.run(dp.start_polling(bot, on_startup=on_startup))
|
| 531 |
except KeyboardInterrupt:
|
|
|
|
| 51 |
try:
|
| 52 |
with open(DATA_FILE, 'w', encoding='utf-8') as f:
|
| 53 |
json.dump(data, f, ensure_ascii=False, indent=4)
|
| 54 |
+
# upload_db_to_hf() убрано отсюда
|
| 55 |
except Exception as e:
|
| 56 |
logger.error(f"Ошибка при сохранении данных: {e}")
|
| 57 |
|
|
|
|
| 85 |
logger.error(f"Ошибка при скачивании: {e}")
|
| 86 |
raise
|
| 87 |
|
| 88 |
+
# Периодическое копирование каждые 30 секунд
|
| 89 |
+
def start_periodic_backup():
|
| 90 |
+
def backup_loop():
|
| 91 |
+
upload_db_to_hf()
|
| 92 |
+
# Запускаем следующий вызов через 30 секунд
|
| 93 |
+
threading.Timer(30, backup_loop).start()
|
| 94 |
+
|
| 95 |
+
# Запускаем первый вызов
|
| 96 |
+
threading.Timer(30, backup_loop).start()
|
| 97 |
+
logger.info("Периодическое копирование каждые 30 секунд запущено")
|
| 98 |
+
|
| 99 |
# Загрузка данных
|
| 100 |
data = load_data()
|
| 101 |
|
|
|
|
| 132 |
return
|
| 133 |
await message.answer("Выберите категорию:", reply_markup=get_category_keyboard())
|
| 134 |
|
|
|
|
| 135 |
@dp.callback_query(F.data.startswith("cat_"))
|
| 136 |
async def show_products_in_category(callback_query: types.CallbackQuery):
|
| 137 |
try:
|
|
|
|
| 143 |
await bot.answer_callback_query(callback_query.id)
|
| 144 |
return
|
| 145 |
|
|
|
|
| 146 |
async def send_product_batch(products_batch):
|
| 147 |
for product in products_batch:
|
| 148 |
photo_url = f"https://huggingface.co/datasets/{REPO_ID}/resolve/main/photos/{product['photo']}" if product.get('photo') else None
|
|
|
|
| 156 |
logger.error(f"Ошибка при отправке: {e}")
|
| 157 |
await bot.send_message(callback_query.from_user.id, caption, reply_markup=get_product_keyboard(product['id']))
|
| 158 |
|
|
|
|
| 159 |
batch_size = 5
|
| 160 |
for i in range(0, len(products_in_cat), batch_size):
|
| 161 |
batch = products_in_cat[i:i + batch_size]
|
| 162 |
await send_product_batch(batch)
|
| 163 |
+
await asyncio.sleep(0.1)
|
| 164 |
|
| 165 |
await bot.answer_callback_query(callback_query.id)
|
| 166 |
except Exception as e:
|
|
|
|
| 244 |
response += f"\nИтого: {total} сом\nДата: {order['date']}"
|
| 245 |
await message.answer(response)
|
| 246 |
|
| 247 |
+
# Админ-панель
|
| 248 |
admin_html = """
|
| 249 |
<!DOCTYPE html>
|
| 250 |
<html>
|
|
|
|
| 395 |
</div>
|
| 396 |
</div>
|
| 397 |
<script>
|
|
|
|
| 398 |
const eventSource = new EventSource('/updates');
|
| 399 |
eventSource.onmessage = function(event) {
|
| 400 |
if (event.data === 'update') {
|
|
|
|
| 421 |
</html>
|
| 422 |
"""
|
| 423 |
|
|
|
|
| 424 |
update_event = threading.Event()
|
| 425 |
|
| 426 |
@app.route('/')
|
|
|
|
| 466 |
'photo': photo_filename
|
| 467 |
})
|
| 468 |
save_data(data)
|
| 469 |
+
update_event.set()
|
| 470 |
return redirect("/")
|
| 471 |
except Exception as e:
|
| 472 |
logger.error(f"Ошибка при добавлении товара: {e}")
|
|
|
|
| 532 |
flask_thread = threading.Thread(target=run_flask, daemon=True)
|
| 533 |
flask_thread.start()
|
| 534 |
logger.info("Flask запущен")
|
| 535 |
+
|
| 536 |
+
# Запуск периодического копирования
|
| 537 |
+
start_periodic_backup()
|
| 538 |
+
|
| 539 |
try:
|
| 540 |
asyncio.run(dp.start_polling(bot, on_startup=on_startup))
|
| 541 |
except KeyboardInterrupt:
|