Ejemplo n.º 1
0
def write_mirrorlist_branch(newbranch: str,
                            filename: str,
                            tty: bool = False,
                            quiet: bool = False) -> None:
    """Write branch in mirrorlist
    :param newbranch:
    :param filename:
    :param tty:
    :param quiet:
    """
    lookfor = "Server ="
    branch = find_mirrorlist_branch(filename=filename, tty=tty)
    try:
        with open(filename) as mirrorlist, tempfile.NamedTemporaryFile(
                "w+t", dir=os.path.dirname(filename), delete=False) as tmp:
            for line in mirrorlist:
                if lookfor in line:
                    line = line.replace(branch, newbranch)
                    tmp.write(f"{line}")
                else:
                    tmp.write(f"{line}")
        os.replace(tmp.name, filename)
        os.chmod(filename, 0o644)
        if not quiet:
            util.msg(message=f"{txt.API_MIRRORLIST_RE_BRANCH}",
                     urgency=txt.INF_CLR,
                     tty=tty)
    except OSError as err:
        util.msg(
            message=f"{txt.CANNOT_READ_FILE}: {err.filename}: {err.strerror}",
            urgency=txt.ERR_CLR,
            tty=tty)
        sys.exit(2)
Ejemplo n.º 2
0
def write_mirror_list(config: object,
                      servers: list,
                      tty: bool = False,
                      custom: bool = False,
                      quiet: bool = False,
                      interactive: bool = False) -> None:
    """
    Write servers to /etc/pacman.d/mirrorlist
    :param config: configuration dictionary
    :param servers: list of servers to write
    :param tty: flag
    :param custom: flag
    :param quiet: flag
    :param interactive: flag
    """
    try:
        with open(config["mirror_list"], "w") as outfile:
            if not quiet:
                util.msg(message=f"{txt.WRITING_MIRROR_LIST}",
                         urgency=txt.INF_CLR,
                         tty=tty)
            # write list header
            write_mirrorlist_header(outfile, custom=custom)
            cols, lines = pacman_mirrors.functions.util.terminal_size()
            for server in servers:
                url = server["url"]
                protocol = server["protocols"][0]
                pos = url.find(":")
                server[
                    "url"] = f'{protocol}{url[pos:]}{config["branch"]}{config["repo_arch"]}'
                if server["resp_time"] == 99.99:
                    # do not write bad servers to mirrorlist
                    continue
                if interactive:
                    if not quiet:
                        message = f'{server["country"]:<15} : {server["url"]}'
                        util.msg(message=f"{message:.{cols}}", tty=tty)
                        # print()
                else:
                    msg_url = f'{protocol}{url[pos:]}{config["branch"]}'
                    if not quiet:
                        message = f'{server["country"]:<15} : {msg_url}'
                        util.msg(message=f"{message:.{cols}}", tty=tty)

                # write list entry
                write_mirrorlist_entry(outfile, server)
            if not quiet:
                util.msg(
                    message=f'{txt.MIRROR_LIST_SAVED}: {config["mirror_list"]}',
                    urgency=txt.INF_CLR,
                    tty=tty)
    except OSError as err:
        util.msg(
            message=f"{txt.CANNOT_WRITE_FILE}: {err.filename}: {err.strerror}",
            urgency=txt.ERR_CLR,
            tty=tty)

        sys.exit(2)
Ejemplo n.º 3
0
def ping_host(host: str, tty: bool = False, count: int = 1) -> bool:
    """Check a hosts availability
    :param host:
    :param count:
    :param tty:
    :rtype: boolean
    """
    util.msg(f"ping {host} x {count}", urgency=txt.INF_CLR, tty=tty)
    return system_call("ping -c{} {} > /dev/null".format(count, host)) == 0
