Files
cs249r_book/book/cli/commands/preview.py

118 lines
3.9 KiB
Python

"""
Preview command implementation for MLSysBook CLI.
Handles starting development servers with live reload for interactive development.
"""
import subprocess
import signal
import sys
from pathlib import Path
from typing import List, Optional
from rich.console import Console
console = Console()
class PreviewCommand:
"""Handles preview operations for the MLSysBook."""
def __init__(self, config_manager, chapter_discovery):
"""Initialize preview command.
Args:
config_manager: ConfigManager instance
chapter_discovery: ChapterDiscovery instance
"""
self.config_manager = config_manager
self.chapter_discovery = chapter_discovery
def preview_full(self, format_type: str = "html") -> bool:
"""Start full preview server for the entire book.
Args:
format_type: Format to preview ('html' only supported)
Returns:
True if server started successfully, False otherwise
"""
if format_type != "html":
console.print(f"[yellow]⚠️ Preview only supports HTML format, not {format_type}[/yellow]")
return False
console.print("[blue]🌐 Starting full book preview server...[/blue]")
# Setup config
config_name = self.config_manager.setup_symlink(format_type)
console.print(f"[blue]🔗 Using {config_name}[/blue]")
console.print("[dim]🛑 Press Ctrl+C to stop the server[/dim]")
try:
# Start Quarto preview server
preview_cmd = ["quarto", "preview"]
console.print(f"[blue]💻 Command: {' '.join(preview_cmd)}[/blue]")
# Run preview server (this will block until Ctrl+C)
result = subprocess.run(
preview_cmd,
cwd=self.config_manager.book_dir
)
return result.returncode == 0
except KeyboardInterrupt:
console.print("\n[yellow]🛑 Preview server stopped[/yellow]")
return True
except Exception as e:
console.print(f"[red]❌ Preview server error: {e}[/red]")
return False
def preview_chapter(self, chapter_name: str) -> bool:
"""Start preview server for a specific chapter.
Args:
chapter_name: Name of the chapter to preview
Returns:
True if server started successfully, False otherwise
"""
# Find the chapter file
chapter_file = self.chapter_discovery.find_chapter_file(chapter_name)
if not chapter_file:
console.print(f"[red]❌ No chapter found matching '{chapter_name}'[/red]")
console.print("[yellow]💡 Available chapters:[/yellow]")
self.chapter_discovery.show_chapters()
return False
target_path = str(chapter_file.relative_to(self.config_manager.book_dir))
chapter_display_name = str(chapter_file.relative_to(self.config_manager.book_dir / "contents")).replace(".qmd", "")
console.print(f"[blue]🌐 Starting preview for[/blue] [bold]{chapter_display_name}[/bold]")
# Setup HTML config for preview
self.config_manager.setup_symlink("html")
console.print("[dim]🛑 Press Ctrl+C to stop the server[/dim]")
try:
# Start Quarto preview for specific file
preview_cmd = ["quarto", "preview", target_path]
console.print(f"[blue]💻 Command: {' '.join(preview_cmd)}[/blue]")
# Run preview server (this will block until Ctrl+C)
result = subprocess.run(
preview_cmd,
cwd=self.config_manager.book_dir
)
return result.returncode == 0
except KeyboardInterrupt:
console.print("\n[yellow]🛑 Preview server stopped[/yellow]")
return True
except Exception as e:
console.print(f"[red]❌ Preview server error: {e}[/red]")
return False