Jarian Cottingham 06877fb2fc feat: add TUI (Textual User Interface) with download queue system
- New TUI using Textual framework with responsive interface
- Search, results, download, and queue screens for YouTube video management
- Download queue system with sequential background downloads
- Status bar with queue count and download progress indicators
- Comprehensive test suite (97 tests) with 100% pass rate
- Modern Python packaging with pyproject.toml and uv support
- Added requirements-tui.txt for TUI-specific dependencies
- Updated setup.py and install.sh for TUI integration
- Enhanced README.md with TUI usage documentation
2026-02-25 15:59:15 -06:00

107 lines
3.2 KiB
Python

#!/usr/bin/env python3
"""
Custom Footer Widget for YouTube TUI
Includes status bar with queue information
"""
from datetime import datetime
from textual.widgets import Footer
from textual.app import App
class CustomFooter(Footer):
"""Custom footer widget with status bar that includes queue info"""
def __init__(self, app: App, *args, **kwargs):
super().__init__(*args, **kwargs)
self._app = app
self.current_screen = "Search"
self.status_message = "Ready"
self.downloading = False
self.queue_pending = 0
self.download_progress = 0
self.yt_dlp_version = "unknown"
self.update_version()
def update_version(self) -> None:
"""Update yt-dlp version"""
try:
import subprocess
result = subprocess.run(
["yt-dlp", "--version"],
capture_output=True,
text=True,
timeout=5,
)
if result.returncode == 0:
self.yt_dlp_version = result.stdout.strip()
else:
self.yt_dlp_version = "not installed"
except Exception:
self.yt_dlp_version = "unknown"
def set_screen(self, screen_name: str) -> None:
"""Set the current screen name"""
self.current_screen = screen_name
self.refresh()
def set_downloading(self, downloading: bool) -> None:
"""Set downloading state"""
self.downloading = downloading
self.refresh()
def set_status(self, message: str) -> None:
"""Set status message"""
self.status_message = message
self.refresh()
def set_queue_pending(self, count: int) -> None:
"""Set the number of pending queue items"""
self.queue_pending = count
self.refresh()
def set_download_progress(self, progress: int) -> None:
"""Set the current download progress percentage"""
self.download_progress = max(0, min(100, progress))
self.refresh()
def update_time(self) -> None:
"""Update the time display"""
self.refresh()
def render(self):
"""Render the footer content with queue status"""
# Get current time
current_time = datetime.now().strftime("%H:%M:%S")
# Get theme info
theme_name = getattr(self._app, "theme", "css")
# Build status string
status_parts = [
f"[bold]{self.current_screen}[/bold]",
f"v{getattr(self._app, 'VERSION', '0.1.0')}",
f"yt-dlp {self.yt_dlp_version}",
]
# Add queue status if available
if self.queue_pending > 0:
status_parts.append(f"[cyan]Queue: {self.queue_pending} pending[/cyan]")
# Add download progress if available
if self.downloading and self.download_progress > 0:
status_parts.append(
f"| [yellow]Downloading: {self.download_progress}%[/yellow]"
)
# Add status message
status_parts.append(f"[bold]{self.status_message}[/bold]")
# Add footer elements
status_parts.append(f"[dim]{current_time}[/dim]")
status_parts.append(f"[dim]{theme_name} theme[/dim]")
return " ".join(status_parts)