Kgshop commited on
Commit
205bee1
·
verified ·
1 Parent(s): 370af8e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -12
app.py CHANGED
@@ -1,4 +1,4 @@
1
- from flask import Flask, render_template_string, request, redirect, url_for
2
  import json
3
  import os
4
  import logging
@@ -8,19 +8,23 @@ from datetime import datetime
8
  from huggingface_hub import HfApi, hf_hub_download
9
  from huggingface_hub.utils import RepositoryNotFoundError
10
  from werkzeug.utils import secure_filename
 
11
 
12
  app = Flask(__name__)
 
13
  DATA_FILE = 'data_lizabrand.json'
14
 
15
- # Настройки Hugging Face
16
  REPO_ID = "Kgshop/clients"
17
  HF_TOKEN_WRITE = os.getenv("HF_TOKEN")
18
  HF_TOKEN_READ = os.getenv("HF_TOKEN_READ")
19
 
20
- # Ссылка на логотип
 
 
 
 
21
  LOGO_URL = "https://cdn-avatars.huggingface.co/v1/production/uploads/67c280ccb9d3dfdee58ecfdd/hyc6QWsSZ6FejTAAqDGUS.jpeg"
22
 
23
- # Настройка логирования
24
  logging.basicConfig(level=logging.DEBUG)
25
 
26
  def load_data():
@@ -93,6 +97,64 @@ def periodic_backup():
93
  upload_db_to_hf()
94
  time.sleep(800)
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  @app.route('/')
97
  def catalog():
98
  data = load_data()
@@ -450,7 +512,6 @@ def catalog():
450
  </div>
451
  </div>
452
 
453
- <!-- Product Modal -->
454
  <div id="productModal" class="modal">
455
  <div class="modal-content">
456
  <span class="close" onclick="closeModal('productModal')">×</span>
@@ -458,7 +519,6 @@ def catalog():
458
  </div>
459
  </div>
460
 
461
- <!-- Quantity and Color Modal -->
462
  <div id="quantityModal" class="modal">
463
  <div class="modal-content">
464
  <span class="close" onclick="closeModal('quantityModal')">×</span>
@@ -469,7 +529,6 @@ def catalog():
469
  </div>
470
  </div>
471
 
472
- <!-- Cart Modal -->
473
  <div id="cartModal" class="modal">
474
  <div class="modal-content">
475
  <span class="close" onclick="closeModal('cartModal')">×</span>
@@ -719,6 +778,9 @@ def product_detail(index):
719
 
720
  @app.route('/admin', methods=['GET', 'POST'])
721
  def admin():
 
 
 
722
  data = load_data()
723
  products = data['products']
724
  categories = data['categories']
@@ -753,7 +815,7 @@ def admin():
753
  photos_list = []
754
 
755
  if photos_files:
756
- for photo in photos_files[:10]: # Ограничение до 10 фото
757
  if photo and photo.filename:
758
  photo_filename = secure_filename(photo.filename)
759
  uploads_dir = 'uploads'
@@ -800,7 +862,7 @@ def admin():
800
 
801
  if photos_files and any(photo.filename for photo in photos_files):
802
  new_photos_list = []
803
- for photo in photos_files[:10]: # Ограничение до 10 фото
804
  if photo and photo.filename:
805
  photo_filename = secure_filename(photo.filename)
806
  uploads_dir = 'uploads'
@@ -957,9 +1019,14 @@ def admin():
957
  </head>
958
  <body>
959
  <div class="container">
960
- <div class="header">
961
- <img src="''' + LOGO_URL + '''" alt="Logo" class="header-logo">
962
- <h1>Админ-панель</h1>
 
 
 
 
 
963
  </div>
964
  <h1>Добавление товара</h1>
965
  <form method="POST" enctype="multipart/form-data">
 
1
+ from flask import Flask, render_template_string, request, redirect, url_for, session
2
  import json
3
  import os
4
  import logging
 
8
  from huggingface_hub import HfApi, hf_hub_download
9
  from huggingface_hub.utils import RepositoryNotFoundError
10
  from werkzeug.utils import secure_filename
11
+ import requests
12
 
13
  app = Flask(__name__)
14
+ app.secret_key = os.getenv("FLASK_SECRET_KEY", "a_very_secret_key_for_development")
15
  DATA_FILE = 'data_lizabrand.json'
16
 
 
17
  REPO_ID = "Kgshop/clients"
18
  HF_TOKEN_WRITE = os.getenv("HF_TOKEN")
19
  HF_TOKEN_READ = os.getenv("HF_TOKEN_READ")
20
 
21
+ VK_APP_ID = os.getenv("VK_APP_ID")
22
+ VK_APP_SECRET = os.getenv("VK_APP_SECRET")
23
+ ADMIN_VK_IDS = os.getenv("ADMIN_VK_IDS", "").split(',')
24
+ REDIRECT_URI = "https://lizabrand-optom.hf.space/vk_callback"
25
+
26
  LOGO_URL = "https://cdn-avatars.huggingface.co/v1/production/uploads/67c280ccb9d3dfdee58ecfdd/hyc6QWsSZ6FejTAAqDGUS.jpeg"
