Skip to content

Commit f649453

Browse files
committed
Add templating feature for datetime and counter
Signed-off-by: DL6ER <[email protected]>
1 parent e53390a commit f649453

3 files changed

Lines changed: 71 additions & 3 deletions

File tree

app/labeldesigner/label.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import logging
55
import barcode
66
from barcode.writer import ImageWriter
7+
import datetime
8+
import re
79

810
logger = logging.getLogger(__name__)
911

@@ -82,7 +84,8 @@ def __init__(
8284
border_thickness=1,
8385
border_roundness=0,
8486
border_distance=(0, 0),
85-
border_color=(0, 0, 0)):
87+
border_color=(0, 0, 0),
88+
timestamp=0):
8689
self._width = width
8790
self._height = height
8891
self.label_content = label_content
@@ -100,6 +103,8 @@ def __init__(
100103
self._border_roundness = border_roundness
101104
self._border_distance = border_distance
102105
self._border_color = border_color
106+
self._counter = 1
107+
self._timestamp = timestamp
103108

104109
@property
105110
def label_content(self):
@@ -343,6 +348,22 @@ def _draw_text(self, img = None, bboxes = [], text_offset = (0, 0)):
343348
# Fix for completely empty text
344349
if len(self.text) == 0 or len(self.text[0]['text']) == 0:
345350
self.text[0]['text'] = " "
351+
352+
# Loop over text lines and replace
353+
# {{datetime:x}} by current datetime in specified format x
354+
# {{counter}} by an incrementing counter
355+
for line in self.text:
356+
line['text'] = line['text'].replace("{{counter}}", str(self._counter))
357+
# Replace {{datetime:x}} with current datetime formatted as x
358+
def datetime_replacer(match):
359+
fmt = match.group(1)
360+
if self._timestamp > 0:
361+
now = datetime.datetime.fromtimestamp(self._timestamp)
362+
else:
363+
now = datetime.datetime.now()
364+
return now.strftime(fmt)
365+
line['text'] = re.sub(r"\{\{datetime:([^}]+)\}\}", datetime_replacer, line['text'])
366+
self._counter += 1
346367

347368
# Iterate over lines of text
348369
for i, line in enumerate(self.text):

app/labeldesigner/routes.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ def create_label_from_request(request):
188188
'image_bw_threshold': int(d.get('image_bw_threshold', 70)),
189189
'image_fit': int(d.get('image_fit', 1)) > 0,
190190
'print_color': d.get('print_color', 'black'),
191+
'timestamp': int(d.get('timestamp', 0))
191192
}
192193

193194
def get_label_dimensions(label_size):
@@ -299,5 +300,6 @@ def get_uploaded_image(image):
299300
border_thickness=context['border_thickness'],
300301
border_roundness=context['border_roundness'],
301302
border_distance=(context['border_distanceX'], context['border_distanceY']),
302-
border_color=border_color
303+
border_color=border_color,
304+
timestamp=context['timestamp']
303305
)

tests/test_labeldesigner_api.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22

3+
from datetime import datetime
34
import json
45
import sys
56
import os
@@ -11,7 +12,7 @@
1112
UPDATE_IMAGES = False
1213
EXAMPLE_FORMDATA = {
1314
'print_type': 'text',
14-
'label_size': '62',
15+
'label_size': 62,
1516
'orientation': 'standard',
1617
'print_count': '1',
1718
'cut_once': '0',
@@ -331,6 +332,50 @@ def test_image_red_and_black_fit(client):
331332
def test_image_black_fit(client):
332333
image_test(client, image_mode="black", fit=True)
333334

335+
336+
def test_generate_datetime(client):
337+
data = EXAMPLE_FORMDATA.copy()
338+
# Mock current datetime.now
339+
data['timestamp'] = int(datetime(2023, 1, 1, 12, 0, 0).timestamp())
340+
341+
data['text'] = json.dumps([
342+
{
343+
'font_family': 'DejaVu Sans',
344+
'font_style': 'Regular',
345+
'text': '{{datetime:%d.%m.%Y %H:%M:%S}}',
346+
'font_size': '30',
347+
'align': 'left'
348+
}
349+
])
350+
351+
response = client.post('/labeldesigner/api/preview', data=data)
352+
assert response.status_code == 200
353+
assert response.content_type in ['image/png', 'text/plain']
354+
355+
# Check image
356+
verify_image(response.data, 'tests/datetime.png')
357+
358+
359+
def test_generate_counter(client):
360+
data = EXAMPLE_FORMDATA.copy()
361+
data['text'] = json.dumps([
362+
{
363+
'font_family': 'DejaVu Sans',
364+
'font_style': 'Regular',
365+
'text': '{{counter}}',
366+
'font_size': '60',
367+
'align': 'left'
368+
}
369+
])
370+
371+
response = client.post('/labeldesigner/api/preview', data=data)
372+
assert response.status_code == 200
373+
assert response.content_type in ['image/png', 'text/plain']
374+
375+
# Check image
376+
verify_image(response.data, 'tests/counter.png')
377+
378+
334379
# We cannot test the print functionality without a physical printer
335380
# def test_print_label(client):
336381
# data = {

0 commit comments

Comments
 (0)