add appslib
This commit is contained in:
parent
1d65bd9ad6
commit
965732f420
2 changed files with 140 additions and 0 deletions
68
appslib/apps_cache.py
Normal file
68
appslib/apps_cache.py
Normal file
|
@ -0,0 +1,68 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
import utils
|
||||
from git import Repo
|
||||
|
||||
|
||||
def apps_cache_path() -> Path:
|
||||
path = apps_repo_root() / ".apps_cache"
|
||||
path.mkdir()
|
||||
return path
|
||||
|
||||
|
||||
def app_cache_path(app: str) -> Path:
|
||||
path = apps_cache_path() / app
|
||||
path.mkdir()
|
||||
return path
|
||||
|
||||
|
||||
# def refresh_all_caches(catalog: dict[str, dict[str, str]]):
|
||||
# for app, infos
|
||||
# pass
|
||||
|
||||
|
||||
def app_cache_clone(app: str, infos: dict[str, str]) -> None:
|
||||
git_depths = {
|
||||
"notworking": 5,
|
||||
"inprogress": 20,
|
||||
"default": 40,
|
||||
}
|
||||
|
||||
Repo.clone_from(
|
||||
infos["url"],
|
||||
to_path=app_cache_path(app),
|
||||
depth=git_depths.get(infos["state"], git_depths["default"]),
|
||||
single_branch=True, branch=infos.get("branch", "master"),
|
||||
)
|
||||
|
||||
|
||||
def app_cache_update(app: str, infos: dict[str, str]) -> None:
|
||||
app_path = app_cache_path(app)
|
||||
age = utils.git_repo_age(app_path)
|
||||
if age is False:
|
||||
return app_cache_clone(app, infos)
|
||||
|
||||
if age < 3600:
|
||||
logging.info(f"Skipping {app}, it's been updated recently.")
|
||||
return
|
||||
|
||||
repo = Repo(app_path)
|
||||
repo.remote("origin").set_url(infos["url"])
|
||||
|
||||
branch = infos.get("branch", "master")
|
||||
if repo.active_branch != branch:
|
||||
all_branches = [str(b) for b in repo.branches]
|
||||
if branch in all_branches:
|
||||
repo.git.checkout(branch, "--force")
|
||||
else:
|
||||
repo.git.remote("set-branches", "--add", "origin", branch)
|
||||
repo.remote("origin").fetch(f"{branch}:{branch}")
|
||||
|
||||
repo.remote("origin").fetch(refspec=branch, force=True)
|
||||
repo.git.reset("--hard", f"origin/{branch}")
|
||||
|
||||
|
||||
def cache_all_apps(catalog: dict[str, dict[str, str]]) -> None:
|
72
appslib/utils.py
Normal file
72
appslib/utils.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
from typing import Any, TextIO, Generator
|
||||
import time
|
||||
from functools import cache
|
||||
from pathlib import Path
|
||||
from git import Repo
|
||||
|
||||
import toml
|
||||
|
||||
REPO_APPS_ROOT = Path(Repo(__file__, search_parent_directories=True).working_dir)
|
||||
|
||||
|
||||
@cache
|
||||
def apps_repo_root() -> Path:
|
||||
return Path(__file__).parent.parent.parent
|
||||
|
||||
|
||||
def git(cmd: list[str], cwd: Path | None = None) -> str:
|
||||
full_cmd = ["git"]
|
||||
if cwd:
|
||||
full_cmd.extend(["-C", str(cwd)])
|
||||
full_cmd.extend(cmd)
|
||||
return subprocess.check_output(
|
||||
full_cmd,
|
||||
# env=my_env,
|
||||
).strip().decode("utf-8")
|
||||
|
||||
|
||||
def git_repo_age(path: Path) -> bool | int:
|
||||
for file in [path / ".git" / "FETCH_HEAD", path / ".git" / "HEAD"]:
|
||||
if file.exists():
|
||||
return int(time.time() - file.stat().st_mtime)
|
||||
return False
|
||||
|
||||
|
||||
# Progress bar helper, stolen from https://stackoverflow.com/a/34482761
|
||||
def progressbar(
|
||||
it: list[Any],
|
||||
prefix: str = "",
|
||||
size: int = 60,
|
||||
file: TextIO = sys.stdout) -> Generator[Any, None, None]:
|
||||
count = len(it)
|
||||
|
||||
def show(j, name=""):
|
||||
name += " "
|
||||
x = int(size * j / count)
|
||||
file.write(
|
||||
"%s[%s%s] %i/%i %s\r" % (prefix, "#" * x, "." * (size - x), j, count, name)
|
||||
)
|
||||
file.flush()
|
||||
|
||||
show(0)
|
||||
for i, item in enumerate(it):
|
||||
yield item
|
||||
show(i + 1, item[0])
|
||||
file.write("\n")
|
||||
file.flush()
|
||||
|
||||
|
||||
@cache
|
||||
def get_catalog(working_only=False):
|
||||
"""Load the app catalog and filter out the non-working ones"""
|
||||
catalog = toml.load((REPO_APPS_ROOT / "apps.toml").open("r", encoding="utf-8"))
|
||||
if working_only:
|
||||
catalog = {
|
||||
app: infos for app, infos in catalog.items()
|
||||
if infos.get("state") != "notworking"
|
||||
}
|
||||
return catalog
|
Loading…
Reference in a new issue