Spaces:
Paused
Paused
File size: 4,376 Bytes
cda2483 | 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 | #!/usr/bin/env python3
"""patch_card_strings.py — IDEMPOTENT self-patch for Product-card strings.
Fixes (requested by owner):
1. Card header: "🆕 SẢN PHẨM MỚI TRÊN V.AI Market 📦" -> "SẢN PHẨM MỚI TRÊN V.AI Market"
(drop both emoji; the owner's target header has NO emoji because emoji
render as broken glyphs on the Zalo font).
2. Label: "Chi tiết sảnphẩm" (missing space) -> "Chi tiết sản phẩm".
3. Residual-old-header safety: any leftover "SẢN PHẨM MỘI VÀO DATASET" or
"Chi titi" variants are mapped to the same corrected strings.
Runs BEFORE the real app via Dockerfile CMD:
CMD ["sh", "-c", "python patch_card_strings.py && exec ...app..."]
Behavior:
- Fixes the LOCAL on-disk file first (so the running app uses the new
strings immediately).
- If anything changed, commits the fixed file(s) back to this Space's repo
(SELF_REPO_ID env) so the repo converges after ONE rebuild.
- Idempotent: if nothing to fix -> prints "already fixed", makes NO commit,
so there is no rebuild loop.
- Never raises / always exits 0 (fail-open): a patch failure must not block
the bot from starting.
"""
import os
import sys
import tempfile
import pathlib
# (old, new) — applied in order. All are safe exact substrings that only occur
# in the product-card header/label code.
REPLACEMENTS = [
("🆕 SẢN PHẨM MỚI TRÊN V.AI Market 📦", "SẢN PHẨM MỚI TRÊN V.AI Market"),
("SẢN PHẨM MỚI TRÊN V.AI Market 📦", "SẢN PHẨM MỚI TRÊN V.AI Market"),
("SẢN PHẨM MỘI VÀO DATASET 📦", "SẢN PHẨM MỚI TRÊN V.AI Market"),
("SẢN PHẨM MỘI VÀO DATASET", "SẢN PHẨM MỚI TRÊN V.AI Market"),
("Chi tiết sảnphẩm", "Chi tiết sản phẩm"),
("Chi titi:", "Chi tiết sản phẩm:"),
("Chi titi", "Chi tiết sản phẩm"),
]
_FILES = ["app.py", "child_app_template.py"]
def _apply(content):
changed = False
for old, new in REPLACEMENTS:
if old in content:
content = content.replace(old, new)
changed = True
return content, changed
def main():
rc = 0
try:
repo_id = os.getenv("SELF_REPO_ID", "").strip()
token = os.getenv("HF_TOKEN", os.getenv("HF_API_TOKEN", "")).strip()
fixed = []
for fname in _FILES:
if not os.path.exists(fname):
continue # child template only exists on the main Space
with open(fname, encoding="utf-8") as f:
content = f.read()
new_content, changed = _apply(content)
if not changed:
print("[patch] already fixed:", fname, flush=True)
continue
with open(fname, "w", encoding="utf-8") as f:
f.write(new_content)
print("[patch] fixed locally:", fname, flush=True)
fixed.append((fname, new_content))
if not fixed:
print("[patch] nothing to do — exiting clean", flush=True)
return 0
if not (repo_id and token):
print("[patch] WARNING: SELF_REPO_ID/HF_TOKEN not set — local files "
"fixed but repo NOT updated (will self-fix again next rebuild)",
flush=True)
return 0
try:
from huggingface_hub import HfApi
api = HfApi(token=token)
with tempfile.TemporaryDirectory() as tmpdir:
tmp = pathlib.Path(tmpdir)
for fname, content in fixed:
(tmp / fname).write_text(content, encoding="utf-8")
api.upload_folder(
repo_id=repo_id,
repo_type="space",
folder_path=str(tmp),
token=token,
commit_message="Fix product card strings: header without emoji + 'Chi tiết sản phẩm' spacing",
)
print("[patch] committed", [f for f, _ in fixed], "->", repo_id, flush=True)
except Exception as e:
print("[patch] commit failed (local fix still applied):",
str(e)[:200], flush=True)
rc = 0
except Exception as e:
print("[patch] FATAL (ignored, fail-open):", str(e)[:200], flush=True)
rc = 0
return rc
if __name__ == "__main__":
sys.exit(main()) |