#!/usr/bin/env python import requests from zebra import Zebra import qrcode from math import ceil, floor from PIL import Image import textwrap import argparse parser=argparse.ArgumentParser() parser.add_argument("id", help="part ID", type=int) parser.add_argument("-x", help="label width, in inches (default: 2\")", type=float) parser.add_argument("-y", help="label height, in inches (default: 1\")", type=float) parser.add_argument("-g", help="label gap, in inches (default: 0.118\")", type=float) parser.add_argument("-q", help="send to selected print queue instead of stdout") parser.add_argument("-p", help="PartDB base URL (default: https://partdb.alfter.us)") parser.add_argument("-k", help="PartDB API key (default: anonymous key for partdb.alfter.us)") parser.add_argument("-r", help="printer resolution (203 or 300; default: 203 dpi)", type=int) args=parser.parse_args() id=args.id if args.x==None: label_width=2 else: label_width=args.x if args.y==None: label_height=1 else: label_height=args.y if args.g==None: label_gap=0.118 else: label_gap=args.g if args.q==None: queue="zebra_python_unittest" else: queue=args.q if args.p==None: base_url="https://partdb.alfter.us" else: base_url=args.p if args.k==None: api_key="tcp_673fc81f0b7837ca4c029fbd6536b27742eb8b742eba27bf547c8136dc6a84f8" else: api_key=args.k if args.r==None: res=203 else: res=args.r if res!=203 and res!=300: raise ValueError("valid resolution options are 203 and 300") # width and height for built-in monospace fonts (includes whitespace) font_metrics={} font_metrics[1]=(10,14) font_metrics[2]=(12,18) font_metrics[3]=(14,22) font_metrics[4]=(16,26) font_metrics[5]=(34,50) # make substitutions for characters not in CP437 def subst(s): repl={} repl["®"]="(R)" repl["©"]="(C)" repl["Ω"]="Ω" # U+2126 -> U+03A9, which is in CP437 repl["±"]="+/-" out="" for i in s: try: out=out+repl[i] except: out=out+i return out # filter out characters not in selected codepage # (printer uses CP437) def filter(s, cp): out="" for i in s: try: i.encode(cp) out=out+i except: pass return out # handle escape characters in strings to be printed def esc(s): out="" for i in s: if i=="\"": out=out+"\\\"" elif i=="\\": out=out+"\\\\" else: out=out+i return out # render a line of text at coordinates # return coordinates of next line def textline(s, loc, fontnum): z.output(f"A{loc[0]},{loc[1]},0,{fontnum},1,1,N,\"{esc(filter(subst(s), "cp437"))}\"\n") return (loc[0], loc[1]+font_metrics[fontnum][1]) # wrap text in a bounding box at coordinates # return coordinates of next line and any unused text def textbox(s, loc, bbox, fontnum): wrapped=textwrap.wrap(filter(subst(s), "cp437"), width=floor(bbox[0]/font_metrics[fontnum][0])) line=0 while line*font_metrics[fontnum][1]