Ejemplo n.º 4
0
def get_mirror_response(url: str, config: object, tty: bool = False, maxwait: int = 2,
                        count: int = 1, quiet: bool = False, ssl_verify: bool = True) -> float:
    """Query mirror by downloading a file and measuring the time taken
    :param config:
    :param ssl_verify:
    :param tty:
    :param url:
    :param maxwait:
    :param count:
    :param quiet:
    :returns always return a float value with response time
    """
    response_time = txt.SERVER_RES  # prepare default return value
    probe_stop = None
    message = ""
    context = ssl.create_default_context()
    arch = "x86_64"
    if config["x32"]:
        arch = "i686"
    if config["arm"]:
        arch = "aarch64"
    probe_url = f"{url}{config['branch']}/core/{arch}/{config['test_file']}"
    if not ssl_verify:
        context.check_hostname = False
        context.verify_mode = ssl.CERT_NONE
    req = urllib.request.Request(url=probe_url, headers=USER_AGENT)
    probe_start = time.time()
    # noinspection PyBroadException
    try:
        for _ in range(count):
            response = urllib.request.urlopen(req, timeout=maxwait, context=context)
            _ = response.read()
        probe_stop = time.time()
    except URLError as err:
        if hasattr(err, "reason"):
            message = f"{err.reason} '{url}'"
        elif hasattr(err, "code"):
            message = f"{err.reason} '{url}'"
    except timeout:
        message = f"{txt.TIMEOUT} '{url}'"
    except HTTPException:
        message = f"{txt.HTTP_EXCEPTION} '{url}'"
    except ssl.CertificateError:
        message = f"{ssl.CertificateError} '{url}'"
    except Exception as e:
        message = f"{e} '{url}'"

    if message and not quiet:
        util.msg(message=message, urgency=txt.ERR_CLR, tty=tty, newline=True)
    if probe_stop:
        response_time = round((probe_stop - probe_start), 3)
    return response_time
Ejemplo n.º 5
0
def download_mirror_pool(config: object, tty: bool = False, quiet: bool = False) -> tuple:
    """Download updates from repo.manjaro.org
    :param config:
    :param quiet:
    :param tty:
    :returns: tuple with True/False for mirrors.json and status.json
    :rtype: tuple
    """
    result = None
    connected = check_internet_connection(tty=tty)
    if connected:
        if not quiet:
            util.msg(message=f"{txt.DOWNLOADING_MIRROR_FILE} {txt.REPO_SERVER}",
                     urgency=txt.INF_CLR,
                     tty=tty)
        result = download_mirrors(config)
    else:
        if not fileFn.check_file(config["status_file"]):
            if not quiet:
                util.msg(message=f"{txt.MIRROR_FILE} {config['status_file']} {txt.IS_MISSING}",
                         urgency=txt.WRN_CLR,
                         tty=tty)
                util.msg(message=f"{txt.FALLING_BACK} {conf.MIRROR_FILE}",
                         urgency=txt.WRN_CLR,
                         tty=tty)
            result = (True, False)
        if not fileFn.check_file(config["mirror_file"]):
            if not quiet:
                util.msg(message=f"{txt.HOUSTON}",
                         urgency=txt.HOUSTON,
                         tty=tty)
            result = (False, False)
    return result
Ejemplo n.º 6
0
def check_internet_connection(tty: bool = False, maxwait: int = 2) -> bool:
    """Check for internet connection
    :param maxwait:
    :param tty:
    """
    resp = None
    hosts = conf.INET_CONN_CHECK_URLS
    for host in hosts:
        # noinspection PyBroadException
        try:
            resp = urllib.request.urlopen(host, timeout=maxwait)
            break
        except Exception as e:
            util.msg(f"{host} '{e}'", urgency=txt.WRN_CLR, tty=tty)
    return bool(resp)
