Document the catalogue sync, tape printing and the skin

This commit is contained in:
jessikitty committed 2026-10-12 21:33:41 +11:00
1 parent b8571697dd
commit bad4787e00
1 file changed
+115 -12
+115 -12
View File
@@ -1,7 +1,8 @@
# Parts Drawer Labels # Parts Drawer Labels
Admin-only labelling system for sorting drawers and bags. Browse a part Admin-only labelling system for sorting drawers and bags. Browse a part
taxonomy, define a label per drawer, and print them onto sticker sheets. taxonomy, define a label per drawer, and print them onto sticker sheets or
continuous tape.
Lives at **`/admin/labels`** — in the admin menu as *Parts Labels*. Lives at **`/admin/labels`** — in the admin menu as *Parts Labels*.
@@ -24,17 +25,18 @@ If you'd rather make the database change deliberately before restarting:
``` ```
python migrate_add_part_labels.py python migrate_add_part_labels.py
python migrate_add_parts_catalogue.py
``` ```
Optional extras: Optional extras:
| What | Why | How | | What | Why | How |
|------|-----|-----| |------|-----|-----|
| Rebrickable API key | Part lookup: numbers, names, artwork | `REBRICKABLE_API_KEY=...` in `.env`, or paste it into *Labels → Settings* | | Rebrickable API key | Part photos when importing a label | `REBRICKABLE_API_KEY=...` in `.env`, or paste it into *Labels → Settings* |
| ReportLab | PDF export button | `pip install reportlab` | | ReportLab | PDF export button for sheets | `pip install reportlab` |
Neither is required. Without them you type labels in by hand, upload your own Neither is required. Without them you type labels in by hand, upload your own
images, and print from the browser. images, and print from the browser. The part catalogue works without a key.
--- ---
@@ -63,9 +65,9 @@ and use them; this is for generating your own.
- *New Label* — name, dimensions, part number, alternates, category, drawer, - *New Label* — name, dimensions, part number, alternates, category, drawer,
colour, image. colour, image.
- Or, with a Rebrickable key, search on the labels page and hit *Add label* on - Or pick them off the *Part Catalogue* tab (see below), which is much faster
a result. It pulls the name, number and image, caches the image locally so for more than a handful.
printing works offline, then drops you on the edit form to set the drawer. - Or, with a Rebrickable key, use the quick lookup box on the labels page.
**The `name` + `dimensions` split matters.** Name is the big bold line **The `name` + `dimensions` split matters.** Name is the big bold line
("Brick", "Plate, Modified with Clip"); dimensions is the geometry ("2 x 4"). ("Brick", "Plate, Modified with Clip"); dimensions is the geometry ("2 x 4").
@@ -75,9 +77,9 @@ mixed drawers.
**Alternate part numbers** are for old moulds that live in the same drawer — **Alternate part numbers** are for old moulds that live in the same drawer —
`3001a, 3001b`. Comma separated, searchable, optionally printed. `3001a, 3001b`. Comma separated, searchable, optionally printed.
**Printing** **Printing to sheets**
1. Tick labels (or *Print whole category*). 1. Tick labels (or *Print whole category*), press **Sheet**.
2. Pick a sheet, set the options, hit *Update preview*. 2. Pick a sheet, set the options, hit *Update preview*.
3. Print from the browser: **margins None, scale 100%** — not "Fit to page", 3. Print from the browser: **margins None, scale 100%** — not "Fit to page",
which is what ruins most label sheets. which is what ruins most label sheets.
@@ -100,15 +102,116 @@ or paper-and-tape.
--- ---
## The part catalogue (the Update button)
*Labels → Part Catalogue*, then **Update catalogue**.
This pulls Rebrickable's published catalogue dumps into a local table so that
making a label is picking a part off a list rather than typing it out:
https://cdn.rebrickable.com/media/downloads/part_categories.csv.gz
https://cdn.rebrickable.com/media/downloads/parts.csv.gz
Two gzipped CSVs, about 60,000 parts, regenerated monthly by Rebrickable and
free to use with a credit. **No API key is needed for this** — the key only
adds the real part photo at the moment a catalogue row becomes a label.
The sync runs on a background thread and reports progress to the page, so you
can close the tab. Re-running it is cheap and idempotent: it only writes rows
that are new or actually changed (a second run on an unchanged catalogue
writes nothing).
**Category mapping.** Rebrickable's categories are theirs; the drawer
taxonomy is yours. Open a Rebrickable category and set *"Parts in this
category become labels in …"* once, and from then on importing any part from
it drops the label straight into the right drawer group. Unmapped categories
just ask you each time.
**Making labels.** Tick parts, optionally override the drawer category, press
*Make labels*. Parts already labelled are flagged and skipped, so you can
re-import a category without creating duplicates. `Brick 2 x 4` is split into
name `Brick` + dimensions `2 x 4` on the way in, because the label stores them
separately so the print options can show or hide the geometry.
Thumbnails in the browse list use Rebrickable's predictable LDraw render path
and quietly disappear for parts that have no LDraw model. That is expected —
the real image is fetched per-part when you create the label.
---
## Printing to the Brother VC-500W
*Labels → tick some labels → **Tape***, or the tape icon on any row.
The VC-500W is AirPrint-enabled, which means it speaks **IPP on port 631** —
an open, documented protocol. So LIM talks to it directly over the network:
no Brother driver, no P-touch Editor, no exporting a PDF and printing it by
hand. Brother publish no raw command protocol for this printer and none is
reverse-engineered here; it is plain standard IPP (RFC 8010/8011).
**Setup.** Put the printer's IP address into *Labels → Settings → Tape
printer*. Give it a DHCP reservation first or the address will wander. Then
hit **Test connection** on the tape page: it reports the model, state, and
exactly which document formats the printer will accept.
**Format negotiation.** LIM renders at the printer's native 313 dpi and sends
whichever format the printer lists that LIM can produce — JPEG, PNG or PDF, in
that order. If your firmware only offers `image/urf` or raster formats, the
test will say so and you use *Download PDF* instead. You can pin a format in
Settings if auto-negotiation ever picks wrong.
**Tape widths.** CZ tape in 9, 12, 19, 25 and 50 mm. Each preset knows its
printable width; labels are sized to the content, or to a fixed length if you
set one. Maximum length is about 430 mm.
> **Check this on your first print:** labels are rotated 90° by default,
> because the tape feeds lengthwise. If your first one comes out sideways,
> untick *Rotate for tape feed* and print again. It is the one setting worth
> testing on a fresh printer, so print one before queueing fifty.
Copies are sent as repeated jobs rather than via the IPP `copies` attribute,
because tape printers vary wildly in whether they honour it.
### What to do when it won't print
| Symptom | Likely cause |
|---|---|
| *Could not reach the printer* | Wrong IP, printer asleep, or on its own ad-hoc Wi-Fi rather than your LAN |
| *Printer rejected the job: …not-supported* | It won't take JPEG/PNG/PDF. Use Download PDF |
| Prints sideways | Untick *Rotate for tape feed* |
| Text clipped at the edges | Raise *Padding*, or lower *Text size* |
| Blank or faint | Cleaning cassette (CK-1000), or the tape is in backwards |
---
## The catalogue look
The labelling pages use a denser, cooler-toned skin than the rest of LIM
(`app/static/css/labels-bricklink.css`, scoped to `.bl`). That is deliberate:
this is a reference catalogue where you scan hundreds of rows, not a library
you browse by cover art — so small type, tight rows, thin rules and counts on
everything. It is our own stylesheet, not a copy of anyone's site, and it does
not leak into the red LEGO-themed pages.
---
## Where things live ## Where things live
``` ```
app/models/part_label.py PartCategory (tree) + PartLabel app/models/part_label.py PartCategory (tree) + PartLabel
app/services/part_catalog.py taxonomy seeding, Rebrickable client app/models/part_catalog_item.py local Rebrickable mirror + sync history
app/services/part_catalog.py taxonomy seeding, Rebrickable API client
app/services/catalog_sync.py the Update button: CSV dumps -> database
app/services/label_render.py sheet geometry, layout, optional PDF app/services/label_render.py sheet geometry, layout, optional PDF
app/routes/labels.py the blueprint (all admin_required) app/services/tape_printer.py 313dpi tape rendering, CZ tape presets
app/services/ipp_client.py minimal IPP client (RFC 8010/8011)
app/routes/labels.py /admin/labels (all admin_required)
app/routes/labels_catalog.py /admin/labels/catalog
app/routes/labels_tape.py /admin/labels/tape
app/data/part_taxonomy.json the starter taxonomy app/data/part_taxonomy.json the starter taxonomy
app/templates/admin/labels/ index, form, categories, settings, print app/static/css/labels-bricklink.css the catalogue skin
app/templates/admin/labels/ index, form, categories, settings, print,
catalog, tape, _nav
<UPLOAD_FOLDER>/parts/ cached and uploaded part images <UPLOAD_FOLDER>/parts/ cached and uploaded part images
``` ```