diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/colors.py | 10 | ||||
-rw-r--r-- | src/config.py | 2 | ||||
-rw-r--r-- | src/options.py | 5 | ||||
-rw-r--r-- | src/util.py | 37 | ||||
-rw-r--r-- | src/verbs/sync.py | 121 | ||||
-rw-r--r-- | src/xi.py | 2 |
6 files changed, 130 insertions, 47 deletions
diff --git a/src/colors.py b/src/colors.py index 760c3f3..c05d49b 100644 --- a/src/colors.py +++ b/src/colors.py @@ -19,3 +19,13 @@ LIGHT_BLUE = esc(94) LIGHT_MAGENTA = esc(95) LIGHT_CYAN = esc(96) LIGHT_WHITE = esc(97) + +BG_BLACK = esc(40) +BG_RED = esc(41) +BG_GREEN = esc(42) +BG_YELLOW = esc(43) +BG_BLUE = esc(44) +BG_MAGENTA = esc(45) +BG_CYAN = esc(46) +BG_WHITE = esc(47) +BG_DEFAULT = esc(49) diff --git a/src/config.py b/src/config.py index c98b076..b7cf915 100644 --- a/src/config.py +++ b/src/config.py @@ -78,7 +78,7 @@ def _parse_line(line, config_file): # if starting with include, then include another file in the same config if key == "include": - included = parse_conf(value) + included = parse_file(value) return included elif value[-1].endswith("{"): return {key: _parse_config(config_file)} diff --git a/src/options.py b/src/options.py index c910ef2..4c419f2 100644 --- a/src/options.py +++ b/src/options.py @@ -22,6 +22,11 @@ options = { "flag" : True, "desc" : "skip syncing with repo sources (not recommended)" }, + "v": { + "name" : "verbose", + "flag" : True, + "desc" : "print more" + }, "c": { "name" : "config", "flag" : False, diff --git a/src/util.py b/src/util.py new file mode 100644 index 0000000..de05b08 --- /dev/null +++ b/src/util.py @@ -0,0 +1,37 @@ +import shutil +import requests +import colors +import time +import os + +def loading_bar(completed, total, text, + unit=""): + + columns, rows = shutil.get_terminal_size((80, 20)) + + count = f"[{completed}{unit}/{total}{unit}]" + + spaces = columns - (len(count) + len(text)) + info = text + "".join([" " for i in range(spaces)]) + count + + + reset_at = int((completed/total)*len(info)) if total > 0 else 0 + info = "".join([info[i] + (colors.RESET if i == reset_at else "") for i in range(len(info))]) + + print(colors.BLACK + colors.BG_GREEN + info, end="\r") + + + + +def curl(url): + r = requests.get(url) + return r.status_code, r.text + +def mkdir(path): + if not os.path.exists(path): + os.makedirs(path) + +if __name__ == "__main__": + for i in range(1000): + loading_bar(i, 1000, "it is loading...") + time.sleep(0.01) diff --git a/src/verbs/sync.py b/src/verbs/sync.py index 95c96f1..fa78112 100644 --- a/src/verbs/sync.py +++ b/src/verbs/sync.py @@ -1,61 +1,92 @@ import os -import requests +import util +import colors +import time -TEMP_DIR = "/tmp/xipkg" +CACHE_DIR = "/var/cache/xipkg" -def curl(url): - r = requests.get(url) - return r.status_code, r.text - -def mkdir(path): - if not os.path.exists(path): - os.makedirs(path) +def list_packages(url): + status, response = util.curl(url + "/packages.list") + if status != 200: + return {} + else: + return { + line.split()[0].split(".")[0]: line.split()[1] + for line in response.split("\n") if len(line.split()) > 0 + } + +def sync_packages(repo, sources): + packages = {} + total = 0 + completed = 0 + for source,url in sources.items(): -def download_repo(output, url): - pkg_list_url = url + "/packages.txt" + listed = list_packages(url + repo if url[-1] == "/" else f"/{repo}") + total += len(listed) + for p in listed: + if not p in packages: + packages[p] = [] - status, response = curl(pkg_list_url) - if status == 404: - print("repo does not exist at", pkg_list_url) - else: - packages = response.split("\n") - for package in packages: - if len(package) > 0: - pkg_url = url + "/" + package - status, package_info = curl(pkg_url) + packages[p].append((listed[p], source)) + completed += 1 + util.loading_bar(completed, total, f"Syncing {repo}") + return packages - if status == 200: - with open(os.path.join(output, package), "w") as file: - file.write(package_info) - else: - print("package is missing at", pkg_url) +def validate_packages(packages, repo): + output = {} + completed = 0 + total = len(packages) + for package, versions in packages.items(): + popularity = {} + for v in versions: + checksum = v[0] + source = v[1] + if not checksum in popularity: + popularity[checksum] = 0 + popularity[checksum] += 1 -# have separate list and download methods for each scheme -def sync_package_infos(source_name, url, repos): + most_popular = sorted(popularity)[0] + + # change the packages dict to list all the sources + output[package] = { + "checksum": most_popular, + "sources" : [v[1] for v in versions if v[0] == most_popular] + } + completed += 1 + util.loading_bar(completed, total, f"Validating {repo}") + return output - source_dir = os.path.join(TEMP_DIR, source_name) +def save_package_list(validated, location): + util.mkdir(location) + for package,info in validated.items(): + package_file = os.path.join(location, package) + + content = "" + with open(package_file, "w") as file: + file.write("checksum=" + info["checksum"] + "\n") + file.write("sources=" + " ".join([source for source in info["sources"]])) - scheme = url.split(":")[0] - print(url) - # TODO: add ftp - if scheme.startswith("http"): - sync_func = download_repo - else: - # Assume its a location on the file system - sync_func = copy_repo - for repo in repos: - out = os.path.join(TEMP_DIR, repo) - mkdir(out) - sync_func(out, url + repo if url[-1] == "/" else f"/{repo}") - -def sync(options, config): +def sync(args, options, config): sources = config["sources"] repos = config["repos"] - mkdir(TEMP_DIR) - for source, url in sources.items(): - sync_package_infos(source, url, repos) + for repo in repos: + packages = sync_packages(repo, sources) + + # find the most popular hash to use + validated = validate_packages(packages, repo) + + save_package_list(validated, os.path.join(config["dir"]["packages"], repo)) + + num_packages = len(validated) + util.loading_bar(num_packages, num_packages, f"Synced {repo}") + print(colors.RESET) + + + + + print("Synced!") @@ -32,7 +32,7 @@ def main(): ( verbs[verb] if verb in verbs else search )( - args[1:] if len(args) > 1 else [], conf + args[1:] if len(args) > 1 else [], opts, conf ) else: options.print_usage() |