Files
klubhaus-doorbell/libraries/FastLED/ci/util/scrapers/scrape_festival_stick.py
2026-02-12 00:45:31 -08:00

207 lines
7.6 KiB
Python

#!/usr/bin/env python3
import asyncio
import os
import sys
from datetime import datetime
from pathlib import Path
from playwright.async_api import async_playwright # type: ignore
HERE = Path(__file__).parent
PROJECT_ROOT = HERE.parent.parent.parent # scrapers is 3 levels down from project root
SCREENSHOTS_DIR = HERE / "screenshots"
# Ensure screenshots directory exists
SCREENSHOTS_DIR.mkdir(exist_ok=True)
# Ensure Playwright browsers are installed
def install_playwright_browsers():
print("Installing Playwright browsers...")
try:
os.system(f"{sys.executable} -m playwright install chromium")
print("Playwright browsers installed successfully.")
except Exception as e:
print(f"Failed to install Playwright browsers: {e}", file=sys.stderr)
sys.exit(1)
async def scrape_festival_stick_example():
"""
Navigate to the online FastLED tool and capture a screenshot of the FestivalStick example
"""
install_playwright_browsers()
# Online FastLED tool URL
fastled_url = "https://fastled.onrender.com/docs"
async with async_playwright() as p:
# Launch browser with a visible window for debugging
browser = await p.chromium.launch(headless=False, slow_mo=1000)
page = await browser.new_page()
# Set viewport size for consistent screenshots
await page.set_viewport_size({"width": 1920, "height": 1080})
try:
print(f"Navigating to {fastled_url}...")
await page.goto(fastled_url, timeout=30000)
# Wait for the page to load
await page.wait_for_load_state("networkidle")
# Look for FastLED examples or upload functionality
print("Looking for FastLED example functionality...")
# Wait a bit for dynamic content to load
await page.wait_for_timeout(3000)
# Try to find any example selection or file upload elements
examples_selector = None
possible_selectors = [
"select[name*='example']",
"select[id*='example']",
".example-selector",
"input[type='file']",
"button:has-text('Example')",
"button:has-text('FestivalStick')",
"a:has-text('Example')",
"a:has-text('FestivalStick')",
]
for selector in possible_selectors:
try:
element = await page.wait_for_selector(selector, timeout=2000)
if element:
print(f"Found element with selector: {selector}")
examples_selector = selector
break
except Exception:
continue
if not examples_selector:
# If no specific example selector found, look for text content
print("Looking for FestivalStick text on page...")
try:
await page.wait_for_selector("text=FestivalStick", timeout=5000)
print("Found FestivalStick text on page!")
except Exception:
print(
"FestivalStick text not found, taking screenshot of current page..."
)
# Try to interact with the FastLED tool interface
print("Attempting to interact with FastLED interface...")
# Look for common web interface elements
interface_elements = [
"canvas",
".led-display",
".visualization",
"#fastled-canvas",
".fastled-viewer",
]
canvas_found = False
canvas = None
for element_selector in interface_elements:
try:
canvas_element = await page.wait_for_selector(
element_selector, timeout=2000
)
if canvas_element:
print(f"Found display element: {element_selector}")
canvas_found = True
canvas = canvas_element
break
except Exception:
continue
if not canvas_found:
print("No specific display canvas found, capturing full page...")
# If there's a file upload option, try to upload the FestivalStick example
try:
file_input = await page.query_selector("input[type='file']")
if file_input:
print("Found file input, attempting to upload FestivalStick.ino...")
festival_stick_path = (
PROJECT_ROOT
/ "examples"
/ "FestivalStick"
/ "FestivalStick.ino"
)
if festival_stick_path.exists():
await file_input.set_input_files(str(festival_stick_path))
await page.wait_for_timeout(3000) # Wait for upload to process
print("FestivalStick.ino uploaded successfully!")
else:
print(f"FestivalStick.ino not found at {festival_stick_path}")
except Exception as e:
print(f"Could not upload file: {e}")
# Wait for any animations or dynamic content to settle
await page.wait_for_timeout(5000)
# Take screenshot
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
screenshot_path = SCREENSHOTS_DIR / f"festival_stick_{timestamp}.png"
print(f"Taking screenshot and saving to {screenshot_path}...")
await page.screenshot(path=str(screenshot_path), full_page=True)
print(f"Screenshot saved successfully to {screenshot_path}")
# Also take a focused screenshot if we found a canvas
if canvas_found and canvas is not None:
try:
canvas_screenshot_path = (
SCREENSHOTS_DIR / f"festival_stick_canvas_{timestamp}.png"
)
await canvas.screenshot(path=str(canvas_screenshot_path))
print(f"Canvas screenshot saved to {canvas_screenshot_path}")
except Exception as e:
print(f"Could not take canvas screenshot: {e}")
# Keep browser open for a few seconds to see the result
print("Keeping browser open for 10 seconds for inspection...")
await page.wait_for_timeout(10000)
except Exception as e:
print(f"An error occurred during scraping: {e}", file=sys.stderr)
# Take an error screenshot for debugging
error_screenshot_path = (
SCREENSHOTS_DIR
/ f"error_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
)
try:
await page.screenshot(path=str(error_screenshot_path), full_page=True)
print(f"Error screenshot saved to {error_screenshot_path}")
except Exception:
pass
raise e
finally:
await browser.close()
async def main():
"""Main function to run the scraping operation"""
try:
await scrape_festival_stick_example()
print("FastLED FestivalStick scraping completed successfully!")
except Exception as e:
print(f"Scraping failed: {e}", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
exit_code = asyncio.run(main())
sys.exit(exit_code)