Feat/rpa harness#20
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces cross-platform support for OpenChronicle by adding Windows UI Automation (UIA) as a capture source and implementing a new RPA harness for pluggable automation providers, including an Android ADB provider. The changes include updates to configuration paths, daemon management for Windows, and robust file I/O operations. I have provided feedback regarding the use of read_bytes() for JSON parsing to improve encoding handling and a minor null-check optimization for the Windows UIA provider.
| """Rewrite a capture JSON without its ``screenshot`` field. Returns True if stripped.""" | ||
| try: | ||
| raw = path.read_text() | ||
| raw = path.read_text(encoding="utf-8") |
There was a problem hiding this comment.
When parsing JSON files, it is recommended to use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions.
| raw = path.read_text(encoding="utf-8") | |
| raw = path.read_bytes() |
References
- When parsing JSON files, use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions, which are a type of ValueError and may not be caught by OSError handlers.
| return {} | ||
| try: | ||
| data = json.loads(path.read_text()) | ||
| data = json.loads(path.read_text(encoding="utf-8")) |
There was a problem hiding this comment.
When parsing JSON files, it is recommended to use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions.
| data = json.loads(path.read_text(encoding="utf-8")) | |
| data = json.loads(path.read_bytes()) |
References
- When parsing JSON files, use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions, which are a type of ValueError and may not be caught by OSError handlers.
| return {} | ||
| try: | ||
| data = json.loads(path.read_text()) | ||
| data = json.loads(path.read_text(encoding="utf-8")) |
There was a problem hiding this comment.
When parsing JSON files, it is recommended to use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions.
| data = json.loads(path.read_text(encoding="utf-8")) | |
| data = json.loads(path.read_bytes()) |
References
- When parsing JSON files, use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions, which are a type of ValueError and may not be caught by OSError handlers.
| for p in files: | ||
| try: | ||
| data = json.loads(p.read_text()) | ||
| data = json.loads(p.read_text(encoding="utf-8")) |
There was a problem hiding this comment.
When parsing JSON files, it is recommended to use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions.
| data = json.loads(p.read_text(encoding="utf-8")) | |
| data = json.loads(p.read_bytes()) |
References
- When parsing JSON files, use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions, which are a type of ValueError and may not be caught by OSError handlers.
| def _load_capture(path: Path) -> dict[str, Any] | None: | ||
| try: | ||
| return json.loads(path.read_text()) | ||
| return json.loads(path.read_text(encoding="utf-8")) |
There was a problem hiding this comment.
When parsing JSON files, it is recommended to use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions.
| return json.loads(path.read_text(encoding="utf-8")) | |
| return json.loads(path.read_bytes()) |
References
- When parsing JSON files, use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions, which are a type of ValueError and may not be caught by OSError handlers.
| def load_manifest(path: str | Path) -> ProviderManifest: | ||
| manifest_path = Path(path) | ||
| try: | ||
| data = json.loads(manifest_path.read_text(encoding="utf-8")) |
There was a problem hiding this comment.
When parsing JSON files, it is recommended to use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions.
| data = json.loads(manifest_path.read_text(encoding="utf-8")) | |
| data = json.loads(manifest_path.read_bytes()) |
References
- When parsing JSON files, use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions, which are a type of ValueError and may not be caught by OSError handlers.
| def load_workflow(path: str | Path) -> dict[str, Any]: | ||
| workflow_path = Path(path) | ||
| try: | ||
| data = json.loads(workflow_path.read_text(encoding="utf-8")) |
There was a problem hiding this comment.
When parsing JSON files, it is recommended to use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions.
| data = json.loads(workflow_path.read_text(encoding="utf-8")) | |
| data = json.loads(workflow_path.read_bytes()) |
References
- When parsing JSON files, use read_bytes() and pass the result to json.loads() to let the JSON library handle encoding detection and prevent unhandled UnicodeDecodeError exceptions, which are a type of ValueError and may not be caught by OSError handlers.
| if _control_identity(focused) != _control_identity(foreground): | ||
| focused_el = _element_from_control(focused, depth=min(self._depth, 3), budget=budget) |
There was a problem hiding this comment.
The focused control can be None if _safe_focused_control fails. While _element_from_control handles None gracefully by returning None, it is more efficient to check for None before calling it.
| if _control_identity(focused) != _control_identity(foreground): | |
| focused_el = _element_from_control(focused, depth=min(self._depth, 3), budget=budget) | |
| if focused is not None and _control_identity(focused) != _control_identity(foreground): | |
| focused_el = _element_from_control(focused, depth=min(self._depth, 3), budget=budget) |
Summary
Verification