spark-server/deploy/popadmin/_hotpatch_media_pull.py
DESKTOP-L8OUL9F\gfl0034 40ce6c7dfa feat: 发布 PopAdmin 通讯录/相册/媒体拉取完整页与门禁
补齐三页查询/开关/授权/数量布局,并附上线上 static-override 与 jar 热补部署脚本。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-02 14:34:45 +08:00

144 lines
5.1 KiB
Python

#!/usr/bin/env python3
"""Compile Pop media-pull related classes and jar-uf into a deployable fat jar."""
from __future__ import annotations
import shutil
import subprocess
import tempfile
import zipfile
from pathlib import Path
ROOT = Path(r"F:\0000wyrs\Aliyun")
JAR = ROOT / "target" / "remote-control-1.0.0.jar"
OUT_JAR = ROOT / "target" / "remote-control-1.0.0.media-pull.jar"
JAVA_HOME = Path(r"C:\Program Files\Eclipse Adoptium\jdk-17.0.20.8-hotspot")
JAVAC = JAVA_HOME / "bin" / "javac.exe"
JAR_BIN = JAVA_HOME / "bin" / "jar.exe"
LOMBOK = ROOT / "scripts" / "lib" / "lombok-1.18.34.jar"
SRC_FILES = [
"com/wyrs/pop/config/PopProperties.java",
"com/wyrs/pop/entity/PopUserMedia.java",
"com/wyrs/pop/repository/PopUserMediaRepository.java",
"com/wyrs/pop/dto/PopMediaPullDtos.java",
"com/wyrs/pop/dto/PopSyncDtos.java",
"com/wyrs/pop/store/PopMediaPullFileStore.java",
"com/wyrs/pop/service/PopMediaPullService.java",
"com/wyrs/pop/service/PopSyncService.java",
"com/wyrs/pop/controller/PopAdminMediaPullController.java",
"com/wyrs/pop/controller/PopClientMediaPullController.java",
"com/wyrs/pop/controller/PopClientOpsController.java",
"com/wyrs/pop/controller/PopClientSyncController.java",
"com/wyrs/pop/controller/PopAdminController.java",
]
def main() -> None:
if not JAR.is_file():
raise SystemExit(f"missing base jar {JAR}")
if not JAVAC.is_file():
raise SystemExit(f"missing javac {JAVAC}")
if not LOMBOK.is_file():
raise SystemExit(f"missing lombok {LOMBOK}")
work = Path(tempfile.mkdtemp(prefix="wyrs-media-pull-"))
try:
extract = work / "extract"
classes_out = work / "classes"
extract.mkdir()
classes_out.mkdir()
print("extracting classpath from fat jar...")
with zipfile.ZipFile(JAR, "r") as z:
for name in z.namelist():
if name.startswith("BOOT-INF/lib/") or name.startswith("BOOT-INF/classes/"):
z.extract(name, extract)
cp_parts = [str(extract / "BOOT-INF" / "classes"), str(LOMBOK)]
lib = extract / "BOOT-INF" / "lib"
for j in sorted(lib.glob("*.jar")):
cp_parts.append(str(j))
cp = ";".join(cp_parts)
src_root = ROOT / "src" / "main" / "java"
src_args = []
for rel in SRC_FILES:
p = src_root / rel
if not p.is_file():
raise SystemExit(f"missing source {p}")
src_args.append(str(p))
cmd = [
str(JAVAC),
"-encoding",
"UTF-8",
"-parameters",
"-cp",
cp,
f"-processorpath",
str(LOMBOK),
"-d",
str(classes_out),
*src_args,
]
print("javac", len(src_args), "files ...")
p = subprocess.run(cmd, capture_output=True)
log = ROOT / "logs"
log.mkdir(parents=True, exist_ok=True)
(log / "javac_media_pull_err.txt").write_bytes(p.stderr or b"")
(log / "javac_media_pull_out.txt").write_bytes(p.stdout or b"")
if p.returncode != 0:
print((p.stderr or b"").decode("utf-8", "replace")[:4000])
raise SystemExit(f"javac failed code={p.returncode}")
# Collect produced class files under packages we care about
produced = list(classes_out.rglob("*.class"))
if not produced:
raise SystemExit("no class files produced")
print(f"produced {len(produced)} class files")
# markers
markers = [b"contactsConsented", b"pullContacts", b"pullDocuments", b"hasContactsConsent"]
blob = b"".join(f.read_bytes() for f in produced)
for m in markers:
print(f"marker {m!r}:", m in blob)
shutil.copy2(JAR, OUT_JAR)
update_root = work / "update"
for f in produced:
rel = f.relative_to(classes_out).as_posix()
dest = update_root / "BOOT-INF" / "classes" / rel
dest.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(f, dest)
# jar uf from update_root
entries = [
"BOOT-INF/classes/" + f.relative_to(classes_out).as_posix() for f in produced
]
print("jar uf", len(entries), "entries ...")
p2 = subprocess.run(
[str(JAR_BIN), "uf", str(OUT_JAR), *entries],
cwd=str(update_root),
capture_output=True,
text=True,
encoding="utf-8",
errors="replace",
)
if p2.returncode != 0:
print(p2.stdout)
print(p2.stderr)
raise SystemExit(f"jar uf failed: {p2.returncode}")
with zipfile.ZipFile(OUT_JAR, "r") as z:
sample = z.read(
"BOOT-INF/classes/com/wyrs/pop/service/PopMediaPullService.class"
)
if b"hasContactsConsent" not in sample and b"contactsConsented" not in sample:
raise SystemExit("patched jar missing consent markers")
print(f"OK {OUT_JAR} ({OUT_JAR.stat().st_size} bytes)")
finally:
shutil.rmtree(work, ignore_errors=True)
if __name__ == "__main__":
main()