Spaces:
Sleeping
Sleeping
| """Solver router: picks the right solver for the captcha type.""" | |
| from __future__ import annotations | |
| import time | |
| from typing import Optional | |
| from captcha_solver.engines import ( | |
| WhisperEngine, | |
| FlorenceEngine, | |
| MoondreamEngine, | |
| QwenEngine, | |
| OllamaEngine, | |
| ) | |
| from captcha_solver.solvers.base import BaseSolver, SolveContext, SolveAttempt | |
| from captcha_solver.solvers.math_solver import MathSolver | |
| from captcha_solver.solvers.audio_solver import AudioSolver | |
| from captcha_solver.solvers.text_ocr_solver import TextOcrSolver | |
| from captcha_solver.solvers.image_grid_solver import ImageGridSolver | |
| from captcha_solver.utils.detector import detect_type | |
| class SolverRouter: | |
| """Routes a SolveRequest to the right solver and returns the result.""" | |
| def __init__(self) -> None: | |
| self._engines: dict | None = None | |
| self._solvers: dict[str, BaseSolver] = {} | |
| def init(self) -> None: | |
| """Load all engines (lazy, in a controlled order).""" | |
| whisper = WhisperEngine() | |
| florence = FlorenceEngine() | |
| moondream = MoondreamEngine() | |
| qwen = QwenEngine() | |
| ollama = OllamaEngine() | |
| for eng in (whisper, florence, moondream, qwen, ollama): | |
| try: | |
| eng.load() | |
| except Exception: | |
| pass | |
| ctx = SolveContext( | |
| whisper=whisper, | |
| florence=florence, | |
| moondream=moondream, | |
| qwen=qwen, | |
| ollama=ollama, | |
| ) | |
| self._engines = { | |
| "whisper": whisper, | |
| "florence2": florence, | |
| "moondream2": moondream, | |
| "qwen": qwen, | |
| "ollama": ollama, | |
| } | |
| for s in (MathSolver, AudioSolver, TextOcrSolver, ImageGridSolver): | |
| self._solvers[s.captcha_type] = s(ctx) | |
| def engine_status(self) -> dict[str, str]: | |
| if self._engines is None: | |
| return {} | |
| return {name: eng.status for name, eng in self._engines.items()} | |
| def solve( | |
| self, | |
| captcha_type: str, | |
| image_b64: Optional[str], | |
| audio_b64: Optional[str], | |
| hint: Optional[str] = None, | |
| min_confidence: float = 0.4, | |
| ) -> SolveAttempt: | |
| if self._engines is None: | |
| self.init() | |
| if captcha_type == "auto": | |
| captcha_type = detect_type(image_b64, audio_b64) | |
| solver = self._solvers.get(captcha_type) | |
| if solver is None: | |
| return SolveAttempt( | |
| answer="", | |
| confidence=0.0, | |
| solver_name="router.unknown", | |
| error=f"unknown captcha type: {captcha_type}", | |
| ) | |
| solver.prepare(image_b64, audio_b64, hint) | |
| return solver.run_all(min_confidence=min_confidence) | |