#!/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 * from JAVABuilder import * from datetime import datetime # TODO: Logging # TODO: Notifications # TODO: Notification for errors (maybe by writing custom exit function? Exit function should also cleanup output files. printerr?) # TODO: Moving files in proper locations # TODO: Run post_script (preferably in any language) # TODO: README # 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') output_file = item+os.path.splitext(tool['name'])[1] if flag == 'force' or not os.path.isfile(output_file) or present_ver < latest_ver: global up_to_date up_to_date = False print(f"{item} has an update ({str(present_ver)} -> {str(latest_ver)})") 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 flag == 'force' or not os.path.isfile('microg.apk') or 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 vanced-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!") # Move apps to proper location def move_apps(): try: os.mkdir('archive') except FileExistsError: pass for app in build_config: if not build_config[app].getboolean('build'): continue name = build_config[app]['output_name'] final_name = f"{name}_{timestamp}.apk" try: os.rename(name+'.apk', 'archive/'+final_name) except FileNotFoundError: pass # sys.exit('There was an error moving the final apk files!') files = [] dir = os.scandir('archive') for f in dir: if name in f.name: files.append(f) files.sort(key=lambda f: f.stat().st_ctime) files.reverse() for f in files[3:]: os.remove(f) print('Deleted old build '+f.name) dir.close() # ------------------------------ # The main function starts here # ------------------------------ # Get a timestamp time = datetime.now() timestamp = time.strftime('%Y%m%d%H%M%S') print(f"Started building ReVanced apps at {time.strftime('%d %B, %Y %H:%M:%S')}") # 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') move_apps() 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 or flag == 'force': present_vers = get_apks(present_vers, build_config, flag) if (flag != 'checkonly' and not up_to_date) or flag in ['force', 'buildonly']: build_apps(build_config, flag) move_apps() # Update version numbers in the versions.json file if up_to_date and flag != 'buildonly': print('There\'s nothing to do.') elif flag not in ['checkonly', 'buildonly']: with open('versions.json', 'w') as f: json.dump(present_vers, f, indent=4)