feat: initial commit - oncology literature search platform
OncoLit: a multi-tenant oncology literature search, feed, and collaboration platform. Built with FastAPI + Vue 3 + PostgreSQL. Includes PubMed pipeline, drug approvals, AI summaries, and systematic review tools.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
# PubMed 增量更新逐文件下载、验证、导入脚本
|
||||
# 用法: ssh到服务器后: nohup bash /tmp/pubmed_update_one_by_one.sh &
|
||||
# 日志: tail -f /data/pubmed/import_update_files.log
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
STAGING=/data/pubmed/staging
|
||||
WORKDIR=/data/pubmed/updatefiles
|
||||
IMPORTED=/data/pubmed/updatefiles/imported
|
||||
COMPOSE_FILE=/root/scilit/docker-compose.prod.yml
|
||||
LOG=/data/pubmed/import_update_files.log
|
||||
|
||||
mkdir -p "$STAGING" "$WORKDIR" "$IMPORTED"
|
||||
|
||||
log() {
|
||||
echo "[$(TZ=Asia/Shanghai date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"
|
||||
}
|
||||
|
||||
log "=== 开始逐文件导入:195 个增量文件(1335-1529)==="
|
||||
log "目录: $STAGING -> $WORKDIR -> $IMPORTED"
|
||||
|
||||
GOOD=0
|
||||
SKIP=0
|
||||
FAIL=0
|
||||
|
||||
for i in $(seq 1335 1529); do
|
||||
FILE="pubmed26n${i}.xml.gz"
|
||||
URL="https://ftp.ncbi.nlm.nih.gov/pubmed/updatefiles/${FILE}"
|
||||
|
||||
log "--- [$((i-1334))/195] $FILE ---"
|
||||
|
||||
# Step 1: Download (single connection, reliable)
|
||||
log " 下载中..."
|
||||
if ! aria2c -x1 -s1 --retry-wait=3 --max-tries=3 \
|
||||
"$URL" -d "$STAGING" -o "$FILE" \
|
||||
>> "$LOG" 2>&1; then
|
||||
log " ERROR: 下载失败,跳过"
|
||||
SKIP=$((SKIP+1))
|
||||
rm -f "$STAGING/$FILE"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Step 2: Gzip integrity check
|
||||
log " 验证完整性..."
|
||||
if ! gzip -t "$STAGING/$FILE" 2>/dev/null; then
|
||||
log " CORRUPT: 文件损坏,重试一次..."
|
||||
rm -f "$STAGING/$FILE"
|
||||
aria2c -x1 -s1 --retry-wait=3 --max-tries=3 \
|
||||
"$URL" -d "$STAGING" -o "$FILE" \
|
||||
>> "$LOG" 2>&1 || true
|
||||
if ! gzip -t "$STAGING/$FILE" 2>/dev/null; then
|
||||
log " FAILED: 重试后仍损坏,跳过"
|
||||
SKIP=$((SKIP+1))
|
||||
rm -f "$STAGING/$FILE"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# Step 3: Prep workdir (only this file)
|
||||
rm -f "$WORKDIR"/*.xml.gz
|
||||
cp "$STAGING/$FILE" "$WORKDIR/"
|
||||
|
||||
# Step 4: Import via docker (--no-deps 避免每次重新启动 migrate)
|
||||
log " 导入中..."
|
||||
if docker compose -f "$COMPOSE_FILE" run --no-deps --rm \
|
||||
-v /data/pubmed/updatefiles:/data/pubmed_baseline \
|
||||
worker python /app/scripts/pubmed_baseline.py \
|
||||
--dir /data/pubmed_baseline >> "$LOG" 2>&1; then
|
||||
mv "$WORKDIR/$FILE" "$IMPORTED/"
|
||||
GOOD=$((GOOD+1))
|
||||
log " ✅ 成功: $FILE"
|
||||
else
|
||||
rm -f "$WORKDIR/$FILE"
|
||||
FAIL=$((FAIL+1))
|
||||
log " ❌ 导入失败: $FILE"
|
||||
fi
|
||||
|
||||
# Clean staging
|
||||
rm -f "$STAGING/$FILE"
|
||||
done
|
||||
|
||||
log "=== 逐文件导入完成 ==="
|
||||
log "结果: 成功=$GOOD 跳过=$SKIP 失败=$FAIL"
|
||||
log "详见: $IMPORTED/"
|
||||
@@ -0,0 +1,124 @@
|
||||
#!/bin/bash
|
||||
# SciLit Oncology — 一键部署脚本
|
||||
# Usage: bash setup.sh [dev|prod]
|
||||
|
||||
set -e
|
||||
|
||||
MODE=${1:-dev}
|
||||
PROJECT_DIR=$(cd "$(dirname "$0")/.." && pwd)
|
||||
|
||||
echo "========================================="
|
||||
echo " SciLit Oncology — Setup ($MODE)"
|
||||
echo "========================================="
|
||||
|
||||
# Check dependencies
|
||||
check_cmd() {
|
||||
if ! command -v "$1" &>/dev/null; then
|
||||
echo "ERROR: $1 is required but not installed."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_cmd docker
|
||||
check_cmd python3
|
||||
|
||||
if [ "$MODE" = "prod" ]; then
|
||||
echo ""
|
||||
echo ">>> Production deployment <<<"
|
||||
echo ""
|
||||
|
||||
# Check env file
|
||||
if [ ! -f "$PROJECT_DIR/.env" ]; then
|
||||
echo "Creating .env from example..."
|
||||
cp "$PROJECT_DIR/backend/.env.example" "$PROJECT_DIR/.env"
|
||||
echo "⚠️ Please edit $PROJECT_DIR/.env with your production secrets!"
|
||||
echo " Required: DB_PASSWORD, JWT_SECRET, S3_ACCESS_KEY, S3_SECRET_KEY"
|
||||
echo " Optional: SMTP_HOST, SMTP_USER, SMTP_PASSWORD"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Starting production services..."
|
||||
docker compose -f "$PROJECT_DIR/docker-compose.prod.yml" up -d
|
||||
|
||||
echo ""
|
||||
echo "Running database migrations..."
|
||||
docker compose -f "$PROJECT_DIR/docker-compose.prod.yml" exec backend alembic upgrade head
|
||||
|
||||
echo ""
|
||||
echo "Loading seed data..."
|
||||
docker compose -f "$PROJECT_DIR/docker-compose.prod.yml" exec backend python scripts/seed_data.py
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo " Production deployment complete!"
|
||||
echo " Frontend: http://localhost"
|
||||
echo " API Docs: http://localhost:8000/docs"
|
||||
echo ""
|
||||
echo " Admin: admin@scilit.cn / admin123"
|
||||
echo " Demo: demo@test.cn / 123456"
|
||||
echo "========================================="
|
||||
|
||||
elif [ "$MODE" = "dev" ]; then
|
||||
echo ""
|
||||
echo ">>> Development setup <<<"
|
||||
echo ""
|
||||
|
||||
# Backend
|
||||
echo "Setting up backend..."
|
||||
cd "$PROJECT_DIR/backend"
|
||||
python3 -m venv venv 2>/dev/null || true
|
||||
source venv/bin/activate 2>/dev/null || source venv/Scripts/activate 2>/dev/null || true
|
||||
pip install -e ".[dev]" 2>/dev/null || pip install fastapi uvicorn sqlalchemy aiosqlite asyncpg pydantic pydantic-settings python-jose passlib bcrypt==4.0.1 python-multipart httpx lxml structlog pyyaml email-validator
|
||||
|
||||
# Initialize DB + seed data
|
||||
echo "Initializing database..."
|
||||
python scripts/seed_data.py
|
||||
|
||||
echo ""
|
||||
echo "Starting backend (dev mode)..."
|
||||
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload &
|
||||
BACKEND_PID=$!
|
||||
echo "Backend PID: $BACKEND_PID"
|
||||
|
||||
# Frontend
|
||||
echo ""
|
||||
echo "Setting up frontend..."
|
||||
cd "$PROJECT_DIR/frontend"
|
||||
npm install
|
||||
|
||||
echo ""
|
||||
echo "Starting frontend (dev mode)..."
|
||||
npm run dev &
|
||||
FRONTEND_PID=$!
|
||||
echo "Frontend PID: $FRONTEND_PID"
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo " Dev environment ready!"
|
||||
echo " Frontend: http://localhost:5173"
|
||||
echo " Backend: http://localhost:8000/docs"
|
||||
echo " Admin: admin@scilit.cn / admin123"
|
||||
echo " Demo: demo@test.cn / 123456"
|
||||
echo ""
|
||||
echo " Press Ctrl+C to stop both services"
|
||||
echo "========================================="
|
||||
|
||||
trap "kill $BACKEND_PID $FRONTEND_PID 2>/dev/null" EXIT
|
||||
wait
|
||||
|
||||
elif [ "$MODE" = "import-pubmed" ]; then
|
||||
echo ">>> PubMed Baseline Import <<<"
|
||||
BASELINE_DIR="$2"
|
||||
if [ -z "$BASELINE_DIR" ]; then
|
||||
echo "Usage: bash setup.sh import-pubmed /path/to/pubmed/baseline/"
|
||||
echo ""
|
||||
echo "Download baseline from: ftp.ncbi.nlm.nih.gov/pubmed/baseline/"
|
||||
exit 1
|
||||
fi
|
||||
cd "$PROJECT_DIR/backend"
|
||||
python scripts/pubmed_baseline.py --dir "$BASELINE_DIR" --demo
|
||||
|
||||
else
|
||||
echo "Usage: bash setup.sh [dev|prod|import-pubmed <dir>]"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user