Esempio n. 1
0
    def _merge_releases(self, data, filename, overwrite_existing=False):
        releases = collections.OrderedDict()

        try:
            with open(filename, "r", encoding="utf-8") as f, \
                    self._lock_file(f) as f:
                releases = json.load(f,
                                     object_pairs_hook=collections.OrderedDict)
        except FileNotFoundError:
            pass
        except Exception as e:
            raise DistroInfoError("failed to load '{}': {}".format(
                filename, str(e)))

        if overwrite_existing or not releases:
            releases = data
        else:
            for release_name, release_data in data.items():
                status = release_data.get("status", "supported")
                releases\
                    .setdefault(release_name, release_data)["status"] = status

        flags = os.O_RDWR | os.O_CREAT
        try:
            with os.fdopen(os.open(filename, flags), 'r+', encoding="utf-8") \
                    as f, self._lock_file(f) as f:
                os.ftruncate(f.fileno(), 0)
                json.dump(releases, f, ensure_ascii=False, indent=4)
        except Exception as e:
            raise DistroInfoError("failed to store '{}': {}".format(
                filename, str(e)))
Esempio n. 2
0
 def _fetch_json(self, url, connection_timeout=30):
     try:
         with urllib.request.urlopen(url, timeout=connection_timeout) \
                 as response:
             return json.loads(response.read().decode("utf-8"),
                               object_pairs_hook=collections.OrderedDict)
     except urllib.error.URLError as e:
         raise DistroInfoError("error retrieving '{}': {}".format(
             url, str(e)))
     except UnicodeDecodeError as e:
         raise DistroInfoError(
             "failed to decode contents of '{}': {}".format(url, str(e)))
Esempio n. 3
0
    def refresh(self, *args):
        config = copy.deepcopy(self.config)

        def print_usage():
            print(
                textwrap.dedent("""
                USAGE:

                  bolt-distro-info refresh [OPTIONS]

                OPTIONS:

                  -h, --help              Print this help message.
                  -r, --releases          Update release info.
                  -m, --mirrors           Update mirrors list.
                  --overwrite-existing    Overwrite existing entries.
                """))

        try:
            opts, args = getopt.getopt(
                args, "hmr",
                ["help", "mirrors", "overwrite-existing", "releases"])
        except getopt.GetoptError as e:
            raise DistroInfoError("error parsing command line: {}".format(
                str(e)))

        kwargs = {
            "releases": False,
            "mirrors": False,
            "overwrite_existing": False,
        }

        for o, v in opts:
            if o in ["-h", "--help"]:
                print_usage()
                sys.exit(EXIT_OK)
            elif o in ["-r", "--releases"]:
                kwargs["releases"] = True
            elif o in ["-m", "--mirrors"]:
                kwargs["mirrors"] = True
            elif o == "--overwrite-existing":
                kwargs["overwrite_existing"] = True
        #end for

        if args:
            print_usage()
            sys.exit(EXIT_ERROR)

        if not (kwargs["releases"] or kwargs["mirrors"]):
            raise DistroInfoError("specify at least one of -r or -m.")

        DistroInfo(**config).refresh(**kwargs)
Esempio n. 4
0
    def pick_mirror(self, release, repo_name, **kwargs):
        repo_info = self.find(release).get("repositories", {}).get(repo_name)
        if not repo_info:
            raise DistroInfoError(
                "could not find information for release '{}' and repo '{}'.".
                format(release, repo_name))
        #end if

        try:
            return next(iter(repo_info.get("mirrors", [])[0].values()))[0]
        except IndexError:
            raise DistroInfoError(
                "repo '{}' for release '{}' has no mirror information listed.".
                format(repo_name, release))
Esempio n. 5
0
    def show(self, *args):
        config = copy.deepcopy(self.config)

        def print_usage():
            print(
                textwrap.dedent("""
                USAGE:

                  bolt-distro-info show [OPTIONS] <release-name>

                OPTIONS:

                  -h, --help           Print this help message.
                """))

        try:
            opts, args = getopt.getopt(args, "h", ["help"])
        except getopt.GetoptError as e:
            raise DistroInfoError("error parsing command line: {}".format(
                str(e)))

        for o, v in opts:
            if o in ["-h", "--help"]:
                print_usage()
                sys.exit(EXIT_OK)

        if len(args) != 1:
            print_usage()
            sys.exit(EXIT_ERROR)

        print(
            json.dumps(DistroInfo(**config).find(release=args[0]),
                       ensure_ascii=False,
                       indent=4))