Ejemplo n.º 7
0
def build_mirror_list(self, limit: int) -> None:
    """
    Fast-track the mirrorlist by filtering only up-to-date mirrors
    The function takes into account the branch selected by the user
      either on commandline or in pacman-mirrors.conf.
    The function returns a filtered list consisting of a number of mirrors
    Only mirrors from the active mirror file is used
      either mirrors.json or custom-mirrors.json
    """
    work_pool = build_pool(self)
    """
    Shuffle the list
    """
    shuffle(work_pool)
    """
    # probe the mirrors
    """
    if limit <= 0 or limit > len(work_pool):
        limit = len(work_pool)
    if self.use_async:
        work_pool = test_mirror_pool_async(self=self,
                                           worklist=work_pool,
                                           limit=limit)
    else:
        work_pool = test_mirror_pool(self=self,
                                     worklist=work_pool,
                                     limit=limit)
    """
    Write mirrorlist
    """
    try:
        _ = work_pool[0]
        """
        # sort the result
        """
        work_pool = sort_mirror_pool(worklist=work_pool,
                                     field="resp_time",
                                     reverse=False)
        write_pacman_mirror_list(self=self, selected_servers=work_pool)
    except IndexError:
        util.msg(message=f"{txt.NO_SELECTION}",
                 urgency=txt.WRN_CLR,
                 tty=self.tty)
        util.msg(message=f"{txt.NO_CHANGE}", urgency=txt.INF_CLR, tty=self.tty)
Ejemplo n.º 8
0
def print_status(self) -> int:
    system_branch, mirrors_pacman = get_local_mirrors()
    try:
        with request.urlopen('https://repo.manjaro.org/status.json') as f_url:
            req = f_url.read()
    except error.URLError:
        msg("Downloading status failed!", color=colors.BLUE)
        msg("Please check you network connection ...", color=colors.YELLOW)
        return 1  # return failure
    json_data = json.loads(req)
    mirrors = []
    for mirror in json_data:
        for protocol in mirror["protocols"]:
            temp = mirror.copy()
            temp["url"] = f"{protocol}://{strip_protocol(temp['url'])}"
            mirrors.append(temp)

    mirrors = [m for m in mirrors if m['url'] in mirrors_pacman]

    printFn.yellow_msg(f"Local mirror status for {system_branch} branch")
    exit_code = 0  # up-to-date
    for i, url in enumerate(mirrors_pacman):  # same order as pacman-conf
        try:
            mirror = [m for m in mirrors if m['url'] == url][0]
            color, text = get_state(mirror["branches"], system_branch)
            len_country = max(len(m['country']) for m in mirrors) + 1
            print(
                f"Mirror #{str(i + 1):2}", color, f"{text}", C_NONE,
                f"{mirror['last_sync']:7} {mirror['country']:{len_country}} {mirror['url']}"
            )
            if i == 0 and color == C_KO:
                exit_code = 4  # first mirror not sync !
        except IndexError:
            print(C_KO, f"Mirror #{i + 1:2}", f"{url} does not exist{C_NONE}")
            exit_code = 5  # not found

    # if exit_code == 0:
    #     msg("All good", color=colors.GREEN)
    # if exit_code == 4:
    #     msg("Primary mirror is not up-to-date", color=colors.YELLOW)
    # if exit_code == 5:
    #     msg("At least one mirror does not exist", color=colors.RED)
    return exit_code
Ejemplo n.º 9
0
def return_mirror_filename(config: object, tty: bool = False) -> tuple:
    """
    Find the mirror pool file
    :param config: config dictionary
    :param tty:
    :returns tuple with file and status
    """
    filename = ""
    status = False  # status.json or mirrors.json
    # decision on file availablity
    if check_file(config["status_file"]):
        status = True
        filename = config["status_file"]
    elif check_file(filename=config["mirror_file"]):
        filename = config["mirror_file"]
    if not filename:
        util.msg(message=f"\n{txt.HOUSTON}\n", tty=tty, color=color.RED)
        sys.exit(3)
    return filename, status
Ejemplo n.º 10
0
def find_mirrorlist_branch(filename: str, tty: bool = False) -> str:
    """find and return the branch found in mirrorlist
    :param filename:
    :param tty:
    """
    try:
        with open(filename) as mirrorlist:
            for line in mirrorlist:
                if "Server = " in line:
                    workstring = line.strip()[-21:]  # /unstable/$repo/$arch
                    pos = workstring.find("/")
                    workstring = workstring[pos + 1:]
                    pos = workstring.find("/")
                    return workstring[:pos]
    except OSError as err:
        util.msg(
            message=f"{txt.CANNOT_READ_FILE}: {err.filename}: {err.strerror}",
            urgency=txt.ERR_CLR,
            tty=tty)
        sys.exit(2)
