- 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>
165 lines
4.5 KiB
Bash
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\"}"
|