diff options
| author | Dennis Camera <cdist@dtnr.ch> | 2021-02-20 21:28:09 +0100 |
|---|---|---|
| committer | Dennis Camera <cdist@dtnr.ch> | 2021-03-19 11:06:07 +0100 |
| commit | 977dd636c62afd0cfca6f5f69b6b6a3e7cd1a487 (patch) | |
| tree | c912522fee5f8d41bb14eb6f8cbeaa6c4ce455c7 /type | |
| parent | c31b8055ba6ad1f3d0e0b91ebf9dcff4475dbc63 (diff) | |
| download | __dtnrch_egov-977dd636c62afd0cfca6f5f69b6b6a3e7cd1a487.tar.gz __dtnrch_egov-977dd636c62afd0cfca6f5f69b6b6a3e7cd1a487.zip | |
[type/__dtnrch_etax_sgnp] Add maintenance script (check-checksums.py)
Diffstat (limited to 'type')
| -rwxr-xr-x | type/__dtnrch_etax_sgnp/files/maint/check-checksums.py | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/type/__dtnrch_etax_sgnp/files/maint/check-checksums.py b/type/__dtnrch_etax_sgnp/files/maint/check-checksums.py new file mode 100755 index 0000000..b08acdf --- /dev/null +++ b/type/__dtnrch_etax_sgnp/files/maint/check-checksums.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 + +import configparser +import datetime +import hashlib +import io +import re +import subprocess +import sys +import urllib.parse +import urllib.request +import tempfile + +def make_request(method, url): + return urllib.request.urlopen( + urllib.request.Request(url, method=method)) + +def human_size(nbytes): + if nbytes > 1000000000: + return "%.2f GB" % (nbytes / 1000000000) + elif nbytes > 1000000: + return "%.2f MB" % (nbytes / 1000000) + elif nbytes > 1000: + return "%u kB" % (nbytes // 1000) + else: + return "%u" % (nbytes) + +def do_download(url): + r = make_request("GET", url) + if r.getcode() != 200: + raise RuntimeError( + "Cannot download %s. Received HTTP status code %u" % (url, r.getcode())) + + size = r.getheader('content-length') + if size: + size = int(size) + bufsiz = max(8192, size // 1000) + else: + bufsiz = None + + f = tempfile.TemporaryFile("w+b") + pos = 0 + + while True: + buf = r.read(bufsiz) + if not buf: + break + f.write(buf) + pos += len(buf) + if size: + print("\r%.1f%% done (%s of %s)\033[0K" % ((100 * pos / size), human_size(pos), human_size(size)), end="") + else: + print("\r%s downloaded\033[0K" % (human_size(pos)), end="") + print("\r%s downloaded.\033[0K" % (human_size(pos))) + f.seek(0) + return f + + +def do_cksum(f): + f.seek(0) + o = subprocess.check_output("cksum", stdin=f, encoding="utf-8", text=True) + return re.match(r"^[0-9]+ [0-9]+", o).group(0) + +def do_sha256(f): + f.seek(0) + m = hashlib.sha256() + m.update(f.read()) + return m.hexdigest() + + +if __name__ == "__main__": + config = configparser.ConfigParser() + with open(sys.argv[1], "r") as cf: + config.read_string("[DEFAULT]\n"+cf.read()) + + config_changed = False + for section in config.sections(): + print("[%s]" % section) + + cksum = None + sha256sum = None + + for k, url in ( + (k, config.get(section, k, fallback=None)) + for k in ("url", "url_alt", "url_archive") + if config.get(section, k, fallback="").strip()): + + try: + print("Downloading %s..." % url) + + with do_download(url) as f: + this_cksum = do_cksum(f) + this_sha256sum = do_sha256(f) + + sum_mismatch= False + if cksum: + if this_cksum != cksum: + print("cksum differs for %s." % k, file=sys.stderr) + sum_mismatch = True + else: + cksum = this_cksum + + if sha256sum: + if this_sha256sum != sha256sum: + print("sha256sum differs for %s." % k, file=sys.stderr) + sum_mismatch = True + else: + sha256sum = this_sha256sum + + if sum_mismatch: + print("Checksum mismatch. Removing %s from META.ini" % (k), + file=sys.stderr) + config.remove_option(section, k) + + if config.has_option(section, "cksum"): + changed_sum = config.get(section, "cksum") != cksum + elif config.has_option(section, "sha256sum"): + changed_sum = config.get(section, "sha256sum") != sha256 + else: + changed_sum = True + + if changed_sum: + print("New release found. Updating checksums in META.ini...") + + config.set(section, "cksum", cksum) + config.set(section, "sha256sum", sha256sum) + config_changed = True + except: + print("Processing %s failed." % k, file=sys.stderr) + + if config_changed: + with tempfile.TemporaryFile("w+t", encoding="utf-8") as out: + config.write(out) + out.seek(0) + fline = out.readline() + if fline != "[DEFAULT]\n": + print("META.ini generation failed", file=sys.stderr) + sys.exit(1) + + with open(sys.argv[1], "w") as of: + of.write(out.read()) + print("META.ini updated.") |
