Files
ordinaceprojekt/SběrDatRůzné/DailyStr8ts/stahni_str8ts.py
T
2026-04-24 09:51:45 +02:00

126 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
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 19 — do bílých buněk piš čísla 19.
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 19 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("<head>", f'<head><base href="{base_url}">', 1)
# Načti HTML do nové stránky a ulož jako PDF
pdf_page = await context.new_page()
await pdf_page.set_content(iframe_html, wait_until="networkidle")
await pdf_page.wait_for_timeout(500)
await pdf_page.pdf(
path=str(output_path),
format="A4",
print_background=True,
margin={"top": "10mm", "bottom": "10mm", "left": "10mm", "right": "10mm"},
)
print(f"PDF uloženo: {output_path}")
await browser.close()
send_mail(
to=RECIPIENT,
subject="Posílám dnešní Str8ts puzzle v příloze",
body=EMAIL_BODY,
attachments=output_path,
)
print(f"Email odeslán na {RECIPIENT}")
if __name__ == "__main__":
asyncio.run(main())