Initial commit: Pixel AI comic/video creation platform

- FastAPI backend with SQLModel, Alembic migrations, AgentScope agents
- Next.js 15 frontend with React 19, Tailwind, Zustand, React Flow
- Multi-provider AI system (DashScope, Kling, MiniMax, Volcengine, OpenAI, etc.)
- All HTTP clients migrated from sync requests to async httpx
- Admin-managed API keys via environment variables
- SSRF vulnerability fixed in ensure_url()
This commit is contained in:
张鹏
2026-04-29 01:20:12 +08:00
commit f9f4560459
808 changed files with 151724 additions and 0 deletions

343
start.sh Normal file
View File

@@ -0,0 +1,343 @@
#!/bin/bash
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
BACKEND_PORT=8000
FRONTEND_PORT=3000
BACKEND_DIR="backend"
FRONTEND_DIR="frontend"
LOG_DIR="logs"
# Create logs directory if it doesn't exist
mkdir -p "$LOG_DIR"
# Log files
BACKEND_LOG="$LOG_DIR/backend.log"
FRONTEND_LOG="$LOG_DIR/frontend.log"
# Function to print colored messages
print_info() {
echo -e "${BLUE}${NC} $1"
}
print_success() {
echo -e "${GREEN}${NC} $1"
}
print_warning() {
echo -e "${YELLOW}${NC} $1"
}
print_error() {
echo -e "${RED}${NC} $1"
}
# Function to kill background processes on exit
cleanup() {
echo ""
print_info "Stopping all services..."
# Kill all background jobs
jobs -p | xargs -r kill 2>/dev/null
# Wait a moment for graceful shutdown
sleep 1
# Force kill if still running
jobs -p | xargs -r kill -9 2>/dev/null
print_success "All services stopped"
exit 0
}
# Function to check if command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to check prerequisites
check_prerequisites() {
print_info "Checking prerequisites..."
local missing_deps=()
# Check for required commands
if ! command_exists "uv"; then
missing_deps+=("uv (Python package manager)")
fi
if ! command_exists "node"; then
missing_deps+=("node (Node.js)")
fi
if ! command_exists "pnpm"; then
missing_deps+=("pnpm (Node package manager)")
fi
if ! command_exists "curl"; then
missing_deps+=("curl")
fi
if ! command_exists "lsof"; then
print_warning "lsof not found, port checking will be limited"
fi
if [ ${#missing_deps[@]} -gt 0 ]; then
print_error "Missing required dependencies:"
for dep in "${missing_deps[@]}"; do
echo " - $dep"
done
echo ""
echo "Please install missing dependencies and try again."
exit 1
fi
print_success "All prerequisites satisfied"
}
# Function to check and free port
check_and_free_port() {
local port=$1
local name=$2
if ! command_exists "lsof"; then
return 0
fi
# Check if port is in use
if lsof -i :$port >/dev/null 2>&1; then
print_warning "Port $port ($name) is in use"
# Get PIDs using the port
local pids=$(lsof -ti :$port)
# Ask user for confirmation
read -p "Kill processes on port $port? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
for pid in $pids; do
print_info "Killing process $pid on port $port..."
kill -9 $pid 2>/dev/null
done
sleep 1
# Verify if port is still in use
if lsof -i :$port >/dev/null 2>&1; then
print_error "Failed to free port $port. Please free it manually."
exit 1
else
print_success "Port $port freed successfully"
fi
else
print_error "Cannot start service on port $port. Exiting."
exit 1
fi
fi
}
# Function to check if directory exists
check_directory() {
local dir=$1
local name=$2
if [ ! -d "$dir" ]; then
print_error "$name directory not found: $dir"
exit 1
fi
}
# Function to start backend
start_backend() {
print_info "Starting Backend on port $BACKEND_PORT..."
cd "$BACKEND_DIR" || exit 1
# Check if .env file exists
if [ ! -f ".env" ]; then
print_warning "Backend .env file not found. Using default configuration."
fi
# Set PYTHONPATH
export PYTHONPATH=$PYTHONPATH:$(pwd)
# Start backend with logging
uv run uvicorn src.main:app --reload --port $BACKEND_PORT > "../$BACKEND_LOG" 2>&1 &
BACKEND_PID=$!
cd ..
print_info "Backend PID: $BACKEND_PID (logs: $BACKEND_LOG)"
}
# Function to wait for backend to be ready
wait_for_backend() {
print_info "Waiting for backend to be ready..."
local max_retries=30
local retry_count=0
local health_url="http://localhost:$BACKEND_PORT/health"
while [ $retry_count -lt $max_retries ]; do
if curl -s "$health_url" > /dev/null 2>&1; then
print_success "Backend is ready!"
return 0
fi
# Check if backend process is still running
if ! kill -0 $BACKEND_PID 2>/dev/null; then
print_error "Backend process died. Check logs: $BACKEND_LOG"
tail -n 20 "$BACKEND_LOG"
return 1
fi
retry_count=$((retry_count + 1))
# Show progress
printf "\r Attempt %d/%d..." $retry_count $max_retries
sleep 1
done
echo ""
print_error "Backend failed to start after $max_retries seconds"
print_info "Last 20 lines of backend log:"
tail -n 20 "$BACKEND_LOG"
return 1
}
# Function to start frontend
start_frontend() {
print_info "Starting Frontend on port $FRONTEND_PORT..."
cd "$FRONTEND_DIR" || exit 1
# Check if node_modules exists
if [ ! -d "node_modules" ]; then
print_warning "node_modules not found. Running pnpm install..."
pnpm install
fi
# Start frontend with logging
pnpm dev > "../$FRONTEND_LOG" 2>&1 &
FRONTEND_PID=$!
cd ..
print_info "Frontend PID: $FRONTEND_PID (logs: $FRONTEND_LOG)"
}
# Function to wait for frontend to be ready
wait_for_frontend() {
print_info "Waiting for frontend to be ready..."
local max_retries=30
local retry_count=0
while [ $retry_count -lt $max_retries ]; do
if curl -s "http://localhost:$FRONTEND_PORT" > /dev/null 2>&1; then
print_success "Frontend is ready!"
return 0
fi
# Check if frontend process is still running
if ! kill -0 $FRONTEND_PID 2>/dev/null; then
print_error "Frontend process died. Check logs: $FRONTEND_LOG"
tail -n 20 "$FRONTEND_LOG"
return 1
fi
retry_count=$((retry_count + 1))
# Show progress
printf "\r Attempt %d/%d..." $retry_count $max_retries
sleep 1
done
echo ""
print_error "Frontend failed to start after $max_retries seconds"
print_info "Last 20 lines of frontend log:"
tail -n 20 "$FRONTEND_LOG"
return 1
}
# Function to display service information
display_info() {
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
print_success "All services started successfully!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo " 📡 Backend API: http://localhost:$BACKEND_PORT"
echo " 📚 API Docs: http://localhost:$BACKEND_PORT/docs"
echo " 📖 ReDoc: http://localhost:$BACKEND_PORT/redoc"
echo " 🏥 Health Check: http://localhost:$BACKEND_PORT/health"
echo " 📊 Metrics: http://localhost:$BACKEND_PORT/metrics"
echo ""
echo " 🎨 Frontend: http://localhost:$FRONTEND_PORT"
echo ""
echo " 📝 Backend Logs: $BACKEND_LOG"
echo " 📝 Frontend Logs: $FRONTEND_LOG"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
print_info "Press Ctrl+C to stop all services"
echo ""
}
# Main execution
main() {
echo ""
echo "╔═══════════════════════════════════════════════════════╗"
echo "║ Pixel Development Environment Startup ║"
echo "╚═══════════════════════════════════════════════════════╝"
echo ""
# Trap SIGINT (Ctrl+C) and call cleanup
trap cleanup SIGINT SIGTERM
# Check prerequisites
check_prerequisites
# Check directories
check_directory "$BACKEND_DIR" "Backend"
check_directory "$FRONTEND_DIR" "Frontend"
# Check and free ports
check_and_free_port $BACKEND_PORT "Backend"
check_and_free_port $FRONTEND_PORT "Frontend"
# Start backend
start_backend
# Wait for backend to be ready
if ! wait_for_backend; then
cleanup
exit 1
fi
# Start frontend
start_frontend
# Wait for frontend to be ready
if ! wait_for_frontend; then
cleanup
exit 1
fi
# Display service information
display_info
# Wait for processes
wait
}
# Run main function
main