Ejemplo n.º 11
0
def write_config_branch(branch: str,
                        filename: str,
                        tty: bool = False,
                        quiet: bool = False) -> None:
    """Write branch
    :param branch:
    :param filename:
    :param tty:
    :param quiet:
    """
    lookfor = "Branch ="
    default = "# Branch = stable\n"
    if branch == "stable":
        branch = default
    else:
        branch = "Branch = {}\n".format(branch)
    try:
        with open(filename) as cnf, tempfile.NamedTemporaryFile(
                "w+t", dir=os.path.dirname(filename), delete=False) as tmp:
            replaced = False
            for line in cnf:
                if lookfor in line:
                    tmp.write(branch)
                    replaced = True
                else:
                    tmp.write(f"{line}")
            if not replaced:
                tmp.write(branch)
        os.replace(tmp.name, filename)
        os.chmod(filename, 0o644)
        if not quiet:
            util.msg(message=f"{txt.API_CONF_RE_BRANCH}",
                     urgency=txt.INF_CLR,
                     tty=tty)
    except OSError as err:
        util.msg(
            message=f"{txt.CANNOT_READ_FILE}: {err.filename}: {err.strerror}",
            urgency=txt.ERR_CLR,
            tty=tty)
        sys.exit(2)
Ejemplo n.º 12
0
def write_protocols(protocols: str,
                    filename: str,
                    tty: bool = False,
                    quiet: bool = False) -> None:
    """Write protocols
    :param protocols:
    :param filename:
    :param tty:
    :param quiet:
    """
    lookfor = "Protocols ="
    default = "# Protocols = \n"
    if protocols:
        protocols = "Protocols = {}\n".format(",".join(protocols))
    else:
        protocols = default
    try:
        with open(filename) as cnf, tempfile.NamedTemporaryFile(
                "w+t", dir=os.path.dirname(filename), delete=False) as tmp:
            replaced = False
            for line in cnf:
                if lookfor in line:
                    tmp.write(protocols)
                    replaced = True
                else:
                    tmp.write(f"{line}")
            if not replaced:
                tmp.write(protocols)
        os.replace(tmp.name, filename)
        os.chmod(filename, 0o644)
        if not quiet:
            util.msg(message=f"{txt.API_CONF_PROTOCOLS}",
                     urgency=txt.INF_CLR,
                     tty=tty)
    except OSError as err:
        util.msg(
            message=f"{txt.CANNOT_READ_FILE}: {err.filename}: {err.strerror}",
            urgency=txt.ERR_CLR,
            tty=tty)
        sys.exit(2)
Ejemplo n.º 13
0
def country_list_is_valid(onlycountry: list,
                          countrylist: list,
                          tty: bool = False) -> bool:
    """Check if the list of countries are valid.
    :param onlycountry: list of countries to check
    :param countrylist: list of available countries
    :param tty:
    :return: True
    :rtype: bool
    """
    for country in onlycountry:
        if country not in countrylist:
            util.msg(
                message=
                f"{txt.OPTION}{txt.OPT_COUNTRY}: {txt.OPT_COUNTRY}: '{txt.UNKNOWN_COUNTRY}'",
                urgency=txt.WRN_CLR,
                tty=tty)
            util.msg(message=f"{txt.AVAILABLE_COUNTRIES}",
                     urgency=txt.INF_CLR,
                     tty=tty)
            print("{}".format(", ".join(countrylist)))
            sys.exit(1)  # exit gracefully
    return True
Ejemplo n.º 14
0
def write_custom_mirrors_json(self, selected_mirrors: list) -> None:
    """
    Output selected mirrors to custom mirror file
    :param self:
    :param selected_mirrors:
    :return:
    """
    util.msg(message=f"{txt.CUSTOM_MIRROR_LIST}",
             urgency=txt.INF_CLR,
             tty=self.tty)
    util.msg(
        message="------------------------------------------------------------",
        tty=self.tty)
    jsonFn.write_json_file(data=selected_mirrors,
                           filename=self.config["custom_file"])
    util.msg(
        message=f'{txt.CUSTOM_MIRROR_FILE_SAVED}: {self.config["custom_file"]}',
        urgency=txt.INF_CLR,
        tty=self.tty)
