port print-web-form app to nested flask structure

Replace stub print/ app with full PDF web print service from
~/print-web-form. Adapt UPLOAD_FOLDER to use Path(__file__).parent,
add pypdf dependency, port all tests (10 passing), remove unused static/.
This commit is contained in:
Connor Rhodes 2026-04-23 20:07:07 -05:00
parent af5d3f148d
commit b0c19d5642
9 changed files with 340 additions and 0 deletions

105
print/app.py Normal file
View file

@ -0,0 +1,105 @@
import os
import subprocess
from pathlib import Path
import pypdf
from flask import Flask, flash, redirect, render_template, request, url_for
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = str(Path(__file__).parent / "uploads")
ALLOWED_EXTENSIONS = {"pdf"}
PRINTER_NAME = "HL-2270DW_series"
MAX_PAGES = 10
app = Flask(__name__)
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER
app.config["SECRET_KEY"] = os.urandom(24)
app.config["MAX_CONTENT_LENGTH"] = 16 * 1024 * 1024
def allowed_file(filename):
return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
def get_pdf_page_count(filepath):
try:
with open(filepath, "rb") as f:
reader = pypdf.PdfReader(f)
return len(reader.pages)
except Exception as e:
app.logger.error(f"Could not read PDF pages: {e}")
return None
@app.route("/", methods=["GET", "POST"])
def upload_and_print():
if request.method == "POST":
if "file" not in request.files:
flash("No file part in the request.", "error")
return redirect(request.url)
file = request.files["file"]
if file.filename == "":
flash("No file selected. Please choose a PDF to print.", "error")
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True)
filepath = os.path.join(app.config["UPLOAD_FOLDER"], filename)
file.save(filepath)
try:
page_count = get_pdf_page_count(filepath)
if page_count is None:
flash(
"Could not process the PDF file. It might be corrupt.", "error"
)
return redirect(request.url)
if page_count > MAX_PAGES:
flash(
f"Error: File has {page_count} pages. The maximum allowed is {MAX_PAGES}.",
"error",
)
return redirect(request.url)
app.logger.info(
f"Sending '{filename}' ({page_count} pages) to printer '{PRINTER_NAME}'"
)
command = ["lp", "-d", PRINTER_NAME, filepath]
result = subprocess.run(
command, capture_output=True, text=True, check=True
)
app.logger.info(f"lp command stdout: {result.stdout}")
flash(f"Success! '{filename}' has been sent to the printer.", "success")
except subprocess.CalledProcessError as e:
app.logger.error(f"Error printing file: {e}")
app.logger.error(f"lp command stderr: {e.stderr}")
flash(
"Error sending file to printer. The printer may be offline or misconfigured.",
"error",
)
except Exception as e:
app.logger.error(f"An unexpected error occurred: {e}")
flash("An unexpected server error occurred.", "error")
finally:
if os.path.exists(filepath):
os.remove(filepath)
app.logger.info(f"Cleaned up temporary file: {filepath}")
return redirect(url_for("upload_and_print"))
else:
flash("Invalid file type. Please upload a PDF file.", "error")
return redirect(request.url)
return render_template("index.html", printer_name=PRINTER_NAME, max_pages=MAX_PAGES)
if __name__ == "__main__":
app.run(host="127.0.0.1", port=57928, debug=False)