Aleksmorshen commited on
Commit
e6e4cd6
·
verified ·
1 Parent(s): c3b4e1f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -30
app.py CHANGED
@@ -2,15 +2,25 @@ from flask import Flask, render_template_string, request, redirect, url_for
2
  import json
3
  import os
4
  import logging
 
 
 
 
5
 
6
  app = Flask(__name__)
7
  DATA_FILE = 'products.json'
8
 
 
 
 
 
 
9
  # Настройка логирования
10
  logging.basicConfig(level=logging.DEBUG)
11
 
12
- # Загрузка данных из JSON-файла
13
  def load_data():
 
14
  if os.path.exists(DATA_FILE):
15
  try:
16
  with open(DATA_FILE, 'r', encoding='utf-8') as file:
@@ -19,13 +29,12 @@ def load_data():
19
  logging.error("Ошибка: Невозможно декодировать JSON файл.")
20
  return []
21
  else:
22
- # Создание пустого файла, если его нет
23
  with open(DATA_FILE, 'w', encoding='utf-8') as file:
24
  json.dump([], file, ensure_ascii=False, indent=4)
25
  return []
26
 
27
- # Сохранение данных в JSON-файл
28
  def save_data(data):
 
29
  try:
30
  with open(DATA_FILE, 'w', encoding='utf-8') as file:
31
  json.dump(data, file, ensure_ascii=False, indent=4)
@@ -33,7 +42,45 @@ def save_data(data):
33
  logging.error(f"Ошибка при сохранении данных: {e}")
34
  raise
35
 
36
- # Главная страница каталога
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  @app.route('/')
38
  def catalog():
39
  products = load_data()
@@ -83,7 +130,6 @@ def catalog():
83
  '''
84
  return render_template_string(catalog_html, products=products)
85
 
86
- # Админ-панель для добавления товаров
87
  @app.route('/admin', methods=['GET', 'POST'])
88
  def admin():
89
  if request.method == 'POST':
@@ -95,13 +141,11 @@ def admin():
95
 
96
  if name and price and description:
97
  try:
98
- # Обработка запятой в числе
99
- price = float(price.replace(',', '.')) # Заменяем запятую на точку (если есть)
100
  except ValueError:
101
  logging.error("Ошибка: Цена должна быть числом.")
102
  return "Ошибка: Цена должна быть числом.", 400
103
 
104
- # Загрузка текущих данных
105
  products = load_data()
106
  products.append({
107
  'name': name,
@@ -109,7 +153,6 @@ def admin():
109
  'description': description
110
  })
111
 
112
- # Сохранение данных
113
  try:
114
  save_data(products)
115
  except Exception as e:
@@ -165,16 +208,6 @@ def admin():
165
  button:hover {
166
  background-color: #218838;
167
  }
168
- .product-list {
169
- margin-top: 20px;
170
- }
171
- .product-item {
172
- background-color: #fff;
173
- border: 1px solid #ddd;
174
- padding: 10px;
175
- margin-bottom: 10px;
176
- border-radius: 5px;
177
- }
178
  </style>
179
  </head>
180
  <body>
@@ -192,19 +225,37 @@ def admin():
192
  <button type="submit">Добавить товар</button>
193
  </form>
194
 
195
- <div class="product-list">
196
- <h2>Список товаров</h2>
197
- {% for product in products %}
198
- <div class="product-item">
199
- <strong>{{ product['name'] }}</strong> - {{ product['price'] }} руб.
200
- <p>{{ product['description'] }}</p>
201
- </div>
202
- {% endfor %}
203
- </div>
 
 
204
  </body>
205
  </html>
206
  '''
207
- return render_template_string(admin_html, products=products)
 
 
 
 
 
 
 
 
 
 
 
 
208
 
209
  if __name__ == '__main__':
210
- app.run(debug=True, host='0.0.0.0', port=7860)
 
 
 
 
 
2
  import json
3
  import os
4
  import logging
5
+ import threading
6
+ import time
7
+ from datetime import datetime
8
+ from huggingface_hub import HfApi, hf_hub_download
9
 
10
  app = Flask(__name__)
11
  DATA_FILE = 'products.json'
12
 
13
+ # --- Настройки Hugging Face ---
14
+ REPO_ID = "Testbase1/testsett" # Замените на ваш репозиторий
15
+ HF_TOKEN_WRITE = os.getenv("HF_TOKEN") # Токен для записи (загрузки)
16
+ HF_TOKEN_READ = os.getenv("HF_TOKEN_READ") # Токен для чтения (скачивания)
17
+
18
  # Настройка логирования
19
  logging.basicConfig(level=logging.DEBUG)
20
 
21
+ # --- Функции для работы с JSON ---
22
  def load_data():
23
+ """Загружает данные из JSON-файла."""
24
  if os.path.exists(DATA_FILE):
