From f187bcd2d3356ad6ba23e8c27965ae4a9b31ba50 Mon Sep 17 00:00:00 2001 From: Leon van Kammen Date: Wed, 30 Jul 2025 15:09:03 +0200 Subject: [PATCH] docker env $UPLOAD_PATH allows specifying default [upload] lib --- manyfold/README.md | 19 +++++++++++-------- manyfold/cli/manyfold.sh | 28 +++++++++++++++++++++------- manyfold/manyfold.sql | 15 ++++++++++++--- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/manyfold/README.md b/manyfold/README.md index 6207e4c..95e338b 100644 --- a/manyfold/README.md +++ b/manyfold/README.md @@ -3,7 +3,7 @@ The XRForge-serverimage is a pre-configured Manyfold container (reproducably via [nix](https://nixos.org) dockertools). It also contains some extra's, to better fit an XR audience. -> To run it, see the [sysadmin](https://manyfold.app/sysadmin/) documentation of the [manyfold](https://github.com/manyfold3d/manyfold) project. +> To run the container, see the [sysadmin](https://manyfold.app/sysadmin/) documentation of the [manyfold](https://github.com/manyfold3d/manyfold) project. # Build the container-image @@ -13,13 +13,14 @@ $ docker load < $(nix-build nix/docker.nix) # Extra environment-variables -| environment variable | default | info | -|----------------------|------------|------------------------| -| `APPNAME` | `manyfold` | manyfold instance name | -| `THEME` | `default` | bootstrap theme | -| `NO_OVERLAYFS` | `` | disable the filesystem overlay mechanism | -| `NO_DEFAULTDB` | `` | disable the default db (activates manyfold installer) | -| `RCLONE_REMOTE` | `` | specify **single** rclone remote name (without semicolon) to mount | +| environment variable | default | info | +|----------------------|--------------|------------------------| +| `APPNAME` | `manyfold` | manyfold instance name | +| `THEME` | `default` | bootstrap theme | +| `NO_OVERLAYFS` | `` | disable the filesystem overlay mechanism | +| `NO_DEFAULTDB` | `` | disable the default db (activates manyfold installer) | +| `RCLONE_REMOTE` | `` | specify **single** rclone remote name (without semicolon) to mount | +| `UPLOAD_PATH` | `/mnt/models`| specify default library where user-files are uploaded (regular dir or mounted rclone path) | # Default database / admin login @@ -51,3 +52,5 @@ Your drives will get automagically mounted and added to the database automagical > NOTE: by default all rclone remotes automagically show up as separate manyfold libraries, however use `RCLONE_REMOTE` this to specify a [combined](https://rclone.org/combine/) or [union](https://rclone.org/union/) rclone remote. +TIP: use **alphanumeric** names for rclone remotes (manyfold libraries choke on dot- or other special-characters) + diff --git a/manyfold/cli/manyfold.sh b/manyfold/cli/manyfold.sh index 40ab74a..a152bc7 100755 --- a/manyfold/cli/manyfold.sh +++ b/manyfold/cli/manyfold.sh @@ -1,6 +1,7 @@ #!/bin/sh oci=$(which podman || which docker) -test -n "$APPNAME" || APPNAME=xrforge +test -n "$APPNAME" || APPNAME=xrforge +test -n "$UPLOAD_PATH" || UPLOAD_PATH=/mnt/models db=/config/manyfold.sqlite3 # utility funcs @@ -21,7 +22,6 @@ run(){ -e SECRET_KEY_BASE=lkjwljlkwejrlkjek34k234l \ -e DATABASE_ADAPTER=sqlite3 \ -e SUDO_RUN_UNSAFELY=enabled \ - -e HTTPS_ONLY=disabled \ -e MULTIUSER=enabled \ -e FEDERATION=enabled \ -e THEME=vapor \ @@ -56,6 +56,19 @@ db(){ "$@" } +add_lib_to_db(){ + name=$(basename $1) + debug sqlite3 $db "INSERT INTO libraries SELECT NULL, '$1', DATE('NOW'), DATE('NOW'), '', '', '$name', NULL, '', 'filesystem', '', '', '', '', '', '$name', 1 WHERE NOT EXISTS (SELECT 1 FROM libraries WHERE path = '$1');" +} + +set_upload_path(){ + echocolor "[$APPNAME]" "configuring upload library" + test -d $UPLOAD_PATH || mkdir $UPLOAD_PATH + add_lib_to_db $UPLOAD_PATH + id=$(sqlite3 $db "select id from libraries where path = '$UPLOAD_PATH';") + debug sqlite3 $db "UPDATE settings set value = $id where var = 'default_library';" +} + rclone_mount(){ libraries(){ @@ -64,15 +77,15 @@ rclone_mount(){ test -d /mnt/$dir || mkdir /mnt/$dir echocolor "[$APPNAME]" "rclone: mounting $remote to /mnt/$dir" debug rclone mount --daemon $remote /mnt/$dir -vv - debug sqlite3 $db "INSERT INTO libraries VALUES(NULL,'/mnt/$dir',DATE('NOW'),DATE('NOW'),'','','$dir',NULL,'','filesystem','','','','','','$dir',1);" + add_lib_to_db /mnt/$dir done } library(){ - echocolor "[$APPNAME]" "rclone: mounting $RCLONE_REMOTE to /mnt/models" - test -d /mnt/models || mkdir /mnt/models - debug rclone mount --daemon ${RCLONE_REMOTE}: /mnt/models -vv - debug sqlite3 $db "INSERT INTO libraries VALUES(NULL,'/mnt/models',DATE('NOW'),DATE('NOW'),'','','$dir',NULL,'','filesystem','','','','','','models',1);" + echocolor "[$APPNAME]" "rclone: mounting $RCLONE_REMOTE to /mnt/$RCLONE_REMOTE" + test -d /mnt/$RCLONE_REMOTE || mkdir /mnt/$RCLONE_REMOTE + debug rclone mount --daemon ${RCLONE_REMOTE}: /mnt/$RCLONE_REMOTE -vv + add_lib_to_db /mnt/$RCLONE_REMOTE } test -n "$RCLONE_REMOTE" && library @@ -105,6 +118,7 @@ boot(){ set_theme set_modelpath rclone_mount + set_upload_path exec "$@" # exec prevents error 's6-overlay-suexec: fatal: can only run as pid 1' } diff --git a/manyfold/manyfold.sql b/manyfold/manyfold.sql index 3bdff24..ef017df 100644 --- a/manyfold/manyfold.sql +++ b/manyfold/manyfold.sql @@ -148,12 +148,21 @@ CREATE TABLE IF NOT EXISTS "links" ("id" integer PRIMARY KEY AUTOINCREMENT NOT N CREATE TABLE IF NOT EXISTS "settings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "var" varchar NOT NULL, "value" text, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL); INSERT INTO settings VALUES(1,'default_library',replace('--- 2\n','\n',char(10)),'2025-07-25 10:58:00.004576','2025-07-28 13:30:03.381376'); INSERT INTO settings VALUES(2,'site_name',replace('--- XRForge\n','\n',char(10)),'2025-07-25 10:59:04.496016','2025-07-25 10:59:04.496016'); -INSERT INTO settings VALUES(3,'site_tagline',replace('--- Selfsovereign XR Experiences based on 3D files & URLs\n','\n',char(10)),'2025-07-25 10:59:04.519264','2025-07-25 10:59:04.519264'); +INSERT INTO settings VALUES(3,'site_tagline',replace('--- Self-sovereign XR Experiences based on 3D files & URLs\n','\n',char(10)),'2025-07-25 10:59:04.519264','2025-07-25 10:59:04.519264'); INSERT INTO settings VALUES(4,'theme','vapor','2025-07-25 10:59:04.522670','2025-07-28 13:47:54.690364'); INSERT INTO settings VALUES(5,'about',replace('--- ''''\n','\n',char(10)),'2025-07-25 10:59:04.527612','2025-07-25 10:59:04.527612'); INSERT INTO settings VALUES(6,'rules',replace('--- ''''\n','\n',char(10)),'2025-07-25 10:59:04.531378','2025-07-25 10:59:04.531378'); INSERT INTO settings VALUES(7,'support_link',replace('--- https://forgejo.isvery.ninja/coderofsalvation/xrforge\n','\n',char(10)),'2025-07-25 10:59:04.533678','2025-07-25 10:59:04.533678'); INSERT INTO settings VALUES(8,'site_icon',replace('--- ''''\n','\n',char(10)),'2025-07-25 10:59:04.536228','2025-07-25 14:19:06.192651'); +INSERT INTO settings VALUES(9,'model_path_template',replace('--- "{tags}/{tags}/{modelName}{modelId}"\n','\n',char(10)),'2025-07-28 15:57:18.598798','2025-07-28 15:57:18.598798'); +INSERT INTO settings VALUES(10,'parse_metadata_from_path',replace('--- true\n','\n',char(10)),'2025-07-28 15:57:18.624917','2025-07-28 15:57:18.624917'); +INSERT INTO settings VALUES(11,'safe_folder_names',replace('--- true\n','\n',char(10)),'2025-07-28 15:57:18.627224','2025-07-28 15:57:18.627224'); +INSERT INTO settings VALUES(12,'model_ignored_files',replace('---\n- !ruby/regexp /^\.[^\.]+/\n- !ruby/regexp /.*\/@eaDir\/.*/\n- !ruby/regexp /__MACOSX/\n','\n',char(10)),'2025-07-28 15:57:18.633182','2025-07-28 15:57:18.633182'); +INSERT INTO settings VALUES(13,'model_tags_filter_stop_words',replace('--- true\n','\n',char(10)),'2025-07-28 15:57:18.637858','2025-07-28 15:57:18.637858'); +INSERT INTO settings VALUES(14,'model_tags_tag_model_directory_name',replace('--- false\n','\n',char(10)),'2025-07-28 15:57:18.640351','2025-07-28 15:57:18.640351'); +INSERT INTO settings VALUES(15,'model_tags_stop_words_locale',replace('--- en\n','\n',char(10)),'2025-07-28 15:57:18.643185','2025-07-28 15:57:18.643185'); +INSERT INTO settings VALUES(16,'model_tags_custom_stop_words',replace('---\n- png\n- jpeg\n- jpg\n- jpe\n- pjpeg\n- gif\n- bmp\n- tiff\n- tif\n- svg\n- webp\n- threeds\n- 3ds\n- amf\n- ldr\n- mpd\n- scad\n- dwg\n- dxf\n- threemf\n- 3mf\n- gltf\n- glb\n- iges\n- igs\n- mtl\n- obj\n- step\n- stp\n- stl\n- collada\n- dae\n- draco\n- drc\n- vrml\n- wrl\n- abc\n- blend\n- brep\n- cheetah3d\n- jas\n- fbx\n- fcstd\n- f3d\n- f3z\n- ipt\n- iam\n- maya\n- ma\n- mb\n- mix\n- modo\n- lxo\n- ply\n- sketchup\n- skp\n- sldprt\n- hfp\n- speedtree\n- spm\n- x3d\n- gcode\n- bgcode\n- lychee\n- lys\n- lyt\n- chitubox\n- ctb\n- mpeg\n- mpg\n- mpe\n- webm\n- mp4\n- m4v\n- html\n- xhtml\n- text\n- txt\n- pdf\n- md\n- doc\n- docx\n- bin\n- gbr\n- gerber\n- geb\n- gb\n- gbrjob\n- drl\n- kicad_pro\n- pro\n- kicad_mod\n- kicad_pcb\n- kicad_sym\n- kicad_sch\n- sch\n- kicad_wks\n- zip\n- gzip\n- gz\n- rar\n- sevenz\n- 7z\n- bz2\n','\n',char(10)),'2025-07-28 15:57:18.645648','2025-07-28 15:57:18.645648'); +INSERT INTO settings VALUES(17,'model_tags_auto_tag_new',replace('--- "!new"\n','\n',char(10)),'2025-07-28 15:57:18.648518','2025-07-28 15:57:18.648518'); CREATE TABLE IF NOT EXISTS "problems" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "problematic_type" varchar, "problematic_id" integer, "category" integer, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, "note" varchar DEFAULT NULL, "ignored" boolean DEFAULT 0 NOT NULL, "public_id" varchar, "in_progress" boolean DEFAULT 0 NOT NULL); CREATE TABLE IF NOT EXISTS "favorites" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "favoritable_type" varchar NOT NULL, "favoritable_id" integer NOT NULL, "favoritor_type" varchar NOT NULL, "favoritor_id" integer NOT NULL, "scope" varchar DEFAULT 'printed' NOT NULL, "blocked" boolean DEFAULT 0 NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL); CREATE TABLE IF NOT EXISTS "flipper_features" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "key" varchar NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL); @@ -244,8 +253,8 @@ INSERT INTO sqlite_sequence VALUES('models',0); INSERT INTO sqlite_sequence VALUES('creators',0); INSERT INTO sqlite_sequence VALUES('collections',0); INSERT INTO sqlite_sequence VALUES('roles',4); -INSERT INTO sqlite_sequence VALUES('libraries',2); -INSERT INTO sqlite_sequence VALUES('settings',8); +INSERT INTO sqlite_sequence VALUES('libraries',5); +INSERT INTO sqlite_sequence VALUES('settings',17); CREATE UNIQUE INDEX "index_tags_on_name" ON "tags" ("name"); CREATE UNIQUE INDEX "taggings_idx" ON "taggings" ("tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"); CREATE INDEX "taggings_taggable_context_idx" ON "taggings" ("taggable_id", "taggable_type", "context");