Vision-module-auto/claude_vision_auto/screenshot.py
Svrnty 52b0813b64 feat: Add YAML-based configuration system
- Add default_config.yaml with customizable settings
- Model selection (minicpm-v, llama3.2-vision, llava)
- Customizable vision prompt for better responses
- Timing parameters (idle threshold, response delay)
- Approval keywords configuration
- User config at ~/.config/claude-vision-auto/config.yaml
- New command: claude-vision-config to generate user config
- Environment variables still override config files
- Added PyYAML dependency

Configuration priority:
1. Environment variables (highest)
2. User config (~/.config/claude-vision-auto/config.yaml)
3. Default config (package default)

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Jean-Philippe Brule <jp@svrnty.io>
2025-10-29 10:19:35 -04:00

127 lines
3.7 KiB
Python

"""
Screenshot capture functionality
"""
import subprocess
import tempfile
import shutil
from pathlib import Path
from typing import Optional
from . import config
class ScreenshotError(Exception):
"""Raised when screenshot capture fails"""
pass
def find_screenshot_tool() -> Optional[str]:
"""Find available screenshot tool on the system"""
for tool in config.SCREENSHOT_TOOLS:
if shutil.which(tool):
return tool
return None
def take_screenshot() -> Optional[str]:
"""
Take screenshot of active terminal window
Returns:
Path to screenshot file, or None if capture failed
"""
tool = find_screenshot_tool()
if not tool:
if config.DEBUG:
print(f"[DEBUG] No screenshot tool found. Tried: {', '.join(config.SCREENSHOT_TOOLS)}")
return None
# Create temporary file
cache_dir = config.get_cache_dir()
screenshot_path = cache_dir / f"screenshot_{int(subprocess.check_output(['date', '+%s']).decode().strip())}.png"
try:
if tool == "scrot":
# Capture active window
subprocess.run(
["scrot", "-u", str(screenshot_path)],
check=True,
capture_output=True,
timeout=config.SCREENSHOT_TIMEOUT
)
elif tool == "gnome-screenshot":
# Capture active window
subprocess.run(
["gnome-screenshot", "-w", "-f", str(screenshot_path)],
check=True,
capture_output=True,
timeout=config.SCREENSHOT_TIMEOUT
)
elif tool == "import":
# ImageMagick - capture root window
subprocess.run(
["import", "-window", "root", str(screenshot_path)],
check=True,
capture_output=True,
timeout=config.SCREENSHOT_TIMEOUT
)
elif tool == "maim":
# Capture active window
subprocess.run(
["maim", "-i", "$(xdotool getactivewindow)", str(screenshot_path)],
shell=True,
check=True,
capture_output=True,
timeout=config.SCREENSHOT_TIMEOUT
)
else:
return None
if screenshot_path.exists():
if config.DEBUG:
print(f"[DEBUG] Screenshot saved to {screenshot_path}")
return str(screenshot_path)
else:
return None
except subprocess.TimeoutExpired:
if config.DEBUG:
print(f"[DEBUG] Screenshot timeout with tool: {tool}")
return None
except subprocess.CalledProcessError as e:
if config.DEBUG:
print(f"[DEBUG] Screenshot failed: {e}")
return None
except Exception as e:
if config.DEBUG:
print(f"[DEBUG] Unexpected error: {e}")
return None
def cleanup_old_screenshots(max_age_seconds: int = None):
"""
Clean up old screenshots from cache directory
Args:
max_age_seconds: Maximum age of screenshots to keep (default from config)
"""
import time
if max_age_seconds is None:
max_age_seconds = config.SCREENSHOT_CACHE_CLEANUP
cache_dir = config.get_cache_dir()
current_time = time.time()
for screenshot in cache_dir.glob("screenshot_*.png"):
if current_time - screenshot.stat().st_mtime > max_age_seconds:
try:
screenshot.unlink()
if config.DEBUG:
print(f"[DEBUG] Cleaned up old screenshot: {screenshot}")
except Exception as e:
if config.DEBUG:
print(f"[DEBUG] Failed to cleanup {screenshot}: {e}")