-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlabelprinter.py
83 lines (66 loc) · 3.03 KB
/
labelprinter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import argparse
import os
import csv
import xml.etree.ElementTree as ET
import time
from typing import Dict, Tuple
import win32com.shell.shell as shell # type:ignore
import win32event # type:ignore
from labelcore import SvgTemplate, InkscapeSubprocess
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Print individual labels (eg, with a thermal printer) from SVG templates.')
parser.add_argument('printer', type=str,
help='Printer name to print to.',
default="ZDesigner GX430t")
parser.add_argument('template', type=str,
help='Input SVG template file.')
parser.add_argument('csv', type=str,
help='Input CSV data file to monitor for changes on.')
# TODO: support user-defineable generated filename
args = parser.parse_args()
template = SvgTemplate(args.template)
def canonicalize_row_dict(row_dict: Dict[str, str]) -> Tuple[Tuple[str, str], ...]:
# Discard empty cells - to not print everything is a new row is added
return tuple(sorted([(k, v) for (k, v) in row_dict.items() if v]))
inkscape = InkscapeSubprocess()
last_mod_time = None # None means initial read, and to not print anything
last_seen_set = set()
while True:
if not os.path.isfile(args.csv):
print("Warning: file not found")
continue
try:
mod_time = os.path.getmtime(args.csv)
except FileNotFoundError:
continue # sometimes the file temporarily disappears, just ignore it
if mod_time == last_mod_time: # file unchanged, ignore
continue
time.sleep(0.25) # TODO HACK: wait for the file the stabilize
with open(args.csv, 'r') as csvfile:
print("File modification detected")
reader = csv.DictReader(csvfile)
seen_set = set()
all_row_dicts = list(reader)
for row_index, row_dict in enumerate(all_row_dicts):
row_set = canonicalize_row_dict(row_dict)
seen_set.add(row_set)
if row_set not in last_seen_set and last_mod_time is not None:
print(f"Printing: {row_dict}")
label = template._create_instance()
instance = template.apply_instance(row_dict, all_row_dicts, row_index)
label.append(instance)
root = ET.ElementTree(label)
root.write("temp.svg")
if os.path.exists('temp.pdf'):
os.remove('temp.pdf')
inkscape.convert('temp.svg', 'temp.pdf')
while not os.path.exists('temp.pdf'): # wait for file creation
time.sleep(0.25)
# wait for the print to execute, so we can then overwrite the file
# https://stackoverflow.com/questions/18025882/how-to-determine-if-win32api-shellexecute-was-successful-using-hinstance
pinfo = shell.ShellExecuteEx(fMask=256+64, lpVerb="print", lpFile='temp.pdf',
lpParameters=f'/d:{args.printer} .')
win32event.WaitForSingleObject(pinfo['hProcess'], win32event.INFINITE)
last_mod_time = mod_time
last_seen_set = seen_set
time.sleep(0.25)