diff options
Diffstat (limited to 'nixpkgs/pkgs/games/papermc/update.py')
-rwxr-xr-x | nixpkgs/pkgs/games/papermc/update.py | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/games/papermc/update.py b/nixpkgs/pkgs/games/papermc/update.py new file mode 100755 index 000000000000..6e2d0ec9274e --- /dev/null +++ b/nixpkgs/pkgs/games/papermc/update.py @@ -0,0 +1,145 @@ +#!/usr/bin/env nix-shell +#! nix-shell -i python -p "python3.withPackages (ps: with ps; [ps.requests ])" + +import hashlib +import base64 +import json + +import requests + + +class Version: + def __init__(self, name: str): + self.name: str = name + self.hash: str | None = None + self.build_number: int | None = None + + @property + def full_name(self): + v_name = f"{self.name}-{self.build_number}" + + # this will probably never happen because the download of a build with NoneType in URL would fail + if not self.name or not self.build_number: + print(f"Warning: version '{v_name}' contains NoneType!") + + return v_name + + +class VersionManager: + def __init__(self, base_url: str = "https://api.papermc.io/v2/projects/paper"): + self.versions: list[Version] = [] + self.base_url: str = base_url + + def fetch_versions(self, not_before_minor_version: int = 18): + """ + Fetch all versions after given minor release + """ + + response = requests.get(self.base_url) + + try: + response.raise_for_status() + + except requests.exceptions.HTTPError as e: + print(e) + return + + # we only want versions that are no pre-releases + release_versions = filter( + lambda v_name: 'pre' not in v_name, response.json()["versions"]) + + for version_name in release_versions: + + # split version string, convert to list ot int + version_split = version_name.split(".") + version_split = list(map(int, version_split)) + + # check if version is higher than 1.<not_before_sub_version> + if (version_split[0] > 1) or (version_split[0] == 1 and version_split[1] >= not_before_minor_version): + self.versions.append(Version(version_name)) + + def fetch_latest_version_builds(self): + """ + Set latest build number to each version + """ + + for version in self.versions: + url = f"{self.base_url}/versions/{version.name}" + response = requests.get(url) + + # check that we've got a good response + try: + response.raise_for_status() + + except requests.exceptions.HTTPError as e: + print(e) + return + + # the highest build in response.json()['builds']: + latest_build = response.json()['builds'][-1] + version.build_number = latest_build + + def generate_version_hashes(self): + """ + Generate and set the hashes for all registered versions (versions will are downloaded to memory) + """ + + for version in self.versions: + url = f"{self.base_url}/versions/{version.name}/builds/{version.build_number}/downloads/paper-{version.full_name}.jar" + version.hash = self.download_and_generate_sha256_hash(url) + + def versions_to_json(self): + return json.dumps( + {version.name: {'hash': version.hash, 'version': version.full_name} + for version in self.versions}, + indent=4 + ) + + def write_versions(self, file_name: str): + """ write all processed versions to json """ + # save json to versions.json + with open(file_name, 'w') as f: + f.write(self.versions_to_json() + "\n") + + @staticmethod + def download_and_generate_sha256_hash(url: str) -> str | None: + """ + Fetch the tarball from the given URL. + Then generate a sha256 hash of the tarball. + """ + + try: + # Download the file from the URL + response = requests.get(url) + response.raise_for_status() + + except requests.exceptions.RequestException as e: + print(f"Error: {e}") + return None + + # Create a new SHA-256 hash object + sha256_hash = hashlib.sha256() + + # Update the hash object with chunks of the downloaded content + for byte_block in response.iter_content(4096): + sha256_hash.update(byte_block) + + # Get the hexadecimal representation of the hash + hash_value = sha256_hash.digest() + + # Encode the hash value in base64 + base64_hash = base64.b64encode(hash_value).decode('utf-8') + + # Format it as "sha256-{base64_hash}" + sri_representation = f"sha256-{base64_hash}" + + return sri_representation + + +if __name__ == '__main__': + version_manager = VersionManager() + + version_manager.fetch_versions() + version_manager.fetch_latest_version_builds() + version_manager.generate_version_hashes() + version_manager.write_versions(file_name="versions.json") |