Merge pull request 'refactor' (#1) from gomelva/ptouch-print-labels:refactor into main

Reviewed-on: polkovnikovaav/ptouch-print-labels#1
This commit is contained in:
Анна Полковникова 2024-06-03 11:01:38 +03:00
commit a57b7f1ea2
2 changed files with 111 additions and 53 deletions

View File

@ -2,9 +2,17 @@
## Использование
```python3 barcodegen.py КОД "Текст"```
либо
```python3 barcodegen.py -i```
для печати нескольких наклеек за раз.
```python3 barcodegen.py ТИП_УСТРОЙСТВА/КОД "Текст"```
Код должен состоять из 12 цифр.
Код должен состоять из 13 цифр.
Тип устройства может быть одним из следующих:
- `comp` - инвентарный номер для компьютера
- `mon` - инвентарный номер для монитора
- `net` - инвентарный номер для сетевого оборудования
- `token` - инвентарный номер для токена
- `print` - инвентарный номер для принтера/МФУ
- `flash` - инвентарный номер для флешки
- `hid` - инвентарный номер для HID устройств
- `ups` - инвентарный номер для UPS устройств
- `other` - инвентарный номер для других устройств

View File

@ -1,56 +1,106 @@
import sys,os
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
from barcode.errors import NumberOfDigitsError, IllegalCharacterError
from PIL import Image, ImageOps, ImageDraw, ImageFont, ImageColor
from PIL.BdfFontFile import BdfFontFile
class ImageWitoutTextWriter(ImageWriter):
def _paint_text(self, xpos, ypos):
pass
PRODUCT_TYPES = {
"comp": ("21", "инвентарный номер для компьютера"),
"mon": ("22", "инвентарный номер для монитора"),
"net": ("23", "инвентарный номер для сетевого оборудования"),
"token": ("24", "инвентарный номер для токена"),
"print": ("25", "инвентарный номер для принтера/МФУ"),
"flash": ("26", "инвентарный номер для флешки"),
"hid": ("27", "инвентарный номер для HID устройств"),
"ups": ("28", "инвентарный номер для UPS устройств"),
"other": ("29", "инвентарный номер для других устройств"),
}
def create_code_png(n, code, text):
my_code = EAN13(code, writer=ImageWitoutTextWriter())
BARCODES_PATH = pathlib.Path().absolute() / "barcodes"
my_code.save("code" + str(n), {"module_height":11.0,"module_width":0.3,"dpi":169, "font_size":0, "text_distance":1})
image_file = Image.open("code{}.png".format(str(n)))
image_file = image_file.convert('1', dither=Image.Dither.NONE)
img=ImageOps.expand(image_file, border=17, fill=1)
draw = ImageDraw.Draw(img)
dst = "terminus.pil"
#with open("/home/applekeeper_cat/Загрузки/Terminus/ter-u16n.bdf", "rb") as f:
# bdf = BdfFontFile(f)
# bdf.save(dst)
font = ImageFont.load(dst)
draw.text((10,3), text, fill="black", font=font)
draw.text((100,100), my_code.get_fullcode(), fill="black", font=font)
img.save('code{}.png'.format(str(n)))
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]))
code = sys.argv[1]
try:
text = sys.argv[2]
except:
pass
n = 1
if(code == "i"):
while(True):
try:
code = input("Код (q для печати/выхода): ")
if(code == "q"):
com_str = "ptouch-print "
for i in range(1, n):
com_str += "--image \"code" + str(i) + ".png\" --pad 5 "
os.system(com_str)
os.system("rm -f code*.png")
break
text = input("Текст: ")
create_code_png(n, code, text)
n+=1
except (NumberOfDigitsError, IllegalCharacterError):
print("Код введен неправильно.")
else:
create_code_png(1, code, text)
os.system("ptouch-print --image \"code1.png\"")
os.system("rm -f code1.png")
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()