#!/usr/bin/env python3 import json import os import re from androguard.core.bytecodes.apk import APK, get_apkid import requests import yaml import apkpure import evozi with open("apps.yml" ,'r') as f: apps = yaml.safe_load(f) def download(): for app_id, app in apps.items(): print(app_id) if "download" in app: r = requests.get(app["download"]) r.raise_for_status() match = re.search(r"^.*(https?://.+?\.apk).*$", r.text) apk_url = match.groups()[0] r = requests.get(apk_url) r.raise_for_status() apk_data = r.content print(f"Downloaded from {apk_url}") else: try: apk_data = apkpure.get(app_id) print(f"Downloaded from apkpure.com") except apkpure.DownloadError: apk_data = evozi.get(app_id) print(f"Downloaded from apps.evozi.com") apk = APK(apk_data, raw=True) if not apk.valid_apk: raise RuntimeError("No valid apk downloaded!") # check certificate fingerprint if "fingerprint" in app: certs = apk.get_certificates() if len(certs) != 1: raise RuntimeError("There should be exactly one certificate in apk.") fingerprint = certs[0].sha256_fingerprint.lower().replace(' ','') if fingerprint != app["fingerprint"]: raise RuntimeError("Certificate fingerprint doesn't match.") else: print("Skipping certificate fingerprint check.") # save apk version = apk.get_androidversion_name() code = apk.get_androidversion_code() os.makedirs("fdroid/repo", exist_ok=True) path = f"fdroid/repo/{app_id}_{code}_{version}.apk" with open(path, "wb") as f: f.write(apk_data) print(f"Done. Saved to {path}.") # write metadata yaml if "metadata" in app: os.makedirs("fdroid/metadata", exist_ok=True) with open(f"fdroid/metadata/{app_id}.yml", 'w') as f: yaml.dump(app["metadata"], f) print(f"Metadata written to fdroid/metadata/{app_id}.yml.") if __name__ == "__main__": download()