25
  try:
26
  with open(DATA_FILE, 'r', encoding='utf-8') as file:
 
29
  logging.error("Ошибка: Невозможно декодировать JSON файл.")
30
  return []
31
  else:
 
32
  with open(DATA_FILE, 'w', encoding='utf-8') as file:
33
  json.dump([], file, ensure_ascii=False, indent=4)
34
  return []
35
 
 
36
  def save_data(data):
37
+ """Сохраняет данные в JSON-файл."""
38
  try:
39
  with open(DATA_FILE, 'w', encoding='utf-8') as file:
40
  json.dump(data, file, ensure_ascii=False, indent=4)
 
42
  logging.error(f"Ошибка при сохранении данных: {e}")
43
  raise
44
 
45
+ # --- Функции для резервного копирования ---
46
+ def upload_db_to_hf():
47
+ """Загружает JSON-файл базы данных в репозиторий Hugging Face."""
48
+ try:
49
+ api = HfApi()
50
+ api.upload_file(
51
+ path_or_fileobj=DATA_FILE,
52
+ path_in_repo=DATA_FILE,
53
+ repo_id=REPO_ID,
54
+ repo_type="dataset",
55
+ token=HF_TOKEN_WRITE,
56
+ commit_message=f"Автоматическое резервное копирование базы данных {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
57
+ )
58
+ logging.info("Резервная копия JSON базы успешно загружена на Hugging Face.")
59
+ except Exception as e:
60
+ logging.error(f"Ошибка при загрузке резервной копии: {e}")
61
+
62
+ def download_db_from_hf():
63
+ """Скачивает JSON-файл базы данных из репозитория Hugging Face."""
64
+ try:
65
+ hf_hub_download(
66
+ repo_id=REPO_ID,
67
+ filename=DATA_FILE,
68
+ repo_type="dataset",
69
+ token=HF_TOKEN_READ,
70
+ local_dir=".",
71
+ local_dir_use_symlinks=False
72
+ )
73
+ logging.info("JSON база успешно скачана из Hugging Face.")
74
+ except Exception as e:
75
+ logging.error(f"Ошибка при скачивании JSON базы: {e}")
76
+
77
+ def periodic_backup():
78
+ """Периодически вызывает функцию upload_db_to_hf() каждые 100 секунд."""
79
+ while True:
80
+ upload_db_to_hf()
81
+ time.sleep(100)
82
+
83
+ # --- Маршруты приложения ---
84
  @app.route('/')
85
  def catalog():
86
  products = load_data()
 
130
  '''
131
  return render_template_string(catalog_html, products=products)
132
 
 
133
  @app.route('/admin', methods=['GET', 'POST'])
134
  def admin():
135
  if request.method == 'POST':
 
141
 
142
  if name and price and description:
143
  try:
144
+ price = float(price.replace(',', '.'))
 
145
  except ValueError:
146
  logging.error("Ошибка: Цена должна быть числом.")
147
  return "Ошибка: Цена должна быть числом.", 400
148
 
 
149
  products = load_data()
150
  products.append({
151
  'name': name,
 
153
  'description': description
154
  })
155
 
 
156
  try:
157
  save_data(products)
158
  except Exception as e:
 
208
  button:hover {
209
  background-color: #218838;
210
  }
 
 
 
 
 
 
 
 
 
 
211
  </style>
212
  </head>
213
  <body>
 
225
  <button type="submit">Добавить товар</button>
226
  </form>
227
 
228
+ <h2>Управление базой данных</h2>
229
+
230
+ <!-- Кнопки для резервной копии и скачивания -->
231
+ <form method="POST" action="{{ url_for('backup') }}">
232
+ <button type="submit">Создать резервную копию</button>
233
+ </form>
234
+
235
+ <form method="GET" action="{{ url_for('download') }}">
236
+ <button type="submit">Скачать базу данных</button>
237
+ </form>
238
+
239
  </body>
240
  </html>
241
  '''
242
+ return render_template_string(admin_html)
243
+
244
+ @app.route('/backup', methods=['POST'])
245
+ def backup():
246
+ """Маршрут для создания резервной копии."""
247
+ upload_db_to_hf()
248
+ return "Резервная копия успешно создана.", 200
249
+
250
+ @app.route('/download', methods=['GET'])
251
+ def download():
252
+ """Маршрут для скачивания базы данных."""
253
+ download_db_from_hf()
254
+ return "База данных успешно скачана.", 200
255
 
256
  if __name__ == '__main__':
257
+ # Запуск фонового потока для периодического резервного копирования
258
+ backup_thread = threading.Thread(target=periodic_backup, daemon=True)
259
+ backup_thread.start()
260
+
261
+ app.run(debug=True, host='0.0.0.0', port=7860)