Files
zTools2/start.sh
zikai fffba79022 feat: 文件浏览页 + 共享白板 + 白板管理页(含补登记分片上传/隧道历史改动)
本次提交包含两批改动(7月2日遗留未入库 + 本次新功能),分述如下:

【补登记:7月2日已上线但未提交的功能】
- 分片上传:chunk_upload_controller/service/dao + UploadSession model/schema,
  支持 4MiB 分片、乱序、断点续传、去重、幂等 complete;后台 reaper 清理过期会话。
- 反向隧道:tunnel_controller/service/dao + TunnelSession model/schema,
  SSH remote forward 经 /api/userPort/{userName} 反代到 user 本地服务。
- 上传页:views/upload_html.py(拖拽/多文件/分片/断点续传 UI)。
- config.py:StorageConfig.chunk_session_dir/ttl、TunnelConfig;
  requirements.txt 加 httpx;start.sh 清理 .work/ 残留;
  schema.sql 加 upload_session/tunnel_session 表;sftp_server 承载隧道转发。

【本次新功能】
- 文件浏览页:GET /files(Basic Auth 同 docs)+ /api/admin/files(list/get/download/DELETE)。
  硬删除(DB 行 + 磁盘文件),删除后列表不再显示。前端 static/file_browser.*。
- 共享白板:GET /whiteboard/{id}(公开,不存在则新建)+ WS /ws/whiteboard/{id}。
  MySQL 持久化(whiteboard 表),Canvas 实时同步,心跳 3s/5 次失活移除,
  清空/复制按钮,移动端兼容。WhiteboardHub 管理 {board_id: set[Connection]},
  disconnect 幂等 + 空 set 清理防泄漏,broadcast 失败连接自动移除。
- 白板管理页:GET /whiteboard-admin(Basic Auth)+ /api/admin/whiteboards(list/DELETE)。
  删除时 hub.close_board 踢出在线连接。
- 清理:合并 UploadService.get_out_with_disk_path(下载/删除复用,消除重复 DB 读),
  移除无用 resolve_disk_path。
- config.py:WhiteboardConfig(heartbeat/threshold/board_id 长度/list_limit);
  schema.sql 加 whiteboard 表;README 补新接口与心跳/内存说明。
- 验证:tests/manual_whiteboard_hub.py / _ws.py / _kick.py 全部通过。
2026-07-21 14:28:13 +00:00

72 lines
2.4 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# 启动 HTTPuvicorn与 SFTP已在运行则跳过幂等
set -euo pipefail
cd "$(dirname "$0")"
ROOT="$(pwd)"
VENV="$ROOT/.venv"
PY="$VENV/bin/python"
[ -x "$PY" ] || { echo "未找到 venv$VENV,请先运行 ./setup.sh" >&2; exit 1; }
[ -f "$ROOT/config.yaml" ] || { echo "未找到 config.yaml请先运行 ./setup.sh" >&2; exit 1; }
mkdir -p "$ROOT/logs" "$ROOT/uploads"
# 启动前清理:
# - upload_service.py 用 .part 后缀做原子写,进程已停时残留必为半成品。
# - chunk_upload_service.py 的分片会话目录 .work/ 同理,残留的未完成会话无法续传。
PART_COUNT=$(find "$ROOT/uploads" -type f -name '*.part' -printf '.' 2>/dev/null | wc -c)
if [ "$PART_COUNT" -gt 0 ]; then
find "$ROOT/uploads" -type f -name '*.part' -delete
echo "清理:删除残留 .part 文件 $PART_COUNT"
fi
WORK_COUNT=0
if [ -d "$ROOT/uploads/.work" ]; then
WORK_COUNT=$(find "$ROOT/uploads/.work" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l)
fi
if [ "$WORK_COUNT" -gt 0 ]; then
rm -rf "$ROOT/uploads/.work"/*
echo "清理:删除残留分片会话目录 $WORK_COUNT"
fi
is_running() { [ -f "$1" ] && kill -0 "$(cat "$1")" 2>/dev/null; }
# --- HTTP ---
APP_PID="$ROOT/app.pid"
if is_running "$APP_PID"; then
echo "HTTP 已在运行 (pid $(cat "$APP_PID"))"
else
read -r HOST PORT <<<"$("$PY" - <<'PY'
import yaml
c = yaml.safe_load(open("config.yaml"))
print(c["server"]["host"], c["server"]["port"])
PY
)"
nohup "$VENV/bin/uvicorn" app.main:app \
--host "$HOST" --port "$PORT" \
>>"$ROOT/logs/app.log" 2>&1 &
echo $! > "$APP_PID"
echo "HTTP 启动 pid=$(cat "$APP_PID") 监听 ${HOST}:${PORT} 日志 logs/app.log"
fi
# --- SFTP ---
SFTP_PID="$ROOT/sftp.pid"
SFTP_ENABLED="$("$PY" - <<'PY'
import yaml
print("true" if yaml.safe_load(open("config.yaml")).get("sftp", {}).get("enabled", True) else "false")
PY
)"
if [ "$SFTP_ENABLED" = "true" ]; then
if is_running "$SFTP_PID"; then
echo "SFTP 已在运行 (pid $(cat "$SFTP_PID"))"
else
nohup "$PY" -m app.services.sftp_server >>"$ROOT/logs/sftp.log" 2>&1 &
echo $! > "$SFTP_PID"
echo "SFTP 启动 pid=$(cat "$SFTP_PID") 日志 logs/sftp.log"
fi
else
echo "SFTP 已在配置中禁用,跳过。"
fi
echo "docs: http://127.0.0.1:6867/docs (对外 https://f.zikai.wang/docs)"