diff --git a/paperless_asn_qr_codes/avery_labels.py b/paperless_asn_qr_codes/avery_labels.py index 8ff7d1b..9f3b7fe 100644 --- a/paperless_asn_qr_codes/avery_labels.py +++ b/paperless_asn_qr_codes/avery_labels.py @@ -18,9 +18,11 @@ from reportlab.lib.units import mm # (with X,Y=0,0 at the lower right) or a string "form" name of a form # previously created with canv.beginForm(). + @dataclass class LabelInfo: """Class for modeling label info""" + _: KW_ONLY labels_horizontal: int labels_vertical: int @@ -29,30 +31,76 @@ class LabelInfo: margin: tuple[float, float] pagesize: tuple[float, float] + labelInfo: dict[str, LabelInfo] = { - "averyL4731": LabelInfo(labels_horizontal= 7, labels_vertical= 27, label_size= (25.4*mm, 10*mm), gutter_size= (2.5*mm, 0), margin= (9*mm, 13.5*mm), pagesize= A4), + "averyL4731": LabelInfo( + labels_horizontal=7, + labels_vertical=27, + label_size=(25.4 * mm, 10 * mm), + gutter_size=(2.5 * mm, 0), + margin=(9 * mm, 13.5 * mm), + pagesize=A4, + ), # 2.6 x 1 address labels - "avery5160": LabelInfo(labels_horizontal= 3, labels_vertical= 10, label_size= (187, 72), gutter_size= (11, 0), margin= (14, 36), pagesize= LETTER), - "avery5161": LabelInfo(labels_horizontal= 2, labels_vertical= 10, label_size= (288, 72), gutter_size= (0, 0), margin= (18, 36), pagesize= LETTER), + "avery5160": LabelInfo( + labels_horizontal=3, + labels_vertical=10, + label_size=(187, 72), + gutter_size=(11, 0), + margin=(14, 36), + pagesize=LETTER, + ), + "avery5161": LabelInfo( + labels_horizontal=2, + labels_vertical=10, + label_size=(288, 72), + gutter_size=(0, 0), + margin=(18, 36), + pagesize=LETTER, + ), # 4 x 2 address labels - "avery5163": LabelInfo(labels_horizontal= 2, labels_vertical= 5, label_size= (288, 144), gutter_size= (0, 0), margin= (18, 36), pagesize= LETTER), + "avery5163": LabelInfo( + labels_horizontal=2, + labels_vertical=5, + label_size=(288, 144), + gutter_size=(0, 0), + margin=(18, 36), + pagesize=LETTER, + ), # 1.75 x 0.5 return address labels - "avery5167": LabelInfo(labels_horizontal= 4, labels_vertical= 20, label_size= (126, 36), gutter_size= (0, 0), margin= (54, 36), pagesize= LETTER), + "avery5167": LabelInfo( + labels_horizontal=4, + labels_vertical=20, + label_size=(126, 36), + gutter_size=(0, 0), + margin=(54, 36), + pagesize=LETTER, + ), # 3.5 x 2 business cards - "avery5371": LabelInfo(labels_horizontal= 2, labels_vertical= 5, label_size= (252, 144), gutter_size= (0, 0), margin= (54, 36), pagesize= LETTER), + "avery5371": LabelInfo( + labels_horizontal=2, + labels_vertical=5, + label_size=(252, 144), + gutter_size=(0, 0), + margin=(54, 36), + pagesize=LETTER, + ), } RETURN_ADDRESS = 5167 BUSINESS_CARDS = 5371 -class AveryLabel: +class AveryLabel: def __init__(self, label, **kwargs): data = labelInfo[label] self.across = data.labels_horizontal self.down = data.labels_vertical self.size = data.label_size - self.labelsep = self.size[0]+data.gutter_size[0], self.size[1]+data.gutter_size[1] + self.labelsep = ( + self.size[0] + data.gutter_size[0], + self.size[1] + data.gutter_size[1], + ) self.margins = data.margin self.topDown = True self.debug = False @@ -61,9 +109,9 @@ class AveryLabel: self.__dict__.update(kwargs) def open(self, filename): - self.canvas = canvas.Canvas( filename, pagesize=self.pagesize ) + self.canvas = canvas.Canvas(filename, pagesize=self.pagesize) if self.debug: - self.canvas.setPageCompression( 0 ) + self.canvas.setPageCompression(0) self.canvas.setLineJoin(1) self.canvas.setLineCap(1) @@ -72,13 +120,13 @@ class AveryLabel: x = self.position if y == None: if self.topDown: - x,y = divmod(x, self.down) + x, y = divmod(x, self.down) else: - y,x = divmod(x, self.across) + y, x = divmod(x, self.across) return ( - self.margins[0]+x*self.labelsep[0], - self.pagesize[1] - self.margins[1] - (y+1)*self.labelsep[1] + self.margins[0] + x * self.labelsep[0], + self.pagesize[1] - self.margins[1] - (y + 1) * self.labelsep[1], ) def advance(self): @@ -100,33 +148,33 @@ class AveryLabel: # Or, pass a callable and an iterator. We'll do one label # per iteration of the iterator. - def render( self, thing, count, *args ): + def render(self, thing, count, *args): assert callable(thing) or isinstance(thing, str) if isinstance(count, Iterator): - return self.render_iterator( thing, count ) + return self.render_iterator(thing, count) canv = self.canvas for i in range(count): canv.saveState() - canv.translate( *self.topLeft() ) + canv.translate(*self.topLeft()) if self.debug: - canv.setLineWidth( 0.25 ) - canv.rect( 0, 0, self.size[0], self.size[1] ) + canv.setLineWidth(0.25) + canv.rect(0, 0, self.size[0], self.size[1]) if callable(thing): - thing( canv, self.size[0], self.size[1], *args ) + thing(canv, self.size[0], self.size[1], *args) elif isinstance(thing, str): canv.doForm(thing) canv.restoreState() self.advance() - def render_iterator( self, func, iterator ): + def render_iterator(self, func, iterator): canv = self.canvas for chunk in iterator: canv.saveState() - canv.translate( *self.topLeft() ) + canv.translate(*self.topLeft()) if self.debug: - canv.setLineWidth( 0.25 ) - canv.rect( 0, 0, self.size[0], self.size[1] ) - func( canv, self.size[0], self.size[1], chunk ) + canv.setLineWidth(0.25) + canv.rect(0, 0, self.size[0], self.size[1]) + func(canv, self.size[0], self.size[1], chunk) canv.restoreState() self.advance() diff --git a/paperless_asn_qr_codes/main.py b/paperless_asn_qr_codes/main.py index 8c57687..c97c9ef 100644 --- a/paperless_asn_qr_codes/main.py +++ b/paperless_asn_qr_codes/main.py @@ -4,29 +4,37 @@ from reportlab.lib.units import mm, cm from reportlab_qrcode import QRCodeImage from paperless_asn_qr_codes import avery_labels -def render(c,x,y): + +def render(c, x, y): global startASN barcode_value = f"ASN{startASN:07d}" startASN = startASN + 1 - - qr = QRCodeImage(barcode_value, size=y*0.9) - qr.drawOn(c,1*mm,y*0.05) - c.setFont("Helvetica", 2*mm) - c.drawString(y, (y-2*mm)/2, barcode_value) + + qr = QRCodeImage(barcode_value, size=y * 0.9) + qr.drawOn(c, 1 * mm, y * 0.05) + c.setFont("Helvetica", 2 * mm) + c.drawString(y, (y - 2 * mm) / 2, barcode_value) + def main(): parser = argparse.ArgumentParser( - prog='paperless-asn-qr-codes', - description='CLI Tool for generating paperless ASN labels with QR codes') - parser.add_argument('start_asn') - parser.add_argument('output_file') - parser.add_argument('--format', choices=avery_labels.labelInfo.keys(), default="averyL4731") + prog="paperless-asn-qr-codes", + description="CLI Tool for generating paperless ASN labels with QR codes", + ) + parser.add_argument("start_asn") + parser.add_argument("output_file") + parser.add_argument( + "--format", choices=avery_labels.labelInfo.keys(), default="averyL4731" + ) args = parser.parse_args() global startASN startASN = int(args.start_asn) label = avery_labels.AveryLabel(args.format) label.open(args.output_file) # by default, we render all labels possible on a single sheet - count = avery_labels.labelInfo[args.format].labels_horizontal*avery_labels.labelInfo[args.format].labels_vertical - label.render(render, count ) + count = ( + avery_labels.labelInfo[args.format].labels_horizontal + * avery_labels.labelInfo[args.format].labels_vertical + ) + label.render(render, count) label.close()