Ejemplo n.º 15
0
def test_mirror_pool_async(self, worklist: list, limit=None) -> list:
    """
    Query server for response time
    """
    if self.custom:
        util.msg(message=f"{txt.USING_CUSTOM_FILE}",
                 urgency=f"{txt.INF_CLR}",
                 tty=self.tty)
    else:
        util.msg(message=f"{txt.USING_DEFAULT_FILE}",
                 urgency=f"{txt.INF_CLR}",
                 tty=self.tty)
    util.msg(message=f"{txt.QUERY_MIRRORS} - {txt.TAKES_TIME}",
             urgency=f"{txt.INF_CLR}",
             tty=self.tty)
    # I don't know how to properly fix this yet
    global counter
    cols, lines = util.terminal_size()
    # set connection timeouts
    # http_wait = self.max_wait_time
    # ssl_wait  = self.max_wait_time * 2
    # ssl_verify = self.config["ssl_verify"]
    result = []

    # Set number of workers depending on the limit
    # Since the operation is relatively IO intensive, 50
    # workers is a sane option
    workers_num = 20
    if limit is not None and workers_num > limit > 0:
        if limit <= 10:
            workers_num = 10
        else:
            workers_num = limit

    # Create the threadpool and submit a task per mirror
    with ThreadPoolExecutor(max_workers=workers_num) as executor, ThreadPoolExecutor(max_workers=1) as canceler:
        mirrors_future = {executor.submit(mirror_fn,
                                          self,
                                          executor,
                                          mirror,
                                          limit,
                                          cols):
                          mirror for mirror in worklist}
        # Submit canceller job if there is a limit
        if limit is not None:
            cancel_fut = canceler.submit(job_canceler, limit, mirrors_future)
        # Get results as they resolve
        for mirror in as_completed(mirrors_future):
            # noinspection PyBroadException
            try:
                mirror_result = mirror.result()
                if mirror_result is not None:
                    result.append(mirror_result)
            except Exception as e:
                # Silence task cancellation exceptions
                pass
        # If there is a limit, wait until
        if limit is not None:
            cancel_fut.result()

    return result
Ejemplo n.º 16
0
def test_mirror_pool(self, worklist: list, limit=None) -> list:
    """
    Query server for response time
    """
    if self.custom:
        util.msg(message=f"{txt.USING_CUSTOM_FILE}",
                 urgency=f"{txt.INF_CLR}",
                 tty=self.tty)
    else:
        util.msg(message=f"{txt.USING_DEFAULT_FILE}",
                 urgency=f"{txt.INF_CLR}",
                 tty=self.tty)
    util.msg(message=f"{txt.QUERY_MIRRORS} - {txt.TAKES_TIME}",
             urgency=f"{txt.INF_CLR}",
             tty=self.tty)
    counter = 0
    cols, lines = util.terminal_size()
    # set connection timeouts
    http_wait = self.max_wait_time
    ssl_wait = self.max_wait_time * 2
    ssl_verify = self.config["ssl_verify"]
    result = []
    for mirror in worklist:
        # create a list for the mirrors available protocols
        probe_items = list_with_protocols(mirror)
        # locate position of protocols separator
        colon = probe_items[0]["url"].find(":")
        # create an url for the mirror without protocol
        url = probe_items[0]["url"][colon:]
        # loop protocols available
        for probe_item in probe_items:

            # get protocol
            probe_proto = probe_item["protocols"][0]

            # generate url with protocol
            probe_item["url"] = f"{probe_proto}{url}"

            # create message for later display
            message = f'  ..... {probe_item["country"]:<15}: {probe_item["url"]}'

            # if self.tty do not print theis
            if not self.quiet:
                if self.tty:
                    pass
                else:
                    print("{:.{}}".format(message, cols), end="")
                    sys.stdout.flush()

            # https/ftps sometimes takes longer for handshake
            if probe_proto.endswith("tps"):  # https or ftps
                self.max_wait_time = ssl_wait
            else:
                self.max_wait_time = http_wait

            # let's see see time spent
            probe_item["resp_time"] = get_mirror_response(url=probe_item["url"],
                                                          config=self.config,
                                                          tty=self.tty,
                                                          maxwait=self.max_wait_time,
                                                          quiet=self.quiet,
                                                          ssl_verify=ssl_verify)

            # create a printable string version from the response with appended zeroes
            r_str = str(probe_item["resp_time"])
            while len(r_str) < 5:
                r_str += "0"

            # validate against the defined wait time
            if probe_item["resp_time"] >= self.max_wait_time:
                # skip line - but not if tty
                if not self.quiet:
                    if self.tty:
                        pass
                    else:
                        print("\r")
            else:
                # only print if not tty
                if not self.quiet:
                    if self.tty:
                        pass
                    else:
                        print(f"\r  {color.GREEN}{r_str}{color.RESET}")

            # we have tty then we print with response time
            if self.tty:
                util.msg(message=message.replace(".....", r_str), tty=self.tty)
                sys.stdout.flush()

        # check the protocols
        probed_mirror = filter_bad_response(work=probe_items)

        if limit is not None:
            if mirror["resp_time"] == txt.SERVER_RES:
                continue
            counter += 1
            result.append(probed_mirror)
        else:
            result.append(probed_mirror)
        """
        Equality check will stop execution
        when the desired number is reached.
        In the possible event the first mirror's
        response time exceeds the predefined response time,
        the loop would stop execution if the check for zero is not present
        """
        if limit is not None and counter is not 0 and counter == limit:
            break
    return result
