import os
import base64
import json
import threading
import time
from datetime import datetime
from uuid import uuid4
from flask import Flask, render_template_string, request, redirect, url_for, flash, jsonify
from huggingface_hub import HfApi, hf_hub_download
from huggingface_hub.utils import RepositoryNotFoundError, HfHubHTTPError
from werkzeug.utils import secure_filename
from dotenv import load_dotenv
import requests
load_dotenv()
app = Flask(__name__)
app.secret_key = 'super_secret_key_store_app_123'
DATA_FILE = 'data.json'
SYNC_FILES = [DATA_FILE]
REPO_ID = os.getenv("REPO_ID", "Kgshop/hkcafe")
HF_TOKEN_WRITE = os.getenv("HF_TOKEN")
HF_TOKEN_READ = os.getenv("HF_TOKEN_READ")
CURRENCY_CODE = 'сом'
def download_db_from_hf(specific_file=None, retries=3, delay=5):
token_to_use = HF_TOKEN_READ if HF_TOKEN_READ else HF_TOKEN_WRITE
files_to_download = [specific_file] if specific_file else SYNC_FILES
all_successful = True
for file_name in files_to_download:
success = False
for attempt in range(retries + 1):
try:
hf_hub_download(
repo_id=REPO_ID,
filename=file_name,
repo_type="dataset",
token=token_to_use,
local_dir=".",
local_dir_use_symlinks=False,
force_download=True,
resume_download=False
)
success = True
break
except RepositoryNotFoundError:
return False
except HfHubHTTPError as e:
if e.response.status_code == 404:
if attempt == 0 and not os.path.exists(file_name):
try:
if file_name == DATA_FILE:
with open(file_name, 'w', encoding='utf-8') as f:
json.dump({'products': [], 'categories': [], 'orders': {}, 'settings': {
'cafe_name': 'HongKong',
'logo_url': 'https://huggingface.co/spaces/Metapp/Tech/resolve/main/1776929812446-019db944-b5db-7524-8f44-73942d70a0f8.png',
'wa_shift1': '+77470623684',
'wa_shift2': '+77470623684',
'active_shift': 1
}}, f)
except Exception:
pass
success = False
break
except requests.exceptions.RequestException:
pass
except Exception:
pass
if attempt < retries:
time.sleep(delay)
if not success:
all_successful = False
return all_successful
def upload_db_to_hf(specific_file=None):
if not HF_TOKEN_WRITE:
return
try:
api = HfApi()
files_to_upload = [specific_file] if specific_file else SYNC_FILES
for file_name in files_to_upload:
if os.path.exists(file_name):
try:
api.upload_file(
path_or_fileobj=file_name,
path_in_repo=file_name,
repo_id=REPO_ID,
repo_type="dataset",
token=HF_TOKEN_WRITE,
commit_message=f"Sync {file_name} {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
)
except Exception:
pass
except Exception:
pass
def periodic_backup():
while True:
time.sleep(1800)
upload_db_to_hf()
def load_data():
default_data = {
'products': [],
'categories': [],
'orders': {},
'settings': {
'cafe_name': 'HongKong',
'logo_url': 'https://huggingface.co/spaces/Metapp/Tech/resolve/main/1776929812446-019db944-b5db-7524-8f44-73942d70a0f8.png',
'wa_shift1': '+77470623684',
'wa_shift2': '+77470623684',
'active_shift': 1
}
}
data = default_data
try:
with open(DATA_FILE, 'r', encoding='utf-8') as file:
data = json.load(file)
if not isinstance(data, dict):
raise FileNotFoundError
if 'products' not in data: data['products'] = []
if 'categories' not in data: data['categories'] = []
if 'orders' not in data: data['orders'] = {}
if 'settings' not in data: data['settings'] = default_data['settings']
except (FileNotFoundError, json.JSONDecodeError):
if download_db_from_hf(specific_file=DATA_FILE):
try:
with open(DATA_FILE, 'r', encoding='utf-8') as file:
data = json.load(file)
if 'products' not in data: data['products'] = []
if 'categories' not in data: data['categories'] = []
if 'orders' not in data: data['orders'] = {}
if 'settings' not in data: data['settings'] = default_data['settings']
except Exception:
data = default_data
else:
data = default_data
except Exception:
data = default_data
migrated_cats = []
for c in data.get('categories', []):
if isinstance(c, str):
migrated_cats.append({'name': c, 'icon': 'fas fa-utensils'})
else:
if 'icon' not in c: c['icon'] = 'fas fa-utensils'
migrated_cats.append(c)
data['categories'] = migrated_cats
for product in data['products']:
if 'product_id' not in product:
product['product_id'] = uuid4().hex
if not os.path.exists(DATA_FILE):
try:
with open(DATA_FILE, 'w', encoding='utf-8') as f:
json.dump(default_data, f)
except Exception:
pass
return data
def save_data(data):
try:
if not isinstance(data, dict):
return
if 'products' not in data: data['products'] = []
if 'categories' not in data: data['categories'] = []
if 'orders' not in data: data['orders'] = {}
if 'settings' not in data: data['settings'] = {
'cafe_name': 'HongKong',
'logo_url': '',
'wa_shift1': '',
'wa_shift2': '',
'active_shift': 1
}
with open(DATA_FILE, 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
upload_db_to_hf(specific_file=DATA_FILE)
except Exception:
pass
CATALOG_TEMPLATE = '''
{{ settings.cafe_name }} | Меню
Добро пожаловать
Меню
Сумма заказа:0 {{ currency_code }}
Ваш заказ
Наш адрес
село Милянфан ул. Фрунзе 99
'''
ORDER_TEMPLATE = '''
Счет №{{ order.id }}
{{ settings.cafe_name }}
Чек №:{{ order.id }}
Дата:{{ order.created_at }}
Тип:{{ 'В заведении' if order.order_type == 'dine_in' else 'Доставка' }}
{% if order.order_type == 'dine_in' %}
Столик:{{ order.table_number }}
{% else %}
Гость:{{ order.customer_name }}
Телефон:{{ order.customer_phone }}
Адрес:{{ order.customer_address }}
{% endif %}
Статус:{{ 'ПОДТВЕРЖДЕН' if order.status == 'confirmed' else 'ОЖИДАЕТ' }}
{% set raw_total = 0 %}
{% for item in order.cart %}
{% set item_sum = item.price * item.quantity %}
{% set raw_total = raw_total + item_sum %}
{{ item.name }}
{{ item.quantity }} x {{ item.price }}
{{ item_sum }} {{ currency_code }}
{% endfor %}
Итого:{{ raw_total }} {{ currency_code }}
{% set discount = order.discount|default(0)|float %}
{% if discount > 0 %}
Скидка:-{{ discount }} {{ currency_code }}
{% endif %}
К ОПЛАТЕ:{{ order.total_price }} {{ currency_code }}
{% for order in orders.values()|sort(attribute='created_at', reverse=True) %}
{% if order.status == 'confirmed' %}
{% set raw_total = 0 %}
{% for item in order.cart %}
{% set raw_total = raw_total + (item.price|float * item.quantity|int) %}
{% endfor %}