107 lines
3.5 KiB
Python
Executable File
107 lines
3.5 KiB
Python
Executable File
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()
|