flpolprojects commited on
Commit
75f90e3
·
verified ·
1 Parent(s): a8bc99d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +85 -80
app.py CHANGED
@@ -11,7 +11,7 @@ import threading
11
 
12
  # Настройка логирования
13
  logging.basicConfig(level=logging.INFO)
14
- logger = logging.getLogger(__name__) # Используем __name__ для логгера
15
 
16
  # Инициализация бота и Flask
17
  BOT_TOKEN = '7734802681:AAGKHGG8O9uNk64JWTHH5yqXzvSxCcoLUdA'
@@ -67,10 +67,8 @@ async def show_products(message: types.Message):
67
  await message.answer("Нет доступных товаров.")
68
  return
69
  for product in data['products']:
70
- await message.answer(
71
- f"🏷 {product['name']} - {product['price']} руб.\nОписание: {product['description']}\n/id: {product['id']}",
72
- reply_markup=get_product_keyboard(product['id'])
73
- )
74
 
75
  @dp.message(F.text == "🛒 Корзина")
76
  async def show_cart(message: types.Message):
@@ -100,11 +98,7 @@ async def add_to_cart(callback_query: types.CallbackQuery):
100
  if not cart:
101
  cart = {'user_id': user_id, 'items': [], 'completed': False, 'date': datetime.now().isoformat()}
102
  data['orders'].append(cart)
103
- cart_item = next((item for item in cart['items'] if item['product_id'] == product_id), None)
104
- if cart_item:
105
- cart_item['quantity'] += 1
106
- else:
107
- cart['items'].append({'product_id': product_id, 'quantity': 1})
108
  save_data(data)
109
  await bot.answer_callback_query(callback_query.id, "Товар добавлен в корзину!")
110
  else:
@@ -139,81 +133,100 @@ async def show_orders(message: types.Message):
139
  response += f"\nИтого: {total} руб.\nДата: {order['date']}"
140
  await message.answer(response)
141
 
