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
#!/usr/bin/env python3
"""Replace the in-app-update steps in the Aether tab with ONE download card:
latest PattNG, fdroid Universal APK — button + file name + size + faded URL.
Parameterized by env so the 5-hourly watch job can reuse it:
PATTNG_TAG (e.g. 2.3.13-P71), PATTNG_FILE, PATTNG_SIZE_FA (e.g. ۱۵۴ مگابایت)
Defaults = the P70 values verified 2026-10-28."""
import os, pathlib, re
SITE = pathlib.Path.home() / "workspace/foxyvpn-tutorial-site"
p = SITE / "plain.html"
html = p.read_text(encoding="utf-8")
TAG = os.environ.get("PATTNG_TAG", "2.3.13-P70")
FILE = os.environ.get("PATTNG_FILE", f"PattNG_fdroid_{TAG}_universal.apk")
SIZE_FA = os.environ.get("PATTNG_SIZE_FA", "۱۵۴ مگابایت")
URL = f"https://github.com/patterniha/PattNG/releases/download/{TAG}/{FILE}"
card = f""" <div class="group-title">اول: نصب آخرین نسخهی PattNG</div>
<div class="step">
<div class="step-header">
<div class="step-number">⬇</div>
<div class="step-title">دانلود PattNG — نسخهی Universal</div>
</div>
<div class="step-content">
<p>اول آخرین نسخهی PattNG را نصب کنید تا کانفیگهای Aether درست کار کنند. فایل زیر نسخهی <strong>Universal</strong> است و روی همهی گوشیها نصب میشود:</p>
<a class="btn-download" href="{URL}" target="_blank" rel="noopener">⬇ دانلود PattNG v{TAG}</a>
<p class="dl-meta">اسم فایل: <span dir="ltr">{FILE}</span> · حجم: {SIZE_FA}</p>
<p class="dl-url">{URL}</p>
<div class="note warning-note">
<strong>نکته:</strong> اگر هنگام نصب بستهی APK برنامه با ارور مواجه شدید، برنامه را یکبار کاملاً پاک کنید و سپس دوباره روی همان بستهی APK کلیک کنید تا فرایند نصب دوباره انجام شود.
</div>
</div>
</div>
"""
css = """
.dl-meta { margin-top: 10px; font-size: 0.88rem; color: var(--text-muted); }
.dl-url {
margin-top: 4px; font-size: 0.8rem; color: var(--text-muted); opacity: 0.7;
direction: ltr; text-align: left; word-break: break-all; user-select: all;
}
"""
if ".dl-meta" not in html:
html = html.replace("</style>", css + " </style>", 1)
# Replace whatever currently sits between the start of the aether panel body
# (after panel-intro) and the connect group title with the download card.
intro_end_marker = "برای وصل شدن این مراحل را انجام دهید.</p>"
i0 = html.find(intro_end_marker)
assert i0 > 0, "panel intro not found"
seg_start = i0 + len(intro_end_marker)
connect_marker = '<div class="group-title">بعد: وصل شدن به کانفیگ Aether</div>'
i1 = html.find(connect_marker)
assert i1 > seg_start, "connect group title not found"
html = html[:seg_start] + "\n\n" + card + html[i1:]
p.write_text(html, encoding="utf-8")
print(f"card set: tag={TAG} file={FILE} size={SIZE_FA}")
print("size:", len(html.encode()))