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())