142
- # Админ-панель (Flask) с HTML-шаблоном
143
  admin_html = """
144
  <!DOCTYPE html>
145
  <html>
146
  <head>
147
- <title>Админ-панель</title>
148
- <style>
149
- body { font-family: Arial; background-color: #f0f0f0; margin: 20px; }
150
- .container { max-width: 800px; margin: auto; }
151
- .product { border: 1px solid #ccc; padding: 10px; margin-bottom: 10px; background-color: #fff; }
152
- </style>
 
 
 
 
153
  </head>
154
  <body>
155
- <div class="container">
156
- <h1>Управление товарами</h1>
157
- <form id="addProductForm">
158
- <input type="text" name="name" placeholder="Название" required><br>
159
- <input type="number" name="price" placeholder="Цена" required><br>
160
- <textarea name="description" placeholder="Описание"></textarea><br>
161
- <button type="submit">Добавить товар</button>
162
- </form>
163
- <h2>Существующие товары</h2>
164
- {% for product in products %}
165
- <div class="product">
166
- <b>{{ product.name }}</b> - {{ product.price }}<br>{{ product.description }}
167
- <button onclick="deleteProduct({{ product.id }})">Удалить</button>
168
- </div>
169
- {% endfor %}
170
- <h2>Заказы</h2>
171
- {% for order in orders %}
172
- <div class="product">
173
- <b>Пользователь:</b> {{ order.user_id }}<br><b>Дата:</b> {{ order.date }}
174
- <ul>{% for item in order.items %} <li>{{ item.quantity }}</li>{% endfor %}</ul></div>{% endfor %}
175
- <script>
176
- // JS для добавления/удаления товаров.
177
- async function deleteProduct(productId) {
178
- const response = await fetch(`/delete_product/${productId}`, { method: 'POST' });
179
- if (response.ok) window.location.reload();
180
- }
181
- document.getElementById('addProductForm').onsubmit = async (e) => {
182
- e.preventDefault();
183
- const formData = new FormData(e.target);
184
- const response = await fetch('/add_product', { method: 'POST', body=formData });
185
- if (response.ok) window.location.reload();
186
- };
187
- </script>
188
- </div></body></html>"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
 
190
  @app.route('/')
191
  def admin_panel():
192
  try:
193
- logger.info(f"Products: {data.get('products')}, Orders: {data.get('orders')}")
194
- return render_template_string(admin_html, products=data.get('products', []), orders=data.get('orders', []))
195
  except Exception as e:
196
  logger.error(f"Ошибка в шаблоне: {e}")
197
- return "Ошибка сервера. Проверьте логи.", 500
198
 
199
  @app.route('/add_product', methods=['POST'])
200
  def add_product():
201
  try:
202
- logger.info("Adding new product")
203
- name = request.form.get('name')
204
- price = float(request.form.get('price'))
205
- description = request.form.get('description')
206
-
207
- # Генерация нового ID для продукта
208
- product_id = max((p['id'] for p in data.get('products', [])), default=0) + 1
209
-
210
- # Добавление продукта в данные и сохранение
211
- data.setdefault('products', []).append({'id': product_id, 'name': name, 'price': price, 'description': description})
212
-
213
- save_data(data)
214
-
215
- return jsonify({'status': 'success'})
216
-
217
  except Exception as e:
218
  logger.error(f"Ошибка при добавлении товара: {e}")
219
  return jsonify({'status': 'error', 'message': str(e)}), 500
@@ -222,14 +235,9 @@ def add_product():
222
  def delete_product(product_id):
223
  try:
224
  logger.info(f"Deleting product with id={product_id}")
225
-
226
- # Удаление продукта из данных и сохранение
227
- data['products'] = [p for p in data.get('products', []) if p['id'] != product_id]
228
-
229
  save_data(data)
230
-
231
  return jsonify({'status': 'success'})
232
-
233
  except Exception as e:
234
  logger.error(f"Ошибка при удалении товара: {e}")
235
  return jsonify({'status': 'error', 'message': str(e)}), 500
@@ -241,15 +249,12 @@ async def on_startup(_):
241
  def run_flask():
242
  try:
243
  logger.info("Starting Flask server on port 7860")
244
-
245
- # Запуск Flask приложения
246
  app.run(host='0.0.0.0', port=7860)
247
-
248
  except Exception as e:
249
  logger.error(f"Ошибка в Flask: {e}")
250
 
251
  if __name__ == '__main__':
252
- # Создаем и запускаем поток для Flask
253
  flask_thread = threading.Thread(target=run_flask, daemon=True)
254
  flask_thread.start()
255
  logger.info("Flask thread started")
@@ -260,4 +265,4 @@ if __name__ == '__main__':
260
  except KeyboardInterrupt:
261
  logger.info("Stopping bot and Flask")
262
  finally:
263
- flask_thread.join() # Ждем завершения потока Flask при завершении программы
 
11
 
12
  # Настройка логирования
13
  logging.basicConfig(level=logging.INFO)
14
+ logger = logging.getLogger(__name__)
15
 
16
  # Инициализация бота и Flask
17
  BOT_TOKEN = '7734802681:AAGKHGG8O9uNk64JWTHH5yqXzvSxCcoLUdA'
 
67
  await message.answer("Нет доступных товаров.")
68
  return
69
  for product in data['products']:
70
+ await message.answer(f"🏷 {product['name']} - {product['price']} руб.\nОписание: {product['description']}\n/id: {product['id']}",
71
+ reply_markup=get_product_keyboard(product['id']))
 
 
72
 
73
  @dp.message(F.text == "🛒 Корзина")
74
  async def show_cart(message: types.Message):
 
98
  if not cart:
99
  cart = {'user_id': user_id, 'items': [], 'completed': False, 'date': datetime.now().isoformat()}
100
  data['orders'].append(cart)
101
+ cart['items'].append({'product_id': product_id, 'quantity': 1})
 
 
 
 
102
  save_data(data)
103
  await bot.answer_callback_query(callback_query.id, "Товар добавлен в корзину!")
104
  else:
 
133
  response += f"\nИтого: {total} руб.\nДата: {order['date']}"
134
  await message.answer(response)
135
 
136
+ # Админ-панель (Flask) с HTML, CSS и JavaScript в строке
137
  admin_html = """
138
  <!DOCTYPE html>
139
  <html>
140
  <head>