Ejemplo n.º 17
0
def set_config(self, set_pfx: str = None, set_branch: str = None,
               re_branch: bool = False, set_protocols: bool = False, set_url: str = None) -> None:
    """
    Api configuration function
    :param self:
    :param set_pfx: prefix to the config paths
    :param set_branch: replace branch in pacman-mirrors.conf
    :param re_branch: replace branch in mirror list
    :param set_protocols: replace protocols in pacman-mirrors.conf
    :param set_url: replace mirror url in mirror list
    """
    if set_url is None:
        set_url = ""

    if set_pfx is None:
        set_pfx = ""

    """
    # apply api configuration to internal configuration object
    # Apply prefix if present
    """
    if set_pfx:
        set_pfx = apifn.sanitize_prefix(set_pfx)
        self.config["config_file"] = set_pfx + self.config["config_file"]
        self.config["custom_file"] = set_pfx + self.config["custom_file"]
        self.config["mirror_file"] = set_pfx + self.config["mirror_file"]
        self.config["mirror_list"] = set_pfx + self.config["mirror_list"]
        self.config["status_file"] = set_pfx + self.config["status_file"]
        self.config["work_dir"] = set_pfx + self.config["work_dir"]

    """
    # First API task: Set branch
    """
    if set_branch:
        # Apply branch to internal config
        self.config["branch"] = set_branch
        util.i686_check(self=self, write=False)
        """
        # pacman-mirrors.conf could absent so check for it
        """
        if not fileFn.check_file(filename=self.config["config_file"]):
            """
            # Copy from host system
            """
            fileFn.create_dir(set_pfx + "/etc")
            shutil.copyfile("/etc/pacman-mirrors.conf",
                            self.config["config_file"])
            """
            # Normalize config
            """
            apifn.normalize_config(filename=self.config["config_file"])
        """
        # Write branch to config
        """
        apifn.write_config_branch(
            branch=self.config["branch"], filename=self.config["config_file"], tty=self.tty, quiet=self.quiet)
    """
    # Second API task: Create a mirror list
    """
    if set_url:
        """
        # mirror list dir could absent so check for it
        """
        fileFn.create_dir(foldername=set_pfx + "/etc/pacman.d")
        mirror = [
            {
                "url": apifn.sanitize_url(set_url),
                "country": "BUILDMIRROR",
                "protocols": [set_url[:set_url.find(":")]],
                "resp_time": "00.00"
            }
        ]
        fileFn.write_mirror_list(
            config=self.config, servers=mirror, tty=self.tty, quiet=self.quiet)
        # exit gracefully
        sys.exit(0)
    """
    # Third API task: Write protocols to config
    """
    if set_protocols:
        apifn.write_protocols(
            protocols=self.config["protocols"], filename=self.config["config_file"], tty=self.tty, quiet=self.quiet)
    """
    # Fourth API task: Rebranch the mirrorl ist
    """
    if re_branch:
        if not set_branch:
            util.msg(message=f"{txt.API_ERROR_BRANCH}", urgency=txt.ERR_CLR, tty=self.tty)
            # print(".: {} {}".format(txt.ERR_CLR, txt.API_ERROR_BRANCH))
            sys.exit(1)
        apifn.write_mirrorlist_branch(
            newbranch=self.config["branch"], filename=self.config["config_file"], tty=self.tty, quiet=self.quiet)
