Update beta 1.2.2.2

This commit is contained in:
MacRimi
2026-06-10 19:53:40 +02:00
parent 7ad5508623
commit df95b50f8c
11 changed files with 1355 additions and 960 deletions

View File

@@ -36,7 +36,10 @@ TRANSLATE_CALL_RE = re.compile(
)
def iter_script_files(scripts_dir: Path) -> Iterable[Path]:
def iter_script_files(
scripts_dir: Path, extra_files: Iterable[Path] = ()
) -> Iterable[Path]:
# Walk the main scripts tree.
for path in sorted(scripts_dir.rglob("*")):
if not path.is_file():
continue
@@ -45,6 +48,14 @@ def iter_script_files(scripts_dir: Path) -> Iterable[Path]:
if path.suffix not in {".sh", ".func"}:
continue
yield path
# Yield additional files passed explicitly (e.g. the root-level `menu`
# entry point or install_proxmenux*.sh). These live outside scripts/
# but still contain translate "..." calls we want in the cache.
# No extension filter and no utils.sh skip — the caller decided
# they belong, we just check the file actually exists.
for extra in extra_files:
if extra.is_file():
yield extra
def decode_shell_string(raw: str, quote_char: str) -> str:
@@ -56,9 +67,11 @@ def decode_shell_string(raw: str, quote_char: str) -> str:
return raw.replace(r"\"", '"').replace(r"\\", "\\")
def extract_translate_texts(scripts_dir: Path) -> list[str]:
def extract_translate_texts(
scripts_dir: Path, extra_files: Iterable[Path] = ()
) -> list[str]:
found: dict[str, None] = {}
for path in iter_script_files(scripts_dir):
for path in iter_script_files(scripts_dir, extra_files):
try:
content = path.read_text(encoding="utf-8")
except UnicodeDecodeError:
@@ -219,6 +232,19 @@ def build_arg_parser() -> argparse.ArgumentParser:
description="Extract translate calls from scripts/ and build json/cache.json."
)
parser.add_argument("--scripts-dir", default="scripts", type=Path)
parser.add_argument(
"--extra-file",
action="append",
default=[],
type=Path,
metavar="PATH",
help=(
"Extra individual files to scan for translate calls in addition "
"to --scripts-dir. Useful for the root-level `menu` entry point "
"and install_proxmenux*.sh, which sit outside scripts/. "
"Pass multiple times to add more than one file."
),
)
parser.add_argument(
"--output-dir",
default=Path("lang"),
@@ -292,7 +318,7 @@ def main() -> int:
print("No destination languages selected.", file=sys.stderr)
return 1
texts = extract_translate_texts(scripts_dir)
texts = extract_translate_texts(scripts_dir, args.extra_file)
if args.limit > 0:
texts = texts[: args.limit]
existing_by_lang = {

View File

@@ -15,6 +15,9 @@ on:
branches: [develop]
paths:
- 'scripts/**/*.sh'
- 'menu'
- 'install_proxmenux.sh'
- 'install_proxmenux_beta.sh'
- '.github/scripts/build_translation_cache.py'
- '.github/workflows/build-translation-cache.yml'
workflow_dispatch:
@@ -69,8 +72,13 @@ jobs:
if [[ "${{ github.event.inputs.refresh }}" == "true" ]]; then
REFRESH_FLAG="--refresh"
fi
# Extra files outside scripts/ that also contain translate "..."
# calls. Keep this list in sync with the `paths` trigger above.
python .github/scripts/build_translation_cache.py \
--scripts-dir scripts \
--extra-file menu \
--extra-file install_proxmenux.sh \
--extra-file install_proxmenux_beta.sh \
--output-dir lang \
--provider googletrans \
$REFRESH_FLAG

View File

@@ -35,12 +35,16 @@
INSTALL_DIR="/usr/local/bin"
BASE_DIR="/usr/local/share/proxmenux"
CONFIG_FILE="$BASE_DIR/config.json"
CACHE_FILE="$BASE_DIR/cache.json"
UTILS_FILE="$BASE_DIR/utils.sh"
LOCAL_VERSION_FILE="$BASE_DIR/version.txt"
BETA_VERSION_FILE="$BASE_DIR/beta_version.txt"
MENU_SCRIPT="menu"
# Legacy path that existed during the Python+googletrans era. Purged on
# install if present — the current translate flow uses pre-built JSON
# files in lang/ and has no runtime venv dependency.
LEGACY_VENV_PATH="/opt/googletrans-env"
MONITOR_INSTALL_DIR="$BASE_DIR"
MONITOR_RUNTIME_DIR="$BASE_DIR/monitor-app"
MONITOR_SERVICE_FILE="/etc/systemd/system/proxmenux-monitor.service"
@@ -304,9 +308,6 @@ cleanup_corrupted_files() {
if [ -f "$CONFIG_FILE" ] && ! jq empty "$CONFIG_FILE" >/dev/null 2>&1; then
rm -f "$CONFIG_FILE"
fi
if [ -f "$CACHE_FILE" ] && ! jq empty "$CACHE_FILE" >/dev/null 2>&1; then
rm -f "$CACHE_FILE"
fi
}
detect_latest_appimage() {
@@ -541,11 +542,70 @@ EOF
}
# ── Main install ───────────────────────────────────────────
select_language() {
if [ -f "$CONFIG_FILE" ] && jq empty "$CONFIG_FILE" >/dev/null 2>&1; then
local existing_language=$(jq -r '.language // empty' "$CONFIG_FILE" 2>/dev/null)
if [[ -n "$existing_language" && "$existing_language" != "null" && "$existing_language" != "empty" ]]; then
LANGUAGE="$existing_language"
msg_ok "Using existing language configuration: $LANGUAGE"
return 0
fi
fi
LANGUAGE=$(whiptail --title "Select Language" --menu "Choose a language for the menu:" 20 60 12 \
"en" "English (Recommended)" \
"es" "Spanish" \
"fr" "French" \
"de" "German" \
"it" "Italian" \
"pt" "Portuguese" 3>&1 1>&2 2>&3)
if [ -z "$LANGUAGE" ]; then
msg_error "No language selected. Exiting."
exit 1
fi
mkdir -p "$(dirname "$CONFIG_FILE")"
if [ ! -f "$CONFIG_FILE" ] || ! jq empty "$CONFIG_FILE" >/dev/null 2>&1; then
echo '{}' > "$CONFIG_FILE"
fi
local tmp_file
tmp_file=$(mktemp)
if jq --arg lang "$LANGUAGE" '. + {language: $lang}' "$CONFIG_FILE" > "$tmp_file" 2>/dev/null; then
mv "$tmp_file" "$CONFIG_FILE"
else
echo "{\"language\": \"$LANGUAGE\"}" > "$CONFIG_FILE"
fi
[ -f "$tmp_file" ] && rm -f "$tmp_file"
msg_ok "Language set to: $LANGUAGE"
}
install_beta() {
local total_steps=4
local total_steps=5
local current_step=1
# ── Step 1: Dependencies ──────────────────────────────
# ── Step 1: Language selection ────────────────────────
# Pre-built translations in lang/<locale>.json make every beta install
# multilingual-capable. Ask the operator once up front; subsequent
# update runs reuse the saved choice without re-prompting.
show_progress $current_step $total_steps "Language selection"
select_language
((current_step++))
# Purge the legacy googletrans virtualenv if a previous install left it
# behind. Runtime translation is now a static JSON lookup — the venv
# is dead weight on disk now.
if [[ -d "$LEGACY_VENV_PATH" ]]; then
msg_info "Removing legacy translation virtualenv at $LEGACY_VENV_PATH..."
rm -rf "$LEGACY_VENV_PATH"
msg_ok "Legacy translation virtualenv removed."
fi
# ── Step 2: Dependencies ──────────────────────────────
show_progress $current_step $total_steps "Installing system dependencies"
if ! command -v jq > /dev/null 2>&1; then
@@ -593,7 +653,7 @@ install_beta() {
msg_ok "Dependencies installed: jq, dialog, curl, git."
# ── Step 2: Clone develop branch ─────────────────────
# ── Step 3: Clone develop branch ─────────────────────
((current_step++))
show_progress $current_step $total_steps "Cloning ProxMenux develop branch"
@@ -612,7 +672,7 @@ install_beta() {
cd "$TEMP_DIR"
# ── Step 3: Files ─────────────────────────────────────
# ── Step 4: Files ─────────────────────────────────────
((current_step++))
show_progress $current_step $total_steps "Creating directories and copying files"
@@ -640,11 +700,23 @@ install_beta() {
cp "./install_proxmenux.sh" "$BASE_DIR/install_proxmenux.sh" 2>/dev/null || true
cp "./install_proxmenux_beta.sh" "$BASE_DIR/install_proxmenux_beta.sh" 2>/dev/null || true
# Pre-built translation cache. The runtime translate() in utils.sh
# reads $BASE_DIR/lang/<lang>.json — these files ship with the repo
# (one per supported language) so every beta install is multilingual
# without any runtime download or Python dependency. Refresh the
# whole dir on every install so a language that was renamed or
# dropped upstream disappears here too.
if [ -d "./lang" ]; then
rm -rf "$BASE_DIR/lang"
mkdir -p "$BASE_DIR/lang"
cp -r "./lang/"* "$BASE_DIR/lang/" 2>/dev/null || true
fi
# Wipe the scripts tree before copying so any file removed upstream
# (renamed, consolidated, deprecated) disappears from the user install.
# Only $BASE_DIR/scripts/ is cleared; config.json, cache.json,
# components_status.json, version.txt, beta_version.txt, monitor.db,
# smart/, oci/ and the AppImage live outside this path and are preserved.
# Only $BASE_DIR/scripts/ is cleared; config.json, components_status.json,
# version.txt, beta_version.txt, monitor.db, smart/, oci/ and the
# AppImage live outside this path and are preserved.
rm -rf "$BASE_DIR/scripts"
mkdir -p "$BASE_DIR/scripts"
cp -r "./scripts/"* "$BASE_DIR/scripts/"
@@ -667,7 +739,7 @@ install_beta() {
msg_ok "Files installed. Beta version: ${beta_version}."
# ── Step 4: Monitor ───────────────────────────────────
# ── Step 5: Monitor ───────────────────────────────────
((current_step++))
show_progress $current_step $total_steps "Installing ProxMenux Monitor (beta)"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -343,7 +343,7 @@ _bk_local() {
# Fallback: gzip (rename archive)
archive="${archive%.zst}"
archive="${archive%.tar}.tar.gz"
if command -v pv >/dev/null 2>&1; then
if hb_ensure_pv; then
local stage_bytes
local pipefail_state
stage_bytes=$(du -sb "$staging_root" 2>/dev/null | awk '{print $1}')
@@ -1115,7 +1115,7 @@ _rs_export_to_file() {
tar_ok=0
: > "$log_file"
if command -v pv >/dev/null 2>&1; then
if hb_ensure_pv; then
# Stream tar through pv so the operator sees a live progress
# bar instead of staring at a frozen title for minutes. We
# mirror the same pattern used by the local backup path
@@ -1132,10 +1132,11 @@ _rs_export_to_file() {
fi
[[ "$pipefail_state" == "off" ]] && set +o pipefail
else
# pv isn't installedat least tell the operator something
# is happening and hint at the package they can install for
# a better experience next time.
msg_info "$(translate "Creating export archive (install 'pv' for a live progress bar)...")"
# Offline / apt unavailable — silently fall back to a plain
# tar so we still produce the archive. No "install pv" message:
# if we couldn't install it ourselves, sending the operator off
# to apt is just shifting our problem onto them.
msg_info "$(translate "Creating export archive...")"
stop_spinner
if tar -czf "$archive" -C "$staging_root" . >>"$log_file" 2>&1; then
tar_ok=1

View File

@@ -1889,6 +1889,18 @@ hb_require_cmd() {
command -v "$cmd" >/dev/null 2>&1
}
# Silent best-effort install of `pv` so callers can pipe tar through it
# for a live progress bar. Returns 0 if pv ends up available, 1 if not.
# Never speaks — pv is purely an UX improvement, asking the operator to
# install it themselves would be backwards (we have apt; they shouldn't).
hb_ensure_pv() {
command -v pv >/dev/null 2>&1 && return 0
if command -v apt-get >/dev/null 2>&1; then
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq pv >/dev/null 2>&1
fi
command -v pv >/dev/null 2>&1
}
# ==========================================================
# Compatibility check — compares backup metadata against the
# current host and surfaces hostname / PVE version / kernel /

View File

@@ -111,13 +111,6 @@ uninstall_proxmenux_monitor() {
}
detect_installation_type() {
# The Translation/Normal split is gone after the googletrans removal.
# All installs are multilingual via pre-built lang/*.json. Keeping the
# function name + a fixed value so callers don't have to change.
echo "normal"
}
check_monitor_status() {
if systemctl list-unit-files | grep -q "$MONITOR_SERVICE"; then
if systemctl is-active --quiet "$MONITOR_SERVICE"; then
@@ -528,9 +521,6 @@ show_monitor_status() {
# ==========================================================
show_config_menu() {
local install_type
install_type=$(detect_installation_type)
while true; do
local menu_options=()
local option_actions=()
@@ -561,35 +551,22 @@ show_config_menu() {
option_actions[$option_num]="change_release_channel"
((option_num++))
# Build menu based on installation type
if [ "$install_type" = "translation" ]; then
menu_options+=("$option_num" "$(translate "Change Language")")
option_actions[$option_num]="change_language"
((option_num++))
menu_options+=("$option_num" "$(translate "Show Version Information")")
option_actions[$option_num]="show_version_info"
((option_num++))
menu_options+=("$option_num" "$(translate "Uninstall ProxMenux")")
option_actions[$option_num]="uninstall_proxmenu"
((option_num++))
menu_options+=("$option_num" "$(translate "Return to Main Menu")")
option_actions[$option_num]="return_main"
else
# Normal version (English only)
menu_options+=("$option_num" "Show Version Information")
option_actions[$option_num]="show_version_info"
((option_num++))
menu_options+=("$option_num" "Uninstall ProxMenux")
option_actions[$option_num]="uninstall_proxmenu"
((option_num++))
menu_options+=("$option_num" "Return to Main Menu")
option_actions[$option_num]="return_main"
fi
# Translation/Normal split is gone — single menu now. Change Language
# is always available since every install ships the lang/*.json cache.
menu_options+=("$option_num" "$(translate "Change Language")")
option_actions[$option_num]="change_language"
((option_num++))
menu_options+=("$option_num" "$(translate "Show Version Information")")
option_actions[$option_num]="show_version_info"
((option_num++))
menu_options+=("$option_num" "$(translate "Uninstall ProxMenux")")
option_actions[$option_num]="uninstall_proxmenu"
((option_num++))
menu_options+=("$option_num" "$(translate "Return to Main Menu")")
option_actions[$option_num]="return_main"
# Show menu
OPTION=$(dialog --clear --backtitle "ProxMenux Configuration" \
@@ -665,8 +642,7 @@ change_language() {
# ==========================================================
show_version_info() {
local version info_message install_type release_channel beta_version
install_type=$(detect_installation_type)
local version info_message release_channel beta_version
release_channel=$(get_release_channel)
if [ -f "$LOCAL_VERSION_FILE" ]; then
@@ -683,15 +659,8 @@ show_version_info() {
fi
info_message+="\n"
# Show installation type
info_message+="$(translate "Installation type:")\n"
if [ "$install_type" = "translation" ]; then
info_message+="$(translate "Translation Version (Multi-language support)")\n"
else
info_message+="$(translate "Normal Version (English only - Lightweight)")\n"
fi
info_message+="\n"
# Translation/Normal split is gone — single install path now.
# Translation support is always present via the lang/*.json cache.
info_message+="$(translate "Installed components:")\n"
if [ -f "$CONFIG_FILE" ]; then
while IFS=': ' read -r component value; do
@@ -749,9 +718,6 @@ show_version_info() {
# ==========================================================
uninstall_proxmenu() {
local install_type
install_type=$(detect_installation_type)
if ! dialog --clear --backtitle "ProxMenux Configuration" \
--title "Uninstall ProxMenux" \
--yesno "\n$(translate "Are you sure you want to uninstall ProxMenux?")" 8 60; then