import argparse import pathlib import subprocess import sys import time from textwrap import dedent from PIL import Image, ImageOps, ImageDraw, ImageFont from barcode import EAN13 from barcode.writer import ImageWriter PRODUCT_TYPES = { "comp": ("21", "инвентарный номер для компьютера"), "mon": ("22", "инвентарный номер для монитора"), "net": ("23", "инвентарный номер для сетевого оборудования"), "token": ("24", "инвентарный номер для токена"), "print": ("25", "инвентарный номер для принтера/МФУ"), "flash": ("26", "инвентарный номер для флешки"), "hid": ("27", "инвентарный номер для HID устройств"), "ups": ("28", "инвентарный номер для UPS устройств"), "other": ("29", "инвентарный номер для других устройств"), } BARCODES_PATH = pathlib.Path().absolute() / "barcodes" def gen_ean13(ptype: str): product_code = PRODUCT_TYPES[ptype][0] digits = product_code + str(round(time.time())) digits = [int(i) for i in digits] checksum = (10 - (sum(digits[1::2]) * 3 + sum(digits[::2])) % 10) % 10 return "".join(str(i) for i in (digits + [checksum])) def create_code_png(filename: str | pathlib.Path, code, text): if not filename.parent.exists(): filename.parent.mkdir(parents=True) my_code = EAN13(code, writer=ImageWriter()) image = my_code.render( writer_options={ "module_height": 11.0, "module_width": 0.3, "dpi": 169, "font_size": 0, "text_distance": 1, "write_text": None, } ) image = image.convert("1", dither=Image.Dither.NONE) image = ImageOps.expand(image, border=17, fill=1) draw = ImageDraw.Draw(image) dst = "terminus.pil" font = ImageFont.load(dst) text_length = draw.textlength(text, font=font) code_text_length = draw.textlength(code, font=font) draw.text(((image.width - text_length) / 2, 3), text, fill="black", font=font) draw.text( ((image.width - code_text_length) / 2, 100), code, fill="black", font=font, ) image.save(filename) def parse_args(): help_for_text = """\ code is must be a 13 digit code or one of the following: """ help_for_text = dedent(help_for_text) + "\n".join( f"{code} - {desc[1]}" for code, desc in PRODUCT_TYPES.items() ) parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) parser.add_argument("code", type=str, help=help_for_text) parser.add_argument( "text", type=str, nargs="?", default="", help="Description for barcode" ) parser.add_argument("--print", action=argparse.BooleanOptionalAction, default=True) return parser.parse_args() def main(): args = parse_args() if args.code not in PRODUCT_TYPES: if args.code.isdigit() and len(args.code) == 13: barcode = args.code else: print("Invalid args") sys.exit(1) else: barcode = gen_ean13(args.code) filename = BARCODES_PATH / f"{barcode}.png" print(f"Generated code: {barcode}") create_code_png(filename, barcode, args.text) if args.print: subprocess.run(["ptouch-print", "--image", filename]) if __name__ == "__main__": main()