Skip to content

Commit 77bfa2b

Browse files
authored
Merge pull request pklaus#9 from DL6ER/more-tests
Increase test coverage
2 parents 3bb89e3 + ae90e2c commit 77bfa2b

15 files changed

Lines changed: 385 additions & 50 deletions

app/labeldesigner/label.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -392,10 +392,6 @@ def _draw_text(self, img = None, bboxes = [], text_offset = (0, 0)):
392392
draw = ImageDraw.Draw(img)
393393
y = 0
394394

395-
# Fix for completely empty text
396-
if len(self.text) == 0 or len(self.text[0]['text']) == 0:
397-
self.text[0]['text'] = " "
398-
399395
# Iterate over lines of text
400396
for i, line in enumerate(self.text):
401397
color = self._fore_color
@@ -478,6 +474,9 @@ def _draw_text(self, img = None, bboxes = [], text_offset = (0, 0)):
478474
return bboxes
479475

480476
def _compute_bbox(self, bboxes):
477+
# Edge case: No text
478+
if not bboxes:
479+
return (0, 0, 0, 0)
481480
# Iterate over right margins of multiple text lines and find the maximum
482481
# width needed to fit all lines of text
483482
max_width = max(bbox[0][2] for bbox in bboxes)

app/labeldesigner/routes.py

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,22 @@ def get_barcodes():
5858
}
5959

6060

61-
@bp.route('/api/preview', methods=['POST', 'GET'])
62-
def get_preview_from_image():
61+
@bp.route('/api/preview', methods=['POST'])
62+
def preview_from_image():
6363
# Set log level if provided
6464
log_level = request.values.get('log_level')
6565
if log_level:
6666
level = getattr(logging, log_level.upper(), None)
6767
if isinstance(level, int):
6868
current_app.logger.setLevel(level)
69-
label = create_label_from_request(request)
7069
try:
70+
label = create_label_from_request(request)
7171
im = label.generate(rotate=True)
7272
except Exception as e:
7373
current_app.logger.exception(e)
74-
# Generate error 400 response
75-
return make_response(jsonify({'message': str(e)}), 400)
74+
error = 413 if "too long" in str(e) else 400
75+
# Generate error response
76+
return make_response(jsonify({'message': str(e)}), error)
7677

7778
return_format = request.values.get('return_format', 'png')
7879

@@ -190,45 +191,42 @@ def get_label_dimensions(label_size):
190191
except KeyError:
191192
raise LookupError("Unknown label_size")
192193

193-
def get_font_path(font_family_name, font_style_name):
194+
def get_font_path(line: dict):
194195
try:
195-
if font_family_name is None or font_style_name is None:
196-
font_family_name = current_app.config['LABEL_DEFAULT_FONT_FAMILY']
197-
font_style_name = current_app.config['LABEL_DEFAULT_FONT_STYLE']
196+
font_family_name = line.get('font_family')
197+
font_style_name = line.get('font_style')
198198
if font_family_name not in FONTS.fonts:
199199
raise LookupError("Unknown font family: %s" % font_family_name)
200200
if font_style_name not in FONTS.fonts[font_family_name]:
201201
font_style_name = current_app.config['LABEL_DEFAULT_FONT_STYLE']
202202
if font_style_name not in FONTS.fonts[font_family_name]:
203-
raise LookupError("Unknown font style: %s for font %s" % (font_style_name, font_family_name))
203+
raise LookupError("Unknown font style: %s for font %s" %
204+
(font_style_name, font_family_name))
204205
font_path = FONTS.fonts[font_family_name][font_style_name]
205206
except KeyError:
206207
raise LookupError("Couln't find the font & style")
207208
return font_path
208209

209210
def get_uploaded_image(image):
210-
try:
211-
name, ext = os.path.splitext(image.filename)
212-
if ext.lower() in ('.png', '.jpg', '.jpeg'):
213-
image = imgfile_to_image(image)
214-
if context['image_mode'] == 'grayscale':
215-
return convert_image_to_grayscale(image)
216-
elif context['image_mode'] == 'red_and_black':
217-
return convert_image_to_red_and_black(image)
218-
elif context['image_mode'] == 'colored':
219-
return image
220-
else:
221-
return convert_image_to_bw(image, context['image_bw_threshold'])
222-
elif ext.lower() in ('.pdf'):
223-
image = pdffile_to_image(image, DEFAULT_DPI)
224-
if context['image_mode'] == 'grayscale':
225-
return convert_image_to_grayscale(image)
226-
else:
227-
return convert_image_to_bw(image, context['image_bw_threshold'])
211+
name, ext = os.path.splitext(image.filename)
212+
if ext.lower() in ('.png', '.jpg', '.jpeg'):
213+
image = imgfile_to_image(image)
214+
if context['image_mode'] == 'grayscale':
215+
return convert_image_to_grayscale(image)
216+
elif context['image_mode'] == 'red_and_black':
217+
return convert_image_to_red_and_black(image)
218+
elif context['image_mode'] == 'colored':
219+
return image
228220
else:
229-
return None
230-
except AttributeError:
231-
return None
221+
return convert_image_to_bw(image, context['image_bw_threshold'])
222+
elif ext.lower() in ('.pdf'):
223+
image = pdffile_to_image(image, DEFAULT_DPI)
224+
if context['image_mode'] == 'grayscale':
225+
return convert_image_to_grayscale(image)
226+
else:
227+
return convert_image_to_bw(image, context['image_bw_threshold'])
228+
else:
229+
raise ValueError("Unsupported file type")
232230

