feat: initialize managed portal

This commit is contained in:
Yoilun
2026-04-27 10:04:36 +08:00
commit d4e351df71
145 changed files with 13425 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
#!/usr/bin/env sh
set -eu
PROJECT_DIR="/opt/people-flow"
CONFIG_TEMPLATE="${PROJECT_DIR}/config/config.example.yaml"
CONFIG_PATH="${CONFIG_PATH:-${PROJECT_DIR}/config/local.yaml}"
OUTPUT_DIR="${OUTPUT_DIR:-${PROJECT_DIR}/outputs}"
RTSP_URL="${RTSP_URL:-}"
API_HOST="${API_HOST:-0.0.0.0}"
API_PORT="${API_PORT:-18082}"
mkdir -p "${OUTPUT_DIR}" "$(dirname "${CONFIG_PATH}")"
if [ ! -f "${CONFIG_PATH}" ]; then
cp "${CONFIG_TEMPLATE}" "${CONFIG_PATH}"
fi
python - "$CONFIG_PATH" "$RTSP_URL" "$OUTPUT_DIR" <<'PY'
from pathlib import Path
import sys
import yaml
config_path = Path(sys.argv[1])
rtsp_url = sys.argv[2]
output_dir = sys.argv[3]
raw = yaml.safe_load(config_path.read_text(encoding="utf-8")) or {}
runtime = raw.setdefault("runtime", {})
if rtsp_url:
runtime["rtsp_url"] = rtsp_url
runtime["output_dir"] = output_dir
yolo = raw.setdefault("yolo", {})
yolo.setdefault("model_path", "weights/yolo11n.pt")
config_path.write_text(
yaml.safe_dump(raw, allow_unicode=True, sort_keys=False),
encoding="utf-8",
)
PY
exec python main.py --config "${CONFIG_PATH}" manage-api --host "${API_HOST}" --port "${API_PORT}"

View File

@@ -0,0 +1,60 @@
#!/usr/bin/env bash
set -euo pipefail
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SETUP_SCRIPT="${PROJECT_DIR}/setup_native_venv.sh"
RUN_SCRIPT="${PROJECT_DIR}/scripts/run.sh"
INSTALL_SERVICE_SCRIPT="${PROJECT_DIR}/scripts/install_service.sh"
PROJECT_USER="${SUDO_USER:-$(id -un)}"
run_privileged() {
if [[ "$(id -u)" -eq 0 ]]; then
"$@"
return
fi
sudo "$@"
}
run_project_user() {
if [[ "$(id -u)" -eq 0 && -n "${SUDO_USER:-}" ]]; then
sudo -u "${PROJECT_USER}" -H "$@"
return
fi
"$@"
}
ensure_system_package() {
local command_name="$1"
local package_name="$2"
if command -v "${command_name}" >/dev/null 2>&1; then
return
fi
echo "Installing missing package: ${package_name}"
run_privileged apt-get -o Acquire::ForceIPv4=true update
run_privileged apt-get -o Acquire::ForceIPv4=true install -y "${package_name}"
}
ensure_system_package ffmpeg ffmpeg
if [[ ! -d "/usr/lib/python3.12/venv" && ! -d "/usr/lib/python3.12/ensurepip" ]]; then
echo "Installing missing package: python3.12-venv"
run_privileged apt-get -o Acquire::ForceIPv4=true update
run_privileged apt-get -o Acquire::ForceIPv4=true install -y python3.12-venv
fi
if ! command -v nvidia-smi >/dev/null 2>&1; then
echo "nvidia-smi is required but not installed." >&2
exit 1
fi
run_project_user env PYTHON_BIN="${PYTHON_BIN:-python3.12}" bash "${SETUP_SCRIPT}"
run_project_user bash "${RUN_SCRIPT}" --prepare-only
bash "${INSTALL_SERVICE_SCRIPT}"
run_privileged systemctl enable --now people-flow.service
cat <<EOF
Offline install complete.
Service started and enabled on boot: people-flow.service
Runtime log: ${PROJECT_DIR}/outputs/rtsp_run.log
EOF

View File

