126 lines
4.9 KiB
Python
126 lines
4.9 KiB
Python
"""
|
||
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("<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())
|