import requests import logging import os import argparse from tqdm import tqdm import re logging.basicConfig(format='%(asctime)s %(levelname)-8s %(message)s', level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S') log = logging.getLogger(__name__) githubApi = "https://api.github.com/repos" applications = { "freecad": { "org": "FreeCAD", # https://github.com/FreeCAD/FreeCAD-Bundle/releases "repo": "FreeCAD-Bundle", "assetRegex": "FreeCAD_weekly-builds-.*-x86_64-.*AppImage$" }, "bambustudio": { "org": "bambulab", # https://github.com/bambulab/BambuStudio/releases "repo": "BambuStudio", "assetRegex": "Bambu_Studio_linux_ubuntu_24.*AppImage$" }, } # 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 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 if os.path.isfile(assetName): log.info("Application " + app + " is already up-to-date (" + assetName + ")") return # 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) # Download to file with progress bar download(assetUrl, assetName + ".tmp") # Rename os.rename(assetName + ".tmp", assetName) # rm link if os.path.isfile(app): os.remove(app) # todo remove old appimages # chmod os.chmod(assetName, 0o755) # link os.symlink(assetName, app) log.info("Application " + app + " updated") if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--app", type=str, required=True, help="Application name") args = parser.parse_args() 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)