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)))
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)))
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)
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))
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))
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]
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)))
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()))
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
def __init__(self, api_version=1, **kwargs): if api_version == 1: self.implementation = DistroInfoV1() else: raise DistroInfoError( 'unknown API version "{}"'.format(api_version))