141
+ <title>Админ-панель</title>
142
+ <style>
143
+ body { font-family: Arial, sans-serif; margin: 20px; background-color: #f0f0f0; }
144
+ .container { max-width: 800px; margin: 0 auto; }
145
+ .product { border: 1px solid #ccc; padding: 15px; margin: 10px 0; background-color: #fff; border-radius: 5px; }
146
+ form { background-color: #fff; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
147
+ input, textarea { width: 100%; margin: 5px 0; padding: 8px; }
148
+ button { background-color: #4CAF50; color: white; padding: 10px 15px; border: none; border-radius: 5px; cursor: pointer; }
149
+ button:hover { background-color: #45a049; }
150
+ </style>
151
  </head>
152
  <body>
153
+ <div class="container">
154
+ <h1>Управление товарами</h1>
155
+ <form id="addProductForm">
156
+ <input type="text" name="name" placeholder="Название" required><br>
157
+ <input type="number" name="price" placeholder="Цена" step="0.01" required><br>
158
+ <textarea name="description" placeholder="Описание" required></textarea><br>
159
+ <button type="submit">Добавить товар</button>
160
+ </form>
161
+ <h2>Существующие товары</h2>
162
+ {% if products %}
163
+ {% for product in products %}
164
+ <div class="product">
165
+ {{ product.name }} - {{ product.price }} руб.<br>
166
+ {{ product.description }}<br>
167
+ <button onclick="deleteProduct({{ product.id }})">Удалить</button>
168
+ </div>
169
+ {% endfor %}
170
+ {% else %}
171
+ <p>Нет товаров.</p>
172
+ {% endif %}
173
+ <h2>Заказы</h2>
174
+ {% if orders %}
175
+ {% for order in orders %}
176
+ <div class="product">
177
+ Пользователь: {{ order.user_id }}<br>
178
+ Дата: {{ order.date }}<br>
179
+ Товары:
180
+ {% for item in order.items %}
181
+ {% for product in products %}
182
+ {% if product.id == item.product_id %}
183
+ {{ item.quantity }} x {{ product.name }}<br>
184
+ {% endif %}
185
+ {% endfor %}
186
+ {% endfor %}
187
+ </div>
188
+ {% endfor %}
189
+ {% else %}
190
+ <p>Нет заказов.</p>
191
+ {% endif %}
192
+ </div>
193
+ <script>
194
+ document.getElementById('addProductForm').onsubmit = async (e) => {
195
+ e.preventDefault();
196
+ const formData = new FormData(e.target);
197
+ const response = await fetch('/add_product', { method: 'POST', body: formData });
198
+ if (response.ok) window.location.reload();
199
+ };
200
+ async function deleteProduct(productId) {
201
+ const response = await fetch(`/delete_product/${productId}`, { method: 'POST' });
202
+ if (response.ok) window.location.reload();
203
+ }
204
+ </script>
205
+ </body>
206
+ </html>
207
+ """
208
 
209
  @app.route('/')
210
  def admin_panel():
211
  try:
212
+ logger.info("Rendering admin panel with products and orders")
213
+ return render_template_string(admin_html, products=data['products'], orders=data['orders'])
214
  except Exception as e:
215
  logger.error(f"Ошибка в шаблоне: {e}")
216
+ return "Ошибка сервера. Проверь логи.", 500
217
 
218
  @app.route('/add_product', methods=['POST'])
219
  def add_product():
220
  try:
221
+ if request.method == 'POST':
222
+ logger.info("Adding new product")
223
+ name = request.form['name']
224
+ price = float(request.form['price'])
225
+ description = request.form['description']
226
+ product_id = max((p['id'] for p in data['products']), default=0) + 1
227
+ data['products'].append({'id': product_id, 'name': name, 'price': price, 'description': description})
228
+ save_data(data)
229
+ return jsonify({'status': 'success'})
 
 
 
 
 
 
230
  except Exception as e:
231
  logger.error(f"Ошибка при добавлении товара: {e}")
232
  return jsonify({'status': 'error', 'message': str(e)}), 500
 
235
  def delete_product(product_id):
236
  try:
237
  logger.info(f"Deleting product with id={product_id}")
238
+ data['products'] = [p for p in data['products'] if p['id'] != product_id]
 
 
 
239
  save_data(data)
 
240
  return jsonify({'status': 'success'})
 
241
  except Exception as e:
242
  logger.error(f"Ошибка при удалении товара: {e}")
243
  return jsonify({'status': 'error', 'message': str(e)}), 500
 
249
  def run_flask():
250
  try:
251
  logger.info("Starting Flask server on port 7860")
 
 
252
  app.run(host='0.0.0.0', port=7860)
 
253
  except Exception as e:
254
  logger.error(f"Ошибка в Flask: {e}")
255
 
256
  if __name__ == '__main__':
257
+ # Создаём и запускаем поток для Flask
258
  flask_thread = threading.Thread(target=run_flask, daemon=True)
259
  flask_thread.start()
260
  logger.info("Flask thread started")
 
265
  except KeyboardInterrupt:
266
  logger.info("Stopping bot and Flask")
267
  finally:
268
+ flask_thread.join() # Ждём завершения потока Flask при завершении программы