Ejemplo n.º 18
0
def setup_config() -> tuple:
    """Get config informations
    :returns: config, custom
    :rtype: tuple
    """
    custom = False
    # default config
    config = {
        "branch": "stable",
        "branches": conf.BRANCHES,
        "config_file": conf.CONFIG_FILE,
        "country_pool": [],
        "custom_file": conf.CUSTOM_FILE,
        "method": "rank",
        "work_dir": conf.WORK_DIR,
        "mirror_file": conf.MIRROR_FILE,
        "mirror_list": conf.MIRROR_LIST,
        "no_update": False,
        "protocols": [],
        "repo_arch": conf.REPO_ARCH,
        "ssl_verify": True,
        "status_file": conf.STATUS_FILE,
        "test_file": conf.TEST_FILE,
        "url_mirrors_json": conf.URL_MIRROR_JSON,
        "url_status_json": conf.URL_STATUS_JSON,
        "x32": False,
        "arm": False
    }
    # try to replace default entries by reading conf file
    try:
        with open(config["config_file"]) as conf_file:
            for line in conf_file:
                line = line.strip()
                if line.startswith("#") or "=" not in line:
                    continue
                (key, value) = line.split("=", 1)
                key = key.rstrip()
                value = value.lstrip()
                if key and value:
                    if value.startswith("\"") and value.endswith("\""):
                        value = value[1:-1]
                    if key == "Method":
                        config["method"] = value
                    if key == "Branch":
                        config["branch"] = value
                    if key == "Protocols":
                        if "," in value:
                            config["protocols"] = value.split(",")
                        else:
                            config["protocols"] = value.split(" ")
                    if key == "SSLVerify":
                        config["ssl_verify"] = value.lower().capitalize()
                    if key == "TestFile":
                        config["test_file"] = value
                        if not config["test_file"]:
                            config["test_file"] = conf.TEST_FILE

    except (PermissionError, OSError) as err:
        util.msg(
            message=f"{txt.CANNOT_READ_FILE}: {err.filename}: {err.strerror}",
            urgency=txt.ERR_CLR,
            tty=self.tty)
        sys.exit(2)
    return config, custom
Ejemplo n.º 19
0
def build_mirror_list(self) -> None:
    """
    Generate common mirrorlist
    """
    work_pool = build_pool(self)
    """
    Check the length of selected_countries against the full countrylist
    If selected_countries is the lesser then we build a custom pool file
    """
    if len(self.selected_countries) < len(self.mirrors.country_pool):
        try:
            _ = self.selected_countries[0]
            write_custom_mirrors_json(self=self, selected_mirrors=work_pool)
        except IndexError:
            pass

    if self.config["method"] == "rank":
        if self.use_async:
            work_pool = test_mirror_pool_async(self=self, worklist=work_pool)
        else:
            work_pool = test_mirror_pool(self=self, worklist=work_pool)
        work_pool = sort_mirror_pool(worklist=work_pool,
                                     field="resp_time",
                                     reverse=False)
    else:
        shuffle(work_pool)
    """
    Write mirrorlist
    """
    try:
        _ = work_pool[0]
        write_pacman_mirror_list(self=self, selected_servers=work_pool)
        if self.custom:
            util.msg(
                message=
                f"{txt.MIRROR_LIST_CUSTOM_RESET} 'sudo {txt.MODIFY_CUSTOM}'",
                urgency=txt.INF_CLR,
                tty=self.tty)
            util.msg(
                message=f"{txt.REMOVE_CUSTOM_CONFIG} 'sudo {txt.RESET_ALL}'",
                urgency=txt.INF_CLR,
                tty=self.tty)
        if self.no_status:
            util.msg(message=f"{txt.OVERRIDE_STATUS_CHOICE}",
                     urgency=txt.WRN_CLR,
                     tty=self.tty)
            util.msg(message=f"{txt.OVERRIDE_STATUS_MIRROR}",
                     urgency=txt.WRN_CLR,
                     tty=self.tty)
    except IndexError:
        util.msg(message=f"{txt.NO_SELECTION}",
                 urgency=txt.WRN_CLR,
                 tty=self.tty)
        util.msg(message=f"{txt.NO_CHANGE}", urgency=txt.INF_CLR, tty=self.tty)
