CI / check (push) Successful in 32s
CI / tests-integration (push) Successful in 1m55s
CI / tests-unit (push) Successful in 2m1s
CI / tests-imaging-browsers (push) Successful in 2m7s
CI / tests-ui (push) Successful in 2m44s
CI / preflight (push) Skipped
CI / tests-quality (push) Successful in 1m46s
CI / deploy (push) Successful in 3m28s
Updating the catalog was only possible from the admin "Catalog audit" page, which streams `runCatalogAudit` over SSE and always compares against every enabled clone source. This adds the same engine to the terminal so it can be run by hand or from cron: - `scripts/catalog-sync.ts` — CLI driver around `runCatalogAudit`. Prints the live progress, the per-source "on the source but not in this hotel" counts and a summary block; generated catalog SQL is saved to `storage/catalog-sync/*.sql` (gitignored). Supports `--list-sources`, `--sources=<a,b>`, `--icons`, `--nitros`, `--furnidata`, `--structure`, `--check-ids`, `--sql`, `--apply-sql`, `--organize-sql`, `--all`, `--json` and `--fail-on-errors`. - `scripts/catalog-sync.sh` — interactive menu (`pnpm catalog:sync`). Lists the configured sources (so the menu always matches `clone_sources`), lets Habbo (COM) be taken with Enter, and offers audit-only through full repair + applying the catalog SQL, each with a distinct confirmation. With no arguments it needs a terminal; with any flag it passes straight through to the CLI. - `runCatalogAudit` gains `sourceIds` to restrict which sites are compared; omitting it keeps the previous "compare against everything enabled" behaviour. An audit writes nothing, and `--apply-sql` is the only flag that changes the catalog. Verified against the live DB: 16370 items_base rows, 16479 catalog items, 2871 Habbo (COM) entries missing from this hotel.
158 lines
4.5 KiB
Bash
Executable File
158 lines
4.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Update the hotel catalog from a clone source (Habbo, retros, …).
|
|
#
|
|
# Two ways to use it:
|
|
# ./scripts/catalog-sync.sh interactive menu
|
|
# ./scripts/catalog-sync.sh --all --sql same flags as the CLI, no menu
|
|
#
|
|
# The menu asks which sites to compare (Habbo is the preset) and what may be
|
|
# written. An audit is read-only; only a repair option touches the catalog, and
|
|
# applying the generated catalog SQL always needs its own choice.
|
|
|
|
cd "$(dirname "$0")/.." || exit 1
|
|
CLI="scripts/catalog-sync.ts"
|
|
# The react-server export condition resolves `server-only` to its no-op build,
|
|
# exactly like `pnpm jobs:worker` — the audit engine imports server modules.
|
|
RUN=(node --conditions=react-server --import tsx "$CLI")
|
|
|
|
# Any flag passed straight through means "no menu", so the same entry point
|
|
# works for cron/CI where only the flag path is safe.
|
|
if [ $# -gt 0 ]; then
|
|
exec "${RUN[@]}" "$@"
|
|
fi
|
|
|
|
if [ ! -t 0 ]; then
|
|
echo "Not a terminal. Use the non-interactive form, e.g.:" >&2
|
|
echo " $0 --all --sources=default-habbo-com" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "=== Catalog sync ==="
|
|
echo
|
|
|
|
# ── Step 1: which sites to compare ───────────────────────────────────────────
|
|
# Ask the CLI for the configured sources so the menu always matches the live
|
|
# `clone_sources` setting (and its defaults) instead of a hardcoded list.
|
|
mapfile -t SOURCE_ROWS < <("${RUN[@]}" --list-sources --tsv)
|
|
if [ "${#SOURCE_ROWS[@]}" -eq 0 ]; then
|
|
echo "No clone sources are configured." >&2
|
|
exit 1
|
|
fi
|
|
|
|
IDS=()
|
|
NAMES=()
|
|
echo "Compare this catalog against:"
|
|
for i in "${!SOURCE_ROWS[@]}"; do
|
|
IFS=$'\t' read -r SOURCE_ID SOURCE_NAME _SOURCE_URL <<<"${SOURCE_ROWS[$i]}"
|
|
IDS+=("$SOURCE_ID")
|
|
NAMES+=("$SOURCE_NAME")
|
|
printf " %2d) %-24s %s\n" "$((i + 1))" "$SOURCE_NAME" "$SOURCE_ID"
|
|
done
|
|
echo
|
|
echo " a) all sources above"
|
|
echo " Enter) preset: ${NAMES[0]}"
|
|
|
|
read -r -p "Sources [a, 1-${#IDS[@]}, Enter]: " SOURCE_CHOICE
|
|
|
|
SELECTED_FLAG=""
|
|
case "$SOURCE_CHOICE" in
|
|
"" | "Habbo" | "habbo" | "habbo.com")
|
|
# Habbo is the first default preset (Habbo (COM)).
|
|
SELECTED_FLAG="--sources=${IDS[0]}"
|
|
SOURCE_LABEL="${NAMES[0]}"
|
|
;;
|
|
a | A | all)
|
|
SOURCE_LABEL="all sources"
|
|
;;
|
|
*)
|
|
SELECTED_IDS=()
|
|
IFS=', ' read -r -a CHOICES <<<"$SOURCE_CHOICE"
|
|
for CHOICE in "${CHOICES[@]}"; do
|
|
[ -z "$CHOICE" ] && continue
|
|
case "$CHOICE" in
|
|
*[!0-9]* | "")
|
|
echo "Invalid choice: '$CHOICE'" >&2
|
|
exit 1
|
|
;;
|
|
*)
|
|
if [ "$CHOICE" -lt 1 ] || [ "$CHOICE" -gt "${#IDS[@]}" ]; then
|
|
echo "Out of range: $CHOICE" >&2
|
|
exit 1
|
|
fi
|
|
SELECTED_IDS+=("${IDS[$((CHOICE - 1))]}")
|
|
;;
|
|
esac
|
|
done
|
|
if [ "${#SELECTED_IDS[@]}" -eq 0 ]; then
|
|
echo "No sources selected." >&2
|
|
exit 1
|
|
fi
|
|
SELECTED_FLAG="--sources=$(IFS=,; echo "${SELECTED_IDS[*]}")"
|
|
SOURCE_LABEL="${#SELECTED_IDS[@]} source(s)"
|
|
;;
|
|
esac
|
|
|
|
# ── Step 2: what may be changed ──────────────────────────────────────────────
|
|
cat <<EOF
|
|
|
|
What should be done? (comparing with: $SOURCE_LABEL)
|
|
1) Audit only — nothing is written
|
|
2) Repair furniture icons + nitro bundles
|
|
3) 2 + FurnitureData.json + catalog structure
|
|
4) 3 + generate the catalog SQL (saved, not applied)
|
|
5) 4 + APPLY the catalog SQL to the catalog
|
|
q) Cancel
|
|
EOF
|
|
|
|
read -r -p "Action [1]: " ACTION_CHOICE
|
|
ACTION_CHOICE="${ACTION_CHOICE:-1}"
|
|
|
|
ACTIONS=(audit)
|
|
CONFIRM=""
|
|
# Empty for the audit-only branch on purpose: no repair flags are passed.
|
|
ACTION_FLAGS=()
|
|
case "$ACTION_CHOICE" in
|
|
1)
|
|
ACTIONS=(audit "[nothing written]")
|
|
;;
|
|
2)
|
|
ACTIONS=(audit "icons + nitro bundles downloaded")
|
|
ACTION_FLAGS=(--icons --nitros)
|
|
;;
|
|
3)
|
|
ACTIONS=(audit "icons + nitro bundles + FurnitureData.json + structure")
|
|
ACTION_FLAGS=(--all)
|
|
;;
|
|
4)
|
|
ACTIONS=(audit "everything + catalog SQL generated")
|
|
ACTION_FLAGS=(--all --sql)
|
|
;;
|
|
5)
|
|
ACTIONS=(audit "everything + catalog SQL APPLIED")
|
|
ACTION_FLAGS=(--all --sql --apply-sql)
|
|
CONFIRM="This writes to the catalog. Continue? [y/N]: "
|
|
;;
|
|
q | Q)
|
|
echo "Cancelled."
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Invalid action: '$ACTION_CHOICE'" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
echo
|
|
printf 'Running: %s against %s\n' "${ACTIONS[1]}" "$SOURCE_LABEL"
|
|
if [ -n "$CONFIRM" ]; then
|
|
read -r -p "$CONFIRM" REPLY
|
|
if [ "$REPLY" != "y" ] && [ "$REPLY" != "Y" ]; then
|
|
echo "Cancelled."
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
echo
|
|
# shellcheck disable=SC2086
|
|
"${RUN[@]}" $SELECTED_FLAG "${ACTION_FLAGS[@]}"
|