Spaces:
Running
Running
File size: 6,157 Bytes
f7b9253 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | import os, base64, re, json
DEFAULT_CONTACTS = {
"phone": "+380675745662",
"phone_display": "+38 067 574 56 62",
"tg_link": "https://t.me/unstop_retail",
"tg_display": "Telegram",
"map_iframe": 'https://www.google.com/maps/d/embed?mid=1pn9YLjrvuNJtrxwioRFoS-RC3eAdPAA&ehbc=2E312F&noprof=1',
"address": "м. Харків, Основ'янський район"
}
def read_file(path, fallback=""):
if os.path.exists(path):
with open(path, "r", encoding="utf-8") as f:
return f.read()
return fallback
def img_b64(path):
ext = os.path.splitext(path)[1].lower()
mime = "image/png" if ext == ".png" else "image/jpeg" if ext in [".jpg", ".jpeg"] else "image/webp"
with open(path, "rb") as f:
return f"data:{mime};base64," + base64.b64encode(f.read()).decode()
def _read_config(base_dir):
config_path = os.path.join(base_dir, "config.json")
if os.path.exists(config_path):
with open(config_path, "r", encoding="utf-8") as f:
return json.load(f)
return {"models": [], "contacts": DEFAULT_CONTACTS.copy()}
def _write_config(base_dir, data):
config_path = os.path.join(base_dir, "config.json")
with open(config_path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=4)
def get_contacts(base_dir):
cfg = _read_config(base_dir)
contacts = cfg.get("contacts", {})
# Fill missing keys with defaults
for k, v in DEFAULT_CONTACTS.items():
contacts.setdefault(k, v)
return contacts
def save_contacts(base_dir, contacts: dict):
cfg = _read_config(base_dir)
cfg["contacts"] = contacts
_write_config(base_dir, cfg)
def get_models_data(base_dir):
config_path = os.path.join(base_dir, "config.json")
models_dir = os.path.join(base_dir, "models")
if not os.path.exists(config_path):
models_list = []
if os.path.exists(models_dir) and os.path.isdir(models_dir):
for i, folder in enumerate(sorted(os.listdir(models_dir))):
folder_path = os.path.join(models_dir, folder)
if os.path.isdir(folder_path):
opis = read_file(os.path.join(folder_path, "Opis.txt"), fallback="")
price = read_file(os.path.join(folder_path, "Price.txt"), fallback="49 000 грн").strip()
subtitle = read_file(os.path.join(folder_path, "Subtitle.txt"), fallback="🔋 Надійна енергія для вашого бізнесу").strip()
models_list.append({
"id": f"m_{i}", "folder": folder, "name": folder,
"title": folder, "subtitle": subtitle, "price": price, "opis_raw": opis
})
if not models_list:
models_list.append({
"id": "m_main", "folder": "", "name": "Базова",
"title": "Unstop Retail 4032W",
"subtitle": "🔋 LiFePO4 • 4032 Wh • 8+ годин автономної роботи",
"price": "49 000 грн",
"opis_raw": read_file(os.path.join(base_dir, "Opis.txt"), fallback="")
})
_write_config(base_dir, {"models": models_list, "contacts": DEFAULT_CONTACTS.copy()})
cfg = _read_config(base_dir)
models = cfg.get("models", [])
for m in models:
folder_name = m.get("folder", "")
folder_path = os.path.join(models_dir, folder_name) if folder_name else base_dir
images = []
if os.path.exists(folder_path):
images = sorted([
os.path.join(folder_path, img) for img in os.listdir(folder_path)
if img.lower().endswith(('.webp', '.png', '.jpg', '.jpeg'))
])
if not images and not folder_name:
candidates = ["image (1).webp", "image (2).webp", "image.webp"]
images = [os.path.join(base_dir, p) for p in candidates if os.path.exists(os.path.join(base_dir, p))]
m["images"] = images
return models
def save_config(base_dir, models_data):
cfg = _read_config(base_dir)
clean_models = []
for m in models_data:
clean_models.append({
"id": m.get("id"), "folder": m.get("folder", ""),
"name": m.get("name", ""), "title": m.get("title", ""),
"subtitle": m.get("subtitle", ""), "price": m.get("price", ""),
"opis_raw": m.get("opis_raw", "")
})
cfg["models"] = clean_models
_write_config(base_dir, cfg)
def opis_to_html(text):
if not text: return "<p>Опис не знайдено.</p>"
lines, parts, in_tbl, tbuf = text.split("\n"), [], False, []
for line in lines:
if line.startswith("## "): parts.append(f"<h2>{line[3:].strip()}</h2>"); continue
if line.startswith("### "): parts.append(f"<h3>{line[4:].strip()}</h3>"); continue
if line.strip() in ("---", "***", "___"): parts.append("<hr>"); continue
if "|" in line and line.strip().startswith("|"):
if not in_tbl: in_tbl, tbuf = True, []
tbuf.append(line); continue
if in_tbl:
parts.append(_tbl(tbuf)); in_tbl = False
if line.startswith("> "):
parts.append(f'<blockquote>{line[2:].strip()}</blockquote>')
elif line.strip():
l = re.sub(r"\*\*(.+?)\*\*", r"<strong>\1</strong>", line)
l = re.sub(r"\*(.+?)\*", r"<em>\1</em>", l)
if l.strip().startswith("- "):
parts.append(f"<li>{l.strip()[2:]}</li>")
else:
parts.append(f"<p>{l.strip()}</p>")
else:
parts.append("")
if in_tbl: parts.append(_tbl(tbuf))
res = "\n".join(parts)
return re.sub(r"((?:<li>.*?</li>\n?)+)", r"<ul>\1</ul>", res)
def _tbl(rows):
html_tbl = "<table>"
for i, row in enumerate(rows):
cells = [c.strip() for c in row.strip().strip("|").split("|")]
if all(set(c) <= set("-: ") for c in cells): continue
tag = "th" if i == 0 else "td"
html_tbl += "<tr>" + "".join(f"<{tag}>{c}</{tag}>" for c in cells) + "</tr>"
return html_tbl + "</table>"
|