Send tape jobs paced, and carry the manual grouping through
Print, preview, PDF and the redirect back all honour a groups= spec, so a hand-built label survives printing instead of reverting to drawers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vunz4VLxAYDBnU5tLciLDC
This commit is contained in:
1 parent
deb009b80e
commit
fb59530f0e
1 file changed
+30
-8
@@ -46,7 +46,15 @@ def printer_config():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _options_query(options, labels):
|
def _group_spec():
|
||||||
|
"""
|
||||||
|
The manual grouping from the page: "1,2|3" means parts 1 and 2 share a
|
||||||
|
label and part 3 is on its own. Empty means "work it out from drawers".
|
||||||
|
"""
|
||||||
|
return (request.values.get('groups') or '').strip()
|
||||||
|
|
||||||
|
|
||||||
|
def _options_query(options, labels, group_spec=None):
|
||||||
"""
|
"""
|
||||||
The chosen options as query args, so a redirect back to the tape page
|
The chosen options as query args, so a redirect back to the tape page
|
||||||
comes back exactly as the user left it. Without this, printing bounced
|
comes back exactly as the user left it. Without this, printing bounced
|
||||||
@@ -65,6 +73,8 @@ def _options_query(options, labels):
|
|||||||
'align': options.align,
|
'align': options.align,
|
||||||
'fields': options.fields,
|
'fields': options.fields,
|
||||||
}
|
}
|
||||||
|
if group_spec:
|
||||||
|
query['groups'] = group_spec
|
||||||
# Checkboxes: only present when on, which is what the parser expects.
|
# Checkboxes: only present when on, which is what the parser expects.
|
||||||
if options.rotate:
|
if options.rotate:
|
||||||
query['rotate'] = '1'
|
query['rotate'] = '1'
|
||||||
@@ -115,13 +125,16 @@ def index():
|
|||||||
source, rotate_default=config['rotate'],
|
source, rotate_default=config['rotate'],
|
||||||
size_default=config['size_mode'], tape_default=config['tape'])
|
size_default=config['size_mode'], tape_default=config['tape'])
|
||||||
|
|
||||||
plan = tape_printer.plan_groups(labels, options)
|
group_spec = _group_spec()
|
||||||
|
plan = tape_printer.plan_groups(labels, options, group_spec)
|
||||||
tape = tape_printer.get_tape(options.tape)
|
tape = tape_printer.get_tape(options.tape)
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
'admin/labels/tape.html',
|
'admin/labels/tape.html',
|
||||||
labels=labels,
|
labels=labels,
|
||||||
plan=plan,
|
plan=plan,
|
||||||
|
group_spec=tape_printer.spec_from_groups(
|
||||||
|
[item['labels'] for item in plan]),
|
||||||
ids=','.join(str(l.id) for l in labels),
|
ids=','.join(str(l.id) for l in labels),
|
||||||
options=options,
|
options=options,
|
||||||
tapes=tape_printer.TAPE_PRESETS,
|
tapes=tape_printer.TAPE_PRESETS,
|
||||||
@@ -235,15 +248,18 @@ def print_tape():
|
|||||||
except ipp_client.IPPError as exc:
|
except ipp_client.IPPError as exc:
|
||||||
flash(f'Could not reach the printer: {exc}', 'danger')
|
flash(f'Could not reach the printer: {exc}', 'danger')
|
||||||
return redirect(url_for('tape.index',
|
return redirect(url_for('tape.index',
|
||||||
**_options_query(options, labels)))
|
**_options_query(options, labels,
|
||||||
|
_group_spec())))
|
||||||
if not mime_type:
|
if not mime_type:
|
||||||
flash('The printer did not offer a format LIM can produce. Use '
|
flash('The printer did not offer a format LIM can produce. Use '
|
||||||
'Download PDF instead.', 'warning')
|
'Download PDF instead.', 'warning')
|
||||||
return redirect(url_for('tape.index',
|
return redirect(url_for('tape.index',
|
||||||
**_options_query(options, labels)))
|
**_options_query(options, labels,
|
||||||
|
_group_spec())))
|
||||||
|
|
||||||
upload_folder = current_app.config['UPLOAD_FOLDER']
|
upload_folder = current_app.config['UPLOAD_FOLDER']
|
||||||
plan = tape_printer.plan_groups(labels, options)
|
group_spec = _group_spec()
|
||||||
|
plan = tape_printer.plan_groups(labels, options, group_spec)
|
||||||
|
|
||||||
if options.is_fixed and not tape_printer.tape_fits_label(options.tape):
|
if options.is_fixed and not tape_printer.tape_fits_label(options.tape):
|
||||||
flash(f'{tape_printer.LABEL_WIDTH_MM:.0f}mm labels need 50mm tape - '
|
flash(f'{tape_printer.LABEL_WIDTH_MM:.0f}mm labels need 50mm tape - '
|
||||||
@@ -261,8 +277,13 @@ def print_tape():
|
|||||||
document = tape_printer.image_to_bytes(image, mime_type)
|
document = tape_printer.image_to_bytes(image, mime_type)
|
||||||
# copies is handled by repeating the job rather than the IPP
|
# copies is handled by repeating the job rather than the IPP
|
||||||
# copies attribute: tape printers vary wildly in honouring it.
|
# copies attribute: tape printers vary wildly in honouring it.
|
||||||
|
#
|
||||||
|
# Paced rather than fired in a burst: the VC-500W takes one job
|
||||||
|
# at a time and answers "busy" to anything arriving while the
|
||||||
|
# tape is still moving, so each job waits for the printer to go
|
||||||
|
# idle and retries while it is still working.
|
||||||
for _ in range(options.copies):
|
for _ in range(options.copies):
|
||||||
ipp_client.print_job(
|
ipp_client.print_job_paced(
|
||||||
host, document, mime_type,
|
host, document, mime_type,
|
||||||
job_name=f'LIM: {name}'[:120],
|
job_name=f'LIM: {name}'[:120],
|
||||||
port=config['port'], path=config['path'])
|
port=config['port'], path=config['path'])
|
||||||
@@ -279,7 +300,8 @@ def print_tape():
|
|||||||
for problem in failures[:5]:
|
for problem in failures[:5]:
|
||||||
flash(problem, 'danger')
|
flash(problem, 'danger')
|
||||||
|
|
||||||
return redirect(url_for('tape.index', **_options_query(options, labels)))
|
return redirect(url_for('tape.index',
|
||||||
|
**_options_query(options, labels, group_spec)))
|
||||||
|
|
||||||
|
|
||||||
@tape_bp.route('/download.pdf', methods=['GET', 'POST'])
|
@tape_bp.route('/download.pdf', methods=['GET', 'POST'])
|
||||||
@@ -298,7 +320,7 @@ def download_pdf():
|
|||||||
source, rotate_default=config['rotate'],
|
source, rotate_default=config['rotate'],
|
||||||
size_default=config['size_mode'], tape_default=config['tape'])
|
size_default=config['size_mode'], tape_default=config['tape'])
|
||||||
buffer = tape_printer.render_batch_pdf(
|
buffer = tape_printer.render_batch_pdf(
|
||||||
labels, options, current_app.config['UPLOAD_FOLDER'])
|
labels, options, current_app.config['UPLOAD_FOLDER'], _group_spec())
|
||||||
if buffer is None:
|
if buffer is None:
|
||||||
flash('Nothing to render.', 'warning')
|
flash('Nothing to render.', 'warning')
|
||||||
return redirect(url_for('labels.index'))
|
return redirect(url_for('labels.index'))
|
||||||
|
|||||||
Reference in new issue
Block a user