mirror of
https://github.com/SinTan1729/ReVancedBuilder.git
synced 2025-04-10 04:16:02 -05:00
fix: Warnings and errors reported by ruff
This commit is contained in:
parent
ad125bfb7b
commit
ee3eef71aa
5 changed files with 256 additions and 230 deletions
105
src/ReVancedBuilder/APKPure_dl.py
Normal file → Executable file
105
src/ReVancedBuilder/APKPure_dl.py
Normal file → Executable file
|
@ -5,61 +5,62 @@
|
|||
|
||||
import os
|
||||
|
||||
from packaging.version import Version
|
||||
import cloudscraper as scraper
|
||||
from bs4 import BeautifulSoup as bs
|
||||
from packaging.version import Version
|
||||
|
||||
from ReVancedBuilder.Cleanup import err_exit
|
||||
|
||||
# Determine the best version available to download
|
||||
|
||||
|
||||
def apkpure_best_match(version, soup):
|
||||
def apkpure_best_match(version, soup, appstate, apk):
|
||||
try:
|
||||
vers_list_str = [x['data-dt-version'] for x in soup.css.select(f"a[data-dt-apkid^=\"b/APK/\"]")]
|
||||
except:
|
||||
err_exit(
|
||||
f" There was some error getting list of versions of {apk}...", appstate)
|
||||
vers_list_str = [
|
||||
x["data-dt-version"] for x in soup.css.select('a[data-dt-apkid^="b/APK/"]')
|
||||
]
|
||||
except Exception as ex:
|
||||
err_exit(f" There was some error getting list of versions of {apk}: {ex}", appstate)
|
||||
|
||||
vers_list = map(lambda x: Version(x), vers_list_str)
|
||||
|
||||
if version != '0':
|
||||
if version != "0":
|
||||
vers_list = filter(lambda x: x <= Version(version), vers_list)
|
||||
|
||||
max_ver = max(vers_list)
|
||||
return next(filter(lambda x: Version(x) == max_ver, vers_list_str))
|
||||
return next(filter(lambda x: Version(x) == max_ver, vers_list_str))
|
||||
|
||||
|
||||
# Download an apk from apkpure.net
|
||||
|
||||
|
||||
def apkpure_dl(apk, appname, version, hard_version, session, present_vers, flag):
|
||||
def apkpure_dl(apk, appname, version, hard_version, session, present_vers, flag, appstate):
|
||||
res = session.get(f"https://apkpure.com/{appname}/{apk}/versions")
|
||||
res.raise_for_status()
|
||||
soup = bs(res.text, 'html.parser')
|
||||
soup = bs(res.text, "html.parser")
|
||||
|
||||
try:
|
||||
if present_vers[apk] == version and flag != 'force' and os.path.isfile(apk+'.apk'):
|
||||
print(
|
||||
f"Recommended version {version} of {apk} is already present.")
|
||||
if present_vers[apk] == version and flag != "force" and os.path.isfile(apk + ".apk"):
|
||||
print(f"Recommended version {version} of {apk} is already present.")
|
||||
return
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if not hard_version:
|
||||
apkpure_version = apkpure_best_match(version, soup)
|
||||
if version not in [apkpure_version, '0']:
|
||||
apkpure_version = apkpure_best_match(version, soup, appstate, apk)
|
||||
if version not in [apkpure_version, "0"]:
|
||||
print(
|
||||
f"Required version {version} not found in APKPure, choosing version {apkpure_version} instead.")
|
||||
f"Required version {version} not found in APKPure, choosing version {apkpure_version} instead."
|
||||
)
|
||||
version = apkpure_version
|
||||
try:
|
||||
if present_vers[apk] == version and flag != 'force' and os.path.isfile(apk+'.apk'):
|
||||
print(
|
||||
f"Recommended version {version} of {apk} is already present.")
|
||||
if present_vers[apk] == version and flag != "force" and os.path.isfile(apk + ".apk"):
|
||||
print(f"Recommended version {version} of {apk} is already present.")
|
||||
return
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if flag == 'checkonly' and present_vers[apk] != version:
|
||||
if flag == "checkonly" and present_vers[apk] != version:
|
||||
print(f"{apk} has an update ({present_vers[apk]} -> {version})")
|
||||
return
|
||||
|
||||
|
@ -67,16 +68,15 @@ def apkpure_dl(apk, appname, version, hard_version, session, present_vers, flag)
|
|||
|
||||
# Get the version code
|
||||
try:
|
||||
ver_code = soup.css.select(
|
||||
f"a[data-dt-version=\"{version}\"][data-dt-apkid^=\"b/APK/\"]")[0]['data-dt-versioncode']
|
||||
except:
|
||||
err_exit(
|
||||
f" There was some error while downloading {apk}...", appname)
|
||||
ver_code = soup.css.select(f'a[data-dt-version="{version}"][data-dt-apkid^="b/APK/"]')[0][
|
||||
"data-dt-versioncode"
|
||||
]
|
||||
except Exception as ex:
|
||||
err_exit(f" There was some error while downloading {apk}: {ex}", appstate)
|
||||
|
||||
res = session.get(
|
||||
f"https://d.apkpure.com/b/APK/{apk}?versionCode={ver_code}", stream=True)
|
||||
res = session.get(f"https://d.apkpure.com/b/APK/{apk}?versionCode={ver_code}", stream=True)
|
||||
res.raise_for_status()
|
||||
with open(apk+'.apk', 'wb') as f:
|
||||
with open(apk + ".apk", "wb") as f:
|
||||
for chunk in res.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
print(" Done!")
|
||||
|
@ -84,11 +84,11 @@ def apkpure_dl(apk, appname, version, hard_version, session, present_vers, flag)
|
|||
|
||||
# Download apk files, if needed
|
||||
def get_apks(appstate):
|
||||
present_vers = appstate['present_vers']
|
||||
build_config = appstate['build_config']
|
||||
flag = appstate['flag']
|
||||
present_vers = appstate["present_vers"]
|
||||
build_config = appstate["build_config"]
|
||||
flag = appstate["flag"]
|
||||
|
||||
print('Downloading required apk files from APKPure...')
|
||||
print("Downloading required apk files from APKPure...")
|
||||
|
||||
# Create a cloudscraper session
|
||||
session = scraper.create_scraper()
|
||||
|
@ -96,51 +96,60 @@ def get_apks(appstate):
|
|||
# Get latest patches using the ReVanced API
|
||||
try:
|
||||
# Get the first result
|
||||
patches = session.get('https://api.revanced.app/v4/patches/list').json()
|
||||
patches = session.get("https://api.revanced.app/v4/patches/list").json()
|
||||
except session.exceptions.RequestException as e:
|
||||
err_exit(f"Error fetching patches, {e}", appstate)
|
||||
|
||||
for app in build_config:
|
||||
# Check if we need to build an app
|
||||
if not build_config[app].getboolean('build'):
|
||||
if not build_config[app].getboolean("build"):
|
||||
continue
|
||||
|
||||
try:
|
||||
apk = build_config[app]['apk']
|
||||
pretty_name = build_config[app]['pretty_name']
|
||||
apkpure_appname = build_config[app]['apkpure_appname']
|
||||
except:
|
||||
err_exit(f"Invalid config for {app} in build_config!", appstate)
|
||||
apk = build_config[app]["apk"]
|
||||
pretty_name = build_config[app]["pretty_name"]
|
||||
apkpure_appname = build_config[app]["apkpure_appname"]
|
||||
except Exception as ex:
|
||||
err_exit(f"Invalid config for {app} in build_config!: {ex}", appstate)
|
||||
|
||||
print(f"Checking {pretty_name}...")
|
||||
try:
|
||||
required_ver = build_config[app]['version']
|
||||
required_ver = build_config[app]["version"]
|
||||
hard_version = True
|
||||
print(f"Using version {required_ver} of {apk} from build_config.")
|
||||
except:
|
||||
except Exception as ex:
|
||||
print(f"Dealing with exception: {ex}")
|
||||
hard_version = False
|
||||
compatible_vers = []
|
||||
for patch in patches:
|
||||
try:
|
||||
compatible_vers.append(patch['compatiblePackages'][apk][-1])
|
||||
compatible_vers.append(patch["compatiblePackages"][apk][-1])
|
||||
except (KeyError, TypeError):
|
||||
pass
|
||||
|
||||
if not compatible_vers:
|
||||
required_ver = Version('0')
|
||||
required_ver = Version("0")
|
||||
else:
|
||||
required_ver = min(map(lambda x: Version(x), compatible_vers))
|
||||
required_ver = next(filter(lambda x: Version(x) == required_ver, compatible_vers))
|
||||
required_ver = next(filter(lambda x: Version(x) == required_ver, compatible_vers))
|
||||
|
||||
print(f"Chosen required version of {apk} is {required_ver}.")
|
||||
|
||||
if apk in appstate['present_vers'] and appstate['present_vers'][apk] == required_ver:
|
||||
if apk in appstate["present_vers"] and appstate["present_vers"][apk] == required_ver:
|
||||
print("It's already present on disk, so skipping download.")
|
||||
else:
|
||||
apkpure_dl(apk, apkpure_appname, required_ver,
|
||||
hard_version, session, present_vers, flag)
|
||||
apkpure_dl(
|
||||
apk,
|
||||
apkpure_appname,
|
||||
required_ver,
|
||||
hard_version,
|
||||
session,
|
||||
present_vers,
|
||||
flag,
|
||||
appstate,
|
||||
)
|
||||
|
||||
present_vers.update({apk: required_ver})
|
||||
|
||||
appstate['present_vers'] = present_vers
|
||||
appstate["present_vers"] = present_vers
|
||||
return appstate
|
||||
|
|
28
src/ReVancedBuilder/Cleanup.py
Normal file → Executable file
28
src/ReVancedBuilder/Cleanup.py
Normal file → Executable file
|
@ -13,28 +13,28 @@ from ReVancedBuilder.Notifications import send_notif
|
|||
|
||||
|
||||
def move_apps(appstate):
|
||||
build_config = appstate['build_config']
|
||||
print = appstate['logger'].info
|
||||
build_config = appstate["build_config"]
|
||||
print = appstate["logger"].info
|
||||
|
||||
try:
|
||||
os.mkdir('archive')
|
||||
os.mkdir("archive")
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
for app in build_config:
|
||||
if not build_config[app].getboolean('build'):
|
||||
if not build_config[app].getboolean("build"):
|
||||
continue
|
||||
name = build_config[app]['output_name']
|
||||
name = build_config[app]["output_name"]
|
||||
final_name = f"{name}_{appstate['timestamp']}.apk"
|
||||
|
||||
try:
|
||||
os.rename(name+'.apk', 'archive/'+final_name)
|
||||
os.rename(name + ".apk", "archive/" + final_name)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
# sys.exit('There was an error moving the final apk files!')
|
||||
|
||||
# Do some cleanup, keep only the last 3 build's worth of files and a week worth of logs
|
||||
with os.scandir('archive') as dir:
|
||||
with os.scandir("archive") as dir:
|
||||
files = []
|
||||
for f in dir:
|
||||
if name in f.name:
|
||||
|
@ -43,10 +43,10 @@ def move_apps(appstate):
|
|||
files.reverse()
|
||||
for f in files[3:]:
|
||||
os.remove(f)
|
||||
print('Deleted old build '+f.name)
|
||||
print("Deleted old build " + f.name)
|
||||
|
||||
# Delete logs older than 7 days
|
||||
with os.scandir('logs') as dir:
|
||||
with os.scandir("logs") as dir:
|
||||
now = time.time()
|
||||
for f in dir:
|
||||
if f.stat().st_ctime < now - 7 * 86400:
|
||||
|
@ -54,18 +54,18 @@ def move_apps(appstate):
|
|||
|
||||
|
||||
def err_exit(msg, appstate, code=1):
|
||||
print = appstate['logger'].info
|
||||
print = appstate["logger"].info
|
||||
|
||||
try:
|
||||
appstate['notification_config']
|
||||
if appstate['flag'] != 'checkonly':
|
||||
appstate["notification_config"]
|
||||
if appstate["flag"] != "checkonly":
|
||||
send_notif(appstate, error=True)
|
||||
except:
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if msg:
|
||||
print(f"ERROR: {msg}")
|
||||
|
||||
# Delete the lockfile
|
||||
os.remove('lockfile')
|
||||
os.remove("lockfile")
|
||||
sys.exit(code)
|
||||
|
|
56
src/ReVancedBuilder/JAVABuilder.py
Normal file → Executable file
56
src/ReVancedBuilder/JAVABuilder.py
Normal file → Executable file
|
@ -3,9 +3,9 @@
|
|||
# SPDX-FileCopyrightText: 2023 Sayantan Santra <sayantan.santra689@gmail.com>
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
import os
|
||||
import configparser as cp
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from ReVancedBuilder.Cleanup import err_exit
|
||||
|
@ -14,33 +14,33 @@ from ReVancedBuilder.Cleanup import err_exit
|
|||
|
||||
|
||||
def build_apps(appstate):
|
||||
build_config = appstate['build_config']
|
||||
flag = appstate['flag']
|
||||
print = appstate['logger'].info
|
||||
build_config = appstate["build_config"]
|
||||
flag = appstate["flag"]
|
||||
print = appstate["logger"].info
|
||||
|
||||
chosen_patches = cp.ConfigParser()
|
||||
chosen_patches.read('chosen_patches')
|
||||
chosen_patches.read("chosen_patches")
|
||||
|
||||
try:
|
||||
included_patches = json.loads(chosen_patches['patches']['included'])
|
||||
except:
|
||||
included_patches = json.loads(chosen_patches["patches"]["included"])
|
||||
except (KeyError, ValueError):
|
||||
included_patches = []
|
||||
try:
|
||||
excluded_patches = json.loads(chosen_patches['patches']['excluded'])
|
||||
except Exception as e:
|
||||
excluded_patches = json.loads(chosen_patches["patches"]["excluded"])
|
||||
except (KeyError, ValueError):
|
||||
excluded_patches = []
|
||||
|
||||
for app in build_config:
|
||||
# Check if we need to build an app
|
||||
if not build_config[app].getboolean('build'):
|
||||
if not build_config[app].getboolean("build"):
|
||||
continue
|
||||
|
||||
# Build the command to be run
|
||||
cmd = 'java -jar revanced-cli.jar patch -p revanced-patches.rvp'
|
||||
cmd = "java -jar revanced-cli.jar patch -p revanced-patches.rvp"
|
||||
|
||||
try:
|
||||
root = build_config[app].getboolean('root')
|
||||
except:
|
||||
root = build_config[app].getboolean("root")
|
||||
except cp.Error:
|
||||
root = False
|
||||
|
||||
if root:
|
||||
|
@ -51,21 +51,21 @@ def build_apps(appstate):
|
|||
for item in excluded_patches:
|
||||
cmd += f" -e {item}"
|
||||
|
||||
if flag == 'experimental':
|
||||
cmd += ' --experimental'
|
||||
if flag == "experimental":
|
||||
cmd += " --experimental"
|
||||
|
||||
try:
|
||||
keystore = build_config[app]['keystore']
|
||||
keystore = build_config[app]["keystore"]
|
||||
if not root:
|
||||
cmd += f" --keystore {keystore} --keystore-entry-alias=alias --keystore-entry-password=ReVanced --keystore-password=ReVanced"
|
||||
except:
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
apk = build_config[app]['apk']
|
||||
pretty_name = build_config[app]['pretty_name']
|
||||
output_name = build_config[app]['output_name']
|
||||
except:
|
||||
apk = build_config[app]["apk"]
|
||||
pretty_name = build_config[app]["pretty_name"]
|
||||
output_name = build_config[app]["output_name"]
|
||||
except KeyError:
|
||||
err_exit(f"Invalid config for {app} in build_config!", appstate)
|
||||
|
||||
cmd += f" -o {output_name}.apk {apk}.apk"
|
||||
|
@ -76,17 +76,17 @@ def build_apps(appstate):
|
|||
print(f"Building {pretty_name} (nonroot) using '{cmd}'")
|
||||
|
||||
try:
|
||||
with subprocess.Popen(cmd, shell=True, bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout as output:
|
||||
with subprocess.Popen(
|
||||
cmd, shell=True, bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
).stdout as output:
|
||||
for line in output:
|
||||
line_utf = line.decode('utf-8').strip('\n')
|
||||
line_utf = line.decode("utf-8").strip("\n")
|
||||
if line_utf:
|
||||
print(line_utf)
|
||||
except Exception as e:
|
||||
err_exit(
|
||||
f"There was an error while building {pretty_name}!\n{e}", appstate)
|
||||
err_exit(f"There was an error while building {pretty_name}!\n{e}", appstate)
|
||||
|
||||
try:
|
||||
os.rename(output_name+'.apk', output_name+'.apk')
|
||||
os.rename(output_name + ".apk", output_name + ".apk")
|
||||
except FileNotFoundError:
|
||||
err_exit(
|
||||
f"There was an error while building {pretty_name}!", appstate)
|
||||
err_exit(f"There was an error while building {pretty_name}!", appstate)
|
||||
|
|
110
src/ReVancedBuilder/Notifications.py
Normal file → Executable file
110
src/ReVancedBuilder/Notifications.py
Normal file → Executable file
|
@ -5,97 +5,99 @@
|
|||
|
||||
import json
|
||||
import re
|
||||
import requests as req
|
||||
import subprocess
|
||||
|
||||
import requests as req
|
||||
|
||||
|
||||
def send_notif(appstate, error=False):
|
||||
print = appstate['logger'].info
|
||||
timestamp = appstate['timestamp']
|
||||
print = appstate["logger"].info
|
||||
timestamp = appstate["timestamp"]
|
||||
|
||||
if error:
|
||||
msg = f"There was an error during build! Please check the logs.\nTimestamp: {timestamp}"
|
||||
else:
|
||||
notification_config = appstate['notification_config']
|
||||
build_config = appstate['build_config']
|
||||
present_vers = appstate['present_vers']
|
||||
flag = appstate['flag']
|
||||
build_config = appstate["build_config"]
|
||||
present_vers = appstate["present_vers"]
|
||||
|
||||
msg = json.dumps(present_vers, indent=0)
|
||||
msg = re.sub('("|\{|\}|,)', '', msg).strip('\n')
|
||||
msg = re.sub('("|\{|\}|,)', "", msg).strip("\n")
|
||||
|
||||
msg = msg.replace('revanced-', 'ReVanced ')
|
||||
msg = msg.replace('cli', 'CLI')
|
||||
msg = msg.replace('integrations', 'Integrations')
|
||||
msg = msg.replace('patches', 'Patches')
|
||||
msg = msg.replace("revanced-", "ReVanced ")
|
||||
msg = msg.replace("cli", "CLI")
|
||||
msg = msg.replace("integrations", "Integrations")
|
||||
msg = msg.replace("patches", "Patches")
|
||||
|
||||
for app in build_config:
|
||||
if not build_config[app].getboolean('build'):
|
||||
if not build_config[app].getboolean("build"):
|
||||
continue
|
||||
msg = msg.replace(
|
||||
build_config[app]['apk'], build_config[app]['pretty_name'])
|
||||
msg = msg.replace(build_config[app]["apk"], build_config[app]["pretty_name"])
|
||||
|
||||
msg += '\nTimestamp: ' + timestamp
|
||||
if appstate['gmscore_updated']:
|
||||
msg += '\nGmsCore was updated.'
|
||||
msg += "\nTimestamp: " + timestamp
|
||||
if appstate["gmscore_updated"]:
|
||||
msg += "\nGmsCore was updated."
|
||||
|
||||
config = appstate['notification_config']
|
||||
config = appstate["notification_config"]
|
||||
for entry in config:
|
||||
if not config[entry].getboolean('enabled'):
|
||||
if not config[entry].getboolean("enabled"):
|
||||
continue
|
||||
encoded_title = '⚙⚙⚙ ReVanced Build ⚙⚙⚙'.encode('utf-8')
|
||||
encoded_title = "⚙⚙⚙ ReVanced Build ⚙⚙⚙".encode("utf-8")
|
||||
|
||||
if entry == 'ntfy':
|
||||
print('Sending notification through ntfy.sh...')
|
||||
if entry == "ntfy":
|
||||
print("Sending notification through ntfy.sh...")
|
||||
try:
|
||||
url = config[entry]['url']
|
||||
topic = config[entry]['topic']
|
||||
except:
|
||||
print('URL or TOPIC not provided!')
|
||||
url = config[entry]["url"]
|
||||
topic = config[entry]["topic"]
|
||||
except KeyError:
|
||||
print("URL or TOPIC not provided!")
|
||||
continue
|
||||
headers = {'Icon': 'https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Revanced-logo-round.svg/240px-Revanced-logo-round.svg.png',
|
||||
'Title': encoded_title}
|
||||
headers = {
|
||||
"Icon": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Revanced-logo-round.svg/240px-Revanced-logo-round.svg.png",
|
||||
"Title": encoded_title,
|
||||
}
|
||||
try:
|
||||
token = config[entry]['token']
|
||||
headers['Authorization'] = 'Bearer ' + token
|
||||
except:
|
||||
token = config[entry]["token"]
|
||||
headers["Authorization"] = "Bearer " + token
|
||||
except KeyError:
|
||||
continue
|
||||
try:
|
||||
req.post(f"{url}/{topic}", msg, headers=headers)
|
||||
except Exception as e:
|
||||
print('Failed!' + str(e))
|
||||
except Exception as ex:
|
||||
print(f"Failed with exception: {ex}")
|
||||
|
||||
elif entry == 'gotify':
|
||||
print('Sending notification through Gotify...')
|
||||
elif entry == "gotify":
|
||||
print("Sending notification through Gotify...")
|
||||
try:
|
||||
url = config[entry]['url']
|
||||
token = config[entry]['token']
|
||||
except:
|
||||
print('URL or TOKEN not provided!')
|
||||
url = config[entry]["url"]
|
||||
token = config[entry]["token"]
|
||||
except KeyError:
|
||||
print("URL or TOKEN not provided!")
|
||||
continue
|
||||
data = {'Title': encoded_title, 'message': msg, 'priority': '5'}
|
||||
data = {"Title": encoded_title, "message": msg, "priority": "5"}
|
||||
try:
|
||||
req.post(f"{url}/message?token={token}", data)
|
||||
except Exception as e:
|
||||
print('Failed!' + str(e))
|
||||
print("Failed!" + str(e))
|
||||
|
||||
elif entry == 'telegram':
|
||||
print('Sending notification through Telegram...')
|
||||
elif entry == "telegram":
|
||||
print("Sending notification through Telegram...")
|
||||
try:
|
||||
chat = config[entry]['chat']
|
||||
token = config[entry]['token']
|
||||
except:
|
||||
print('CHAT or TOKEN not provided!')
|
||||
chat = config[entry]["chat"]
|
||||
token = config[entry]["token"]
|
||||
except KeyError:
|
||||
print("CHAT or TOKEN not provided!")
|
||||
continue
|
||||
cmd = f"./telegram.sh -t {token} -c {chat} -T {encoded_title} -M \"{msg}\""
|
||||
cmd = f'./telegram.sh -t {token} -c {chat} -T {encoded_title} -M "{msg}"'
|
||||
try:
|
||||
with subprocess.Popen(cmd, shell=True, bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout as output:
|
||||
with subprocess.Popen(
|
||||
cmd, shell=True, bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
).stdout as output:
|
||||
for line in output:
|
||||
line_utf = line.decode('utf-8').strip('\n')
|
||||
line_utf = line.decode("utf-8").strip("\n")
|
||||
if line_utf:
|
||||
print(line_utf)
|
||||
except Exception as e:
|
||||
err_exit(f"Failed!\n{e}", appstate)
|
||||
except Exception as ex:
|
||||
print(f"Failed to send notification with exception: {ex}")
|
||||
|
||||
else:
|
||||
print('Don\'t know how to send notifications to ' + entry)
|
||||
print("Don't know how to send notifications to " + entry)
|
||||
|
|
|
@ -3,93 +3,105 @@
|
|||
# SPDX-FileCopyrightText: 2023 Sayantan Santra <sayantan.santra689@gmail.com>
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
import sys
|
||||
import os
|
||||
import configparser as cp
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
import requests as req
|
||||
from packaging.version import Version
|
||||
from datetime import datetime
|
||||
|
||||
from ReVancedBuilder.APKPure_dl import get_apks
|
||||
from ReVancedBuilder.Cleanup import err_exit, move_apps
|
||||
from ReVancedBuilder.JAVABuilder import build_apps
|
||||
from ReVancedBuilder.Notifications import send_notif
|
||||
from ReVancedBuilder.Cleanup import move_apps, err_exit
|
||||
|
||||
|
||||
# Update the ReVanced tools, if needed
|
||||
def update_tools(appstate):
|
||||
for item in ['revanced-cli', 'revanced-patches']:
|
||||
for item in ["revanced-cli", "revanced-patches"]:
|
||||
print(f"Checking updates for {item}...")
|
||||
tools = appstate['tools']
|
||||
tool = next(filter(lambda x: x['repository'] == 'revanced/'+item and x['content_type'] not in ['application/pgp-keys', 'application/json'], tools))
|
||||
latest_ver = Version(tool['version'])
|
||||
tools = appstate["tools"]
|
||||
tool = next(
|
||||
filter(
|
||||
lambda x: x["repository"] == "revanced/" + item
|
||||
and x["content_type"] not in ["application/pgp-keys", "application/json"],
|
||||
tools,
|
||||
)
|
||||
)
|
||||
latest_ver = Version(tool["version"])
|
||||
|
||||
try:
|
||||
present_ver = Version(appstate['present_vers'][item])
|
||||
present_ver = Version(appstate["present_vers"][item])
|
||||
except KeyError:
|
||||
present_ver = Version('0')
|
||||
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
|
||||
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':
|
||||
if flag != "checkonly":
|
||||
print(f"Downloading {output_file}...")
|
||||
res = req.get(tool['browser_download_url'], stream=True)
|
||||
res = req.get(tool["browser_download_url"], stream=True)
|
||||
res.raise_for_status()
|
||||
with open(output_file, 'wb') as f:
|
||||
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)})
|
||||
appstate["present_vers"].update({item: str(latest_ver)})
|
||||
print("Done!")
|
||||
|
||||
return appstate
|
||||
|
||||
|
||||
# Update GmsCore, if needed
|
||||
def update_gmscore(appstate):
|
||||
print('Checking updates for GmsCore...')
|
||||
print("Checking updates for GmsCore...")
|
||||
# Pull the latest information using the ReVanced API
|
||||
try:
|
||||
data = req.get('https://api.revanced.app/v2/gmscore/releases/latest').json()['release']
|
||||
data = req.get("https://api.revanced.app/v2/gmscore/releases/latest").json()["release"]
|
||||
except req.exceptions.RequestException as e:
|
||||
err_exit(f"Error fetching GmsCore information, {e}", appstate)
|
||||
|
||||
latest_ver = Version(data['metadata']['tag_name'])
|
||||
|
||||
latest_ver = Version(data["metadata"]["tag_name"])
|
||||
|
||||
try:
|
||||
present_ver = Version(appstate['present_vers']['GmsCore'])
|
||||
present_ver = Version(appstate["present_vers"]["GmsCore"])
|
||||
except KeyError:
|
||||
present_ver = Version('0')
|
||||
present_ver = Version("0")
|
||||
|
||||
try:
|
||||
variant = appstate['build_config']['gmscore']['variant']
|
||||
variant = appstate["build_config"]["gmscore"]["variant"]
|
||||
except KeyError:
|
||||
variant = "regular"
|
||||
|
||||
if variant == "alt":
|
||||
gmscore_link = next(filter(lambda x: "-hw-" in x['name'], data['assets']))['browser_download_url']
|
||||
else:
|
||||
gmscore_link = next(filter(lambda x: "-hw-" not in x['name'], data['assets']))['browser_download_url']
|
||||
|
||||
if flag == 'force' or not os.path.isfile('GmsCore.apk') or present_ver < latest_ver:
|
||||
appstate['up-to-date'] = False
|
||||
print(f"GmsCore has an update ({str(present_ver)} -> {str(latest_ver)})")
|
||||
if flag != 'checkonly':
|
||||
print(f"Downloading GmsCore...")
|
||||
res = req.get(gmscore_link, stream=True)
|
||||
res.raise_for_status()
|
||||
with open('GmsCore.apk', 'wb') as f:
|
||||
for chunk in res.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
appstate['present_vers'].update({'GmsCore': str(latest_ver)})
|
||||
print("Done!")
|
||||
appstate['gmscore_updated'] = True
|
||||
if variant == "alt":
|
||||
gmscore_link = next(filter(lambda x: "-hw-" in x["name"], data["assets"]))[
|
||||
"browser_download_url"
|
||||
]
|
||||
else:
|
||||
gmscore_link = next(filter(lambda x: "-hw-" not in x["name"], data["assets"]))[
|
||||
"browser_download_url"
|
||||
]
|
||||
|
||||
if flag == "force" or not os.path.isfile("GmsCore.apk") or present_ver < latest_ver:
|
||||
appstate["up-to-date"] = False
|
||||
print(f"GmsCore has an update ({str(present_ver)} -> {str(latest_ver)})")
|
||||
if flag != "checkonly":
|
||||
print("Downloading GmsCore...")
|
||||
res = req.get(gmscore_link, stream=True)
|
||||
res.raise_for_status()
|
||||
with open("GmsCore.apk", "wb") as f:
|
||||
for chunk in res.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
appstate["present_vers"].update({"GmsCore": str(latest_ver)})
|
||||
print("Done!")
|
||||
appstate["gmscore_updated"] = True
|
||||
|
||||
return appstate
|
||||
|
||||
|
||||
# ------------------------------
|
||||
# The main function starts here
|
||||
# ------------------------------
|
||||
|
@ -99,111 +111,114 @@ appstate = {}
|
|||
|
||||
# Get a timestamp
|
||||
time = datetime.now()
|
||||
appstate['timestamp'] = time.strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||
appstate["timestamp"] = time.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
# Read arguments
|
||||
try:
|
||||
os.chdir(sys.argv[1])
|
||||
except IndexError:
|
||||
sys.exit('Please provide a working directory as argument!')
|
||||
sys.exit("Please provide a working directory as argument!")
|
||||
except FileNotFoundError:
|
||||
sys.exit('Invalid working directory provided!')
|
||||
sys.exit("Invalid working directory provided!")
|
||||
|
||||
# Try to make sure only one instance is running in a given working directory
|
||||
try:
|
||||
if os.path.exists('lockfile'):
|
||||
if os.path.exists("lockfile"):
|
||||
raise FileExistsError
|
||||
with open('tmplockfile', 'x') as f:
|
||||
with open("tmplockfile", "x") as f:
|
||||
f.flush()
|
||||
os.fsync(f.fileno())
|
||||
os.replace('tmplockfile', 'lockfile')
|
||||
os.replace("tmplockfile", "lockfile")
|
||||
except FileExistsError:
|
||||
sys.exit('Another instance is already running in the same working directory!')
|
||||
sys.exit("Another instance is already running in the same working directory!")
|
||||
|
||||
# Set up logging
|
||||
try:
|
||||
os.mkdir('logs')
|
||||
os.mkdir("logs")
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(message)s')
|
||||
logging.basicConfig(level=logging.INFO, format="%(message)s")
|
||||
logger = logging.getLogger()
|
||||
logger.addHandler(logging.FileHandler(f"logs/{appstate['timestamp']}.log", 'w'))
|
||||
logger.addHandler(logging.FileHandler(f"logs/{appstate['timestamp']}.log", "w"))
|
||||
print = logger.info
|
||||
appstate['logger'] = logger
|
||||
appstate["logger"] = logger
|
||||
|
||||
# Get the flag
|
||||
try:
|
||||
flag = sys.argv[2]
|
||||
except:
|
||||
except IndexError:
|
||||
flag = None
|
||||
|
||||
if flag not in ['buildonly', 'checkonly', 'force', 'experimental', None]:
|
||||
err_exit(f"Unknown flag: {flag}", appstate)
|
||||
if flag not in ["buildonly", "checkonly", "force", "experimental", None]:
|
||||
err_exit(f"Unknown flag: {flag}", appstate)
|
||||
|
||||
appstate['flag'] = flag
|
||||
appstate['gmscore_updated'] = False
|
||||
appstate["flag"] = flag
|
||||
appstate["gmscore_updated"] = False
|
||||
|
||||
print(f"Started building ReVanced apps at {time.strftime('%d %B, %Y %H:%M:%S')}")
|
||||
print('----------------------------------------------------------------------')
|
||||
print("----------------------------------------------------------------------")
|
||||
|
||||
# Read configs
|
||||
try:
|
||||
appstate['build_config']=cp.ConfigParser()
|
||||
appstate['build_config'].read_file(open('build_config', 'r'))
|
||||
appstate["build_config"] = cp.ConfigParser()
|
||||
appstate["build_config"].read_file(open("build_config", "r"))
|
||||
except FileNotFoundError:
|
||||
err_exit('No build config provided, exiting. Please look at the GitHub page for more information:\n https://github.com/SinTan1729/ReVancedBuilder', appstate)
|
||||
err_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')
|
||||
appstate["notification_config"] = cp.ConfigParser()
|
||||
appstate["notification_config"].read("notification_config")
|
||||
|
||||
# Pull the latest information using the ReVanced API
|
||||
try:
|
||||
tools = req.get('https://api.revanced.app/tools').json()['tools']
|
||||
appstate['tools'] = tools
|
||||
tools = req.get("https://api.revanced.app/tools").json()["tools"]
|
||||
appstate["tools"] = tools
|
||||
except req.exceptions.RequestException as e:
|
||||
err_exit(f"Error fetching patch list, {e}", appstate)
|
||||
|
||||
try:
|
||||
with open('versions.json', 'r') as f:
|
||||
appstate['present_vers'] = json.load(f)
|
||||
except:
|
||||
with open("versions.json", "r") as f:
|
||||
appstate["present_vers"] = json.load(f)
|
||||
except FileNotFoundError:
|
||||
# We'll treat empty as 0 later
|
||||
appstate['present_vers'] = json.loads('{}')
|
||||
appstate["present_vers"] = json.loads("{}")
|
||||
|
||||
appstate['up-to-date'] = True
|
||||
appstate["up-to-date"] = True
|
||||
# send_notif(appstate, error=False) # <,,,,,,,,<,,,,,,,,,,,,,
|
||||
if flag != 'buildonly':
|
||||
if flag != "buildonly":
|
||||
appstate = update_tools(appstate)
|
||||
appstate = update_gmscore(appstate)
|
||||
if (not appstate['up-to-date'] and flag != 'checkonly') or flag == 'force':
|
||||
if (not appstate["up-to-date"] and flag != "checkonly") or flag == "force":
|
||||
appstate = get_apks(appstate)
|
||||
|
||||
if (flag != 'checkonly' and not appstate['up-to-date']) or flag in ['force', 'buildonly']:
|
||||
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)
|
||||
if appstate["up-to-date"] and flag != "buildonly":
|
||||
print("There's nothing to do.")
|
||||
elif flag != "checkonly":
|
||||
err_exit("", appstate, 0)
|
||||
try:
|
||||
os.rename('versions.json', 'versions-old.json')
|
||||
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)
|
||||
if flag != "buildonly":
|
||||
with open("versions.json", "w") as f:
|
||||
json.dump(appstate["present_vers"], f, indent=4)
|
||||
try:
|
||||
cmd = f"{appstate['build_config']['post_script']['file']} {appstate['timestamp']}"
|
||||
print(f"Running the post command '{cmd}'")
|
||||
subprocess.run(cmd, shell=True)
|
||||
except:
|
||||
pass
|
||||
except Exception as ex:
|
||||
print(f"Got exception while running the build: '{ex}'")
|
||||
|
||||
# Delete the lockfile
|
||||
os.remove('lockfile')
|
||||
os.remove("lockfile")
|
||||
|
||||
sys.exit(0)
|
||||
|
|
Loading…
Reference in a new issue