From 4ce96c303d778bf865be2ac2094b73902bf7c1a2 Mon Sep 17 00:00:00 2001 From: def Date: Sat, 3 Dec 2022 22:27:10 +0400 Subject: [PATCH] feat: loading percentage --- selfprivacy_api/jobs/nix_collect_garbage.py | 71 +++++++++++++++++---- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/selfprivacy_api/jobs/nix_collect_garbage.py b/selfprivacy_api/jobs/nix_collect_garbage.py index 9bb6268..2c81324 100644 --- a/selfprivacy_api/jobs/nix_collect_garbage.py +++ b/selfprivacy_api/jobs/nix_collect_garbage.py @@ -1,3 +1,4 @@ +from time import sleep import re import subprocess @@ -12,21 +13,69 @@ def nix_collect_garbage(job: Job): job=job, status=JobStatus.RUNNING, progress=0, - status_text="Start cleaning.", + status_text="Сalculate the number of dead packages...", ) - output = subprocess.check_output(["nix-collect-garbage", "-d"]) - - pat = re.compile(r"linking saves ([+-]?\d+\.\d+ \w+).+?([+-]?\d+\.\d+ \w+) freed") - match = re.search( - pat, - output, + output = subprocess.check_output( + ["nix-store --gc --print-dead", "--gc", "--print-dead"] ) + dead_packages = len(re.findall("/nix/store/", output.decode("utf-8"))) + package_equal_to_percent = 100 / dead_packages + Jobs.update( job=job, - status=JobStatus.FINISHED, - progress=100, - status_text="Сleaning completed.", - result=f"Currently hard linking saves {match.group(1)}, {match.group(2)} freed", + status=JobStatus.RUNNING, + progress=0, + status_text=f"Found {dead_packages} packages to remove!", ) + + def _parse_line(line): + pattern = re.compile(r"[+-]?\d+\.\d+ \w+ freed") + match = re.search( + pattern, + line, + ) + + if match is None: + Jobs.update( + job=job, + status=JobStatus.FINISHED, + progress=100, + status_text="Completed with an error", + result="We are sorry, result was not found :(", + ) + + else: + Jobs.update( + job=job, + status=JobStatus.FINISHED, + progress=100, + status_text="Сleaning completed.", + result=f"{match.group(0)} have been cleared", + ) + + def _stream_process(process): + go = process.poll() is None + percent = 0 + + for line in process.stdout: + if "deleting '/nix/store/" in line: + percent += package_equal_to_percent + + Jobs.update( + job=job, + status=JobStatus.RUNNING, + progress=int(percent), + status_text="Сleaning...", + ) + + elif "store paths deleted," in line: + _parse_line(line) + + return go + + process = subprocess.Popen( + ["nix-collect-garbage", "-d"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) + _stream_process(process)