Skip to content

Commit ae90e2c

Browse files
committed
Increase test coverage
Signed-off-by: DL6ER <[email protected]>
1 parent 847457c commit ae90e2c

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
@@ -67,21 +67,22 @@ def get_barcodes():
6767
}
6868

6969

70-
@bp.route('/api/preview', methods=['POST', 'GET'])
71-
def get_preview_from_image():
70+
@bp.route('/api/preview', methods=['POST'])
71+
def preview_from_image():
7272
# Set log level if provided
7373
log_level = request.values.get('log_level')
7474
if log_level:
7575
level = getattr(logging, log_level.upper(), None)
7676
if isinstance(level, int):
7777
current_app.logger.setLevel(level)
78-
label = create_label_from_request(request)
7978
try:
79+
label = create_label_from_request(request)
8080
im = label.generate(rotate=True)
8181
except Exception as e:
8282
current_app.logger.exception(e)
83-
# Generate error 400 response
84-
return make_response(jsonify({'message': str(e)}), 400)
83+
error = 413 if "too long" in str(e) else 400
84+
# Generate error response
85+
return make_response(jsonify({'message': str(e)}), error)
8586

8687
return_format = request.values.get('return_format', 'png')
8788

@@ -198,45 +199,42 @@ def get_label_dimensions(label_size):
198199
raise LookupError("Unknown label_size")
199200
return ls['dots_printable']
200201

201-
def get_font_path(font_family_name, font_style_name):
202+
def get_font_path(line: dict):
202203
try:
203-
if font_family_name is None or font_style_name is None:
204-
font_family_name = current_app.config['LABEL_DEFAULT_FONT_FAMILY']
205-
font_style_name = current_app.config['LABEL_DEFAULT_FONT_STYLE']
204+
font_family_name = line.get('font_family')
205+
font_style_name = line.get('font_style')
206206
if font_family_name not in FONTS.fonts:
207207
raise LookupError("Unknown font family: %s" % font_family_name)
208208
if font_style_name not in FONTS.fonts[font_family_name]:
209209
font_style_name = current_app.config['LABEL_DEFAULT_FONT_STYLE']
210210
if font_style_name not in FONTS.fonts[font_family_name]:
211-
raise LookupError("Unknown font style: %s for font %s" % (font_style_name, font_family_name))
211+
raise LookupError("Unknown font style: %s for font %s" %
212+
(font_style_name, font_family_name))
212213
font_path = FONTS.fonts[font_family_name][font_style_name]
213214
except KeyError:
214215
raise LookupError("Couln't find the font & style")
215216
return font_path
216217

217218
def get_uploaded_image(image):
218-
try:
219-
name, ext = os.path.splitext(image.filename)
220-
if ext.lower() in ('.png', '.jpg', '.jpeg'):
221-
image = imgfile_to_image(image)
222-
if context['image_mode'] == 'grayscale':
223-
return convert_image_to_grayscale(image)
224-
elif context['image_mode'] == 'red_and_black':
225-
return convert_image_to_red_and_black(image)
226-
elif context['image_mode'] == 'colored':
227-
return image
228-
else:
229-
return convert_image_to_bw(image, context['image_bw_threshold'])
230-
elif ext.lower() in ('.pdf'):
231-
image = pdffile_to_image(image, DEFAULT_DPI)
232-
if context['image_mode'] == 'grayscale':
233-
return convert_image_to_grayscale(image)
234-
else:
235-
return convert_image_to_bw(image, context['image_bw_threshold'])
219+
name, ext = os.path.splitext(image.filename)
220+
if ext.lower() in ('.png', '.jpg', '.jpeg'):
221+
image = imgfile_to_image(image)
222+
if context['image_mode'] == 'grayscale':
223+
return convert_image_to_grayscale(image)
224+
elif context['image_mode'] == 'red_and_black':
225+
return convert_image_to_red_and_black(image)
226+
elif context['image_mode'] == 'colored':
227+
return image
236228
else:
237-
return None
238-
except AttributeError:
239-
return None
229+
return convert_image_to_bw(image, context['image_bw_threshold'])
230+
elif ext.lower() in ('.pdf'):
231+
image = pdffile_to_image(image, DEFAULT_DPI)
232+
if context['image_mode'] == 'grayscale':
233+
return convert_image_to_grayscale(image)
234+
else:
235+
return convert_image_to_bw(image, context['image_bw_threshold'])
236+
else:
237+
raise ValueError("Unsupported file type")
240238

241239
if context['print_type'] == 'text':
242240
label_content = LabelContent.TEXT_ONLY
@@ -271,13 +269,30 @@ def get_uploaded_image(image):
271269
if label_orientation == LabelOrientation.ROTATED:
272270
height, width = width, height
273271

272+
# Fix for completely empty text
273+
if len(context['text']) > 0 and len(context['text'][0]['text']) == 0:
274+
context['text'][0]['text'] = " "
275+
274276
# For each line in text, we determine and add the font path
275277
for line in context['text']:
276-
line['font_path'] = get_font_path(line['font_family'], line['font_style'])
278+
if 'font_family' not in line:
279+
line['font_family'] = current_app.config['LABEL_DEFAULT_FONT_FAMILY']
280+
if 'font_style' not in line:
281+
line['font_style'] = current_app.config['LABEL_DEFAULT_FONT_STYLE']
282+
if 'font_size' not in line:
283+
raise ValueError("Font size is required")
284+
line['font_path'] = get_font_path(line)
285+
286+
# Reject extraordinary long texts
287+
if len(line['text']) > 10_000:
288+
raise ValueError("Text is too long")
277289

278290
fore_color = (255, 0, 0) if context['print_color'] == 'red' else (0, 0, 0)
279291
border_color = (255, 0, 0) if context['border_color'] == 'red' else (0, 0, 0)
280292

293+
uploaded = request.files.get('image', None)
294+
image = get_uploaded_image(uploaded) if uploaded is not None else None
295+
281296
return SimpleLabel(
282297
width=width,
283298
height=height,
@@ -295,7 +310,7 @@ def get_uploaded_image(image):
295310
barcode_type=context['barcode_type'],
296311
qr_size=context['qrcode_size'],
297312
qr_correction=context['qrcode_correction'],
298-
image=get_uploaded_image(request.files.get('image', None)),
313+
image=image,
299314
image_fit=context['image_fit'],
300315
border_thickness=context['border_thickness'],
301316
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)