Publish full source including logcat visual map engine
This commit is contained in:
parent
10902567d8
commit
ac609bc80c
132 changed files with 19071 additions and 2759 deletions
174
scripts/gen_debloat_db.py
Normal file
174
scripts/gen_debloat_db.py
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Generate frontend/src/lib/debloat_db.ts from UAD-ng's uad_lists.json.
|
||||
|
||||
Usage:
|
||||
python3 scripts/gen_debloat_db.py <path/to/uad_lists.json> [output.ts]
|
||||
|
||||
UAD-ng (github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation)
|
||||
ships its package database as resources/assets/uad_lists.json: a flat object keyed
|
||||
by package name, each value having {list, description, dependencies, neededBy,
|
||||
labels, removal}.
|
||||
|
||||
ATK keeps a richer per-manufacturer categorisation than upstream (UAD-ng collapsed
|
||||
all OEM packages into a single "Oem" list). To preserve ATK's UX we re-derive the
|
||||
manufacturer from the package-name prefix for the Oem bucket.
|
||||
|
||||
Mappings:
|
||||
removal -> safety: Recommended->safe, Advanced->caution, Expert->caution, Unsafe->keep
|
||||
list -> category: Google->Google, Carrier->Carriers, Aosp->AOSP, Misc->Misc,
|
||||
Oem-> inferred by prefix (Samsung/Xiaomi/.../Other OEM)
|
||||
"""
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
|
||||
REMOVAL_TO_SAFETY = {
|
||||
"Recommended": "safe",
|
||||
"Advanced": "caution",
|
||||
"Expert": "caution",
|
||||
"Unsafe": "keep",
|
||||
}
|
||||
|
||||
# Emit categories in this order; empty categories are skipped.
|
||||
CATEGORY_ORDER = [
|
||||
"Google", "Samsung", "Xiaomi", "Huawei", "OnePlus/Oppo", "Sony",
|
||||
"Motorola", "LG", "Nokia/HMD", "Asus", "Carriers", "AOSP", "Misc", "Other OEM",
|
||||
]
|
||||
|
||||
# Prefix rules for splitting UAD's "Oem" bucket back into manufacturers.
|
||||
# First match wins; checked against the lower-cased package name.
|
||||
OEM_RULES = [
|
||||
("Samsung", ["com.samsung", "com.sec.android", "com.sec.", ".samsung."]),
|
||||
("Xiaomi", ["com.xiaomi", "com.miui", "com.mi.", ".miui.", "com.redmi"]),
|
||||
("Huawei", ["com.huawei", "com.hihonor", ".huawei.", ".hihonor."]),
|
||||
("OnePlus/Oppo", ["com.oneplus", "com.oppo", "com.coloros", "com.nearme",
|
||||
"com.heytap", "com.realme", "com.oplus"]),
|
||||
("Sony", ["com.sonymobile", "com.sony", ".sonyericsson"]),
|
||||
("Motorola", ["com.motorola", "com.moto", ".motorola."]),
|
||||
("LG", ["com.lge", "com.lg.", ".lge."]),
|
||||
("Nokia/HMD", ["com.hmdglobal", "com.nokia", "com.evenwell", ".hmd"]),
|
||||
("Asus", ["com.asus", ".asus."]),
|
||||
]
|
||||
|
||||
|
||||
def categorize(pkg: str, uad_list: str) -> str:
|
||||
if uad_list == "Google":
|
||||
return "Google"
|
||||
if uad_list == "Carrier":
|
||||
return "Carriers"
|
||||
if uad_list == "Aosp":
|
||||
return "AOSP"
|
||||
if uad_list == "Misc":
|
||||
return "Misc"
|
||||
# "Oem" (or anything unexpected) -> infer manufacturer from the prefix.
|
||||
p = pkg.lower()
|
||||
for cat, subs in OEM_RULES:
|
||||
if any(s in p for s in subs):
|
||||
return cat
|
||||
return "Other OEM"
|
||||
|
||||
|
||||
def make_label(pkg: str) -> str:
|
||||
seg = pkg.split(".")[-1] or pkg
|
||||
return seg[:1].upper() + seg[1:] if seg else pkg
|
||||
|
||||
|
||||
def clean_desc(desc: str, pkg: str) -> str:
|
||||
if not desc or not desc.strip():
|
||||
return f"Package: {pkg}"
|
||||
return re.sub(r"\s+", " ", desc).strip()
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if len(sys.argv) < 2:
|
||||
print(__doc__)
|
||||
return 1
|
||||
src = sys.argv[1]
|
||||
out = sys.argv[2] if len(sys.argv) > 2 else "frontend/src/lib/debloat_db.ts"
|
||||
|
||||
with open(src, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
buckets = {name: [] for name in CATEGORY_ORDER}
|
||||
for pkg, meta in data.items():
|
||||
removal = meta.get("removal", "Unsafe")
|
||||
safety = REMOVAL_TO_SAFETY.get(removal, "keep")
|
||||
cat = categorize(pkg, meta.get("list", "Oem"))
|
||||
entry = {
|
||||
"pkg": pkg,
|
||||
"label": make_label(pkg),
|
||||
"description": clean_desc(meta.get("description", ""), pkg),
|
||||
"safety": safety,
|
||||
}
|
||||
deps = meta.get("dependencies") or []
|
||||
needed = meta.get("neededBy") or []
|
||||
if deps:
|
||||
entry["deps"] = deps
|
||||
if needed:
|
||||
entry["neededBy"] = needed
|
||||
buckets[cat].append(entry)
|
||||
|
||||
total = sum(len(v) for v in buckets.values())
|
||||
n_cats = sum(1 for v in buckets.values() if v)
|
||||
|
||||
lines = []
|
||||
lines.append("// Auto-generated from UAD package list (Universal Android Debloater)")
|
||||
lines.append("// Source: github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation")
|
||||
lines.append(f"// Generated by scripts/gen_debloat_db.py - {total} packages across {n_cats} categories")
|
||||
lines.append("// Do not edit by hand; re-run the generator against a fresh uad_lists.json instead.")
|
||||
lines.append("")
|
||||
lines.append("export type Safety = 'safe' | 'caution' | 'keep'")
|
||||
lines.append("")
|
||||
lines.append("export interface DebloatPackage {")
|
||||
lines.append(" pkg: string")
|
||||
lines.append(" label: string")
|
||||
lines.append(" description: string")
|
||||
lines.append(" safety: Safety")
|
||||
lines.append(" deps?: string[]")
|
||||
lines.append(" neededBy?: string[]")
|
||||
lines.append("}")
|
||||
lines.append("")
|
||||
lines.append("export interface Category {")
|
||||
lines.append(" name: string")
|
||||
lines.append(" packages: DebloatPackage[]")
|
||||
lines.append("}")
|
||||
lines.append("")
|
||||
lines.append("export const DEBLOAT_CATEGORIES: Category[] = [")
|
||||
|
||||
for name in CATEGORY_ORDER:
|
||||
pkgs = buckets[name]
|
||||
if not pkgs:
|
||||
continue
|
||||
pkgs.sort(key=lambda e: e["pkg"])
|
||||
lines.append(" {")
|
||||
lines.append(f" name: {json.dumps(name)},")
|
||||
lines.append(" packages: [")
|
||||
for e in pkgs:
|
||||
parts = [
|
||||
f"pkg: {json.dumps(e['pkg'])}",
|
||||
f"label: {json.dumps(e['label'])}",
|
||||
f"description: {json.dumps(e['description'], ensure_ascii=False)}",
|
||||
f"safety: {json.dumps(e['safety'])}",
|
||||
]
|
||||
if "deps" in e:
|
||||
parts.append(f"deps: {json.dumps(e['deps'], ensure_ascii=False)}")
|
||||
if "neededBy" in e:
|
||||
parts.append(f"neededBy: {json.dumps(e['neededBy'], ensure_ascii=False)}")
|
||||
lines.append(" { " + ", ".join(parts) + " },")
|
||||
lines.append(" ],")
|
||||
lines.append(" },")
|
||||
lines.append("]")
|
||||
lines.append("")
|
||||
|
||||
with open(out, "w", encoding="utf-8") as f:
|
||||
f.write("\n".join(lines))
|
||||
|
||||
print(f"Wrote {out}: {total} packages, {n_cats} categories")
|
||||
for name in CATEGORY_ORDER:
|
||||
if buckets[name]:
|
||||
print(f" {name:14} {len(buckets[name])}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Loading…
Add table
Add a link
Reference in a new issue