@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
TEMPLATE_PATH="${PROJECT_DIR}/deploy/people-flow.service.tpl"
CONFIG_PATH="${CONFIG_PATH:-${PROJECT_DIR}/config/local.yaml}"
SERVICE_NAME="${SERVICE_NAME:-people-flow.service}"
OUTPUT_PATH="${PROJECT_DIR}/deploy/${SERVICE_NAME}"
RUN_USER="${RUN_USER:-${SUDO_USER:-$(id -un)}}"
RUN_GROUP="${RUN_GROUP:-$(id -gn "${RUN_USER}")}"
if [[ ! -f "${TEMPLATE_PATH}" ]]; then
echo "Missing service template: ${TEMPLATE_PATH}" >&2
exit 1
fi
if [[ ! -f "${CONFIG_PATH}" ]]; then
echo "Missing config file: ${CONFIG_PATH}" >&2
exit 1
fi
sed \
-e "s|__PROJECT_DIR__|${PROJECT_DIR}|g" \
-e "s|__CONFIG_PATH__|${CONFIG_PATH}|g" \
-e "s|__RUN_USER__|${RUN_USER}|g" \
-e "s|__RUN_GROUP__|${RUN_GROUP}|g" \
"${TEMPLATE_PATH}" > "${OUTPUT_PATH}"
sudo cp "${OUTPUT_PATH}" "/etc/systemd/system/${SERVICE_NAME}"
sudo systemctl daemon-reload
echo "Service installed to /etc/systemd/system/${SERVICE_NAME}"
echo "Enable and start it with: sudo systemctl enable --now ${SERVICE_NAME}"

View File

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
set -euo pipefail
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
VENV_PYTHON="${PROJECT_DIR}/.venv/bin/python"
CONFIG_TEMPLATE="${PROJECT_DIR}/config/config.example.yaml"
CONFIG_PATH="${PROJECT_DIR}/config/local.yaml"
RTSP_URL="${RTSP_URL:-rtsp://user:password@camera-ip:554/h264/ch1/main/av_stream}"
OUTPUT_DIR="${OUTPUT_DIR:-${PROJECT_DIR}/outputs}"
PREPARE_ONLY=0
if [[ "${1:-}" == "--prepare-only" ]]; then
PREPARE_ONLY=1
shift
fi
if [[ ! -x "${VENV_PYTHON}" ]]; then
echo "Virtual environment is missing. Run scripts/install.sh first." >&2
exit 1
fi
if [[ "${RTSP_URL}" == "rtsp://user:password@camera-ip:554/h264/ch1/main/av_stream" ]]; then
echo "Please edit scripts/run.sh and set RTSP_URL before starting." >&2
exit 1
fi
mkdir -p "${OUTPUT_DIR}" "${PROJECT_DIR}/config"
cp "${CONFIG_TEMPLATE}" "${CONFIG_PATH}"
sed -i.bak \
-e "s|^ rtsp_url: .*| rtsp_url: \"${RTSP_URL}\"|" \
-e "s|^ output_dir: .*| output_dir: \"${OUTPUT_DIR}\"|" \
"${CONFIG_PATH}"
rm -f "${CONFIG_PATH}.bak"
if [[ "${PREPARE_ONLY}" -eq 1 ]]; then
echo "Prepared config at ${CONFIG_PATH}"
exit 0
fi
exec "${VENV_PYTHON}" "${PROJECT_DIR}/main.py" --config "${CONFIG_PATH}" rtsp "$@"

View File

@@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -euo pipefail
if [[ $# -lt 2 ]]; then
echo "Usage: $0 <rtsp_url> <host_output_dir>"
exit 1
fi
RTSP_URL="$1"
HOST_OUTPUT_DIR="$2"
mkdir -p "$HOST_OUTPUT_DIR"
docker run -d \
--name people-flow-rtsp \
--restart unless-stopped \
--network host \
--gpus all \
--shm-size 1g \
-v "$HOST_OUTPUT_DIR:/opt/people-flow/output" \
people-flow-rtsp:x86-cuda \
--config /opt/people-flow/configs/docker_x86_config.yaml \
--output-dir /opt/people-flow/output \
--device cuda:0 \
rtsp \
--input "$RTSP_URL"