diff --git a/app/services/box.py b/app/services/box.py index d21de14..b8bd4bc 100644 --- a/app/services/box.py +++ b/app/services/box.py @@ -86,6 +86,7 @@ class BoxService: type='box', product_line='mtg' ) + self.db.add(product) box = Box( product_id=product.id, type=create_box_data.type, @@ -93,7 +94,6 @@ class BoxService: sku=create_box_data.sku, num_cards_expected=create_box_data.num_cards_expected ) - self.db.add(product) self.db.add(box) return box, True diff --git a/app/services/print.py b/app/services/print.py new file mode 100644 index 0000000..eb0eb81 --- /dev/null +++ b/app/services/print.py @@ -0,0 +1,168 @@ +from brother_ql.conversion import convert +from brother_ql.backends.helpers import send +from brother_ql.raster import BrotherQLRaster +from PIL import Image, ImageDraw, ImageFont +import platform +import pandas as pd +from time import sleep +import pdf2image +import io + +# Printer settings +printer_model = "QL-1100" +backend = 'pyusb' # Changed from network to USB +printer = 'usb://0x04f9:0x20a7' + +def convert_pdf_to_image(pdf_path): + """Converts a PDF to PIL Image""" + try: + # Convert PDF to image + images = pdf2image.convert_from_path(pdf_path) + if images: + return images[0] # Return first page + return None + except Exception as e: + print(f"Error converting PDF: {str(e)}") + return None + +def create_address_label(input_data, font_size=30, is_pdf=False): + """Creates and returns the label image without printing""" + if is_pdf: + if isinstance(input_data, str): # If path is provided + return convert_pdf_to_image(input_data) + else: # If PIL Image is provided + return input_data + + # Regular text-based label creation + label_width = 991 + label_height = 306 + + image = Image.new('L', (label_width, label_height), 'white') + draw = ImageDraw.Draw(image) + + # Font selection based on OS + if platform.system() == 'Windows': + font = ImageFont.truetype("C:\\Windows\\Fonts\\arial.ttf", size=font_size) + elif platform.system() == 'Darwin': + font = ImageFont.truetype("/Library/Fonts/Arial.ttf", size=font_size) + + margin = 20 + lines = input_data.split('\n') + line_height = font_size + 5 + total_height = line_height * len(lines) + start_y = (label_height - total_height) // 2 + + for i, line in enumerate(lines): + y = start_y + (i * line_height) + draw.text((margin, y), line, font=font, fill='black') + + return image + +def preview_label(input_data, font_size=30, is_pdf=False): + """Creates and displays the label preview""" + image = create_address_label(input_data, font_size, is_pdf) + if image: + image.show() + +def print_address_label(input_data, font_size=30, is_pdf=False, label_size='29x90'): + """Prints the label with support for both text and PDF inputs""" + try: + image = create_address_label(input_data, font_size, is_pdf) + if not image: + raise Exception("Failed to create label image") + + # For 4x6 shipping labels from Pirate Ship + if label_size == '4x6': + # Resize image to fit 4x6 format if needed + target_width = 1164 # Adjusted for 4x6 format + target_height = 1660 + 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], + label='29x90' if label_size == '29x90' else '102x152', + threshold=70.0, + dither=False, + compress=False, + red=False, + dpi_600=False, + hq=True, + #cut=True + cut=False + ) + + 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)}") + +def process_pirate_ship_pdf(pdf_path, preview=False): + """Process and print a Pirate Ship PDF shipping label""" + if preview: + preview_label(pdf_path, is_pdf=True) + else: + print_address_label(pdf_path, is_pdf=True, label_size='4x6') + +def process_tcg_shipping_export(file_path, require_input=False, font_size=60, preview=False): + # Load the CSV file, all columns are strings + df = pd.read_csv(file_path, dtype=str) + print(df.dtypes) + for i, row in df.iterrows(): + line1 = str(row['FirstName']) + ' ' + str(row['LastName']) + line2 = str(row['Address1']) + if not pd.isna(row['Address2']): + line2 += ' ' + str(row['Address2']) + line3 = str(row['City']) + ', ' + str(row['State']) + ' ' + str(row['PostalCode']) + address = f"{line1}\n{line2}\n{line3}" + if preview: + preview_label(address, font_size=font_size) + else: + print_address_label(address, font_size=font_size) + if require_input: + input("Press Enter to continue...") + else: + sleep(1) + +# Example usage +if __name__ == "__main__": + # Example for regular address label + address = """John Doe +123 Main Street +Apt 4B +City, State 12345""" + + # Example for TCG Player export + shipping_export_file = "_TCGplayer_ShippingExport_20250201_115949.csv" + + # Example for Pirate Ship PDF + pirate_ship_pdf = "C:\\Users\\joshu\\Downloads\\2025-02-10---greg-creek---9400136208070411592215.pdf" + + # Choose which type to process + label_type = input("Enter label type (1 for regular, 2 for TCG, 3 for Pirate Ship): ") + + if label_type == "1": + preview_label(address, font_size=60) + user_input = input("Press 'p' to print the label or any other key to cancel: ") + if user_input.lower() == 'p': + print_address_label(address, font_size=60) + + elif label_type == "2": + process_tcg_shipping_export(shipping_export_file, font_size=60, preview=False) + + elif label_type == "3": + process_pirate_ship_pdf(pirate_ship_pdf, preview=True) + user_input = input("Press 'p' to print the label or any other key to cancel: ") + if user_input.lower() == 'p': + process_pirate_ship_pdf(pirate_ship_pdf, preview=False) diff --git a/requests.md b/requests.md index 06983f3..715baee 100644 --- a/requests.md +++ b/requests.md @@ -6,9 +6,9 @@ curl -J -X POST http://192.168.1.41:8000/api/tcgplayer/inventory/add \ --remote-name curl -X POST http://192.168.1.41:8000/api/boxes \ --F "type=draft" \ --F "set_code=WOE" \ --F "sku=195166231631" \ +-F "type=play" \ +-F "set_code=FDN" \ +-F "sku=195166261782" \ -F "num_cards_expected=540" curl -X POST "http://192.168.1.41:8000/api/boxes/588dddad-0661-4541-a16c-beba1c564b4f/open" \