Files
scripts/podcast/podcast-pipeline.sh
ealmeida 6035542b67 feat: scripts de projectos vindos do Hub (podcast, alojadamaria, clip, ocr, etc.)
Movidos do vault Hub para centralizar scripts. Hub mantem symlinks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 20:53:29 +01:00

162 lines
4.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/scripts/lib.sh"
usage() {
cat << EOF
Podcast Descomplicar Digital — Pipeline Automatizado
Usage: $0 <command> [args]
Commands:
batch N Process next N episodes (content generation)
status Show pipeline state
retry NNN Re-run failed stage for episode NNN
csv [start] [N] Generate Canva CSV (default: next 7 episodes)
publish NNN D Generate publish commands for episode NNN on date D (YYYY-MM-DD)
init NNN Add episode NNN to pipeline state
produce NNN F Post-produce episode NNN from raw audio file F
Examples:
$0 batch 5
$0 status
$0 csv 20 10
$0 produce 20 /path/to/raw.wav
$0 publish 20 2026-04-14
EOF
exit 1
}
[[ $# -lt 1 ]] && usage
CMD="$1"; shift
ensure_state_file
mkdir -p "$LOG_DIR"
case "$CMD" in
batch)
COUNT="${1:-5}"
START="$(jq -r '.next_episode' "$STATE_FILE")"
END=$((START + COUNT - 1))
log_info "=== BATCH: Processing episodes ${START}-${END} ==="
CURRENT_DATE="$(jq -r '.next_publish_date' "$STATE_FILE")"
[[ -z "$CURRENT_DATE" || "$CURRENT_DATE" == "null" ]] && CURRENT_DATE="$(date '+%Y-%m-%d')"
for ((ep=START; ep<=END; ep++)); do
log_info "--- Episode ${ep} ---"
STATUS="$(get_episode_status "$ep")"
if [[ "$STATUS" == "not_found" || "$STATUS" == "pending" ]]; then
"${SCRIPT_DIR}/scripts/generate-content.sh" "$ep" || {
log_error "EP$(pad_number "$ep"): Content generation failed, stopping batch"
exit 1
}
else
log_info "EP$(pad_number "$ep"): Already at status '${STATUS}', skipping content generation"
fi
STATUS="$(get_episode_status "$ep")"
if [[ "$STATUS" == "script_done" ]]; then
log_warn "EP$(pad_number "$ep"): Audio TTS needed (manual step via AI Studio)"
log_warn " -> Generate audio, save to Episodios/Audios/raw/ep_$(pad_number "$ep")_raw.wav"
log_warn " -> Then run: $0 produce ${ep} <raw_audio_path>"
fi
CURRENT_DATE="$(next_weekday "$CURRENT_DATE")"
done
jq --argjson n "$((END + 1))" --arg d "$CURRENT_DATE" \
'.next_episode = $n | .next_publish_date = $d' \
"$STATE_FILE" > "${STATE_FILE}.tmp" && mv "${STATE_FILE}.tmp" "$STATE_FILE"
log_info "=== BATCH COMPLETE. Next episode: $((END + 1)), next date: ${CURRENT_DATE} ==="
;;
status)
echo "=== Pipeline Status ==="
echo "Next episode: $(jq -r '.next_episode' "$STATE_FILE")"
echo "Next publish date: $(jq -r '.next_publish_date' "$STATE_FILE")"
echo ""
EPISODE_COUNT="$(jq '.episodes | length' "$STATE_FILE")"
if [[ "$EPISODE_COUNT" -gt 0 ]]; then
echo "Episodes in pipeline:"
jq -r '.episodes[] | " EP\(.number | tostring | if length < 3 then "0" * (3 - length) + . else . end): \(.status) - \(.title)"' "$STATE_FILE"
echo ""
echo "Counts:"
jq -r '.episodes | group_by(.status) | map({status: .[0].status, count: length}) | .[] | " \(.status): \(.count)"' "$STATE_FILE"
else
echo "No episodes in pipeline yet. Run 'batch' to start."
fi
;;
retry)
EP="${1:?Episode number required}"
STATUS="$(get_episode_status "$EP")"
log_info "Retrying EP$(pad_number "$EP") (current status: ${STATUS})"
case "$STATUS" in
pending|not_found)
"${SCRIPT_DIR}/scripts/generate-content.sh" "$EP"
;;
script_done)
log_warn "Audio TTS needed — manual step via AI Studio"
;;
audio_done)
RAW=""
for f in "${PROJECT_ROOT}/Episodios/Audios/raw/ep_$(pad_number "$EP")_"*; do
[[ -f "$f" ]] && RAW="$f" && break
done
if [[ -n "$RAW" ]]; then
"${SCRIPT_DIR}/scripts/post-produce.sh" "$EP" "$RAW"
else
log_error "Raw audio not found. Use: $0 produce ${EP} <path>"
fi
;;
produced)
log_info "Ready to publish. Use: $0 publish ${EP} YYYY-MM-DD"
;;
*)
log_warn "Unknown status: ${STATUS}"
;;
esac
;;
csv)
"${SCRIPT_DIR}/scripts/generate-csv.sh" "${@}"
;;
produce)
EP="${1:?Episode number required}"
RAW="${2:?Raw audio path required}"
"${SCRIPT_DIR}/scripts/post-produce.sh" "$EP" "$RAW"
;;
publish)
EP="${1:?Episode number required}"
SCHED_DATE="${2:-$(jq -r '.next_publish_date' "$STATE_FILE")}"
"${SCRIPT_DIR}/scripts/publish-episode.sh" "$EP" "$SCHED_DATE"
;;
init)
EP="${1:?Episode number required}"
MAP_FILE="${PROJECT_ROOT}/config/episode-guide-map.json"
EP_DATA="$(jq -r --arg n "$EP" '.[$n] // empty' "$MAP_FILE")"
if [[ -n "$EP_DATA" ]]; then
TITLE="$(echo "$EP_DATA" | jq -r '.podcast_title')"
URL="$(echo "$EP_DATA" | jq -r '.guide_url')"
add_episode "$EP" "$TITLE" "$URL"
log_info "Added EP$(pad_number "$EP"): ${TITLE}"
else
log_error "Episode $EP not found in episode-guide-map.json"
fi
;;
*)
usage
;;
esac