diff --git a/.idea/misc.xml b/.idea/misc.xml index c137101..6f37644 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,7 @@ + + \ No newline at end of file diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 0000000..b1e9b6f --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,17 @@ +# Maintainer: linux-aarhus + +pkgname='manjaro-get-iso' +pkgver=0.5 +pkgrel=1 +pkgdesc='A tool to download Manjaro ISO' +arch=('any') +url='https://scm.nix.dk/root/manjaro-get-iso' +licnse=('GPL') +depends=('python-requests' 'p7zip') +source=("${url}/archive/v${pkgver}.tar.gz") + +package() { + install -d m755 "$pkgdir/usr/bin" + install -m755 "$srcdir/$pkgname/get-iso" "$pkgdir/usr/bin" +} +sha256sums=('2a9a4c69003cbe435f59e8774cb69a22cdfd758211452ae3ff7a6b855b51a4b1') diff --git a/get-iso b/get-iso index 902fd67..aacf489 100755 --- a/get-iso +++ b/get-iso @@ -1,22 +1,29 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # -*- coding: utf-8 -*- # # @linux-aarhus - root.nix.dk -# License: GNU GPL, version 3 or later; https://www.gnu.org/licenses/gpl.html +# License: GNU GPL, version 3 or later; import argparse -import subprocess -import sys import os import requests +import subprocess +import sys import time -from typing import List +import requests.exceptions from pathlib import Path +from pprint import pprint -DEF_URL = "https://gitlab.manjaro.org/webpage/iso-info/-/raw/master/file-info.json" +DEF_URL = \ + "https://gitlab.manjaro.org/webpage/iso-info/-/raw/master/file-info.json" FOLDER = Path.home() PROG_NAME = os.path.basename(__file__) -PROG_VERSION = "0.2" +PROG_VERSION = "0.6" GNU_URL = "https://www.gnu.org/licenses/gpl.html" +REVIEW_URL = \ + "https://api.github.com/repos/manjaro/release-review/releases/latest" +REVIEW_DEV_URL = \ + "https://api.github.com/repos/manjaro-edition/download/releases/latest" +review_editions = ["gnome", "kde", "xfce"] def download_file(url: str, folder_name: str) -> bool: @@ -28,7 +35,6 @@ def download_file(url: str, folder_name: str) -> bool: block_size = 1024 if total_size_in_bytes < block_size: block_size = total_size_in_bytes - with open(path, "wb") as f: progress = 0 for data in response.iter_content(block_size): @@ -37,10 +43,10 @@ def download_file(url: str, folder_name: str) -> bool: progress += len(data) else: progress += block_size - print(f"Receiving <- {progress}/{total_size_in_bytes}", end="\r") - + print(f"Downloading {round(progress/1024/1024)}MiB of " + f"{round(total_size_in_bytes/1024/1024)}MiB", end="\r") except Exception as e: - print(e) + print(f"{e}") return False return True @@ -56,75 +62,217 @@ def get_definitions(url: str) -> dict: return iso_def -def init_iso_list(url: str) -> List: +def init_iso_list(url: str, review: bool = False, developer: bool = False) -> list: + if review: + return init_review_iso_list(url) + if developer: + return init_dev_preview_iso_list(url) + return init_official_iso_list(url) + + +def init_official_iso_list(url: str) -> list: data = get_definitions(url) - data_official = data.get("official") - data_community = data.get("community") + data_official: dict = data.get("official") + data_community: dict = data.get("community") init_iso_result = [] for ok, ov in data_official.items(): try: init_iso_result.append({"name": ok, - "full": {"img": ov["image"], "sig": ov["signature"]}, - "minimal": {"img": ov["minimal"]["image"], "sig": ov["minimal"]["signature"]} + "full": { + "img": ov["image"], + "sig": ov["signature"] + }, + "minimal": { + "img": ov["minimal"]["image"], + "sig": ov["minimal"]["signature"] + } }) - except: + except KeyError: continue - for ck, cv in data_community.items(): try: init_iso_result.append({"name": ck, - "full": {"img": cv["image"], "sig": cv["signature"]}, - "minimal": {"img": cv["minimal"]["image"], "sig": cv["minimal"]["signature"]} - }) - except: + "full": { + "img": cv["image"], + "sig": cv["signature"] + }, + "minimal": { + "img": cv["minimal"]["image"], + "sig": cv["minimal"]["signature"] + }}) + except KeyError: continue + return init_iso_result + + +def init_review_iso_list(url: str) -> list: + """ + Get data from review endpoint + :param url: + :return: + """ + # from the assets list we want to extract + # the browser_download_url propoerty for each asset + init_iso_result = [] + data = get_definitions(url) + data_assets: dict = data.get("assets") + url_list = [] + for asset in data_assets: + url_list.append(asset["browser_download_url"]) + + minimal = "minimal" + sha256sum = ".iso.sha256" + part = ".iso.z" + for edition in review_editions: + urls = [x for x in url_list if edition in x] + full_iso = [x for x in urls if minimal not in x] + minimal_iso = [x for x in urls if minimal in x] + f_part = [x for x in full_iso if part in x] + f_256sum = [x for x in full_iso if sha256sum in x] + m_part = [x for x in minimal_iso if part in x] + m_256sum = [x for x in minimal_iso if sha256sum in x] + result = {"name": edition, + "full": {"img": f_part, "shasum": f_256sum[0]}, + "minimal": {"img": m_part, "shasum": m_256sum[0]}} + init_iso_result.append(result) + + return init_iso_result + + +def init_dev_preview_iso_list(url: str) -> list: + """ + Get data from review endpoint + :param url: + :return: + """ + # from the assets list we want to extract + # the browser_download_url propoerty for each asset + init_iso_result = [] + for edition in review_editions: + if edition == "kde": + edition = "plasma" + data = get_definitions(url.replace("edition", edition)) + data_assets: dict = data.get("assets") + url_list = [] + for asset in data_assets: + url_list.append(asset["browser_download_url"]) + minimal = "minimal" + sha256sum = ".iso.sha256" + part = ".iso.z" + + full_iso = [x for x in url_list if minimal not in x] + minimal_iso = [x for x in url_list if minimal in x] + f_part = [x for x in full_iso if part in x] + f_256sum = [x for x in full_iso if sha256sum in x] + m_part = [x for x in minimal_iso if part in x] + m_256sum = [x for x in minimal_iso if sha256sum in x] + result = {"name": edition, + "full": {"img": f_part, "shasum": f_256sum[0]}, + "minimal": {"img": m_part, "shasum": m_256sum[0]} + } + + init_iso_result.append(result) return init_iso_result def download(url: str) -> bool: - print(f'Downloading: {url.split("/")[-1]}') + print(f'Download: {url.split("/")[-1]}') success = download_file(url, f"{FOLDER}") return success def main(): - iso_files = init_iso_list(DEF_URL) + iso_files = init_iso_list(DEF_URL, review=False) choices = [] for c in iso_files: choices.append(c["name"]) parser = argparse.ArgumentParser( prog=f"{PROG_NAME}", - description="This tool will download a named Manjaro ISO and verify the signature", + description="This tool will download a named Manjaro ISO", epilog=f"{PROG_NAME} v. {PROG_VERSION} - GPL v3 or later <{GNU_URL}>") parser.add_argument("edition", type=str, - help="edition e.g. plasma or xfce", + help="Edition e.g. plasma or xfce.", choices=choices) parser.add_argument("-f", "--full", required=False, action="store_true", help="Download full ISO") + previews = parser.add_argument_group("Previews") + preview = previews.add_mutually_exclusive_group() + preview.add_argument("-r", "--review", + required=False, + action="store_true", + help="Get Latest Release Review ISO") + preview.add_argument("-d", "--development", + required=False, + action="store_true", + help="Get Latest Developer Preview ISO") + args = parser.parse_args() - if args.edition is None: - parser.print_usage() - edition = [x for x in iso_files if args.edition == x["name"]] - for x in edition: - if args.full: - iso = x["full"] + + if args.review is not None: + if args.edition == "plasma": + args.edition = "kde" + if args.edition in review_editions: + iso_files = init_iso_list(REVIEW_URL, review=True) else: - iso = x["minimal"] + print("Invalid review edition. Valid editions: " + + ", ".join(review_editions)) + sys.exit(1) + + if args.development is not None: + if args.edition in review_editions: + iso_files = init_iso_list(REVIEW_DEV_URL, developer=True) + else: + print("Invalid review edition. Valid editions: " + + ", ".join(review_editions)) + sys.exit(1) + + edition = [x for x in iso_files if args.edition == x["name"]] + + if args.full: + iso = edition[0]["full"] + else: + iso = edition[0]["minimal"] + + if args.review or args.development: + sha_result = download(iso["shasum"]) + shaname = iso["shasum"].split("/")[-1] + isozip = [x for x in iso["img"] if ".iso.zip" in x] + zipname = isozip[0].split("/")[-1] + zip_result = False + for part in iso["img"]: + zip_result = download(part) + if not zip_result: + break + + if zip_result and sha_result: + subprocess.run(["7z", "-y", "t", f"{zipname}"], + cwd=f"{FOLDER}") + subprocess.run(["7z", "-y", "x", f"{zipname}"], + cwd=f"{FOLDER}") + print("\nWait for checksum to complete ...") + subprocess.run(["sha256sum", "-c", f"{shaname}"], + cwd=f"{FOLDER}") + else: + print("Download failied") + sys.exit(1) + + else: iso_result = download(iso["img"]) sig_result = download(iso["sig"]) + if sig_result and iso_result: - print("Wait for verification ...") + print("Wait for verification to complete ...") time.sleep(5) - result = subprocess.run( - ["gpg", "--verify", f'{iso["sig"].split("/")[-1]}'], - cwd=f"{FOLDER}") + subprocess.run(["gpg", "--verify", f'{iso["sig"].split("/")[-1]}'], + cwd=f"{FOLDER}") else: - print("Download ISO failed") - sys.exit(0) + print("Download failed") + sys.exit(1) + sys.exit(0)