diff --git a/app.py b/app.py index 9378464..2cc49e2 100644 --- a/app.py +++ b/app.py @@ -27,6 +27,32 @@ import logging logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) +def patch_chrome_binary(): + """Патчит бинарный файл Chrome для удаления строки cdc_, которую ищут антифроды""" + possible_paths = [ + "/opt/google/chrome/chrome", + "/usr/bin/google-chrome", + "/usr/bin/chromium", + ] + + for path in possible_paths: + if os.path.exists(path) and not os.path.islink(path): + try: + logger.info(f"Attempting to patch Chrome binary at {path}...") + with open(path, 'rb') as f: + content = f.read() + + if b'cdc_' in content: + logger.info(f"Found cdc_ in {path}, patching...") + new_content = content.replace(b'cdc_', b'abc_') + with open(path, 'wb') as f: + f.write(new_content) + logger.info(f"Successfully patched {path}") + else: + logger.info(f"cdc_ not found in {path} or already patched.") + except Exception as e: + logger.warning(f"Could not patch {path}: {e}") + @asynccontextmanager async def lifespan(app: FastAPI): # Startup logic @@ -34,6 +60,9 @@ async def lifespan(app: FastAPI): from importlib import metadata logger.info(f"Python version: {sys.version}") + # Патчим Chrome для максимальной скрытности + patch_chrome_binary() + # Автоматический запуск Chrome при старте, если включен Remote Debugging if REMOTE_DEBUGGING_ENABLED: logger.info("Remote Debugging enabled, starting Chrome on startup...") @@ -162,6 +191,20 @@ async def run_browser_task(task_id: str, task: str, max_steps: int, model: str): user_data_dir = "/app/browser-data/main_profile" os.makedirs(user_data_dir, exist_ok=True) + # Удаляем файл блокировки профиля, если он остался от предыдущего запуска + # В Linux это обычно симлинк SingletonLock + for lock_name in ["SingletonLock", "SingletonCookie", "SingletonSocket"]: + lock_path = os.path.join(user_data_dir, lock_name) + if os.path.exists(lock_path) or os.path.islink(lock_path): + try: + logger.info(f"[{task_id}] Removing stale Chrome lock: {lock_path}") + if os.path.islink(lock_path): + os.unlink(lock_path) + else: + os.remove(lock_path) + except Exception as e: + logger.warning(f"[{task_id}] Could not remove lock {lock_name}: {e}") + # Внутренний порт для Chrome CHROME_INTERNAL_PORT = REMOTE_DEBUGGING_PORT + 1 # 9223 @@ -191,6 +234,13 @@ async def run_browser_task(task_id: str, task: str, max_steps: int, model: str): "--use-mock-keychain", "--force-color-profile=srgb", "--disable-features=IsolateOrigins,site-per-process", + "--disable-notifications", + "--disable-popup-blocking", + "--disable-print-preview", + "--disable-prompt-on-repost", + "--disable-sync", + "--no-pings", + "--mute-audio", "about:blank" ]