Kgshop commited on
Commit
b939cf6
·
verified ·
1 Parent(s): 4fd35fd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -13
app.py CHANGED
@@ -13,12 +13,12 @@ app = Flask(__name__)
13
  DATA_FILE = 'data_udeda.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://huggingface.co/spaces/Udeda/tkani/resolve/main/Picsart_25-03-18_13-31-30-910.jpg"
22
 
23
  # Настройка логирования
24
  logging.basicConfig(level=logging.DEBUG)
@@ -29,6 +29,12 @@ def load_data():
29
  with open(DATA_FILE, 'r', encoding='utf-8') as file:
30
  data = json.load(file)
31
  logging.info("Данные успешно загружены из JSON")
 
 
 
 
 
 
32
  if not isinstance(data, dict) or 'products' not in data or 'categories' not in data:
33
  return {'products': [], 'categories': [] if not isinstance(data, list) else data}
34
  return data
@@ -535,7 +541,7 @@ def catalog():
535
  zoom: { maxRatio: 3 }
536
  });
537
  }
538
-
539
  function openQuantityModal(index) {
540
  selectedProductIndex = index;
541
  const product = products[index];
@@ -562,12 +568,20 @@ def catalog():
562
  if (selectedProductIndex === null) return;
563
  const quantity = parseInt(document.getElementById('quantityInput').value) || 1;
564
  const color = document.getElementById('colorSelect').value;
 
 
 
 
 
 
 
 
565
  if (quantity <= 0) {
566
  alert("Укажите количество больше 0");
567
  return;
568
  }
569
  let cart = JSON.parse(localStorage.getItem('cart') || '[]');
570
- const product = products[selectedProductIndex];
571
  const cartItemId = `${product.name}-${color}`;
572
  const existingItem = cart.find(item => item.id === cartItemId);
573
 
@@ -580,7 +594,8 @@ def catalog():
580
  price: product.price,
581
  photo: product.photos && product.photos.length > 0 ? product.photos[0] : '',
582
  quantity: quantity,
583
- color: color
 
584
  });
585
  }
586
 
@@ -609,6 +624,7 @@ def catalog():
609
  <div>
610
  <strong>${item.name}</strong>
611
  <p>$${item.price} × ${item.quantity} (Цвет: ${item.color})</p>
 
612
  </div>
613
  </div>
614
  <span>$${itemTotal}</span>
@@ -631,10 +647,10 @@ def catalog():
631
  cart.forEach((item, index) => {
632
  const itemTotal = item.price * item.quantity;
633
  total += itemTotal;
634
- orderText += `${index + 1}. ${item.name} - $${item.price} × ${item.quantity} (Цвет: ${item.color})%0A`;
635
  });
636
  orderText += `Итого: $${total}`;
637
- window.open(`https://api.whatsapp.com/send?phone=996703763333&text=${orderText}`, '_blank');
638
  }
639
 
