← back to AgentAbrams

media/engine.py

139 lines

#!/usr/bin/env python3
"""
engine.py — Unified media engine for AgentAbrams.

One function call generates: blog, podcast, video, transcript, chapters, social posts.

Usage:
    python3 media/engine.py <post.md> [developer_name]
"""

import os
import sys
from pathlib import Path

# Add project root and sibling dirs to path
PROJECT_ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(PROJECT_ROOT / "media"))
sys.path.insert(0, str(PROJECT_ROOT / "video"))
sys.path.insert(0, str(PROJECT_ROOT / "podcast"))

from md_to_blog import transform as blog_transform
from md_to_podcast import transform as podcast_transform
from chapters import generate_chapters
from social import generate_social


def build(md_path: str, developer: str = "Agent Abrams"):
    out = Path("media/output")
    out.mkdir(parents=True, exist_ok=True)

    print(f"{'='*60}")
    print("AgentAbrams Media Engine")
    print(f"Source: {md_path}")
    print(f"Developer: {developer}")
    print(f"{'='*60}")
    print()

    # 1. Blog
    print("[1/6] Generating blog post...")
    blog = blog_transform(md_path, developer)
    blog_file = out / "blog_output.md"
    blog_file.write_text(blog, encoding="utf-8")
    print(f"  → {blog_file}")
    print()

    # 2. Podcast script
    print("[2/6] Generating podcast script...")
    script = podcast_transform(md_path, developer)
    script_file = out / "podcast_script.txt"
    script_file.write_text(script, encoding="utf-8")
    print(f"  → {script_file}")
    print()

    # 3. TTS Audio (requires ELEVEN_API_KEY)
    voice_file = out / "voice.mp3"
    episode_file = out / "episode.mp3"

    if os.environ.get("ELEVEN_API_KEY"):
        print("[3/6] Generating TTS audio...")
        try:
            from tts_engine import generate_audio
            generate_audio(script, str(voice_file))

            # Mix with intro/outro
            from audio_mixer import mix_audio
            mix_audio(str(voice_file), str(episode_file))
        except Exception as e:
            print(f"  WARNING: TTS failed: {e}")
            print("  Skipping audio generation.")
    else:
        print("[3/6] Skipping TTS (ELEVEN_API_KEY not set)")
        print("  Set ELEVEN_API_KEY to enable audio generation.")
    print()

    # 4. Chapters
    print("[4/6] Generating chapter markers...")
    chapters = generate_chapters(md_path)
    print()

    # 5. Video (requires ffmpeg + audio)
    if episode_file.exists():
        print("[5/6] Generating video...")
        try:
            from video import build_video
            build_video(str(episode_file))
        except Exception as e:
            print(f"  WARNING: Video generation failed: {e}")
    else:
        print("[5/6] Skipping video (no audio file)")
    print()

    # 6. Social posts
    print("[6/6] Generating social posts...")
    generate_social(str(blog_file))
    print()

    # 7. Transcript (bonus, if whisper available)
    if episode_file.exists():
        print("[bonus] Generating transcript...")
        try:
            from transcript import generate_transcript
            generate_transcript(str(episode_file))
        except Exception as e:
            print(f"  Transcript skipped: {e}")
        print()

    # Summary
    print(f"{'='*60}")
    print("BUILD COMPLETE")
    print(f"{'='*60}")
    print()
    print("Outputs:")
    for f in sorted(out.iterdir()):
        size = f.stat().st_size
        print(f"  {f.name:30s}  {size:>10,} bytes")
    print()
    print("Next steps:")
    print("  1. Review media/output/blog_output.md")
    print("  2. Run: python3 snippets/redact_lint.py media/output/blog_output.md")
    print("  3. Publish to goodquestion.ai")
    print("  4. Upload video: python3 video/upload_youtube.py media/output/video.mp4")
    print()


def main():
    if len(sys.argv) < 2:
        print("Usage: engine.py <post.md> [developer_name]", file=sys.stderr)
        sys.exit(2)
    if not Path(sys.argv[1]).is_file():
        print(f"File not found: {sys.argv[1]}", file=sys.stderr)
        sys.exit(2)

    developer = sys.argv[2] if len(sys.argv) > 2 else "Agent Abrams"
    build(sys.argv[1], developer)


if __name__ == "__main__":
    main()