233231
if context['print_type'] == 'text':
234232
label_content = LabelContent.TEXT_ONLY
@@ -263,13 +261,30 @@ def get_uploaded_image(image):
263261
if label_orientation == LabelOrientation.ROTATED:
264262
height, width = width, height
265263

264+
# Fix for completely empty text
265+
if len(context['text']) > 0 and len(context['text'][0]['text']) == 0:
266+
context['text'][0]['text'] = " "
267+
266268
# For each line in text, we determine and add the font path
267269
for line in context['text']:
268-
line['font_path'] = get_font_path(line['font_family'], line['font_style'])
270+
if 'font_family' not in line:
271+
line['font_family'] = current_app.config['LABEL_DEFAULT_FONT_FAMILY']
272+
if 'font_style' not in line:
273+
line['font_style'] = current_app.config['LABEL_DEFAULT_FONT_STYLE']
274+
if 'font_size' not in line:
275+
raise ValueError("Font size is required")
276+
line['font_path'] = get_font_path(line)
277+
278+
# Reject extraordinary long texts
279+
if len(line['text']) > 10_000:
280+
raise ValueError("Text is too long")
269281

270282
fore_color = (255, 0, 0) if context['print_color'] == 'red' else (0, 0, 0)
271283
border_color = (255, 0, 0) if context['border_color'] == 'red' else (0, 0, 0)
272284

285+
uploaded = request.files.get('image', None)
286+
image = get_uploaded_image(uploaded) if uploaded is not None else None
287+
273288
return SimpleLabel(
274289
width=width,
275290
height=height,
@@ -287,7 +302,7 @@ def get_uploaded_image(image):
287302
barcode_type=context['barcode_type'],
288303
qr_size=context['qrcode_size'],
289304
qr_correction=context['qrcode_correction'],
290-
image=get_uploaded_image(request.files.get('image', None)),
305+
image=image,
291306
image_fit=context['image_fit'],
292307
border_thickness=context['border_thickness'],
293308
border_roundness=context['border_roundness'],

app/labeldesigner/templates/labeldesigner.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,8 @@
391391
{% endblock %}
392392

393393
{% block javascript %}
394-
const url_for_print_label = '{{ url_for('.print_label') }}';
395-
const url_for_get_preview = '{{ url_for('.get_preview_from_image') }}';
394+
const url_for_print = '{{ url_for('.print_label') }}';
395+
const url_for_preview = '{{ url_for('.preview_from_image') }}';
396396
const url_for_get_font_styles = '{{url_for('.get_font_styles')}}';
397397
const url_for_get_barcodes = '{{ url_for('.get_barcodes') }}';
398398
const url_for_get_printer_status = '{{ url_for('.get_printer_status') }}';

app/static/js/main.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ function gen_label(preview = true, cut_once = false) {
245245
}
246246

247247
// Send printing request
248-
const url = preview ? (url_for_get_preview + '?return_format=base64') : url_for_print_label;
248+
const url = preview ? (url_for_preview + '?return_format=base64') : url_for_print;
249249
$.ajax({
250250
type: 'POST',
251251
url: url,
@@ -307,9 +307,9 @@ var imageDropZone;
307307
Dropzone.options.myAwesomeDropzone = {
308308
url: function () {
309309
if (dropZoneMode == 'preview') {
310-
return url_for_get_preview + "?return_format=base64";
310+
return url_for_preview + "?return_format=base64";
311311
} else {
312-
return url_for_print_label;
312+
return url_for_print;
313313
}
314314
},
315315
paramName: "image",

tests/empty_label.png

187 Bytes
Loading

tests/extra_fields.png

751 Bytes
Loading

tests/html_in_text_plain.png

1.18 KB
Loading

tests/large_label.png

189 KB
Loading

tests/minimal_label.png

209 Bytes
Loading

tests/missing_optional_fields.png

1.11 KB
Loading

0 commit comments

Comments
 (0)