27
 
 
28
  logging.basicConfig(level=logging.DEBUG)
29
 
30
  def load_data():
 
97
  upload_db_to_hf()
98
  time.sleep(800)
99
 
100
+ @app.route('/login')
101
+ def login():
102
+ if not VK_APP_ID:
103
+ return "VK_APP_ID не настроен на сервере.", 500
104
+ vk_auth_url = f"https://oauth.vk.com/authorize?client_id={VK_APP_ID}&display=page&redirect_uri={REDIRECT_URI}&scope=offline&response_type=code&v=5.131"
105
+ login_html = f'''
106
+ <!DOCTYPE html>
107
+ <html lang="ru">
108
+ <head>
109
+ <meta charset="UTF-8">
110
+ <title>Вход</title>
111
+ <style>
112
+ body {{ display: flex; justify-content: center; align-items: center; height: 100vh; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; background-color: #f0f2f5; }}
113
+ a {{ padding: 12px 24px; background-color: #4C75A3; color: white; text-decoration: none; border-radius: 8px; font-size: 16px; font-weight: 500; box-shadow: 0 2px 4px rgba(0,0,0,0.1); transition: background-color 0.2s; }}
114
+ a:hover {{ background-color: #456b92; }}
115
+ </style>
116
+ </head>
117
+ <body>
118
+ <a href="{vk_auth_url}">Войти через ВКонтакте</a>
119
+ </body>
120
+ </html>
121
+ '''
122
+ return render_template_string(login_html)
123
+
124
+ @app.route('/vk_callback')
125
+ def vk_callback():
126
+ code = request.args.get('code')
127
+ if not code:
128
+ return "Ошибка: код авторизации не получен.", 400
129
+ if not VK_APP_ID or not VK_APP_SECRET:
130
+ return "Учетные данные приложения VK не настроены на сервере.", 500
131
+
132
+ token_url = 'https://oauth.vk.com/access_token'
133
+ params = {
134
+ 'client_id': VK_APP_ID,
135
+ 'client_secret': VK_APP_SECRET,
136
+ 'redirect_uri': REDIRECT_URI,
137
+ 'code': code
138
+ }
139
+ try:
140
+ response = requests.get(token_url, params=params)
141
+ response.raise_for_status()
142
+ data = response.json()
143
+ except requests.RequestException as e:
144
+ return f"Сетевая ошибка при аутентификации: {e}", 500
145
+
146
+ if 'access_token' in data and 'user_id' in data:
147
+ session['vk_user_id'] = data['user_id']
148
+ return redirect(url_for('admin'))
149
+ else:
150
+ error_description = data.get('error_description', 'Неизвестная ошибка')
151
+ return f"Ошибка при аутентификации: {error_description}", 400
152
+
153
+ @app.route('/logout')
154
+ def logout():
155
+ session.pop('vk_user_id', None)
156
+ return redirect(url_for('catalog'))
157
+
158
  @app.route('/')
159
  def catalog():
160
  data = load_data()
 
512
  </div>
513
  </div>
514
 
 
515
  <div id="productModal" class="modal">
516
  <div class="modal-content">
517
  <span class="close" onclick="closeModal('productModal')">×</span>
 
519
  </div>
520
  </div>
521
 
 
522
  <div id="quantityModal" class="modal">
523
  <div class="modal-content">
524
  <span class="close" onclick="closeModal('quantityModal')">×</span>
 
529
  </div>
530
  </div>
531
 
 
532
  <div id="cartModal" class="modal">
533
  <div class="modal-content">
534
  <span class="close" onclick="closeModal('cartModal')">×</span>
 
778
 
779
  @app.route('/admin', methods=['GET', 'POST'])
780
  def admin():
781
+ if 'vk_user_id' not in session or str(session.get('vk_user_id')) not in ADMIN_VK_IDS:
782
+ return redirect(url_for('login'))
783
+
784
  data = load_data()
785
  products = data['products']
786
  categories = data['categories']
 
815
  photos_list = []
816
 
817
  if photos_files:
818
+ for photo in photos_files[:10]:
819
  if photo and photo.filename:
820
  photo_filename = secure_filename(photo.filename)
821
  uploads_dir = 'uploads'
 
862
 
863
  if photos_files and any(photo.filename for photo in photos_files):
864
  new_photos_list = []
865
+ for photo in photos_files[:10]:
866
  if photo and photo.filename:
867
  photo_filename = secure_filename(photo.filename)
868
  uploads_dir = 'uploads'
 
1019
  </head>
1020
  <body>
1021
  <div class="container">
1022
+ <div class="header" style="justify-content: space-between;">
1023
+ <div style="display: flex; align-items: center;">
1024
+ <img src="''' + LOGO_URL + '''" alt="Logo" class="header-logo">
1025
+ <h1 style="margin-bottom: 0;">Админ-панель</h1>
1026
+ </div>
1027
+ <a href="{{ url_for('logout') }}" style="text-decoration: none;">
1028
+ <button type="button" class="delete-button" style="margin-top: 0;">Выйти</button>
1029
+ </a>
1030
  </div>
1031
  <h1>Добавление товара</h1>
1032
  <form method="POST" enctype="multipart/form-data">