105 lines
3.0 KiB
Python
105 lines
3.0 KiB
Python
"""
|
|
Stáhne 10 puzzle z MySQL (tabulka sudoku_killer), ořízne ray-cast metodou
|
|
a uloží do Testy/verify/ pro vizuální verifikaci.
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
import fitz
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent / "Knihovny"))
|
|
from mysql_db import connect_mysql
|
|
|
|
import pymysql.cursors
|
|
|
|
sys.stdout.reconfigure(encoding="utf-8")
|
|
sys.stderr.reconfigure(encoding="utf-8")
|
|
|
|
OUT_DIR = Path(__file__).parent / "verify"
|
|
OUT_DIR.mkdir(exist_ok=True)
|
|
|
|
MARGIN = 2 # pt — minimální rámeček
|
|
|
|
|
|
def crop_raycast(pdf_bytes: bytes) -> bytes:
|
|
doc = fitz.open(stream=pdf_bytes, filetype="pdf")
|
|
page = doc[0]
|
|
paths = page.get_drawings()
|
|
|
|
ph = page.mediabox.height
|
|
y_mid = ph / 2
|
|
|
|
hit_h = [(p["rect"], p.get("width") or 0) for p in paths
|
|
if p["rect"].y0 <= y_mid <= p["rect"].y1]
|
|
if not hit_h:
|
|
raise ValueError("Horizontální paprsek nenašel žádné kresby")
|
|
|
|
rects = [r for r, _ in hit_h]
|
|
x_left = min(r.x0 for r in rects)
|
|
x_right = max(r.x1 for r in rects)
|
|
top_cut = min(r.y0 for r in rects)
|
|
bot_cut = max(r.y1 for r in rects)
|
|
|
|
# lineWidth svislých okrajových čar — souřadnice jsou středy, ne vizuální okraje
|
|
lw_left = next((lw for r, lw in hit_h if r.x0 == x_left), 0)
|
|
lw_right = next((lw for r, lw in hit_h if r.x1 == x_right), 0)
|
|
|
|
vis_x_left = x_left - lw_left / 2
|
|
vis_x_right = x_right + lw_right / 2
|
|
# top_cut / bot_cut jsou již vnější vizuální hrany (shodují se s okrajem horizontálních čar)
|
|
|
|
clip = fitz.Rect(
|
|
vis_x_left - MARGIN,
|
|
top_cut - MARGIN,
|
|
vis_x_right + MARGIN,
|
|
bot_cut + MARGIN,
|
|
)
|
|
|
|
doc_new = fitz.open()
|
|
p = doc_new.new_page(width=clip.width, height=clip.height)
|
|
p.show_pdf_page(fitz.Rect(0, 0, clip.width, clip.height), doc, 0, clip=clip)
|
|
|
|
out = doc_new.tobytes()
|
|
doc.close()
|
|
doc_new.close()
|
|
return out
|
|
|
|
|
|
def main():
|
|
import pymysql.cursors
|
|
conn = connect_mysql(database="puzzle", cursorclass=pymysql.cursors.DictCursor)
|
|
cursor = conn.cursor()
|
|
|
|
cursor.execute("""
|
|
SELECT puzzle_number, puzzle_date, difficulty, file_puzzle
|
|
FROM sudoku_killer
|
|
WHERE file_puzzle IS NOT NULL
|
|
ORDER BY puzzle_number
|
|
LIMIT 10
|
|
""")
|
|
rows = cursor.fetchall()
|
|
cursor.close()
|
|
conn.close()
|
|
|
|
print(f"Staženo {len(rows)} záznamů z DB.")
|
|
|
|
for row in rows:
|
|
num = row["puzzle_number"]
|
|
date = row["puzzle_date"]
|
|
diff = row["difficulty"]
|
|
pdf_bytes = bytes(row["file_puzzle"])
|
|
|
|
try:
|
|
cropped = crop_raycast(pdf_bytes)
|
|
out_path = OUT_DIR / f"{date} Puzzle SudokuKiller {num} [diff {diff}] cropped.pdf"
|
|
out_path.write_bytes(cropped)
|
|
print(f" OK #{num} → {out_path.name}")
|
|
except Exception as e:
|
|
print(f" CHYBA #{num}: {e}", file=sys.stderr)
|
|
|
|
print(f"\nHotovo. Soubory v: {OUT_DIR}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|