640
  function clearCart() {
@@ -711,8 +727,9 @@ def product_detail(index):
711
  </div>
712
  <p><strong>Категория:</strong> {{ product.get('category', 'Без категории') }}</p>
713
  <p><strong>Цена:</strong> ${{ product['price'] }}</p>
714
- <p><strong>Описание:</strong> {{ product['description'] }}</p>
715
  <p><strong>Доступные цвета:</strong> {{ product.get('colors', ['Нет цветов'])|join(', ') }}</p>
 
716
  </div>
717
  '''
718
  return render_template_string(detail_html, product=product, repo_id=REPO_ID)
@@ -750,6 +767,7 @@ def admin():
750
  category = request.form.get('category')
751
  photos_files = request.files.getlist('photos')
752
  colors = request.form.getlist('colors')
 
753
  photos_list = []
754
 
755
  if photos_files:
@@ -758,6 +776,7 @@ def admin():
758
  photo_filename = secure_filename(photo.filename)
759
  uploads_dir = 'uploads'
760
  os.makedirs(uploads_dir, exist_ok=True)
 
761
  temp_path = os.path.join(uploads_dir, photo_filename)
762
  photo.save(temp_path)
763
  api = HfApi()
@@ -773,17 +792,23 @@ def admin():
773
  if os.path.exists(temp_path):
774
  os.remove(temp_path)
775
 
776
- if not name or not price or not description:
777
  return "Ошибка: Заполните все обязательные поля", 400
778
 
779
  price = float(price.replace(',', '.'))
 
 
 
 
 
780
  new_product = {
781
  'name': name,
782
  'price': price,
783
  'description': description,
784
  'category': category if category in categories else 'Без категории',
785
  'photos': photos_list,
786
- 'colors': colors if colors else []
 
787
  }
788
  products.append(new_product)
789
  save_data(data)
@@ -797,6 +822,7 @@ def admin():
797
  category = request.form.get('category')
798
  photos_files = request.files.getlist('photos')
799
  colors = request.form.getlist('colors')
 
800
 
801
  if photos_files and any(photo.filename for photo in photos_files):
802
  new_photos_list = []
@@ -820,12 +846,21 @@ def admin():
820
  if os.path.exists(temp_path):
821
  os.remove(temp_path)
822
  products[index]['photos'] = new_photos_list
 
 
 
 
 
 
 
 
823
 
824
  products[index]['name'] = name
825
  products[index]['price'] = float(price.replace(',', '.'))
826
  products[index]['description'] = description
827
  products[index]['category'] = category if category in categories else 'Без категории'
828
  products[index]['colors'] = colors if colors else []
 
829
  save_data(data)
830
  return redirect(url_for('admin'))
831
 
@@ -968,7 +1003,7 @@ def admin():
968
  <input type="text" name="name" required>
969
  <label>Цена ($):</label>
970
  <input type="number" name="price" step="0.01" required>
971
- <label>Описание:</label>
972
  <textarea name="description" rows="4" required></textarea>
973
  <label>Категория:</label>
974
  <select name="category">
@@ -986,6 +1021,8 @@ def admin():
986
  </div>
987
  </div>
988
  <button type="button" class="add-color-btn" onclick="addColorInput()">Добавить цвет</button>
 
 
989
  <button type="submit">Добавить товар</button>
990
  </form>
991
 
@@ -1026,8 +1063,9 @@ def admin():
1026
  <h3>{{ product['name'] }}</h3>
1027
  <p><strong>Категория:</strong> {{ product.get('category', 'Без категории') }}</p>
1028
  <p><strong>Цена:</strong> ${{ product['price'] }}</p>
1029
- <p><strong>Описание:</strong> {{ product['description'] }}</p>
1030
  <p><strong>Цвета:</strong> {{ product.get('colors', ['Нет цветов'])|join(', ') }}</p>
 
1031
  {% if product.get('photos') and product['photos']|length > 0 %}
1032
  <div style="display: flex; flex-wrap: wrap; gap: 10px;">
1033
  {% for photo in product['photos'] %}
@@ -1046,7 +1084,7 @@ def admin():
1046
  <input type="text" name="name" value="{{ product['name'] }}" required>
1047
  <label>Цена ($):</label>
1048
  <input type="number" name="price" step="0.01" value="{{ product['price'] }}" required>
1049
- <label>Описание:</label>
1050
  <textarea name="description" rows="4" required>{{ product['description'] }}</textarea>
1051
  <label>Категория:</label>
1052
  <select name="category">
@@ -1066,6 +1104,8 @@ def admin():
1066
  {% endfor %}
1067
  </div>
1068
  <button type="button" class="add-color-btn" onclick="addColorInput('edit-color-inputs-{{ loop.index0 }}')">Добавить цвет</button>
 
 
1069
  <button type="submit">Сохранить</button>
1070
  </form>
1071
  </details>
 
13
  DATA_FILE = 'data_udeda.json'
14
 
15
  # Настройки Hugging Face
16
+ REPO_ID = "Kgshop/clients" # Замените на ваш ID репозитория
17
  HF_TOKEN_WRITE = os.getenv("HF_TOKEN")
18
  HF_TOKEN_READ = os.getenv("HF_TOKEN_READ")
19
 
20
  # Ссылка на логотип
21
+ LOGO_URL = "https://huggingface.co/spaces/Udeda/tkani/resolve/main/Picsart_25-03-18_13-31-30-910.jpg" # Замените на вашу ссылку
22
 
23
  # Настройка логирования
24
  logging.basicConfig(level=logging.DEBUG)
 
29
  with open(DATA_FILE, 'r', encoding='utf-8') as file:
30
  data = json.load(file)
31
  logging.info("Данные успешно загружены из JSON")
32
+ # Добавим проверку наличия roll_meters, если его нет - проинициализируем
33
+ if isinstance(data, dict) and 'products' in data:
34
+ for product in data['products']:
35
+ if 'roll_meters' not in product:
36
+ product['roll_meters'] = 0 # Или другое значение по умолчанию
37
+
38
  if not isinstance(data, dict) or 'products' not in data or 'categories' not in data:
39
  return {'products': [], 'categories': [] if not isinstance(data, list) else data}
40
  return data
 
541
  zoom: { maxRatio: 3 }
542
  });
543
  }
544
+
545
  function openQuantityModal(index) {
546
  selectedProductIndex = index;
547
  const product = products[index];
 
568
  if (selectedProductIndex === null) return;
569
  const quantity = parseInt(document.getElementById('quantityInput').value) || 1;
570
  const color = document.getElementById('colorSelect').value;
571
+ const product = products[selectedProductIndex];
572
+
573
+ // Проверка на минимальное количество метров (roll_meters)
574
+ if (quantity < product.roll_meters) {
575
+ alert(`Минимальный заказ для этого товара: ${product.roll_meters} метров.`);
576
+ return;
577
+ }
578
+
579
  if (quantity <= 0) {
580
  alert("Укажите количество больше 0");
581
  return;
582
  }
583
  let cart = JSON.parse(localStorage.getItem('cart') || '[]');
584
+
585
  const cartItemId = `${product.name}-${color}`;
586
  const existingItem = cart.find(item => item.id === cartItemId);
587
 
 
594
  price: product.price,
595
  photo: product.photos && product.photos.length > 0 ? product.photos[0] : '',
596
  quantity: quantity,
597
+ color: color,
598
+ roll_meters: product.roll_meters // Добавляем roll_meters в корзину
599
  });
600
  }
601
 
 
624
  <div>
625
  <strong>${item.name}</strong>
626
  <p>$${item.price} × ${item.quantity} (Цвет: ${item.color})</p>
627
+ <p>Метров в рулоне: ${item.roll_meters}</p>
628
  </div>
629
  </div>
630
  <span>$${itemTotal}</span>
 
647
  cart.forEach((item, index) => {
648
  const itemTotal = item.price * item.quantity;
649
  total += itemTotal;
650
+ orderText += `${index + 1}. ${item.name} - $${item.price} × ${item.quantity} (Цвет: ${item.color}, Метров в рулоне: ${item.roll_meters})%0A`;
651
  });
652
  orderText += `Итого: $${total}`;
653
+ window.open(`https://api.whatsapp.com/send?phone=996775581999&text=${orderText}`, '_blank');
654
  }
655
 
656
  function clearCart() {
 
727
  </div>
728
  <p><strong>Категория:</strong> {{ product.get('category', 'Без категории') }}</p>
729
  <p><strong>Цена:</strong> ${{ product['price'] }}</p>
730
+ <p><strong>Состав:</strong> {{ product['description'] }}</p>
731
  <p><strong>Доступные цвета:</strong> {{ product.get('colors', ['Нет цветов'])|join(', ') }}</p>
732
+ <p><strong>Метров в рулоне:</strong> {{ product.get('roll_meters', 'Не указано') }}</p>
733
  </div>
734
  '''
735
  return render_template_string(detail_html, product=product, repo_id=REPO_ID)
 
767
  category = request.form.get('category')
768
  photos_files = request.files.getlist('photos')
769
  colors = request.form.getlist('colors')
770
+ roll_meters = request.form.get('roll_meters') # Получаем roll_meters
771
  photos_list = []
772
 
773
  if photos_files:
 
776
  photo_filename = secure_filename(photo.filename)
777
  uploads_dir = 'uploads'
778
  os.makedirs(uploads_dir, exist_ok=True)
779
+
780
  temp_path = os.path.join(uploads_dir, photo_filename)
781
  photo.save(temp_path)
782
  api = HfApi()
 
792
  if os.path.exists(temp_path):
793
  os.remove(temp_path)
794
 
795
+ if not name or not price or not description or not roll_meters:
796
  return "Ошибка: Заполните все обязательные поля", 400
797
 
798
  price = float(price.replace(',', '.'))
799
+ try:
800
+ roll_meters = int(roll_meters)
801
+ except ValueError:
802
+ return "Ошибка: Количество метров в рулоне должно быть целым числом", 400
803
+
804
  new_product = {
805
  'name': name,
806
  'price': price,
807
  'description': description,
808
  'category': category if category in categories else 'Без категории',
809
  'photos': photos_list,
810
+ 'colors': colors if colors else [],
811
+ 'roll_meters': roll_meters # Добавляем roll_meters в продукт
812
  }
813
  products.append(new_product)
814
  save_data(data)
 
822
  category = request.form.get('category')
823
  photos_files = request.files.getlist('photos')
824
  colors = request.form.getlist('colors')
825
+ roll_meters = request.form.get('roll_meters') # Добавляем roll_meters
826
 
827
  if photos_files and any(photo.filename for photo in photos_files):
828
  new_photos_list = []
 
846
  if os.path.exists(temp_path):
847
  os.remove(temp_path)
848
  products[index]['photos'] = new_photos_list
849
+
850
+ if not roll_meters:
851
+ return "Ошибка: Укажите количество метров в рулоне", 400
852
+
853
+ try:
854
+ roll_meters = int(roll_meters)
855
+ except ValueError:
856
+ return "Ошибка: Количество метров в рулоне должно быть целым числом", 400
857
 
858
  products[index]['name'] = name
859
  products[index]['price'] = float(price.replace(',', '.'))
860
  products[index]['description'] = description
861
  products[index]['category'] = category if category in categories else 'Без категории'
862
  products[index]['colors'] = colors if colors else []
863
+ products[index]['roll_meters'] = roll_meters # Обновляем roll_meters
864
  save_data(data)
865
  return redirect(url_for('admin'))
866
 
 
1003
  <input type="text" name="name" required>
1004
  <label>Цена ($):</label>
1005
  <input type="number" name="price" step="0.01" required>
1006
+ <label>Состав:</label>
1007
  <textarea name="description" rows="4" required></textarea>
1008
  <label>Категория:</label>
1009
  <select name="category">
 
1021
  </div>
1022
  </div>
1023
  <button type="button" class="add-color-btn" onclick="addColorInput()">Добавить цвет</button>
1024
+ <label>Метров в рулоне:</label>
1025
+ <input type="number" name="roll_meters" required>
1026
  <button type="submit">Добавить товар</button>
1027
  </form>
1028
 
 
1063
  <h3>{{ product['name'] }}</h3>
1064
  <p><strong>Категория:</strong> {{ product.get('category', 'Без категории') }}</p>
1065
  <p><strong>Цена:</strong> ${{ product['price'] }}</p>
1066
+ <p><strong>Состав:</strong> {{ product['description'] }}</p>
1067
  <p><strong>Цвета:</strong> {{ product.get('colors', ['Нет цветов'])|join(', ') }}</p>
1068
+ <p><strong>Метров в рулоне:</strong> {{ product.get('roll_meters', 'Не указано') }}</p>
1069
  {% if product.get('photos') and product['photos']|length > 0 %}
1070
  <div style="display: flex; flex-wrap: wrap; gap: 10px;">
1071
  {% for photo in product['photos'] %}
 
1084
  <input type="text" name="name" value="{{ product['name'] }}" required>
1085
  <label>Цена ($):</label>
1086
  <input type="number" name="price" step="0.01" value="{{ product['price'] }}" required>
1087
+ <label>Состав:</label>
1088
  <textarea name="description" rows="4" required>{{ product['description'] }}</textarea>
1089
  <label>Категория:</label>
1090
  <select name="category">
 
1104
  {% endfor %}
1105
  </div>
1106
  <button type="button" class="add-color-btn" onclick="addColorInput('edit-color-inputs-{{ loop.index0 }}')">Добавить цвет</button>
1107
+ <label>Метров в рулоне:</label>
1108
+ <input type="number" name="roll_meters" value="{{ product.get('roll_meters', '') }}" required>
1109
  <button type="submit">Сохранить</button>
1110
  </form>
1111
  </details>