No description
Find a file
dlawler489 f401eb4ca4 Merge phase 1: library core (duplicates, trash, notes, search and filters)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:36:26 +10:00
.forgejo/workflows CI: push image using a Forgejo access token 2026-06-22 17:48:57 +10:00
db Add duplicate finder, trash, notes, and library search/filters 2026-09-14 23:06:09 +10:00
lib Stream-parse 3MF files so Bambu projects don't exhaust memory 2026-09-15 07:02:00 +10:00
public Add duplicate finder, trash, notes, and library search/filters 2026-09-14 23:06:09 +10:00
test Stream-parse 3MF files so Bambu projects don't exhaust memory 2026-09-15 07:02:00 +10:00
tools Stream-parse 3MF files so Bambu projects don't exhaust memory 2026-09-15 07:02:00 +10:00
.dockerignore Add Forgejo Actions CI to build & push the image 2026-06-22 17:00:49 +10:00
.env.example Initial commit: Printhive 3D-print file library 2026-06-22 13:15:17 +10:00
.gitignore Stream-parse 3MF files so Bambu projects don't exhaust memory 2026-09-15 07:02:00 +10:00
docker-compose.yml Add email/password auth + SMTP password resets 2026-06-22 22:33:11 +10:00
Dockerfile Add Docker packaging (Dockerfile, compose, sidecar deps) 2026-06-22 16:51:06 +10:00
package-lock.json Add email/password auth + SMTP password resets 2026-06-22 22:33:11 +10:00
package.json Add duplicate finder, trash, notes, and library search/filters 2026-09-14 23:06:09 +10:00
README.md Add duplicate finder, trash, notes, and library search/filters 2026-09-14 23:06:09 +10:00
server.js Add duplicate finder, trash, notes, and library search/filters 2026-09-14 23:06:09 +10:00

Printhive

A self-hosted web app for organizing your 3D-printing files (STL, 3MF, OBJ, STEP, GCODE, ZIP) into a searchable library — with in-browser 3D previews, collections, license/commercial-use tracking, and one-paste import from popular model sites.

Features

  • Library of models, each owning one or more files; tags, collections, descriptions, print settings.
  • Import from URL:
    • Thingiverse — downloads files automatically via the official API (needs a free app token).
    • Printables — downloads files automatically via its public GraphQL API (no auth needed for free models).
    • MakerWorld — downloads files via FlareSolverr (solves Cloudflare) + your account token.
    • cubee3d (Hive) and any other URL — imports title/description/preview image; you add the files manually.
  • In-browser 3D viewer (Three.js) for STL/OBJ, and for 3MF via a server-side trimesh GLB conversion (handles Bambu/MakerWorld production-extension files the JS loader can't).
  • Auto thumbnails rendered from the model; embedded 3MF thumbnails used when present.
  • License & commercial-use tracking — captured per source, with a "sellable / non-commercial" indicator (a guide; verify before selling).
  • Collections — group models (a model can be in many); rename/delete without losing models.
  • Editing — rename/retag, edit print settings, override commercial-use, refresh metadata from source, re-download files, download all files as a zip.
  • Notes — free-form notes per model, saved as you type.
  • Search, filters & sorting — search across names, descriptions, notes, tags, file names and designers; filter by format, source and license; include or exclude tags (match any/all); sort and group by source or format. Press / to search.
  • Duplicate finder — every file gets a SHA-256 content hash plus (for STL/OBJ/3MF) a geometry fingerprint, computed in the background. Models sharing files are grouped as exact copies or same shape (renamed, re-exported, converted — or mirrored, so check those), with a recommended copy to keep. Keeping one merges the others' tags, collections and notes into it and moves them to the trash; groups can be dismissed as "not duplicates".
  • Trash — deleting moves a model to the trash; restore it, delete it forever, or empty the trash (only then are files removed from disk).
  • Settings — API tokens / FlareSolverr URL stored in the database (with .env fallback), secrets masked.

Tech stack

  • Node.js + Express, vanilla-JS frontend (no build step), PostgreSQL.
  • Three.js (viewer) via CDN import map.
  • Python + trimesh sidecar for 3MF→GLB conversion, volume, and geometry fingerprints.
  • Optional FlareSolverr for Cloudflare-protected sources.

Setup

  1. Postgres — create a database and point DATABASE_URL at it. The schema is applied automatically on startup.
  2. Python sidecar (for 3MF previews/volume and shape-based duplicate detection — without it, duplicates are still found by content hash):
    python3 -m venv tools/venv
    tools/venv/bin/pip install trimesh numpy networkx lxml
    
  3. Install deps and run:
    npm install
    cp .env.example .env   # set DATABASE_URL (+ optional tokens)
    npm start
    
  4. Open http://localhost:3000

Run the unit tests with npm test.

Configuration

Settings live in the database (editable in the app's Settings menu) and fall back to environment variables:

Setting Env var Purpose
Thingiverse API token THINGIVERSE_TOKEN Thingiverse auto-download
FlareSolverr URL FLARESOLVERR_URL Read Cloudflare-protected sites (MakerWorld)
MakerWorld auth token MAKERWORLD_TOKEN MakerWorld downloads (bearer token from your session)
Printables auth token PRINTABLES_TOKEN Optional; account-gated Printables files

Notes

  • Auto-download from MakerWorld/Printables relies on their private/session APIs and can break if they change; failed/partial imports can be recovered with "Download files from source".
  • The commercial-use badge is a best-effort read of the license — always confirm on the source page before selling.