Ejemplo n.º 20
0
def build_mirror_list(self) -> None:
    """
    Prompt the user to select the mirrors with an interface.
    Outputs a "custom" mirror file
    Outputs a pacman mirrorlist,
    """

    worklist = build_pool(self)

    # rank or shuffle the mirrorlist before showing the ui
    if not self.default:
        # if not default run method before selection
        if self.config["method"] == "rank":
            worklist = test_mirror_pool(self=self, worklist=worklist)
            worklist = sort_mirror_pool(worklist=worklist,
                                        field="resp_time",
                                        reverse=False)
        else:
            shuffle(worklist)
    """
    Create a list for display in ui.
    The gui and the console ui expect the supplied list
    to be in the old country dictionary format.
    {
        "country": "country_name",
        "resp_time": "m.sss",
        "last_sync": "HHh MMm",
        "url": "http://server/repo/"
    }
    """
    interactive_list = translate_pool_to_interactive(mirror_pool=worklist,
                                                     tty=self.tty)

    # import the correct ui
    if self.no_display:
        # in console mode
        from pacman_mirrors.dialogs import consoleui as ui
    else:
        # gtk mode
        from pacman_mirrors.dialogs import graphicalui as ui

    interactive = ui.run(server_list=interactive_list,
                         random=self.config["method"] == "random",
                         default=self.default)

    # process user choices
    if interactive.is_done:
        """
        translate interactive list back to our json format
        """
        custom_pool, mirror_list = translate_interactive_to_pool(
            selection=interactive.custom_list,
            mirror_pool=self.mirrors.mirror_pool,
            tty=self.tty)
        """
        Try selected method on the mirrorlist
        """
        try:
            _ = mirror_list[0]
            # using the default runs method after selection
            if self.default:
                if self.config["method"] == "rank":
                    mirror_list = test_mirror_pool(self=self,
                                                   worklist=mirror_list)
                    mirror_list = sorted(mirror_list,
                                         key=itemgetter("resp_time"))
                else:
                    shuffle(mirror_list)
        except IndexError:
            pass
        """
        Write custom mirror pool
        Write mirrorlist
        """
        try:
            _ = custom_pool[0]
            self.custom = True
            self.config["country_pool"] = ["Custom"]
            """
            Writing the custom mirror pool file
            """
            write_custom_mirrors_json(self=self, selected_mirrors=custom_pool)
            """
            Writing mirrorlist
            If the mirror list is empty because 
            no up-to-date mirrors exist for users branch
            raise IndexError to the outer try-catch
            """
            try:
                _ = mirror_list[0]
                write_pacman_mirror_list(self, mirror_list)
                if self.no_status:
                    util.msg(message=f"{txt.OVERRIDE_STATUS_CHOICE}",
                             urgency=txt.WRN_CLR,
                             tty=self.tty)
                    util.msg(message=f"{txt.OVERRIDE_STATUS_MIRROR}",
                             urgency=txt.WRN_CLR,
                             tty=self.tty)
            except IndexError:
                raise IndexError
        except IndexError:
            util.msg(message=f"{txt.NO_SELECTION}",
                     urgency=txt.WRN_CLR,
                     tty=self.tty)
            util.msg(message=f"{txt.NO_CHANGE}",
                     urgency=txt.INF_CLR,
                     tty=self.tty)