diff options
Diffstat (limited to 'nixpkgs/pkgs/tools/security/enpass/update_script.py')
-rw-r--r-- | nixpkgs/pkgs/tools/security/enpass/update_script.py | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/tools/security/enpass/update_script.py b/nixpkgs/pkgs/tools/security/enpass/update_script.py new file mode 100644 index 000000000000..f8ec715cb5e4 --- /dev/null +++ b/nixpkgs/pkgs/tools/security/enpass/update_script.py @@ -0,0 +1,95 @@ +from __future__ import print_function + + +import argparse +import bz2 +import email +import json +import logging + +from itertools import product +from operator import itemgetter + +import attr +import pkg_resources + +from pathlib2 import Path +from requests import Session +from six.moves.urllib_parse import urljoin + + +@attr.s +class ReleaseElement(object): + sha256 = attr.ib(repr=False) + size = attr.ib(convert=int) + path = attr.ib() + +log = logging.getLogger('enpass.updater') + + +parser = argparse.ArgumentParser() +parser.add_argument('--repo') +parser.add_argument('--target', type=Path) + + +session = Session() + + +def parse_bz2_msg(msg): + msg = bz2.decompress(msg) + if '\n\n' in msg: + parts = msg.split('\n\n') + return list(map(email.message_from_string, parts)) + return email.message_from_string(msg) + + +def fetch_meta(repo, name, parse=email.message_from_string, split=False): + url = urljoin(repo, 'dists/stable', name) + response = session.get("{repo}/dists/stable/{name}".format(**locals())) + return parse(response.content) + + +def fetch_filehashes(repo, path): + meta = fetch_meta(repo, path, parse=parse_bz2_msg) + for item in meta: + yield { + 'version': pkg_resources.parse_version(str(item['Version'])), + 'path': item['Filename'], + 'sha256': item['sha256'], + } + + +def fetch_archs(repo): + m = fetch_meta(repo, 'Release') + + architectures = m['Architectures'].split() + elements = [ReleaseElement(*x.split()) for x in m['SHA256'].splitlines()] + elements = [x for x in elements if x.path.endswith('bz2')] + + for arch, elem in product(architectures, elements): + if arch in elem.path: + yield arch, max(fetch_filehashes(repo, elem.path), + key=itemgetter('version')) + + +class OurVersionEncoder(json.JSONEncoder): + def default(self, obj): + # the other way around to avoid issues with + # newer setuptools having strict/legacy versions + if not isinstance(obj, (dict, str)): + return str(obj) + return json.JSONEncoder.default(self, obj) + + +def main(repo, target): + logging.basicConfig(level=logging.DEBUG) + with target.open(mode='wb') as fp: + json.dump( + dict(fetch_archs(repo)), fp, + cls=OurVersionEncoder, + indent=2, + sort_keys=True) + + +opts = parser.parse_args() +main(opts.repo, opts.target) |