nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at netboot-syslinux-multiplatform 100 lines 3.6 kB view raw
1#! /usr/bin/env nix-shell 2#! nix-shell -i python3 -p python3 python3.pkgs.packaging python3.pkgs.requests python3.pkgs.xmltodict 3import json 4import pathlib 5import logging 6import requests 7import sys 8import xmltodict 9from packaging import version 10 11updates_url = "https://www.jetbrains.com/updates/updates.xml" 12versions_file_path = pathlib.Path(__file__).parent.joinpath("versions.json").resolve() 13 14logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) 15 16 17def one_or_more(x): 18 return x if isinstance(x, list) else [x] 19 20 21def download_channels(): 22 logging.info("Checking for updates from %s", updates_url) 23 updates_response = requests.get(updates_url) 24 updates_response.raise_for_status() 25 root = xmltodict.parse(updates_response.text) 26 products = root["products"]["product"] 27 return { 28 channel["@name"]: channel 29 for product in products 30 for channel in one_or_more(product["channel"]) 31 } 32 33 34def build_version(build): 35 build_number = build["@fullNumber"] if "@fullNumber" in build else build["@number"] 36 return version.parse(build_number) 37 38 39def latest_build(channel): 40 builds = one_or_more(channel["build"]) 41 latest = max(builds, key=build_version) 42 return latest 43 44 45def download_sha256(url): 46 url = f"{url}.sha256" 47 download_response = requests.get(url) 48 download_response.raise_for_status() 49 return download_response.content.decode('UTF-8').split(' ')[0] 50 51 52channels = download_channels() 53 54 55def update_product(name, product): 56 update_channel = product["update-channel"] 57 logging.info("Updating %s", name) 58 channel = channels.get(update_channel) 59 if channel is None: 60 logging.error("Failed to find channel %s.", update_channel) 61 logging.error("Check that the update-channel in %s matches the name in %s", versions_file_path, updates_url) 62 else: 63 try: 64 build = latest_build(channel) 65 new_version = build["@version"] 66 new_build_number = build["@fullNumber"] 67 if "EAP" not in channel["@name"]: 68 version_or_build_number = new_version 69 else: 70 version_or_build_number = new_build_number 71 version_number = new_version.split(' ')[0] 72 download_url = product["url-template"].format(version=version_or_build_number, versionMajorMinor=version_number) 73 product["url"] = download_url 74 if "sha256" not in product or product.get("build_number") != new_build_number: 75 logging.info("Found a newer version %s with build number %s.", new_version, new_build_number) 76 product["version"] = new_version 77 product["build_number"] = new_build_number 78 product["sha256"] = download_sha256(download_url) 79 else: 80 logging.info("Already at the latest version %s with build number %s.", new_version, new_build_number) 81 except Exception as e: 82 logging.exception("Update failed:", exc_info=e) 83 logging.warning("Skipping %s due to the above error.", name) 84 logging.warning("It may be out-of-date. Fix the error and rerun.") 85 86 87def update_products(products): 88 for name, product in products.items(): 89 update_product(name, product) 90 91 92with open(versions_file_path, "r") as versions_file: 93 versions = json.load(versions_file) 94 95for products in versions.values(): 96 update_products(products) 97 98with open(versions_file_path, "w") as versions_file: 99 json.dump(versions, versions_file, indent=2) 100 versions_file.write("\n")