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' 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) elif platform.system() == 'Linux': font = ImageFont.truetype("/usr/share/fonts/truetype/msttcorefonts/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") if label_size == '4x6': target_width = 1164 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=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) if __name__ == "__main__": # 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": address = input("Enter the address to print: ") 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": shipping_export_file = input("Enter the path to the TCG Player shipping export CSV file: ") process_tcg_shipping_export(shipping_export_file, font_size=60, preview=False) elif label_type == "3": pirate_ship_pdf = input("Enter the path to the Pirate Ship PDF file: ") 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)