feat: forward plateindex for index-coded .gcode.3mf uploads
Gcode inside a .gcode.3mf is index-coded (Metadata/plate_<N>.gcode) and a
bundle may carry several, so the upload must name which plate to print —
even a single-plate bundle, since its entry is still indexed.
A 1-based plate index is stored in PrintHostUpload::extended_info when use_3mf
is set; the OctoPrint and Moonraker hosts forward it as a `plateindex` form
field. Servers that don't use it ignore the unknown field, so the plain G-code
path is unchanged.
OrcaSlicer currently ships an "Octo/Klipper" host type that maps to the
OctoPrint REST endpoints (api/version, api/files/local). It works for
Klipper setups that run Moonraker with the OctoPrint-emulation plugin,
but native Moonraker — and Moonraker-compatible firmwares like the
Prusa-Firmware-Buddy buddy-klipper fork — speak a different shape:
distinct paths, JSON body for /printer/print/start, {"result":...}
envelope. There's no host type for that today.
Add a new Moonraker class deriving from PrintHost. Endpoints used,
matching the Moonraker spec:
- GET /server/info — connection test, reads
result.klippy_state
- GET /server/files/roots — storage-picker dropdown
(returns roots with 'w'
permission); gracefully
degrades if absent
- POST /server/files/upload (multipart) — upload (form fields:
file, root)
- POST /printer/print/start (json) — {"filename":"<path>"}; the
filename is whatever the
upload response returned
in result.item.path, so any
server-side rename
(collision suffix etc.) is
respected. JSON body is
built via property_tree
write_json so exotic
characters in the path are
properly escaped.
Auth: X-Api-Key header, only when printhost_apikey is non-empty
(Moonraker can be configured to require it but doesn't by default).
HTTP Basic / Digest are not part of the Moonraker spec and are not
sent.
Storage root is read from upload_data.storage with "gcodes" as the
fallback default, so the existing storage-picker plumbing in
PrintHostDialogs lights up automatically once enumerable roots are
returned.
UI: registers as the "Moonraker (Klipper)" entry under host_type;
selectable via the existing Physical Printer dialog (sidebar's
connection button on the printer card).
Verified against a Prusa-Firmware-Buddy buddy-klipper fork (firmware
identifies as moonraker_version "0.8.0-prusalink-shim"): /server/info
test, multipart upload to /server/files/upload, and JSON
/printer/print/start all work end-to-end. The existing "Octo/Klipper"
entry is left untouched so users currently relying on Moonraker's
OctoPrint-emulation plugin keep working.