#!/bin/sh set -eu source_script=/tmp/wechat-local-ocr.py source_bridge=/tmp/wechat-gui-bridge source_recorder_unit=/tmp/wechat-local-ocr-recorder.service source_responder_unit=/tmp/wechat-local-ocr-responder.service source_defaults=/tmp/wechat-local-ocr.default runtime_user=${JWEBOT_RUNTIME_USER:-jwebot} target_script=/usr/local/sbin/wechat-local-ocr target_bridge=/usr/local/sbin/wechat-gui-bridge target_recorder_unit=/etc/systemd/system/wechat-local-ocr-recorder.service target_responder_unit=/etc/systemd/system/wechat-local-ocr-responder.service target_defaults=/etc/default/wechat-local-ocr venv_python=${JWEBOT_RUNTIME_PYTHON:-/opt/jwebot/venv/bin/python} timestamp=$(date +%Y%m%d-%H%M%S) backup_dir="/root/wechat-local-ocr-backup-${timestamp}" enable_legacy_ocr=${ENABLE_LEGACY_OCR:-0} success=0 recorder_enabled=$(systemctl is-enabled wechat-local-ocr-recorder.service 2>/dev/null || true) recorder_active=$(systemctl is-active wechat-local-ocr-recorder.service 2>/dev/null || true) responder_enabled=$(systemctl is-enabled wechat-local-ocr-responder.service 2>/dev/null || true) responder_active=$(systemctl is-active wechat-local-ocr-responder.service 2>/dev/null || true) restore_file() { name=$1 target=$2 if [ -f "${backup_dir}/${name}" ]; then cp -a "${backup_dir}/${name}" "$target" else rm -f "$target" fi } restore_service_state() { systemctl disable --now \ wechat-local-ocr-recorder.service \ wechat-local-ocr-responder.service \ >/dev/null 2>&1 || true case "$recorder_enabled" in enabled) systemctl enable wechat-local-ocr-recorder.service >/dev/null 2>&1 || true ;; masked) systemctl mask wechat-local-ocr-recorder.service >/dev/null 2>&1 || true ;; esac case "$responder_enabled" in enabled) systemctl enable wechat-local-ocr-responder.service >/dev/null 2>&1 || true ;; masked) systemctl mask wechat-local-ocr-responder.service >/dev/null 2>&1 || true ;; esac case "$recorder_active" in active|activating|reloading) systemctl start wechat-local-ocr-recorder.service >/dev/null 2>&1 || true ;; esac case "$responder_active" in active|activating|reloading) systemctl start wechat-local-ocr-responder.service >/dev/null 2>&1 || true ;; esac } rollback() { status=$? if [ "$success" -eq 0 ]; then systemctl disable --now wechat-local-ocr-recorder.service >/dev/null 2>&1 || true systemctl disable --now wechat-local-ocr-responder.service >/dev/null 2>&1 || true restore_file wechat-local-ocr "$target_script" restore_file wechat-gui-bridge "$target_bridge" restore_file wechat-local-ocr-recorder.service "$target_recorder_unit" restore_file wechat-local-ocr-responder.service "$target_responder_unit" restore_file wechat-local-ocr.default "$target_defaults" systemctl daemon-reload || true restore_service_state fi exit "$status" } trap rollback EXIT HUP INT TERM test -x "$venv_python" test -f "$source_script" test -f "$source_bridge" test -f "$source_recorder_unit" test -f "$source_responder_unit" test -f "$source_defaults" install -d -o root -g root -m 0700 "$backup_dir" for pair in \ "wechat-local-ocr:$target_script" \ "wechat-gui-bridge:$target_bridge" \ "wechat-local-ocr-recorder.service:$target_recorder_unit" \ "wechat-local-ocr-responder.service:$target_responder_unit" \ "wechat-local-ocr.default:$target_defaults" do name=${pair%%:*} target=${pair#*:} if [ -f "$target" ]; then cp -a "$target" "${backup_dir}/${name}" fi done rendered_recorder_unit="${backup_dir}/wechat-local-ocr-recorder.rendered.service" rendered_responder_unit="${backup_dir}/wechat-local-ocr-responder.rendered.service" sed \ -e "s/^User=.*/User=$runtime_user/" \ -e "s/^Group=.*/Group=$runtime_user/" \ -e "s#/opt/jwebot/venv/bin/python#$venv_python#g" \ "$source_recorder_unit" >"$rendered_recorder_unit" sed \ -e "s#/opt/jwebot/venv/bin/python#$venv_python#g" \ "$source_responder_unit" >"$rendered_responder_unit" install -o root -g root -m 0755 "$source_script" "$target_script" install -o root -g root -m 0755 "$source_bridge" "$target_bridge" install -o root -g root -m 0644 "$rendered_recorder_unit" "$target_recorder_unit" install -o root -g root -m 0644 "$rendered_responder_unit" "$target_responder_unit" install -o root -g root -m 0644 "$source_defaults" "$target_defaults" install -d -o "$runtime_user" -g "$runtime_user" -m 0700 \ /var/lib/wechat-local-ocr \ /var/lib/wechat-local-ocr/history \ /var/lib/wechat-local-ocr/queue \ /var/lib/wechat-local-ocr/failed chown -R "$runtime_user:$runtime_user" /var/lib/wechat-local-ocr touch /var/lib/wechat-local-ocr/gui-interaction.lock chown "$runtime_user:$runtime_user" /var/lib/wechat-local-ocr/gui-interaction.lock chmod 0600 /var/lib/wechat-local-ocr/gui-interaction.lock "$venv_python" -m py_compile "$target_script" bash -n "$target_bridge" systemd-analyze verify "$target_recorder_unit" "$target_responder_unit" systemctl daemon-reload systemctl disable --now \ wechat-local-ocr-recorder.service \ wechat-local-ocr-responder.service \ >/dev/null 2>&1 || true if [ "$enable_legacy_ocr" -eq 1 ]; then systemctl enable wechat-local-ocr-recorder.service systemctl start wechat-local-ocr-recorder.service systemctl is-active --quiet wechat-local-ocr-recorder.service fi success=1 trap - EXIT HUP INT TERM echo "backup_dir=$backup_dir" sha256sum "$target_script" "$target_bridge" "$target_recorder_unit" "$target_responder_unit" "$target_defaults" if [ "$enable_legacy_ocr" -eq 1 ]; then systemctl status wechat-local-ocr-recorder.service --no-pager -l | sed -n '1,28p' else echo "legacy_ocr=disabled" fi