From 1dcfe7f74259e5433837638554c50f382194ff7c Mon Sep 17 00:00:00 2001 From: zman Date: Mon, 7 Apr 2025 14:35:09 -0400 Subject: [PATCH] first commit --- Dockerfile | 13 +++++ app.py | 123 +++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 18 +++++++ 3 files changed, 154 insertions(+) create mode 100644 Dockerfile create mode 100644 app.py create mode 100644 requirements.txt diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..991e310 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.13-slim + +WORKDIR /app + +COPY requirements.txt . + +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +EXPOSE 8000 + +CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..733b208 --- /dev/null +++ b/app.py @@ -0,0 +1,123 @@ +from flask import Flask, request, jsonify +import os +import threading +import queue +import pdf2image +from brother_ql.conversion import convert +from brother_ql.backends.helpers import send +from brother_ql.raster import BrotherQLRaster +from PIL import Image +import mimetypes + +app = Flask(__name__) + +# Create a queue to hold the files for processing +file_queue = queue.Queue() + +# Directory to save uploaded files (you can modify this path) +UPLOAD_FOLDER = './uploads' +os.makedirs(UPLOAD_FOLDER, exist_ok=True) + +# Printer configuration +printer_model = "QL-1100" +backend = 'pyusb' +printer = 'usb://0x04f9:0x20a7' + +# Convert PDF to image +def convert_pdf_to_image(pdf_path): + """Converts a PDF to a PIL Image""" + try: + # Convert PDF to image (get the first page) + images = pdf2image.convert_from_path(pdf_path) + if images: + return images[0] # We will only print the first page for now + return None + except Exception as e: + print(f"Error converting PDF: {str(e)}") + return None + +# Function to print address labels +def print_address_label(pdf_path): + try: + # Convert PDF to image + image = convert_pdf_to_image(pdf_path) + if not image: + raise Exception("Failed to create label images") + + target_width = 1164 + target_height = 1660 + image = image.convert("RGB") + image = image.resize((target_width, target_height), Image.LANCZOS) + + qlr = BrotherQLRaster(printer_model) + qlr.exception_on_warning = True + + print("Converting image to printer instructions...") + instructions = convert( + qlr=qlr, + images=[image], # Pass as a list with the single image + label='102x152', + threshold=70.0, + dither=False, + compress=False, + red=False, + dpi_600=False, + hq=True, + cut=True + ) + + print("Sending to printer...") + send( + instructions=instructions, + printer_identifier=printer, + backend_identifier=backend, + blocking=True + ) + print("Print job sent successfully") + + except Exception as e: + print(f"Error during printing: {str(e)}") + +# Worker thread that processes files from the queue +def process_queue(): + while True: + # Wait until a file is available in the queue + file_path = file_queue.get() + if file_path is None: # Shutdown signal + break + # Process the file (convert and print) + print_address_label(file_path) + # Signal that the task is done + file_queue.task_done() + +# Start the worker thread +thread = threading.Thread(target=process_queue, daemon=True) +thread.start() + +@app.route('/upload', methods=['POST']) +def upload_file(): + # Check if a file is part of the request + if 'file' not in request.files: + return jsonify({'error': 'No file part'}), 400 + + file = request.files['file'] + + if file.filename == '': + return jsonify({'error': 'No selected file'}), 400 + + # Check file type (ensure it's a PDF) + mime_type, _ = mimetypes.guess_type(file.filename) + if mime_type != 'application/pdf': + return jsonify({'error': 'Only PDF files are allowed'}), 400 + + # Save the file to the uploads folder + file_path = os.path.join(UPLOAD_FOLDER, file.filename) + file.save(file_path) + + # Add the file path to the queue for processing + file_queue.put(file_path) + + return jsonify({'message': f'File {file.filename} uploaded and queued for processing'}), 200 + +if __name__ == '__main__': + app.run(debug=True) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..d930f1e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,18 @@ +attrs==25.3.0 +blinker==1.9.0 +brother_ql_next==0.11.3 +click==8.1.8 +Flask==3.1.0 +future==1.0.0 +h11==0.14.0 +itsdangerous==2.2.0 +Jinja2==3.1.6 +jsons==1.6.3 +MarkupSafe==3.0.2 +packbits==0.6 +pdf2image==1.17.0 +pillow==11.1.0 +pyusb==1.3.1 +typish==1.9.3 +uvicorn==0.34.0 +Werkzeug==3.1.3