Merge pull request #66 from YunoHost/custom-catalog

[enh] add custom catalog builder
This commit is contained in:
Alexandre Aubin 2022-11-20 00:57:13 +01:00 committed by GitHub
commit 646e449995
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 179 additions and 1 deletions

View file

@ -0,0 +1,15 @@
{
"0testapp": {
"antifeatures": [
"non-free-assets"
],
"branch": "master",
"category": "games",
"level": 8,
"potential_alternative_to": [
"Google Agenda",
"Microsoft Outlook"
],
"state": "working"
}
}

120
custom-catalog/catalog_manager.py Executable file
View file

@ -0,0 +1,120 @@
#!/usr/bin/python3
import sys
import os
import json
import toml
import yaml
import time
from collections import OrderedDict
CATALOG_LIST_PATH = "/etc/yunohost/apps_catalog.yml"
assert os.path.exists(CATALOG_LIST_PATH), f"Catalog list yaml file '{CATALOG_LIST_PATH} does not exists"
now = time.time()
my_env = os.environ.copy()
my_env["GIT_TERMINAL_PROMPT"] = "0"
DEFAULT_APPS_FOLDER = "/ynh-dev/custom-catalog/"
DEFAULT_APP_BRANCH = "master"
def build(folder=DEFAULT_APPS_FOLDER):
assert os.path.exists(folder), f"'{folder}' doesn't exists."
app_list_path = os.path.join(folder, "apps.json")
assert os.path.exists(app_list_path), "no 'apps.json' app list found."
with open(app_list_path) as f:
app_list = json.load(f)
apps = {}
fail = False
for app, infos in app_list.items():
app = app.lower()
try:
app_dict = build_app_dict(app, infos, folder)
except Exception as e:
print(f"[\033[1m\033[31mFAIL\033[00m] Processing {app} failed: {str(e)}")
fail = True
continue
apps[app_dict["id"]] = app_dict
# We also remove the app install question and resources parts which aint needed anymore by webadmin etc (or at least we think ;P)
for app in apps.values():
if "manifest" in app and "install" in app["manifest"]:
del app["manifest"]["install"]
if "manifest" in app and "resources" in app["manifest"]:
del app["manifest"]["resources"]
output_file = os.path.join(folder, "catalog.json")
data = {
"apps": apps,
"from_api_version": 3,
}
with open(output_file, "w") as f:
f.write(json.dumps(data, sort_keys=True, indent=2))
if fail:
sys.exit(1)
def build_app_dict(app, infos, folder):
app_folder = os.path.join(folder, app + "_ynh")
# Build the dict with all the infos
manifest_toml = os.path.join(app_folder, "manifest.toml")
manifest_json = os.path.join(app_folder, "manifest.json")
if os.path.exists(manifest_toml):
with open(manifest_toml) as f:
manifest = toml.load(f, _dict=OrderedDict)
else:
with open(manifest_json) as f:
manifest = json.load(f, _dict=OrderedDict)
return {
"id": app,
"git": {
"branch": infos.get("branch", DEFAULT_APP_BRANCH),
"revision": infos.get("revision", "HEAD"),
"url": f"file://{app_folder}",
},
"lastUpdate": now,
"manifest": manifest,
"state": infos.get("state", "notworking"),
"level": infos.get("level", -1),
"maintained": infos.get("maintained", True),
# "high_quality": infos.get("high_quality", False),
# "featured": infos.get("featured", False),
"category": infos.get("category", None),
"subtags": infos.get("subtags", []),
"potential_alternative_to": infos.get("potential_alternative_to", []),
"antifeatures": list(
set(
list(manifest.get("antifeatures", {}).keys())
+ infos.get("antifeatures", [])
)
),
}
def reset():
with open(CATALOG_LIST_PATH, "w") as f:
catalog_list = [{"id": "default", "url": "https://app.yunohost.org/default/"}]
yaml.safe_dump(catalog_list, f, default_flow_style=False)
def add():
with open(CATALOG_LIST_PATH) as f:
catalog_list = yaml.load(f, Loader=yaml.FullLoader)
ids = [catalog["id"] for catalog in catalog_list]
if "custom" not in ids:
catalog_list.append({"id": "custom", "url": None})
with open(CATALOG_LIST_PATH, "w") as f:
yaml.safe_dump(catalog_list, f, default_flow_style=False)
def override():
with open(CATALOG_LIST_PATH, "w") as f:
catalog_list = [{"id": "custom", "url": None}]
yaml.safe_dump(catalog_list, f, default_flow_style=False)

45
ynh-dev
View file

@ -19,7 +19,11 @@ function show_usage() {
test [PKG] Deploy, update and run tests for some packages
Tests for single modules and functions can ran with
e.g. ./ynh-dev test yunohost/appurl:urlavailable
catalog
build Rebuild the custom catalog
add Add the custom catalog in Yunohost catalog list
override Override default catalog with the custom catalog
reset Reset the catalog list to Yunohost's default
EOF
}
@ -43,6 +47,8 @@ function main()
use-git|--use-git) use_git $ARGUMENTS ;;
test|--test) run_tests $ARGUMENTS ;;
catalog|--catalog) catalog $ARGUMENTS ;;
*) critical "Unknown action ${ACTION}." ;;
esac
}
@ -483,4 +489,41 @@ function run_tests()
done
}
function catalog()
{
assert_inside_vm
local ACTION="$1"
local CUSTOM_APPS_FOLDER=${2:-"/ynh-dev/custom-catalog"}
local CUSTOM_CAT_PATH="${CUSTOM_APPS_FOLDER}/catalog.json"
local CACHE_FOLDER="/var/cache/yunohost/repo"
cd /ynh-dev/custom-catalog/
case "${ACTION}" in
build)
info "Rebuilding custom app catalog"
python3 -c "from catalog_manager import build; build(folder='${CUSTOM_APPS_FOLDER}')" && success "Successfully build custom catalog list in '${CUSTOM_CAT_PATH}'"
;;
add)
info "Injecting custom catalog in YunoHost catalog list"
create_sym_link "${CUSTOM_CAT_PATH}" "${CACHE_FOLDER}/custom.json"
python3 -c "from catalog_manager import add; add()" && success "Custom catalog '${CUSTOM_CAT_PATH}' added to catalog list"
;;
override)
info "Overriding default catalog by custom one"
create_sym_link "${CUSTOM_CAT_PATH}" "${CACHE_FOLDER}/custom.json"
python3 -c "from catalog_manager import override; override()" && success "Default catalog is now overrided by '$CUSTOM_CAT_PATH'"
;;
reset)
info "Reseting to YunoHost default catalog list"
[ -e "$CACHE_FOLDER/custom.json" ] && rm "$CACHE_FOLDER/custom.json"
python3 -c "from catalog_manager import reset; reset()" || exit 1
success "Returned to default"
;;
*)
critical "Unknown catalog action '${ACTION}'."
;;
esac
}
main $@