#!/usr/bin/env python3 """Generate F-Droid v2 metadata for a signed APK. Usage: fdroid_metadata.py Prints the F-Droid metadata lines to stdout. The workflow separately computes the F-Droid signature (base64 of double SHA-256). """ import hashlib import re import shutil import subprocess import sys def main(): apk = sys.argv[1] with open(apk, "rb") as f: data = f.read() sha256 = hashlib.sha256(data).hexdigest() aapt2 = shutil.which("aapt2") if aapt2 is None: sys.exit("aapt2 not found on PATH; add the Android build-tools dir to PATH") dump = subprocess.run([aapt2, "dump", "badging", apk], check=True, capture_output=True, text=True).stdout m_pkg = re.search(r"package: name='([^']+)'", dump) m_ver = re.search(r"versionName='([^']+)'", dump) m_code = re.search(r"versionCode='(\d+)'", dump) if not (m_pkg and m_ver and m_code): sys.exit(f"could not parse APK badging:\n{dump[:2000]}") pkg = m_pkg.group(1) ver = m_ver.group(1) code = int(m_code.group(1)) lines = [ f"VersionName: {ver}", f"VersionCode: {code}", "MinSdkVersion: 24", "TargetSdkVersion: 36", "Permissions:", " android.permission.INTERNET", " android.permission.CAMERA", " android.permission.RECEIVE_BOOT_COMPLETED", " android.permission.REQUEST_INSTALL_PACKAGES", " android.permission.SYSTEM_ALERT_WINDOW", " android.permission.WRITE_EXTERNAL_STORAGE", f"UpdateUrl: https://git.obahan.xyz/frank/wirevpn/releases", f"Sha256Digest: {sha256}", f"AndroidPackageInfoName: {pkg}", ] print("\n".join(lines)) if __name__ == "__main__": main()