| 10 | |
| 11 | |
| 12 | class MirrorListHandler: |
| 13 | def __init__( |
| 14 | self, |
| 15 | local_mirrorlist: Path = MIRRORLIST, |
| 16 | offline: bool = False, |
| 17 | verbose: bool = False, |
| 18 | ) -> None: |
| 19 | self._local_mirrorlist = local_mirrorlist |
| 20 | self._status_mappings: dict[str, list[MirrorStatusEntryV3]] | None = None |
| 21 | self._fetched_remote: bool = False |
| 22 | self.offline = offline |
| 23 | self.verbose = verbose |
| 24 | |
| 25 | def _mappings(self) -> dict[str, list[MirrorStatusEntryV3]]: |
| 26 | if self._status_mappings is None: |
| 27 | self.load_mirrors() |
| 28 | |
| 29 | assert self._status_mappings is not None |
| 30 | return self._status_mappings |
| 31 | |
| 32 | def get_mirror_regions(self) -> list[MirrorRegion]: |
| 33 | available_mirrors = [] |
| 34 | mappings = self._mappings() |
| 35 | |
| 36 | for region_name, status_entry in mappings.items(): |
| 37 | urls = [entry.server_url for entry in status_entry] |
| 38 | region = MirrorRegion(region_name, urls) |
| 39 | available_mirrors.append(region) |
| 40 | |
| 41 | return available_mirrors |
| 42 | |
| 43 | def load_mirrors(self) -> None: |
| 44 | if self.offline: |
| 45 | self._fetched_remote = False |
| 46 | self.load_local_mirrors() |
| 47 | else: |
| 48 | self._fetched_remote = self.load_remote_mirrors() |
| 49 | debug(f'load mirrors: {self._fetched_remote}') |
| 50 | if not self._fetched_remote: |
| 51 | self.load_local_mirrors() |
| 52 | |
| 53 | def load_remote_mirrors(self) -> bool: |
| 54 | url = 'https://archlinux.org/mirrors/status/json/' |
| 55 | attempts = 3 |
| 56 | |
| 57 | for attempt_nr in range(attempts): |
| 58 | try: |
| 59 | mirrorlist = fetch_data_from_url(url) |
| 60 | self._status_mappings = self._parse_remote_mirror_list(mirrorlist) |
| 61 | return True |
| 62 | except Exception as e: |
| 63 | debug(f'Error while fetching mirror list: {e}') |
| 64 | time.sleep(attempt_nr + 1) |
| 65 | |
| 66 | debug('Unable to fetch mirror list remotely, falling back to local mirror list') |
| 67 | return False |
| 68 | |
| 69 | def load_local_mirrors(self) -> None: |
no outgoing calls