appImage-updater/update.py

131 lines
4.2 KiB
Python
Raw Normal View History

2024-08-18 21:17:43 +00:00
import requests
import logging
import os
import argparse
from tqdm import tqdm
import re
githubApi = "https://api.github.com/repos"
applications = {
"freecad": { "org": "FreeCAD", # https://github.com/FreeCAD/FreeCAD-Bundle/releases
2024-08-18 22:56:23 +00:00
"repo": "FreeCAD-Bundle",
"assetRegex": "FreeCAD_weekly-builds-.*-x86_64-.*AppImage$" },
2024-08-18 21:17:43 +00:00
"bambustudio": { "org": "bambulab", # https://github.com/bambulab/BambuStudio/releases
2024-08-18 22:56:23 +00:00
"repo": "BambuStudio",
# "assetRegex": "Bambu_Studio_linux_ubuntu_24.*AppImage$" },
"assetRegex": "Bambu_Studio_ubuntu.*AppImage$" },
2024-08-18 21:17:43 +00:00
}
2024-08-18 22:56:23 +00:00
# get script path
scriptFolder = os.path.dirname(os.path.realpath(__file__))
2024-08-18 21:17:43 +00:00
# Cortesy: https://gist.github.com/yanqd0/c13ed29e29432e3cf3e7c38467f42f51
def download(url: str, fname: str, chunk_size=1024):
log.info("Downloading " + url)
resp = requests.get(url, stream=True)
total = int(resp.headers.get('content-length', 0))
with open(fname, 'wb') as file, tqdm(
desc=fname,
total=total,
unit='iB',
unit_scale=True,
unit_divisor=1024,
) as bar:
for data in resp.iter_content(chunk_size=chunk_size):
size = file.write(data)
bar.update(size)
def main(app):
org = applications[app]["org"]
repo = applications[app]["repo"]
# releaseTag = applications[app]["releaseTag"]
url = githubApi + "/" + org + "/" + repo + "/releases"
log.debug("url: " + url)
response = requests.get(url)
data = response.json()
# log.info("response: " + str(data))
assets = data[0]["assets"]
# log.info("Assets: " + str(assets))
assetName = None
assetUrl = None
for asset in assets:
# Eg. "FreeCAD_weekly-builds-38467-conda-Linux-x86_64-py311.AppImage"
# regex match
log.debug("Asset: " + asset["name"])
2024-08-18 21:17:43 +00:00
if re.match(applications[app]["assetRegex"], asset["name"]):
log.debug("Asset: " + str(asset["name"]))
assetName = asset["name"]
assetUrl = asset["browser_download_url"]
break
if assetName:
# if file exists
2024-08-18 22:56:23 +00:00
if os.path.isfile(scriptFolder + "/" + assetName):
2024-08-18 21:17:43 +00:00
log.info("Application " + app + " is already up-to-date (" + assetName + ")")
2024-08-18 22:35:04 +00:00
else: # Download it
# Eg. https://github.com/FreeCAD/FreeCAD-Bundle/releases/download/weekly-builds/FreeCAD_weekly-builds-38467-conda-Linux-x86_64-py311.AppImage
log.debug("url: " + assetUrl)
2024-08-18 21:17:43 +00:00
2024-08-18 22:35:04 +00:00
# Download to file with progress bar
2024-08-18 22:56:23 +00:00
download(assetUrl, scriptFolder + "/" + assetName + ".tmp")
2024-08-18 21:17:43 +00:00
2024-08-18 22:35:04 +00:00
# Rename
2024-08-18 22:56:23 +00:00
os.rename(scriptFolder + "/" + assetName + ".tmp", assetName)
2024-08-18 21:17:43 +00:00
2024-08-18 22:35:04 +00:00
# todo remove old appimages
# chmod
2024-08-18 22:56:23 +00:00
os.chmod(scriptFolder + "/" + assetName, 0o755)
2024-08-18 21:17:43 +00:00
2024-08-18 22:56:23 +00:00
# get user home directory
home = os.path.expanduser("~")
2024-08-18 21:17:43 +00:00
# link
2024-08-18 22:56:23 +00:00
if os.path.isfile(scriptFolder + "/" + app):
os.remove(scriptFolder + "/" + app)
os.symlink(scriptFolder + "/" + assetName, scriptFolder + "/" + app)
# Add link to start menu
desktopLink = home + "/.local/share/applications/" + app + ".desktop"
if os.path.isfile(desktopLink):
os.remove(desktopLink)
os.symlink(scriptFolder + "/" + app + ".desktop", desktopLink)
2024-08-18 21:17:43 +00:00
2024-08-18 22:35:04 +00:00
# log.info("Application " + app + " updated")
else:
log.error("No matching asset found in the latest release!")
exit(2)
2024-08-18 21:17:43 +00:00
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--app", type=str, required=True, help="Application name")
parser.add_argument("-v", action='store_true', help="Show verbose log")
2024-08-18 21:17:43 +00:00
args = parser.parse_args()
if args.v:
loglevel = logging.DEBUG
else:
loglevel = logging.INFO
logging.basicConfig(format='%(asctime)s %(levelname)-8s %(message)s', level=loglevel, datefmt='%Y-%m-%d %H:%M:%S')
log = logging.getLogger(__name__)
2024-08-18 21:17:43 +00:00
for app in applications:
if app == args.app:
main(app)
exit(0)
break
log.error("Application '" + args.app + "' not found")
log.error("Supported applications: '" + "', '".join((applications.keys())) + "'")
exit(1)