secubox-openwrt/package/secubox/secubox-app-peertube/files/www/cgi-bin/peertube-import
CyberMind-FR bbf2b19415 feat(peertube): Add video import with multi-track subtitle sync
- New peertube-import script for importing from YouTube, Vimeo, 1000+ sites
- CGI endpoints for portal integration (peertube-import, peertube-import-status)
- Portal UI: Video Import card with progress tracking
- Multi-language subtitle download and PeerTube caption upload
- Fixed stdout/stderr separation for reliable function returns
- UCI config: uses peertube.admin.username/password
- Package version bumped to 1.2.0
- Added README.md with full documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-21 20:18:51 +01:00

165 lines
4.5 KiB
Bash

#!/bin/sh
# CGI endpoint for PeerTube video import
# Returns JSON response
# Set headers
printf "Content-Type: application/json\r\n"
printf "Access-Control-Allow-Origin: *\r\n"
printf "Access-Control-Allow-Methods: POST, OPTIONS\r\n"
printf "Access-Control-Allow-Headers: Content-Type\r\n"
printf "\r\n"
# Handle OPTIONS (CORS preflight)
if [ "$REQUEST_METHOD" = "OPTIONS" ]; then
exit 0
fi
# Only allow POST
if [ "$REQUEST_METHOD" != "POST" ]; then
echo '{"error": "Method not allowed"}'
exit 0
fi
# Read input
INPUT=$(cat)
# Parse JSON (use jq if available, else jsonfilter)
if command -v jq >/dev/null 2>&1; then
URL=$(echo "$INPUT" | jq -r '.url // empty')
LANGUAGES=$(echo "$INPUT" | jq -r '.languages // "fr,en"')
CHANNEL_ID=$(echo "$INPUT" | jq -r '.channel_id // "1"')
PRIVACY=$(echo "$INPUT" | jq -r '.privacy // "1"')
else
URL=$(echo "$INPUT" | jsonfilter -e '@.url' 2>/dev/null)
LANGUAGES=$(echo "$INPUT" | jsonfilter -e '@.languages' 2>/dev/null)
CHANNEL_ID=$(echo "$INPUT" | jsonfilter -e '@.channel_id' 2>/dev/null)
PRIVACY=$(echo "$INPUT" | jsonfilter -e '@.privacy' 2>/dev/null)
fi
# Handle array of languages
if echo "$LANGUAGES" | grep -q '^\['; then
if command -v jq >/dev/null 2>&1; then
LANGUAGES=$(echo "$INPUT" | jq -r '.languages | if type == "array" then join(",") else . end')
else
LANGUAGES="fr,en"
fi
fi
# Validate URL
if [ -z "$URL" ]; then
echo '{"error": "URL is required"}'
exit 0
fi
# Sanitize URL (basic security check)
case "$URL" in
http://*|https://*)
# Valid URL prefix
;;
*)
echo '{"error": "Invalid URL format"}'
exit 0
;;
esac
# Set defaults
[ -z "$LANGUAGES" ] && LANGUAGES="fr,en"
[ -z "$CHANNEL_ID" ] && CHANNEL_ID="1"
[ -z "$PRIVACY" ] && PRIVACY="1"
# Generate job ID
JOB_ID="import_$(date +%s)_$$"
STATUS_FILE="/tmp/peertube-import-${JOB_ID}.status"
RESULT_FILE="/tmp/peertube-import-${JOB_ID}.json"
LOG_FILE="/tmp/peertube-import-${JOB_ID}.log"
PROGRESS_FILE="/tmp/peertube-import-${JOB_ID}.progress"
# Check for import script
if [ ! -x "/usr/sbin/peertube-import" ]; then
echo '{"error": "peertube-import not installed"}'
exit 0
fi
# Initialize status
echo "starting" > "$STATUS_FILE"
echo "0" > "$PROGRESS_FILE"
# Start import in background
(
echo "downloading" > "$STATUS_FILE"
echo "10" > "$PROGRESS_FILE"
# Run the import
OUTPUT=$(/usr/sbin/peertube-import \
--lang "$LANGUAGES" \
--channel "$CHANNEL_ID" \
--privacy "$PRIVACY" \
"$URL" 2>&1)
RC=$?
echo "$OUTPUT" >> "$LOG_FILE"
if [ $RC -eq 0 ]; then
echo "completed" > "$STATUS_FILE"
echo "100" > "$PROGRESS_FILE"
# Extract JSON result from output (last JSON block)
local result_json
result_json=$(echo "$OUTPUT" | grep -E '^\{' | tail -1)
if [ -n "$result_json" ]; then
# Parse and rebuild result
if command -v jq >/dev/null 2>&1; then
VIDEO_ID=$(echo "$result_json" | jq -r '.video_id // empty')
VIDEO_UUID=$(echo "$result_json" | jq -r '.video_uuid // empty')
VIDEO_URL=$(echo "$result_json" | jq -r '.video_url // empty')
TITLE=$(echo "$result_json" | jq -r '.title // "Imported Video"')
else
VIDEO_ID=$(echo "$result_json" | jsonfilter -e '@.video_id' 2>/dev/null)
VIDEO_UUID=$(echo "$result_json" | jsonfilter -e '@.video_uuid' 2>/dev/null)
VIDEO_URL=$(echo "$result_json" | jsonfilter -e '@.video_url' 2>/dev/null)
TITLE="Imported Video"
fi
cat > "$RESULT_FILE" << EOF
{
"success": true,
"job_id": "$JOB_ID",
"video_id": $VIDEO_ID,
"video_uuid": "$VIDEO_UUID",
"video_url": "$VIDEO_URL",
"title": "$TITLE",
"status": "completed"
}
EOF
else
cat > "$RESULT_FILE" << EOF
{
"success": true,
"job_id": "$JOB_ID",
"status": "completed",
"message": "Import completed but no result JSON found"
}
EOF
fi
else
echo "failed" > "$STATUS_FILE"
echo "0" > "$PROGRESS_FILE"
# Get last error from log
ERROR_MSG=$(tail -5 "$LOG_FILE" 2>/dev/null | tr '\n' ' ' | sed 's/"/\\"/g' | head -c 500)
cat > "$RESULT_FILE" << EOF
{
"success": false,
"job_id": "$JOB_ID",
"status": "failed",
"error": "$ERROR_MSG"
}
EOF
fi
) &
# Return job ID for polling
echo "{\"success\": true, \"message\": \"Import started\", \"job_id\": \"$JOB_ID\"}"