""" Stáhne daily Str8ts puzzle jako PDF ze solitaire.org a uloží do stejné složky. Název souboru: yyyy-mm-dd Daily Str8ts puzzle.pdf """ import asyncio import sys sys.stdout.reconfigure(encoding="utf-8") sys.stderr.reconfigure(encoding="utf-8") from datetime import date from pathlib import Path from playwright.async_api import async_playwright sys.path.insert(0, str(Path(__file__).parent.parent.parent / "Knihovny")) from EmailMessagingGraph import send_mail from najdi_dropbox import get_dropbox_root OUTPUT_DIR = Path(get_dropbox_root()) / "!!!Days" / "Downloads Z230" URL = "https://www.solitaire.org/daily-str8ts/" RECIPIENT = ["vladimir.buzalka@buzalka.cz", "alica.buzalkova@buzalka.cz"] EMAIL_BODY = """Str8ts — pravidla Hrací pole 9×9, každá buňka je buď bílá nebo černá. 1. Číslice 1–9 — do bílých buněk piš čísla 1–9. 2. Žádné opakování v řádku/sloupci — stejné číslo se nesmí opakovat v celém řádku ani sloupci (jako Sudoku). 3. Straights (sekvence) — bílé buňky oddělené černými tvoří skupiny. Čísla v každé skupině musí tvořit sadu po sobě jdoucích čísel (v libovolném pořadí). Např. skupinka tří buněk může obsahovat {3,4,5} nebo {7,8,9}, ale ne {1,3,5}. 4. Délka sekvence — skupina o délce n musí obsahovat právě n různých čísel jdoucích za sebou. 5. Černé buňky s číslem — někdy mají předvyplněné číslo jako nápovědu; toto číslo se nepočítá do sekvencí, ale blokuje opakování v řádku/sloupci. Rozdíl od Sudoku: nemusíš vyplnit 1–9 do každé skupiny — jen zajistit, že čísla v každé skupině tvoří „straight" (jako v pokeru). """ async def main(): today = date.today().strftime("%Y-%m-%d") output_path = OUTPUT_DIR / f"{today} Daily Str8ts puzzle.pdf" if output_path.exists(): print(f"Soubor již existuje: {output_path}") return async with async_playwright() as p: browser = await p.chromium.launch(headless=True) context = await browser.new_context( viewport={"width": 1280, "height": 900}, ) # Krok 1: načti hlavní stránku a zjisti URL iframu s hrou page = await context.new_page() print(f"Načítám {URL} ...") await page.goto(URL, wait_until="networkidle", timeout=60_000) game_url = None for frame in page.frames: if frame.url != page.url and frame.url.strip() not in ("", "about:blank"): game_url = frame.url print(f" Nalezen iframe: {game_url}") break if not game_url: # Zkus najít iframe src přímo v DOM iframe_src = await page.get_attribute("iframe", "src") if iframe_src: game_url = iframe_src if iframe_src.startswith("http") else f"https://www.solitaire.org{iframe_src}" print(f" Iframe src z DOM: {game_url}") await page.close() # Krok 2: otevři URL hry game_page = await context.new_page() target_url = game_url if game_url else URL print(f"Načítám hru přímo: {target_url} ...") await game_page.goto(target_url, wait_until="networkidle", timeout=60_000) # Game.printDaily() vytvoří iframe #printFrame a zapíše do něj puzzle HTML await game_page.evaluate("Game.printDaily()") await game_page.wait_for_timeout(1_000) # Přečti HTML přímo z iframu iframe_html = await game_page.evaluate("""() => { const iframe = document.getElementById('printFrame'); if (!iframe) return null; try { return iframe.contentDocument.documentElement.outerHTML; } catch(e) { return null; } }""") if not iframe_html: raise RuntimeError("Nepodařilo se získat HTML z #printFrame") print(f" iframe HTML zachycen ({len(iframe_html)} znaků), ukládám PDF...") # Přidej base URL aby se načetly obrázky (img/black.png, img/title.jpg) base_url = "https://www.solitaire.org/daily-str8ts/" iframe_html = iframe_html.replace("
", f'