from flask import Flask, render_template_string, request, redirect, url_for
import json
import os
import logging
import threading
import time
from datetime import datetime
import zoneinfo
from huggingface_hub import HfApi, hf_hub_download
from huggingface_hub.utils import RepositoryNotFoundError
app = Flask(__name__)
DATA_FILE = 'data_fabrics.json'
REPO_ID = "Kgshop/Konka"
HF_TOKEN_WRITE = os.getenv("HF_TOKEN")
HF_TOKEN_READ = os.getenv("HF_TOKEN_READ")
logging.basicConfig(level=logging.ERROR)
def get_almaty_time():
return datetime.now(zoneinfo.ZoneInfo("Asia/Almaty")).strftime('%d.%m.%Y %H:%M:%S')
def load_data():
try:
download_db_from_hf()
with open(DATA_FILE, 'r', encoding='utf-8') as file:
data = json.load(file)
if not isinstance(data, dict):
data = {'products': [], 'history': []}
if 'products' not in data:
data['products'] = []
if 'history' not in data:
data['history'] = []
for p in data['products']:
if 'category' in p: del p['category']
if 'price' in p: del p['price']
if 'wholesale_price' in p: del p['wholesale_price']
if 'min_wholesale' in p: del p['min_wholesale']
if 'discount' in p: del p['discount']
if 'photos' in p: del p['photos']
for c in p.get('colors', []):
wr = c.get('warehouse_rolls', c.get('rolls', 0))
c['warehouse_rolls'] = wr
c['shop_rolls'] = c.get('shop_rolls', 0)
if 'rolls' in c: del c['rolls']
return data
except Exception:
return {'products': [], 'history': []}
def save_data(data):
try:
with open(DATA_FILE, 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
upload_db_to_hf()
except Exception:
pass
def upload_db_to_hf():
try:
api = HfApi()
api.upload_file(
path_or_fileobj=DATA_FILE,
path_in_repo=DATA_FILE,
repo_id=REPO_ID,
repo_type="dataset",
token=HF_TOKEN_WRITE,
commit_message=f"Backup {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
)
except Exception:
pass
def download_db_from_hf():
try:
hf_hub_download(
repo_id=REPO_ID,
filename=DATA_FILE,
repo_type="dataset",
token=HF_TOKEN_READ,
local_dir=".",
local_dir_use_symlinks=False
)
except Exception:
pass
def periodic_backup():
while True:
upload_db_to_hf()
time.sleep(800)
@app.route('/')
def catalog():
data = load_data()
catalog_html = '''
Каталог Тканей
Каталог Тканей
'''
return render_template_string(catalog_html, products=data['products'])
@app.route('/admin', methods=['GET', 'POST'])
def admin():
data = load_data()
products = data.get('products', [])
history = data.get('history', [])
if request.method == 'POST':
action = request.form.get('action')
if action == 'add':
color_names = request.form.getlist('color_names')
color_rolls = request.form.getlist('color_rolls')
colors_list = []
for name, rolls in zip(color_names, color_rolls):
name = name.strip()
if name:
try: r = int(rolls)
except ValueError: r = 0
colors_list.append({"name": name, "warehouse_rolls": r, "shop_rolls": 0})
new_product = {
'name': request.form['name'],
'description': request.form['description'],
'colors': colors_list
}
products.append(new_product)
elif action == 'income':
idx = int(request.form['product_index'])
color_name = request.form['color_name']
if color_name == '__new__':
color_name = request.form['new_color_input'].strip()
rolls_to_add = int(request.form['rolls'])
found = False
for c in products[idx].get('colors', []):
if c['name'] == color_name:
c['warehouse_rolls'] = c.get('warehouse_rolls', 0) + rolls_to_add
found = True
break
if not found:
if 'colors' not in products[idx]:
products[idx]['colors'] = []
products[idx]['colors'].append({"name": color_name, "warehouse_rolls": rolls_to_add, "shop_rolls": 0})
history.insert(0, {
'time': get_almaty_time(),
'action': 'Приход',
'product': products[idx]['name'],
'color': color_name,
'amount': rolls_to_add
})
elif action == 'delete':
index = int(request.form['index'])
if 0 <= index < len(products):
del_name = products[index]['name']
products.pop(index)
history.insert(0, {
'time': get_almaty_time(),
'action': 'Удаление',
'product': del_name,
'color': '-',
'amount': 0
})
elif action == 'process_color':
p_idx = int(request.form.get('pIndex', -1))
c_name = request.form.get('cName')
amt = int(request.form.get('amt', 0))
act_type = request.form.get('actType')
if 0 <= p_idx < len(products) and amt > 0:
for c in products[p_idx].get('colors', []):
if c['name'] == c_name:
if act_type in ['sell_warehouse', 'to_shop']:
av = c.get('warehouse_rolls', 0)
if amt > av: amt = av
elif act_type in ['sell_shop', 'to_warehouse']:
av = c.get('shop_rolls', 0)
if amt > av: amt = av
if amt <= 0:
break
if act_type == 'sell_warehouse':
c['warehouse_rolls'] -= amt
elif act_type == 'to_shop':
c['warehouse_rolls'] -= amt
c['shop_rolls'] = c.get('shop_rolls', 0) + amt
elif act_type == 'sell_shop':
c['shop_rolls'] -= amt
elif act_type == 'to_warehouse':
c['shop_rolls'] -= amt
c['warehouse_rolls'] = c.get('warehouse_rolls', 0) + amt
action_map = {
'sell_warehouse': 'Продажа (Склад)',
'to_shop': 'В магазин',
'sell_shop': 'Продажа (Магазин)',
'to_warehouse': 'На склад'
}
history.insert(0, {
'time': get_almaty_time(),
'action': action_map.get(act_type, act_type),
'product': products[p_idx]['name'],
'color': c_name,
'amount': amt
})
break
history = history[:1000]
save_data({'products': products, 'history': history})
return redirect(url_for('admin'))
admin_html = '''
Учет тканей - Админ