Update on Chrome examples; Refactor on logic of controlling
This commit is contained in:
@@ -1,22 +1,24 @@
|
||||
import requests
|
||||
import json
|
||||
from requests_toolbelt.multipart.encoder import MultipartEncoder
|
||||
|
||||
import uuid
|
||||
import os.path
|
||||
|
||||
from typing import Dict, List
|
||||
from typing import Any, Union
|
||||
|
||||
import logging
|
||||
import os.path
|
||||
import time
|
||||
import traceback
|
||||
import uuid
|
||||
from typing import Any, Union
|
||||
from typing import Dict, List
|
||||
|
||||
import requests
|
||||
from playwright.sync_api import sync_playwright
|
||||
from requests_toolbelt.multipart.encoder import MultipartEncoder
|
||||
from desktop_env.evaluators.metrics.utils import compare_urls
|
||||
|
||||
logger = logging.getLogger("desktopenv.setup")
|
||||
|
||||
import traceback
|
||||
|
||||
class SetupController:
|
||||
def __init__(self, http_server: str, cache_dir: str):
|
||||
self.http_server: str = http_server
|
||||
self.http_server_setup_root = http_server + "/setup"
|
||||
def __init__(self, vm_ip: str, cache_dir: str):
|
||||
self.vm_ip: str = vm_ip
|
||||
self.http_server: str = f"http://{vm_ip}:5000"
|
||||
self.cache_dir: str = cache_dir
|
||||
|
||||
def reset_cache_dir(self, cache_dir: str):
|
||||
@@ -52,31 +54,31 @@ class SetupController:
|
||||
# can add other setup steps
|
||||
|
||||
# ZDY_COMMENT: merged with launch
|
||||
#def _command_setup(self, command: str):
|
||||
#"""
|
||||
#Directly send a command into the virtual machine os for setting up.
|
||||
#"""
|
||||
#payload = json.dumps({"command": command})
|
||||
#headers = {
|
||||
#'Content-Type': 'application/json'
|
||||
#}
|
||||
#timeout = 5
|
||||
#timout_whitelist = ["vlc"]
|
||||
#
|
||||
#try:
|
||||
#
|
||||
#response = requests.post(self.http_server + "/execute", headers=headers, data=payload, timeout=timeout)
|
||||
#if response.status_code == 200:
|
||||
#print("Command executed successfully:", response.text)
|
||||
#else:
|
||||
#print("Failed to execute command. Status code:", response.status_code)
|
||||
#except requests.exceptions.Timeout as e:
|
||||
#if command in timout_whitelist:
|
||||
#print("Command executed successfully:", command)
|
||||
#else:
|
||||
#print("An error occurred while trying to execute the command:", e)
|
||||
#except requests.exceptions.RequestException as e:
|
||||
#print("An error occurred while trying to execute the command:", e)
|
||||
# def _command_setup(self, command: str):
|
||||
# """
|
||||
# Directly send a command into the virtual machine os for setting up.
|
||||
# """
|
||||
# payload = json.dumps({"command": command})
|
||||
# headers = {
|
||||
# 'Content-Type': 'application/json'
|
||||
# }
|
||||
# timeout = 5
|
||||
# timout_whitelist = ["vlc"]
|
||||
#
|
||||
# try:
|
||||
#
|
||||
# response = requests.post(self.http_server + "/execute", headers=headers, data=payload, timeout=timeout)
|
||||
# if response.status_code == 200:
|
||||
# print("Command executed successfully:", response.text)
|
||||
# else:
|
||||
# print("Failed to execute command. Status code:", response.status_code)
|
||||
# except requests.exceptions.Timeout as e:
|
||||
# if command in timout_whitelist:
|
||||
# print("Command executed successfully:", command)
|
||||
# else:
|
||||
# print("An error occurred while trying to execute the command:", e)
|
||||
# except requests.exceptions.RequestException as e:
|
||||
# print("An error occurred while trying to execute the command:", e)
|
||||
|
||||
def _download_setup(self, files: List[Dict[str, str]]):
|
||||
"""
|
||||
@@ -138,8 +140,8 @@ class SetupController:
|
||||
|
||||
# send request to server to upload file
|
||||
try:
|
||||
logger.debug("REQUEST ADDRESS: %s", self.http_server_setup_root + "/upload")
|
||||
response = requests.post(self.http_server_setup_root + "/upload", headers=headers, data=form)
|
||||
logger.debug("REQUEST ADDRESS: %s", self.http_server + "/setup" + "/upload")
|
||||
response = requests.post(self.http_server + "/setup" + "/upload", headers=headers, data=form)
|
||||
if response.status_code == 200:
|
||||
logger.info("Command executed successfully: %s", response.text)
|
||||
else:
|
||||
@@ -164,7 +166,7 @@ class SetupController:
|
||||
|
||||
# send request to server to change wallpaper
|
||||
try:
|
||||
response = requests.post(self.http_server_setup_root + "/change_wallpaper", headers=headers, data=payload)
|
||||
response = requests.post(self.http_server + "/setup" + "/change_wallpaper", headers=headers, data=payload)
|
||||
if response.status_code == 200:
|
||||
logger.info("Command executed successfully: %s", response.text)
|
||||
else:
|
||||
@@ -191,7 +193,7 @@ class SetupController:
|
||||
|
||||
# send request to server to open file
|
||||
try:
|
||||
response = requests.post(self.http_server_setup_root + "/open_file", headers=headers, data=payload)
|
||||
response = requests.post(self.http_server + "/setup" + "/open_file", headers=headers, data=payload)
|
||||
if response.status_code == 200:
|
||||
logger.info("Command executed successfully: %s", response.text)
|
||||
else:
|
||||
@@ -211,7 +213,7 @@ class SetupController:
|
||||
headers = {"Content-Type": "application/json"}
|
||||
|
||||
try:
|
||||
response = requests.post(self.http_server_setup_root + "/launch", headers=headers, data=payload)
|
||||
response = requests.post(self.http_server + "/setup" + "/launch", headers=headers, data=payload)
|
||||
if response.status_code == 200:
|
||||
logger.info("Command executed successfully: %s", response.text)
|
||||
else:
|
||||
@@ -227,7 +229,7 @@ class SetupController:
|
||||
headers = {"Content-Type": "application/json"}
|
||||
|
||||
try:
|
||||
response = requests.post(self.http_server_setup_root + "/execute", headers=headers, data=payload)
|
||||
response = requests.post(self.http_server + "/setup" + "/execute", headers=headers, data=payload)
|
||||
if response.status_code == 200:
|
||||
results: Dict[str, str] = response.json()
|
||||
if stdout:
|
||||
@@ -236,10 +238,10 @@ class SetupController:
|
||||
if stderr:
|
||||
with open(os.path.join(self.cache_dir, stderr), "w") as f:
|
||||
f.write(results["error"])
|
||||
logger.info( "Command executed successfully: %s -> %s"
|
||||
, " ".join(command)
|
||||
, response.text
|
||||
)
|
||||
logger.info("Command executed successfully: %s -> %s"
|
||||
, " ".join(command)
|
||||
, response.text
|
||||
)
|
||||
else:
|
||||
logger.error("Failed to launch application. Status code: %s", response.text)
|
||||
except requests.exceptions.RequestException as e:
|
||||
@@ -252,6 +254,7 @@ class SetupController:
|
||||
def _act_setup(self, action_seq: List[Union[Dict[str, Any], str]]):
|
||||
# TODO
|
||||
raise NotImplementedError()
|
||||
|
||||
def _replay_setup(self, trajectory: str):
|
||||
"""
|
||||
Args:
|
||||
@@ -260,3 +263,84 @@ class SetupController:
|
||||
|
||||
# TODO
|
||||
raise NotImplementedError()
|
||||
|
||||
# Chrome setup
|
||||
def _chrome_open_tabs_setup(self, urls_to_open: List[str]):
|
||||
host = self.vm_ip
|
||||
port = 9222 # fixme: this port is hard-coded, need to be changed from config file
|
||||
|
||||
remote_debugging_url = f"http://{host}:{port}"
|
||||
with sync_playwright() as p:
|
||||
browser = None
|
||||
for attempt in range(15):
|
||||
try:
|
||||
browser = p.chromium.connect_over_cdp(remote_debugging_url)
|
||||
break
|
||||
except Exception as e:
|
||||
if attempt < 14:
|
||||
logger.error(f"Attempt {attempt + 1}: Failed to connect, retrying. Error: {e}")
|
||||
time.sleep(1)
|
||||
else:
|
||||
logger.error(f"Failed to connect after multiple attempts: {e}")
|
||||
raise e
|
||||
|
||||
if not browser:
|
||||
return
|
||||
|
||||
for i, url in enumerate(urls_to_open):
|
||||
# Use the first context (which should be the only one if using default profile)
|
||||
if i == 0:
|
||||
context = browser.contexts[0]
|
||||
|
||||
page = context.new_page() # Create a new page (tab) within the existing context
|
||||
page.goto(url)
|
||||
logger.info(f"Opened tab {i + 1}: {url}")
|
||||
|
||||
if i == 0:
|
||||
# clear the default tab
|
||||
default_page = context.pages[0]
|
||||
default_page.close()
|
||||
|
||||
# Do not close the context or browser; they will remain open after script ends
|
||||
return browser, context
|
||||
|
||||
def _chrome_close_tabs_setup(self, urls_to_close: List[str]):
|
||||
time.sleep(5) # Wait for Chrome to finish launching
|
||||
|
||||
host = self.vm_ip
|
||||
port = 9222 # fixme: this port is hard-coded, need to be changed from config file
|
||||
|
||||
remote_debugging_url = f"http://{host}:{port}"
|
||||
with sync_playwright() as p:
|
||||
browser = None
|
||||
for attempt in range(15):
|
||||
try:
|
||||
browser = p.chromium.connect_over_cdp(remote_debugging_url)
|
||||
break
|
||||
except Exception as e:
|
||||
if attempt < 14:
|
||||
logger.error(f"Attempt {attempt + 1}: Failed to connect, retrying. Error: {e}")
|
||||
time.sleep(1)
|
||||
else:
|
||||
logger.error(f"Failed to connect after multiple attempts: {e}")
|
||||
raise e
|
||||
|
||||
if not browser:
|
||||
return
|
||||
|
||||
for i, url in enumerate(urls_to_close):
|
||||
# Use the first context (which should be the only one if using default profile)
|
||||
if i == 0:
|
||||
context = browser.contexts[0]
|
||||
|
||||
for page in context.pages:
|
||||
|
||||
# if two urls are the same, close the tab
|
||||
if compare_urls(page.url, url):
|
||||
context.pages.pop(context.pages.index(page))
|
||||
page.close()
|
||||
logger.info(f"Closed tab {i + 1}: {url}")
|
||||
break
|
||||
|
||||
# Do not close the context or browser; they will remain open after script ends
|
||||
return browser, context
|
||||
|
||||
Reference in New Issue
Block a user