From 7bf4eccc6a4d00a659dd58f098680b57ff99429d Mon Sep 17 00:00:00 2001 From: SinTan1729 Date: Tue, 8 Aug 2023 23:33:09 -0500 Subject: [PATCH] new: Downloading works --- .gitignore | 3 ++ APKPure_dl.py | 102 +++++++++++++++++++++++++++++++++++++++ ReVancedBuilder.py | 117 +++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 4 ++ 4 files changed, 226 insertions(+) create mode 100644 APKPure_dl.py create mode 100755 ReVancedBuilder.py create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore index 096edb2..2228d0b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ build/ .editorconfig patches.txt .vscode/ +.directory +.venv/ +__pycache__/ diff --git a/APKPure_dl.py b/APKPure_dl.py new file mode 100644 index 0000000..590b74f --- /dev/null +++ b/APKPure_dl.py @@ -0,0 +1,102 @@ +import sys +import json +from packaging.version import Version +import requests as req +from bs4 import BeautifulSoup as bs + +# Determine the best version available to download +def apkpure_best_match(apk, appname, version, session): + res = session.get(f"https://apkpure.com/{appname}/{apk}/versions") + res.raise_for_status() + data = bs(res.text, 'html.parser') + try: + vers_list = [Version(x['data-dt-version']) for x in data.css.select(f"a[data-dt-apkid^=\"b/APK/\"]")] + except: + sys.exit(f" There was some error getting list of versions of {apk}...") + + if version != '0': + vers_list = filter(lambda x: x <= Version(version), vers_list) + + return max(vers_list) + +# Download an apk from APKPure.com +def apkpure_dl(apk, appname, version, hard_version, session, present_vers): + if not hard_version: + version = apkpure_best_match(apk, appname, version, session) + + try: + if present_vers[apk] == version: + print(f"Recommended version {version} of {apk} is already present.") + return + except KeyError: + pass + print(f" Downloading {apk} version {version}...") + + # Get the version code + res = session.get(f"https://apkpure.com/{appname}/{apk}/versions") + res.raise_for_status() + data = bs(res.text, 'html.parser') + try: + ver_code = data.css.select(f"a[data-dt-version=\"{version}\"][data-dt-apkid^=\"b/APK/\"]")[0]['data-dt-versioncode'] + except: + sys.exit(f" There was some error while downloading {apk}...") + + res = session.get(f"https://d.apkpure.com/b/APK/{apk}?versionCode={ver_code}", stream=True) + res.raise_for_status() + with open(apk, 'wb') as f: + for chunk in res.iter_content(chunk_size=8192): + f.write(chunk) + print(" Done!") + + + +# Download apk files, if needed +def get_apks(present_vers, build_config): + print('Downloading required apk files from APKPure...') + + # Get latest patches using the ReVanced API + try: + patches = req.get('https://releases.revanced.app/patches').json() + except req.exceptions.RequestException as e: + sys.exit(e) + + session = req.Session() + session.headers.update({'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/116.0'}) + + for app in build_config: + # Check if we need to build an app + if not build_config[app].getboolean('build'): + continue + print(f"Checking {app}...") + + try: + apk = build_config[app]['apk'] + apkpure_appname = build_config[app]['apkpure_appname'] + except: + sys.exit(f"Invalid config for {app} in build_config.toml!") + + try: + required_ver = build_config[app]['version'] + required_ver[0] + hard_version = True + print(f"Using version {required_ver} of {app} from ") + except: + hard_version = False + compatible_vers = [] + for patch in patches: + for pkg in patch['compatiblePackages']: + if pkg['name'] == apk: + try: + compatible_vers.append(pkg['versions'][-1]) + except IndexError: + pass + + if not compatible_vers: + required_ver = Version('0') + else: + required_ver = min(map(lambda x: Version(x), compatible_vers)) + + apkpure_dl(apk, apkpure_appname, str(required_ver), hard_version, session, present_vers) + + present_vers.update({apk: str(required_ver)}) + return present_vers \ No newline at end of file diff --git a/ReVancedBuilder.py b/ReVancedBuilder.py new file mode 100755 index 0000000..ab96b93 --- /dev/null +++ b/ReVancedBuilder.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 + +import sys +import os +import configparser as cp +import requests as req +import json +from packaging.version import Version +from APKPure_dl import * + +# Update the ReVanced tools, if needed +def update_tools(): + for item in ['revanced-cli', 'revanced-integrations', 'revanced-patches']: + *_, tool = filter(lambda x: x['repository'] == 'revanced/'+item, tools) # Get the last result + latest_ver = Version(tool['version']) + + try: + present_ver = Version(present_vers[item]) + except KeyError: + present_ver = Version('0') + + if present_ver < latest_ver: + global up_to_date + up_to_date = False + print(f"{item} has an update ({str(present_ver)} -> {str(latest_ver)})") + output_file = item.split('-')[1]+os.path.splitext(tool['name'])[1] + if flag != 'checkonly': + print(f"Downloading {output_file}...") + res = req.get(tool['browser_download_url'], stream=True) + res.raise_for_status() + with open(output_file, 'wb') as f: + for chunk in res.iter_content(chunk_size=8192): + f.write(chunk) + present_vers.update({item: str(latest_ver)}) + print("Done!") + +# Update microG, if needed +def update_microg(): + try: + data = req.get('https://api.github.com/repos/inotia00/VancedMicroG/releases/latest').json()['tag_name'] + latest_ver = Version(data) + except req.exceptions.RequestException as e: + sys.exit(e) + + try: + present_ver = Version(present_vers['VancedMicroG']) + except KeyError: + present_ver = Version('0') + + if present_ver < latest_ver: + global up_to_date + up_to_date = False + print(f"Vanced microG has an update ({str(present_ver)} -> {str(latest_ver)})") + if flag != 'checkonly': + print(f"Downloading microg.apk...") + res = req.get('https://github.com/inotia00/VancedMicroG/releases/latest/download/microg.apk', stream=True) + res.raise_for_status() + with open('microg.apk', 'wb') as f: + for chunk in res.iter_content(chunk_size=8192): + f.write(chunk) + present_vers.update({'VancedMicroG': str(latest_ver)}) + print("Done!") + +# Read configs +try: + os.chdir(sys.argv[1]) +except IndexError: + sys.exit('Please provide a working directory as argument!') +except FileNotFoundError: + sys.exit('Invalid working directory provided!') + +try: + flag = sys.argv[2] +except: + flag = None + +try: + build_config=cp.ConfigParser() + build_config.read_file(open('build_config.toml', 'r')) +except FileNotFoundError: + sys.exit('No build config provided, exiting. Please look at the GitHub page for more information:\n https://github.com/SinTan1729/ReVancedBuilder') + +notification_config = cp.ConfigParser() +notification_config.read('notification_config.toml') + +# Pull the latest information using the ReVanced API +try: + tools = req.get('https://releases.revanced.app/tools').json()['tools'] +except req.exceptions.RequestException as e: + sys.exit(e) + +global present_vers +try: + with open('versions.json', 'r') as f: + present_vers = json.load(f) +except: + # We'll treat empty as 0 later + present_vers = json.loads('{}') + +global up_to_date +up_to_date = True + +if flag != 'buildonly': + update_tools() + update_microg() + # if not up_to_date: + present_vers = get_apks(present_vers, build_config) + +# if (flag != 'checkonly' and not up_to_date) or flag == 'force': +# build_apps() + +# Update version numbers in the versions.json file +if up_to_date: + print('There\'s nothing to do.') +elif flag != 'checkonly': + with open('versions.json', 'w') as f: + json.dump(present_vers, f, indent=4) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..d8c6174 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +requests +semver +packaging +bs4 \ No newline at end of file