flpolprojects commited on
Commit
fb3841b
·
verified ·
1 Parent(s): ae2aa5f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -98
app.py CHANGED
@@ -11,13 +11,13 @@ import threading
11
 
12
  # Настройка логирования
13
  logging.basicConfig(level=logging.INFO)
14
- logger = logging.getLogger(__name__) # Исправлено: Использование __name__
15
 
16
  # Инициализация бота и Flask
17
  BOT_TOKEN = '7734802681:AAGKHGG8O9uNk64JWTHH5yqXzvSxCcoLUdA'
18
  bot = Bot(token=BOT_TOKEN)
19
  dp = Dispatcher()
20
- app = Flask(__name__) # Исправлено: Использование __name__
21
 
22
  # Путь для хранения данных (товары и заказы)
23
  DATA_FILE = 'data.json'
@@ -67,8 +67,10 @@ async def show_products(message: types.Message):
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,7 +100,11 @@ async def add_to_cart(callback_query: types.CallbackQuery):
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,85 +139,59 @@ async def show_orders(message: types.Message):
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
- logger.info(f"Products: {data['products']}, Orders: {data['orders']}") # Логирование данных
214
- return render_template_string(admin_html, products=data['products'], orders=data['orders'])
215
  except Exception as e:
216
  logger.error(f"Ошибка в шаблоне: {e}")
217
  return "Ошибка сервера. Проверьте логи.", 500
@@ -219,15 +199,21 @@ def admin_panel():
219
  @app.route('/add_product', methods=['POST'])
220
  def add_product():
221
  try:
222
- if request.method == 'POST':
223
- logger.info("Adding new product")
224
- name = request.form['name']
225
- price = float(request.form['price'])
226
- description = request.form['description']
227
- product_id = max((p['id'] for p in data['products']), default=0) + 1
228
- data['products'].append({'id': product_id, 'name': name, 'price': price, 'description': description})
229
- save_data(data)
230
- return jsonify({'status': 'success'})
 
 
 
 
 
 
231
  except Exception as e:
232
  logger.error(f"Ошибка при добавлении товара: {e}")
233
  return jsonify({'status': 'error', 'message': str(e)}), 500
@@ -236,9 +222,14 @@ def add_product():
236
  def delete_product(product_id):
237
  try:
238
  logger.info(f"Deleting product with id={product_id}")
239
- data['products'] = [p for p in data['products'] if p['id'] != product_id]
 
 
 
240
  save_data(data)
 
241
  return jsonify({'status': 'success'})
 
242
  except Exception as e:
243
  logger.error(f"Ошибка при удалении товара: {e}")
244
  return jsonify({'status': 'error', 'message': str(e)}), 500
@@ -250,20 +241,23 @@ async def on_startup(_):
250
  def run_flask():
251
  try:
252
  logger.info("Starting Flask server on port 7860")
253
- app.run(host='0.0.0.0', port=7860)
254
- except Exception as e:
255
- logger.error(f"Ошибка в Flask: {e}")
 
 
 
256
 
257
  if __name__ == '__main__':
258
- # Создаём и запускаем поток для Flask
259
- flask_thread = threading.Thread(target=run_flask, daemon=True)
260
- flask_thread.start()
261
- logger.info("Flask thread started")
262
 
263
- # Запускаем бота в главном потоке
264
- try:
265
- asyncio.run(dp.start_polling(bot, on_startup=on_startup))
266
- except KeyboardInterrupt:
267
- logger.info("Stopping bot and Flask")
268
- finally:
269
- flask_thread.join() # Ждём завершения потока Flask при завершении программы
 
11
 
12
  # Настройка логирования
13
  logging.basicConfig(level=logging.INFO)
14
+ logger = logging.getLogger(__name__) # Используем __name__ для логгера
15
 
16
  # Инициализация бота и Flask
17
  BOT_TOKEN = '7734802681:AAGKHGG8O9uNk64JWTHH5yqXzvSxCcoLUdA'
18
  bot = Bot(token=BOT_TOKEN)
19
  dp = Dispatcher()
20
+ app = Flask(__name__)
21
 
22
  # Путь для хранения данных (товары и заказы)
23
  DATA_FILE = 'data.json'
 
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
  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
  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
 
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
  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
  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")
256
 
257
+ # Запускаем бота в главном потоке
258
+ try:
259
+ asyncio.run(dp.start_polling(bot, on_startup=on_startup))
260
+ except KeyboardInterrupt:
261
+ logger.info("Stopping bot and Flask")
262
+ finally:
263
+ flask_thread.join() # Ждем завершения потока Flask при завершении программы