mirror of
https://github.com/SinTan1729/ReVancedBuilder.git
synced 2024-12-26 12:48:36 -06:00
191 lines
No EOL
6.3 KiB
Python
Executable file
191 lines
No EOL
6.3 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
# SPDX-FileCopyrightText: 2023 Sayantan Santra <sayantan.santra@ou.edu>
|
|
# SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
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
|
|
from Notifications import send_notif
|
|
from Cleanup import *
|
|
import logging
|
|
import subprocess
|
|
|
|
# TODO: README
|
|
# TODO: PATCHES_GUIDE.md (maybe delete it?)
|
|
# TODO: Install using pip
|
|
|
|
# Update the ReVanced tools, if needed
|
|
def update_tools(appstate):
|
|
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(appstate['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:
|
|
appstate['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)
|
|
appstate['present_vers'].update({item: str(latest_ver)})
|
|
print("Done!")
|
|
|
|
return appstate
|
|
|
|
# Update microG, if needed
|
|
def update_microg(appstate):
|
|
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:
|
|
clean_exit(e, appstate)
|
|
|
|
try:
|
|
present_ver = Version(appstate['present_vers']['VancedMicroG'])
|
|
except KeyError:
|
|
present_ver = Version('0')
|
|
|
|
if flag == 'force' or not os.path.isfile('microg.apk') or present_ver < latest_ver:
|
|
appstate['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)
|
|
appstate['present_vers'].update({'VancedMicroG': str(latest_ver)})
|
|
print("Done!")
|
|
appstate['microg_updated'] = True
|
|
|
|
return appstate
|
|
|
|
# ------------------------------
|
|
# The main function starts here
|
|
# ------------------------------
|
|
|
|
# Create a dict for storing important data
|
|
appstate = {}
|
|
|
|
# Get a timestamp
|
|
time = datetime.now()
|
|
appstate['timestamp'] = time.strftime('%Y%m%d%H%M%S')
|
|
|
|
# Read arguments
|
|
try:
|
|
os.chdir(sys.argv[1])
|
|
except IndexError:
|
|
clean_exit('Please provide a working directory as argument!', appstate)
|
|
except FileNotFoundError:
|
|
clean_exit('Invalid working directory provided!', appstate)
|
|
|
|
# Try to make sure only one instance is running in a given working directory
|
|
try:
|
|
if os.path.exists('lockfile'):
|
|
raise FileExistsError
|
|
with open('tmplockfile', 'x') as f:
|
|
f.flush()
|
|
os.fsync(f.fileno())
|
|
os.replace('tmplockfile', 'lockfile')
|
|
except FileExistsError:
|
|
sys.exit('Another instance is already running in the same working directory!')
|
|
|
|
# Set up logging
|
|
try:
|
|
os.mkdir('logs')
|
|
except FileExistsError:
|
|
pass
|
|
|
|
logging.basicConfig(level=logging.INFO, format='%(message)s')
|
|
logger = logging.getLogger()
|
|
logger.addHandler(logging.FileHandler(f"logs/{appstate['timestamp']}.log", 'w'))
|
|
print = logger.info
|
|
appstate['logger'] = logger
|
|
|
|
# Get the flag
|
|
try:
|
|
flag = sys.argv[2]
|
|
except:
|
|
flag = None
|
|
|
|
if flag not in ['buildonly', 'checkonly', 'force', 'experimental', None]:
|
|
clean_exit(f"Unknown flag: {flag}", appstate)
|
|
|
|
appstate['flag'] = flag
|
|
appstate['microg_updated'] = False
|
|
|
|
print(f"Started building ReVanced apps at {time.strftime('%d %B, %Y %H:%M:%S')}")
|
|
print('----------------------------------------------------------------------')
|
|
|
|
# Read configs
|
|
try:
|
|
appstate['build_config']=cp.ConfigParser()
|
|
appstate['build_config'].read_file(open('build_config.toml', 'r'))
|
|
except FileNotFoundError:
|
|
clean_exit('No build config provided, exiting. Please look at the GitHub page for more information:\n https://github.com/SinTan1729/ReVancedBuilder', appstate)
|
|
|
|
appstate['notification_config'] = cp.ConfigParser()
|
|
appstate['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:
|
|
clean_exit(e, appstate)
|
|
|
|
try:
|
|
with open('versions.json', 'r') as f:
|
|
appstate['present_vers'] = json.load(f)
|
|
except:
|
|
# We'll treat empty as 0 later
|
|
appstate['present_vers'] = json.loads('{}')
|
|
|
|
appstate['up-to-date'] = True
|
|
# send_notif(appstate, error=False) # <,,,,,,,,<,,,,,,,,,,,,,
|
|
if flag != 'buildonly':
|
|
appstate = update_tools(appstate)
|
|
appstate = update_microg(appstate)
|
|
if not appstate['up-to-date'] or flag == 'force':
|
|
appstate = get_apks(appstate)
|
|
|
|
if (flag != 'checkonly' and not appstate['up-to-date']) or flag in ['force', 'buildonly']:
|
|
build_apps(appstate)
|
|
move_apps(appstate)
|
|
|
|
# Update version numbers in the versions.json file
|
|
if appstate['up-to-date'] and flag != 'buildonly':
|
|
print('There\'s nothing to do.')
|
|
elif flag != ['checkonly']:
|
|
send_notif(appstate)
|
|
try:
|
|
os.rename('versions.json', 'versions-old.json')
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
if flag != 'buildonly':
|
|
with open('versions.json', 'w') as f:
|
|
json.dump(appstate['present_vers'], f, indent=4)
|
|
try:
|
|
subprocess.run(f"{appstate['build_config']['post_script']['file']} {timestamp}", shell=True)
|
|
except:
|
|
pass
|
|
|
|
# Delete the lockfile
|
|
os.remove('lockfile') |