diff --git a/desktop_env/controllers/setup.py b/desktop_env/controllers/setup.py index 6067c6b..614ac48 100644 --- a/desktop_env/controllers/setup.py +++ b/desktop_env/controllers/setup.py @@ -6,12 +6,13 @@ import uuid import os.path from typing import Dict, List -from typing import Any, Union +from typing import Any, Union, Optional import logging logger = logging.getLogger("desktopenv.setup") import traceback +import time class SetupController: def __init__(self, http_server: str, cache_dir: str): @@ -45,6 +46,8 @@ class SetupController: assert hasattr(self, setup_function) getattr(self, setup_function)(**parameters) + logger.info("SETUP: %s(%s)", setup_function, str(parameters)) + # self._download_setup(config) # self._change_wallpaper(config) # self._tidy_desktop(config) todo: implement this @@ -219,35 +222,60 @@ class SetupController: except requests.exceptions.RequestException as e: logger.error("An error occurred while trying to send the request: %s", e) - def _execute_setup(self, command: List[str], stdout: str = "", stderr: str = ""): + def _execute_setup( self, command: List[str] + , stdout: str = "", stderr: str = "" + , shell: bool = False, until: Optional[Dict[str, Any]] = None): if not command: raise Exception("Empty comman to launch.") - payload = json.dumps({"command": command}) + until: Dict[str, Any] = until or {} + terminates: bool = False + nb_failings = 0 + + payload = json.dumps({"command": command, "shell": shell}) headers = {"Content-Type": "application/json"} - try: - response = requests.post(self.http_server_setup_root + "/execute", headers=headers, data=payload) - if response.status_code == 200: - results: Dict[str, str] = response.json() - if stdout: - with open(os.path.join(self.cache_dir, stdout), "w") as f: - f.write(results["output"]) - 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 - ) - else: - logger.error("Failed to launch application. Status code: %s", response.text) - except requests.exceptions.RequestException as e: - logger.error("An error occurred while trying to send the request: %s", e) - traceback.print_exc() + while not terminates: + try: + response = requests.post(self.http_server_setup_root + "/execute", headers=headers, data=payload) + if response.status_code == 200: + results: Dict[str, str] = response.json() + if stdout: + with open(os.path.join(self.cache_dir, stdout), "w") as f: + f.write(results["output"]) + 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 + ) + else: + logger.error("Failed to launch application. Status code: %s", response.text) + results = None + nb_failings += 1 + except requests.exceptions.RequestException as e: + logger.error("An error occurred while trying to send the request: %s", e) + traceback.print_exc() - def _command_setup(self, command: List[str], stdout: str = "", stderr: str = ""): - self._execute_setup(command, stdout, stderr) + results = None + nb_failings += 1 + + if len(until)==0: + terminates = True + elif results is not None: + terminates = "returncode" in until and results["returncode"]==until["returncode"]\ + or "stdout" in until and until["stdout"] in results["output"]\ + or "stderr" in until and until["stderr"] in results["error"] + terminates = terminates or nb_failings>=5 + if not terminates: + time.sleep(0.3) + + def _command_setup(self, command: List[str], **kwargs): + self._execute_setup(command, **kwargs) + + def _sleep_setup(self, seconds: float): + time.sleep(seconds) def _act_setup(self, action_seq: List[Union[Dict[str, Any], str]]): # TODO diff --git a/desktop_env/evaluators/getters/__init__.py b/desktop_env/evaluators/getters/__init__.py index e985caa..7f59d4b 100644 --- a/desktop_env/evaluators/getters/__init__.py +++ b/desktop_env/evaluators/getters/__init__.py @@ -1,5 +1,4 @@ from .file import get_cloud_file, get_vm_file, get_cache_file -from .misc import get_rule from .info import get_vm_screen_size, get_vm_window_size, get_vm_wallpaper from .misc import get_rule, get_accessibility_tree from .vlc import get_vlc_playing_info, get_vlc_config diff --git a/desktop_env/evaluators/metrics/__init__.py b/desktop_env/evaluators/metrics/__init__.py index 6f7759d..01abfa6 100644 --- a/desktop_env/evaluators/metrics/__init__.py +++ b/desktop_env/evaluators/metrics/__init__.py @@ -9,4 +9,8 @@ from .table import check_sheet_list, check_xlsx_freeze, check_xlsx_zoom from .table import compare_table from .vlc import is_vlc_playing, is_vlc_recordings_folder, is_vlc_fullscreen, compare_images, compare_audios, \ compare_videos + from .gimp import increase_saturation, decrease_brightness +from .general import check_csv, check_accessibility_tree, check_list +from .thunderbird import check_thunderbird_prefs, check_thunderbird_filter + diff --git a/desktop_env/evaluators/metrics/general.py b/desktop_env/evaluators/metrics/general.py index 256ad53..d0795a6 100644 --- a/desktop_env/evaluators/metrics/general.py +++ b/desktop_env/evaluators/metrics/general.py @@ -11,6 +11,7 @@ from lxml.cssselect import CSSSelector from lxml.etree import _Element from rapidfuzz import fuzz +from .utils import _match_record def exact_match(result, rules) -> float: expect = rules["expected"] @@ -27,11 +28,6 @@ def fuzzy_match(result, rules) -> float: return fuzz.ratio(result, expect) / 100. - -def _match_record(pattern: Dict[str, str], item: Dict[str, str]) -> float: - return all(k in item and item[k] == val for k, val in pattern.items()) - - def check_csv(result: str, rules: Dict[str, List[Dict[str, str]]]) -> float: """ Args: @@ -46,6 +42,9 @@ def check_csv(result: str, rules: Dict[str, List[Dict[str, str]]]) -> float: float """ + if result is None: + return 0. + expect_metrics = [False] * len(rules.get("expect", [])) unexpect_metric = True with open(result) as f: @@ -72,6 +71,9 @@ def check_list(result: str, rules: Dict[str, List[str]]) -> float: float """ + if result is None: + return 0. + expect_patterns: List[Pattern[str]] = [re.compile(ptt) for ptt in rules.get("expect", [])] unexpect_patterns: List[Pattern[str]] = [re.compile(ptt) for ptt in rules.get("unexpect", [])] @@ -130,9 +132,10 @@ def check_accessibility_tree(result: str, rules: Dict[str, Any]) -> float: return 0. if "text" in rules: - match_func: Callable[[str], Number] = functools.partial(operator.eq if rules["exact"] else fuzz.ratio - , rules["text"] - ) + match_func: Callable[[str], Number] = functools.partial( operator.eq if rules["exact"]\ + else (lambda a, b: fuzz.ratio(a, b)/100.) + , rules["text"] + ) match_score: Number = 0 for elm in elements: match_score = max(match_score, match_func(elm.text or None)) diff --git a/desktop_env/evaluators/metrics/thunderbird.py b/desktop_env/evaluators/metrics/thunderbird.py index 581b8d1..b202d94 100644 --- a/desktop_env/evaluators/metrics/thunderbird.py +++ b/desktop_env/evaluators/metrics/thunderbird.py @@ -1,53 +1,210 @@ -#from playwright.sync_api import sync_playwright, Browser -#from marionette_driver.marionette import Marionette -#import marionette -#import pyatspi +from typing import List, Pattern, Dict, Match, Tuple +from typing import Union, Any, Optional, Iterable, TypeVar, Callable -import lxml.etree -from lxml.cssselect import CSSSelector -from lxml.etree import _Element +import re +import functools +import operator +import json +from .utils import _match_record -from typing import List +import logging +logger = logging.getLogger("desktopenv.metric.thunderbird") + +V = TypeVar("Value") + +def _match_pref(value: Any, rule: Dict[str, Union[str, Any]]) -> bool: + # function _match_pref {{{ # + if rule["method"].startswith("re"): + flags: List[str] = rule["method"].split(".")[1:] + flags: Iterable[re.RegexFlag] = (getattr(re, fl) for fl in flags) + flag: re.RegexFlag = functools.reduce(operator.or_, flags, re.RegexFlag(0)) + logger.debug("REFLAG: %s", repr(flag)) + + match_: Optional[Match[str]] = re.search(rule["ref"], value, flag) + return match_ is not None + if rule["method"] in { "eq", "ne" + , "le", "lt" + , "ge", "gt" + }: + return getattr(operator, rule["method"])(value, rule["ref"]) + raise NotImplementedError() + # }}} function _match_pref # + +_pref_pattern: Pattern[str] = re.compile(r'^user_pref\("(?P(?:[^"]|\\")+)\", (?P.+)\);$'); +def check_thunderbird_prefs(result: str, rule: Dict[str, Dict[str, Dict[str, Any]]]): + """ + Args: + result (str): path to result file + rule (Dict[str, Dict[str, Dict[str, Any]]]): dict like + { + "expect": { + str: { + "method": str + "ref": something + } + } + "unexpect": { + str: { + "method": str + "ref": something + } + } + } + + Returns: + float + """ + + if result is None: + return 0. + + expect_rules = rule.get("expect", {}) + unexpect_rules = rule.get("unexpect", {}) + + expect_metrics = {k: False for k in expect_rules} + unexpect_metric = True + with open(result) as f: + for l in f: + match_: Match[str] = _pref_pattern.match(l.strip()) + if match_ is None: + continue + + key: str = match_.group("key") + #value: str = match_.group("val") + #if value in {"true", "false"}: + #value = value.title() + #value: V = eval(value) + value = json.loads(match_.group("val")) + if key in expect_rules: + logger.debug("K: %s, V: %s", key, repr(value)) + expect_metrics[key] = _match_pref(value, expect_rules[key]) + elif key in unexpect_rules: + unexpect_metric = unexpect_metric and not _match_pref(value, unexpect_rules[key]) + + return float(all(expect_metrics.values()) and unexpect_metric) + +_value_processor: Callable[[str], str] = lambda val: val.replace("\\\"", "\"").replace("\\\\", "\\") +#_condition_pattern: Pattern[str] = re.compile(r'(?PAND|OR) \((?P[\w ]+),(?P[\w ' + '\'' + r']+),(?:"(?P(?:[^"]|\")+)"|(?P[^)]+))\)') +_condition_pattern: Pattern[str] = re.compile(r'(?:AND|OR) \((?:[\w ]+),(?:[\w ' + '\'' + r']+),(?:"(?:(?:[^"]|\")+)"|(?:[^)]+))\)') +def check_thunderbird_filter(result: str, rules: Dict[str, List[Dict[str, str]]]) -> float: + """ + Args: + result (str): path to filter def file + rules (Dict[str, List[Dict[str, str]]]): dict like + { + "expect": [{key: value}] + "unexpect": [{key: value}] + } + + Returns: + float + """ + + if result is None: + return 0. + + # read filter def file + # a filter: + # { + # "name": "Name", + # "enabled": "yes" | "no", + # "type": "17", + # "action": "Move to folder" | ..., + # "actionValue": ..., + # "condition": [...] + # } + filters: List[Dict[str, Union[str, List[str]]]] = [] + with open(result) as f: + for l in f: + if l.startswith("name="): + filter_: Dict[str, Union[str, List[str]]] = {} + filter_["name"] = _value_processor(l[6:-2]) + elif l.startswith("enabled="): + filter_["enabled"] = _value_processor(l[9:-2]) + elif l.startswith("type="): + filter_["type"] = _value_processor(l[6:-2]) + elif l.startswith("action="): + filter_["action"] = _value_processor(l[8:-2]) + elif l.startswith("actionValue="): + filter_["actionValue"] = _value_processor(l[13:-2]) + elif l.startswith("condition="): + condition_str: str = _value_processor(l[11:-2]) + logger.debug("FILTER CONDITION: %s", condition_str) + + conditions: List[str] =\ + _condition_pattern.findall(condition_str) + logger.debug("FILTER CONDITIONS: %s", repr(conditions)) + + filter_["condition"] = conditions + logger.debug("FILTER %s", repr(filter_)) + filters.append(filter_) + + expect_metrics = [False] * len(rules.get("expect", [])) + unexpect_metric = True + for flt in filters: + for i, r in enumerate(rules.get("expect", [])): + expect_metrics[i] = expect_metrics[i] or _match_record(r, flt) + unexpect_metric = unexpect_metric and not any(_match_record(r, flt) for r in rules.get("unexpect", [])) + return float(all(expect_metrics) and unexpect_metric) if __name__ == "__main__": - #with sync_playwright() as plwr: - #while True: - ##try: - #thunderbird: Browser = plwr.firefox.connect("http://127.0.0.1:6000", timeout=60) - #break - ##except: - ##pass - #for ctx in thunderbird.contexts: - #for p in ctx.pages: - #print(p.url) - - #thunderbird = Marionette() - #print(thunderbird.start_session()) - #print(thunderbird.chrome_window_handles) - #print(thunderbird.window_handles) - #print(thunderbird.current_chrome_window_handle) - #thunderbird.set_context(Marionette.CONTEXT_CONTENT) - #print(thunderbird.current_window_handle) - #thunderbird.switch_to_window(thunderbird.chrome_window_handles[0]) - #thunderbird.switch_to_default_content() - #thunderbird.switch_to_frame() - #print(thunderbird.get_url()) - #print(thunderbird.get_window_type()) - #thunderbird.fullscreen() - #print(thunderbird.close()) - - #registry = pyatspi.Registry.get_default() - #registry + import lxml.etree + from lxml.cssselect import CSSSelector + from lxml.etree import _Element #xml = "../../任务数据/Thunderbird/vertical-card-view.xml" - xml = "../../任务数据/Thunderbird/vertical-table-view.xml" - at: _Element = lxml.etree.parse(xml) + #xml = "../../任务数据/Thunderbird/vertical-table-view.xml" + #at: _Element = lxml.etree.parse(xml) #elements: List[_Element] = CSSSelector('application[name=Thunderbird] page-tab-list')(at) # page tab tags #elements: List[_Element] = CSSSelector('application[name=Thunderbird] panel>scroll-pane>internal-frame>panel[name$="anonym-x2024@outlook.com"]')(at) # email tag page #elements: List[_Element] = CSSSelector('application[name=Thunderbird] panel>scroll-pane>internal-frame>panel[name$="anonym-x2024@outlook.com"]>section:nth-child(3)')(at) # email tag page #elements: List[_Element] = CSSSelector('application[name=Thunderbird] panel>scroll-pane>internal-frame>panel[name$="anonym-x2024@outlook.com"]>section[attr|id=threadPane]>section[attr|id="threadTree"]>table[attr|class="tree-table"]>section[attr|class~="tree-table-header"]>table-row>column-header[name=Subject]>push-button', namespaces={"attr": "uri:deskat:attributes.at-spi.gnome.org"})(at) # table view, column header - elements: List[_Element] = CSSSelector('application[name=Thunderbird] panel>scroll-pane>internal-frame>panel[name$="anonym-x2024@outlook.com"]>section[attr|id=threadPane]>section[attr|id="threadTree"]>table[attr|class="tree-table"]>tree>tree-item>section[name="Subject"]>section>section', namespaces={"attr": "uri:deskat:attributes.at-spi.gnome.org"})(at) # table view, column header - print(len(elements)) - for elm in elements: - print(lxml.etree.tostring(elm, encoding="unicode", pretty_print=True)) + #elements: List[_Element] = CSSSelector('application[name=Thunderbird] panel>scroll-pane>internal-frame>panel[name$="anonym-x2024@outlook.com"]>section[attr|id=threadPane]>section[attr|id="threadTree"]>table[attr|class="tree-table"]>tree>tree-item>section[name="Subject"]>section>section', namespaces={"attr": "uri:deskat:attributes.at-spi.gnome.org"})(at) # table view, column header + #print(len(elements)) + #for elm in elements: + #print(lxml.etree.tostring(elm, encoding="unicode", pretty_print=True)) + + import datetime + import os + import sys + + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) + + datetime_str: str = datetime.datetime.now().strftime("%Y%m%d@%H%M%S") + + file_handler = logging.FileHandler(os.path.join("logs", "normal-{:}.log".format(datetime_str))) + debug_handler = logging.FileHandler(os.path.join("logs", "debug-{:}.log".format(datetime_str))) + stdout_handler = logging.StreamHandler(sys.stdout) + sdebug_handler = logging.FileHandler(os.path.join("logs", "sdebug-{:}.log".format(datetime_str))) + + file_handler.setLevel(logging.INFO) + debug_handler.setLevel(logging.DEBUG) + stdout_handler.setLevel(logging.INFO) + sdebug_handler.setLevel(logging.DEBUG) + + formatter = logging.Formatter(fmt="\x1b[1;33m[%(asctime)s \x1b[31m%(levelname)s \x1b[32m%(module)s/%(lineno)d-%(processName)s\x1b[1;33m] \x1b[0m%(message)s") + file_handler.setFormatter(formatter) + debug_handler.setFormatter(formatter) + stdout_handler.setFormatter(formatter) + sdebug_handler.setFormatter(formatter) + + stdout_handler.addFilter(logging.Filter("desktopenv")) + sdebug_handler.addFilter(logging.Filter("desktopenv")) + + logger.addHandler(file_handler) + logger.addHandler(debug_handler) + logger.addHandler(stdout_handler) + logger.addHandler(sdebug_handler) + + print( check_thunderbird_filter( "../../任务数据/Thunderbird/msgFilterRules.dat" + , { "expect": [ { "enabled": "yes" + , "action": "Move to folder" + , "actionValue": "mailbox://nobody@Local%20Folders/Promotions" + , "condition": ["AND (subject,contains,discount)"] + } + ] + } + ) + ) diff --git a/desktop_env/evaluators/metrics/utils.py b/desktop_env/evaluators/metrics/utils.py index 93bc778..6f20d30 100644 --- a/desktop_env/evaluators/metrics/utils.py +++ b/desktop_env/evaluators/metrics/utils.py @@ -125,6 +125,9 @@ def load_charts(xlsx_file: Workbook, **options) -> Dict[str, Any]: chart_set[series] = info return chart_set +def _match_record(pattern: Dict[str, Any], item: Dict[str, Any]) -> bool: + return all(k in item and item[k]==val for k, val in pattern.items()) + if __name__ == "__main__": path1 = "../../../../../任务数据/LibreOffice Calc/Create_column_charts_using_statistics_gold_line_scatter.xlsx" workbook1: Workbook = openpyxl.load_workbook(filename=path1) diff --git a/desktop_env/server/main.py b/desktop_env/server/main.py index a49b565..11de773 100644 --- a/desktop_env/server/main.py +++ b/desktop_env/server/main.py @@ -48,7 +48,8 @@ def execute_command(): return jsonify({ 'status': 'success', 'output': result.stdout, - 'error': result.stderr + 'error': result.stderr, + 'returncode': result.returncode }) except Exception as e: return jsonify({ diff --git a/evaluation_examples/examples/thunderbird/06fe7178-4491-4589-810f-2e2bc9502122.json b/evaluation_examples/examples/thunderbird/06fe7178-4491-4589-810f-2e2bc9502122.json index 969b193..2dc8b0b 100644 --- a/evaluation_examples/examples/thunderbird/06fe7178-4491-4589-810f-2e2bc9502122.json +++ b/evaluation_examples/examples/thunderbird/06fe7178-4491-4589-810f-2e2bc9502122.json @@ -1,7 +1,7 @@ { "id": "06fe7178-4491-4589-810f-2e2bc9502122", "snapshot": "thunderbird", - "instruction": "Could you help me back up all the email files in my profile to ~/email.bak? Please save them in eml format.", + "instruction": "Could you help me back up all the email files in my profile to ~/email.bak? Please save them separately in eml format.", "source": "https://www.quora.com/How-do-I-backup-email-files-in-Mozilla-Thunderbird", "config": [ { diff --git a/evaluation_examples/examples/thunderbird/6766f2b8-8a72-417f-a9e5-56fcaa735837.json b/evaluation_examples/examples/thunderbird/6766f2b8-8a72-417f-a9e5-56fcaa735837.json new file mode 100644 index 0000000..4e01ff5 --- /dev/null +++ b/evaluation_examples/examples/thunderbird/6766f2b8-8a72-417f-a9e5-56fcaa735837.json @@ -0,0 +1,75 @@ +{ + "id": "6766f2b8-8a72-417f-a9e5-56fcaa735837", + "snapshot": "thunderbird", + "instruction": "Set up a signature using my name and affiliation. My name is Anonym and my affiliation is XYZ Lab.", + "source": "https://www.adsigner.com/user-manual/signatures/setup-email-client-thunderbird/#:~:text=is%20probably%20hidden.-,Right%20click%20on%20the%20empty%20space%20at%20the%20top%20of,signature%20from%20a%20file%20instead.", + "config": [ + { + "type": "download", + "parameters": { + "files": [ + { + "url": "https://drive.usercontent.google.com/download?id=1EHLRWzBCOsyERkSMUnTF2pnsR0n6ZvtR&export=download&authuser=0&confirm=t&uuid=de09bd5e-bef8-499a-b599-c642af190e10&at=APZUnTXqOsQkxl0zMSX6R1Sgp_v3:1704362491712", + "path": "/home/user/thunderbird-profile.tar.gz" + } + ] + } + }, + { + "type": "execute", + "parameters": { + "command": [ + "tar", + "-xzv", + "--recursive-unlink", + "-f", + "/home/user/thunderbird-profile.tar.gz", + "-C", + "/home/user/" + ] + } + }, + { + "type": "launch", + "parameters": { + "command": [ + "/usr/bin/thunderbird" + ] + } + } + ], + "trajectory": "trajectories/6766f2b8-8a72-417f-a9e5-56fcaa735837", + "related_apps": [ + "thunderbird" + ], + "evaluator": { + "postconfig": [ + { + "type": "command", + "parameters": { + "command": ["wmctrl", "-xFc", "Mail.thunderbird"], + "until": { + "returncode": 1 + } + } + } + ], + "result": { + "type": "vm_file", + "path": "/home/user/.thunderbird/t5q2a5hp.default-release/prefs.js", + "dest": "thunder-prefs.js" + }, + "expected": { + "type": "rule", + "rules": { + "expect": { + "mail.identity.id1.htmlSigText": { + "method": "re.S", + "ref": "Anonym.+XYZ Lab" + } + } + } + }, + "func": "check_thunderbird_prefs" + } +} diff --git a/evaluation_examples/examples/thunderbird/6766f2b8-8a72-417f-a9e5-56fcaa735837.json.nosetup b/evaluation_examples/examples/thunderbird/6766f2b8-8a72-417f-a9e5-56fcaa735837.json.nosetup new file mode 100644 index 0000000..f0a416a --- /dev/null +++ b/evaluation_examples/examples/thunderbird/6766f2b8-8a72-417f-a9e5-56fcaa735837.json.nosetup @@ -0,0 +1,53 @@ +{ + "id": "6766f2b8-8a72-417f-a9e5-56fcaa735837", + "snapshot": "thunderbird", + "instruction": "Set up a signature using my name and affiliation. My name is Anonym and my affiliation is XYZ Lab.", + "source": "https://www.adsigner.com/user-manual/signatures/setup-email-client-thunderbird/#:~:text=is%20probably%20hidden.-,Right%20click%20on%20the%20empty%20space%20at%20the%20top%20of,signature%20from%20a%20file%20instead.", + "config": [ + { + "type": "download", + "parameters": { + "files": [ + { + "url": "https://drive.usercontent.google.com/download?id=1EHLRWzBCOsyERkSMUnTF2pnsR0n6ZvtR&export=download&authuser=0&confirm=t&uuid=de09bd5e-bef8-499a-b599-c642af190e10&at=APZUnTXqOsQkxl0zMSX6R1Sgp_v3:1704362491712", + "path": "/home/user/thunderbird-profile.tar.gz" + } + ] + } + } + ], + "trajectory": "trajectories/6766f2b8-8a72-417f-a9e5-56fcaa735837", + "related_apps": [ + "thunderbird" + ], + "evaluator": { + "postconfig": [ + { + "type": "command", + "parameters": { + "command": ["wmctrl", "-xFc", "Mail.thunderbird"], + "until": { + "returncode": 1 + } + } + } + ], + "result": { + "type": "vm_file", + "path": "/home/user/.thunderbird/t5q2a5hp.default-release/prefs.js", + "dest": "thunder-prefs.js" + }, + "expected": { + "type": "rule", + "rules": { + "expect": { + "mail.identity.id1.htmlSigText": { + "method": "re.S", + "ref": "Anonym.+XYZ Lab" + } + } + } + }, + "func": "check_thunderbird_prefs" + } +} diff --git a/evaluation_examples/examples/thunderbird/e1e75309-3ddb-4d09-92ec-de869c928143.json b/evaluation_examples/examples/thunderbird/e1e75309-3ddb-4d09-92ec-de869c928143.json new file mode 100644 index 0000000..3dd986a --- /dev/null +++ b/evaluation_examples/examples/thunderbird/e1e75309-3ddb-4d09-92ec-de869c928143.json @@ -0,0 +1,77 @@ +{ + "id": "e1e75309-3ddb-4d09-92ec-de869c928143", + "snapshot": "thunderbird", + "instruction": "Create a local folder called \"Promotions\" and create a filter to auto move the inbox emails whose subject contains “discount” to the new folder", + "source": "https://support.mozilla.org/en-US/kb/organize-your-messages-using-filters", + "config": [ + { + "type": "download", + "parameters": { + "files": [ + { + "url": "https://drive.usercontent.google.com/download?id=1EHLRWzBCOsyERkSMUnTF2pnsR0n6ZvtR&export=download&authuser=0&confirm=t&uuid=de09bd5e-bef8-499a-b599-c642af190e10&at=APZUnTXqOsQkxl0zMSX6R1Sgp_v3:1704362491712", + "path": "/home/user/thunderbird-profile.tar.gz" + } + ] + } + }, + { + "type": "execute", + "parameters": { + "command": [ + "tar", + "-xzv", + "--recursive-unlink", + "-f", + "/home/user/thunderbird-profile.tar.gz", + "-C", + "/home/user/" + ] + } + }, + { + "type": "launch", + "parameters": { + "command": [ + "/usr/bin/thunderbird" + ] + } + } + ], + "trajectory": "trajectories/e1e75309-3ddb-4d09-92ec-de869c928143", + "related_apps": [ + "thunderbird" + ], + "evaluator": { + "postconfig": [ + { + "type": "command", + "parameters": { + "command": ["wmctrl", "-Fc", "Message Filters"], + "until": { + "returncode": 1 + } + } + } + ], + "func": "check_thunderbird_filter", + "result": { + "type": "vm_file", + "path": "/home/user/.thunderbird/t5q2a5hp.default-release/ImapMail/outlook.office365.com/msgFilterRules.dat", + "dest": "msgFilterRules.dat" + }, + "expected": { + "type": "rule", + "rules": { + "expect": [ + { + "enabled": "yes", + "action": "Move to folder", + "actionValue": "mailbox://nobody@Local%20Folders/Promotions", + "condition": ["AND (subject,contains,discount)"] + } + ] + } + } + } +} diff --git a/evaluation_examples/examples/thunderbird/e1e75309-3ddb-4d09-92ec-de869c928143.json.nosetup b/evaluation_examples/examples/thunderbird/e1e75309-3ddb-4d09-92ec-de869c928143.json.nosetup new file mode 100644 index 0000000..66af75d --- /dev/null +++ b/evaluation_examples/examples/thunderbird/e1e75309-3ddb-4d09-92ec-de869c928143.json.nosetup @@ -0,0 +1,55 @@ +{ + "id": "e1e75309-3ddb-4d09-92ec-de869c928143", + "snapshot": "thunderbird", + "instruction": "Create a local folder called \"Promotions\" and create a filter to auto move the inbox emails whose subject contains “discount” to the new folder", + "source": "https://support.mozilla.org/en-US/kb/organize-your-messages-using-filters", + "config": [ + { + "type": "download", + "parameters": { + "files": [ + { + "url": "https://drive.usercontent.google.com/download?id=1EHLRWzBCOsyERkSMUnTF2pnsR0n6ZvtR&export=download&authuser=0&confirm=t&uuid=de09bd5e-bef8-499a-b599-c642af190e10&at=APZUnTXqOsQkxl0zMSX6R1Sgp_v3:1704362491712", + "path": "/home/user/thunderbird-profile.tar.gz" + } + ] + } + } + ], + "trajectory": "trajectories/e1e75309-3ddb-4d09-92ec-de869c928143", + "related_apps": [ + "thunderbird" + ], + "evaluator": { + "postconfig": [ + { + "type": "command", + "parameters": { + "command": ["wmctrl", "-Fc", "Message Filters"], + "until": { + "returncode": 1 + } + } + } + ], + "func": "check_thunderbird_filter", + "result": { + "type": "vm_file", + "path": "/home/user/.thunderbird/t5q2a5hp.default-release/ImapMail/outlook.office365.com/msgFilterRules.dat", + "dest": "msgFilterRules.dat" + }, + "expected": { + "type": "rule", + "rules": { + "expect": [ + { + "enabled": "yes", + "action": "Move to folder", + "actionValue": "mailbox://nobody@Local%20Folders/Promotions", + "condition": ["AND (subject,contains,discount)"] + } + ] + } + } + } +} diff --git a/main.py b/main.py index f062e85..5da8091 100644 --- a/main.py +++ b/main.py @@ -44,16 +44,14 @@ def human_agent(): Runs the Gym environment with human input. """ - with open("evaluation_examples/examples/thunderbird/06fe7178-4491-4589-810f-2e2bc9502122.json", "r") as f: + with open("evaluation_examples/examples/thunderbird/e1e75309-3ddb-4d09-92ec-de869c928143.json.nosetup", "r") as f: example = json.load(f) - example["snapshot"] = "Snapshot 11" - - env = DesktopEnv( - path_to_vm=r"C:\Users\tianbaox\Documents\Virtual Machines\Ubuntu\Ubuntu.vmx", - action_space="computer_13", - task_config=example - ) + example["snapshot"] = "Snapshot 18" + env = DesktopEnv( path_to_vm="../../../../大文件/镜像/Ubuntu-1218/Ubuntu/Ubuntu.vmx" + , action_space="computer_13" + , task_config=example + ) # reset the environment to certain snapshot observation = env.reset() done = False @@ -94,7 +92,7 @@ def human_agent(): #input("PAUSING") - env.close() + #env.close() logger.info("Environment closed.")