""" 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 full screen Returns: Path to screenshot file, or None if capture failed """ import os import time 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(time.time())}.png" # Preserve DISPLAY environment variable env = os.environ.copy() if 'DISPLAY' not in env: env['DISPLAY'] = ':0' # Default X display try: if tool == "scrot": # Capture full screen (more reliable than -u for active window) result = subprocess.run( ["scrot", str(screenshot_path)], check=True, capture_output=True, timeout=config.SCREENSHOT_TIMEOUT, env=env ) elif tool == "gnome-screenshot": # Capture full screen result = subprocess.run( ["gnome-screenshot", "-f", str(screenshot_path)], check=True, capture_output=True, timeout=config.SCREENSHOT_TIMEOUT, env=env ) elif tool == "import": # ImageMagick - capture root window result = subprocess.run( ["import", "-window", "root", str(screenshot_path)], check=True, capture_output=True, timeout=config.SCREENSHOT_TIMEOUT, env=env ) elif tool == "maim": # Capture full screen result = subprocess.run( ["maim", str(screenshot_path)], check=True, capture_output=True, timeout=config.SCREENSHOT_TIMEOUT, env=env ) 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 as e: 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 with {tool}: {e}") if e.stderr: print(f"[DEBUG] Error output: {e.stderr.decode('utf-8', errors='ignore')}") return None except Exception as e: if config.DEBUG: print(f"[DEBUG] Unexpected screenshot error: {type(e).__name__}: {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}")