Esempio n. 6
0
    def find(self, release, **kwargs):
        releases = self._load_json_file("releases")

        if release not in releases:
            raise ReleaseNotFoundError(
                "release '{}' not found, need to refresh?".format(release))

        mirrors = self._load_json_file("mirrors")

        for repo_id, repo_dict in \
                releases[release].get("repositories", {}).items():
            repo_mirrors = repo_dict.get("mirrors", [])

            for i in range(len(repo_mirrors)):
                mirror_id = repo_mirrors[i]

                if mirror_id not in mirrors:
                    raise DistroInfoError(
                        "encountered unknown mirror id '{}'.".format(
                            mirror_id))

                repo_mirrors[i] = mirrors[mirror_id]
            #end for
        #end for

        return releases[release]
Esempio n. 7
0
    def _merge_mirrors(self, data, filename, overwrite_existing=False):
        mirrors = collections.OrderedDict()

        try:
            with open(filename, "r", encoding="utf-8") as f, \
                    self._lock_file(f) as f:
                mirrors = json.load(f,
                                    object_pairs_hook=collections.OrderedDict)
        except FileNotFoundError:
            pass
        except Exception as e:
            raise DistroInfoError("failed to load '{}': {}".format(
                filename, str(e)))

        if overwrite_existing or not mirrors:
            mirrors = data
        else:
            for mirror_id, mirror_dict in data.items():
                if mirror_id not in mirrors:
                    mirrors[mirror_id] = mirror_dict
                else:
                    regions = mirrors[mirror_id]

                    for region_id, mirror_list in mirror_dict.items():
                        if region_id not in regions:
                            regions[region_id] = mirror_list
                        else:
                            url_set = set(regions[region_id])
                            for url in mirror_list:
                                url_set.add(url)
                            regions[region_id] = list(url_set)
                    #end for
                #end if
            #end for
        #end if

        flags = os.O_RDWR | os.O_CREAT
        try:
            with os.fdopen(os.open(filename, flags), 'r+', encoding="utf-8") \
                    as f, self._lock_file(f) as f:
                os.ftruncate(f.fileno(), 0)
                json.dump(mirrors, f, ensure_ascii=False, indent=4)
        except Exception as e:
            raise DistroInfoError("failed to store '{}': {}".format(
                filename, str(e)))
Esempio n. 8
0
    def list(self, *args):
        config = copy.deepcopy(self.config)

        def print_usage():
            print(
                textwrap.dedent("""
                USAGE:

                  bolt-distro-info list [OPTIONS]

                OPTIONS:

                  -h, --help           Print this help message.
                  -s, --supported      Show supported releases.
                  -u, --unsupported    Show old, unsupported releases.

                Per default supported and unsupported releases are listed.
                """))

        try:
            opts, args = getopt.getopt(args, "hsu",
                                       ["help", "supported", "unsupported"])
        except getopt.GetoptError as e:
            raise DistroInfoError("error parsing command line: {}".format(
                str(e)))

        supported = False
        unsupported = False

        for o, v in opts:
            if o in ["-h", "--help"]:
                print_usage()
                sys.exit(EXIT_OK)
            elif o in ["-s", "--supported"]:
                supported = True
            elif o in ["-u", "--unsupported"]:
                unsupported = True

        if not (supported or unsupported):
            supported = unsupported = True

        if args:
            print_usage()
            sys.exit(EXIT_ERROR)

        dists = DistroInfo(**config).list(supported=supported,
                                          unsupported=unsupported)

        if dists:
            print("\n".join(dists.keys()))
Esempio n. 9
0
    def _load_json_file(self, which):
        result = collections.OrderedDict()

        json_file = os.path.join(UserInfo.config_folder(),
                                 "{}.json".format(which))

        if not os.path.exists(json_file):
            self.refresh(**{which: True})

        try:
            with open(json_file, "r", encoding="utf-8") as f, \
                    self._lock_file(f) as f:
                result = json.load(f,
                                   object_pairs_hook=collections.OrderedDict)
            #end with
        except DistroInfoError:
            raise
        except Exception as e:
            raise DistroInfoError("error loading '{}': {}".format(
                json_file, str(e)))

        return result
Esempio n. 10
0
 def __init__(self, api_version=1, **kwargs):
     if api_version == 1:
         self.implementation = DistroInfoV1()
     else:
         raise DistroInfoError(
             'unknown API version "{}"'.format(api_version))