download.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #!/usr/bin/env python3
  2. import json
  3. import os
  4. import re
  5. from androguard.core.bytecodes.apk import APK, get_apkid
  6. import requests
  7. import yaml
  8. import apkpure
  9. with open("apps.yml" ,'r') as f:
  10. apps = yaml.safe_load(f)
  11. def download():
  12. for app_id, app in apps.items():
  13. print(app_id)
  14. if "download" in app:
  15. r = requests.get(app["download"])
  16. r.raise_for_status()
  17. match = re.search(r"^.*(https?://.+?\.apk).*$", r.text)
  18. apk_url = match.groups()[0]
  19. r = requests.get(apk_url)
  20. r.raise_for_status()
  21. apk_data = r.content
  22. else:
  23. apk_data = apkpure.get(app_id)
  24. apk = APK(apk_data, raw=True)
  25. if not apk.valid_apk:
  26. raise RuntimeError("No valid apk downloaded!")
  27. # check certificate fingerprint
  28. if "fingerprint" in app:
  29. certs = apk.get_certificates()
  30. if len(certs) != 1:
  31. raise RuntimeError("There should be exactly one certificate in apk.")
  32. fingerprint = certs[0].sha256_fingerprint.lower().replace(' ','')
  33. if fingerprint != app["fingerprint"]:
  34. raise RuntimeError("Certificate fingerprint doesn't match.")
  35. else:
  36. print("Skipping certificate fingerprint check.")
  37. # save apk
  38. version = apk.get_androidversion_name()
  39. code = apk.get_androidversion_code()
  40. os.makedirs("fdroid/repo", exist_ok=True)
  41. path = f"fdroid/repo/{app_id}_{code}_{version}.apk"
  42. with open(path, "wb") as f:
  43. f.write(apk_data)
  44. print(f"Done. Saved to {path}.")
  45. # write metadata yaml
  46. if "metadata" in app:
  47. os.makedirs("fdroid/metadata", exist_ok=True)
  48. with open(f"fdroid/metadata/{app_id}.yml", 'w') as f:
  49. yaml.dump(app["metadata"], f)
  50. print(f"Metadata written to fdroid/metadata/{app_id}.yml.")
  51. if __name__ == "__main__":
  52. download()