Add ECW/HTTP planner scripts, browser crash recovery, and Planner error-overlay handling

- Add ecw_download.py and onedrive_planner_http.py for ECW and HTTP-based Planner access
- Add build_exe.bat for packaging
- Restart Chrome automatically on crash mid-run in planner_download.py
- Detect and recover from Planner "something went wrong" error overlays
- Improve board-load waiting, sort-descending menu matching, and screenshot timestamp rendering in chrome.py/onedrive_planner.py
This commit is contained in:
Lubna Fathima committed 2026-07-09 08:41:28 -07:00
1 parent c2dec96b1f
commit 291507c2f7
6 files changed
+2134 -49

No files matched your search

+48 -7
View File
@@ -397,10 +397,33 @@ def _is_image_mostly_black(path: Path, *, threshold: int = 18) -> bool:
return False
def _load_timestamp_font(size: int = 22):
"""Return a PIL ImageFont at the requested size, falling back to the built-in bitmap font."""
try:
from PIL import ImageFont
candidates = [
"C:/Windows/Fonts/segoeui.ttf",
"C:/Windows/Fonts/arial.ttf",
"C:/Windows/Fonts/calibri.ttf",
"C:/Windows/Fonts/verdana.ttf",
]
for path in candidates:
try:
return ImageFont.truetype(path, size)
except Exception:
continue
except Exception:
pass
try:
from PIL import ImageFont
return ImageFont.load_default()
except Exception:
return None
def _capture_browser_with_timestamp_bar(driver: webdriver.Chrome, path: Path) -> bool:
"""
Fallback when desktop capture is black: maximized browser PNG plus a taskbar-style clock strip.
"""
"""Browser viewport PNG with a timestamp bar showing machine time."""
try:
import io
@@ -409,18 +432,36 @@ def _capture_browser_with_timestamp_bar(driver: webdriver.Chrome, path: Path) ->
prepare_browser_for_screenshot(driver)
png = driver.get_screenshot_as_png()
browser = Image.open(io.BytesIO(png)).convert("RGB")
bar_h = 48
canvas = Image.new("RGB", (browser.width, browser.height + bar_h), (30, 30, 30))
bar_h = 36
canvas = Image.new("RGB", (browser.width, browser.height + bar_h), (24, 24, 24))
canvas.paste(browser, (0, 0))
draw = ImageDraw.Draw(canvas)
stamp = datetime.now().strftime("%I:%M %p %m/%d/%Y").lstrip("0")
draw.text((max(browser.width - 260, 8), browser.height + 14), stamp, fill=(255, 255, 255))
stamp = datetime.now().strftime("%I:%M:%S %p %m/%d/%Y").lstrip("0")
font = _load_timestamp_font(22)
y = browser.height + (bar_h - 22) // 2
if font:
draw.text((12, y), stamp, fill=(220, 220, 220), font=font)
else:
draw.text((12, y), stamp, fill=(220, 220, 220))
canvas.save(str(path), "PNG")
return path.is_file() and path.stat().st_size > 0
except Exception:
return False
def capture_browser_screenshot(driver: webdriver.Chrome, path: Path) -> bool:
"""Capture only the Chromium browser viewport — no dependency on the host desktop."""
path = Path(path)
path.parent.mkdir(parents=True, exist_ok=True)
log_step("Browser screenshot", path=str(path))
if _capture_browser_with_timestamp_bar(driver, path):
log_step("Browser screenshot saved", path=str(path))
return True
driver.save_screenshot(str(path))
log_step("Viewport screenshot saved", path=str(path))
return path.is_file()
def capture_fullscreen_screenshot(driver: webdriver.Chrome, path: Path) -> bool:
"""
Full-screen capture with system taskbar visible when an interactive desktop exists.