Clips folders: create an empty .stlocal with the folder (Syncthing refuses to scan while the #include target is missing)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-11-01 19:08:58 -06:00
parent 2078a53419
commit f32730ba94
5 changed files with 8 additions and 3 deletions

View File

@@ -53,7 +53,7 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea
| MediaMTX | RTMP/SRT ingest, records fMP4; publish auth delegated to dumpd (tokens via `/mtx-auth`); on-ready hook posts "is live" and runs the WebRTC audio mirror (`<path>.webrtc`, audio → Opus, never recorded) | live, token auth verified | | MediaMTX | RTMP/SRT ingest, records fMP4; publish auth delegated to dumpd (tokens via `/mtx-auth`); on-ready hook posts "is live" and runs the WebRTC audio mirror (`<path>.webrtc`, audio → Opus, never recorded) | live, token auth verified |
| copyparty | browse/scrub/download/finals upload | behind Authentik, group permissions (`editors`, `media-admins`), Discord-only, no WebDAV | live | | copyparty | browse/scrub/download/finals upload | behind Authentik, group permissions (`editors`, `media-admins`), Discord-only, no WebDAV | live |
| dumpd + dock | dump, stream tokens, MediaMTX auth hook, `/time`, `/me` identity (on `live.`), `/me/clips` Syncthing self-service (on `clips.`); OBS dock with timecode-band setup | identity from Authentik headers | live | | dumpd + dock | dump, stream tokens, MediaMTX auth hook, `/time`, `/me` identity (on `live.`), `/me/clips` Syncthing self-service (on `clips.`); OBS dock with timecode-band setup | identity from Authentik headers | live |
| `media.` gateway, `clips.` self-service | static pages behind the gate | — | live (first real pairing pending) | | `media.` gateway, `clips.` self-service | static pages behind the gate | — | live; **first real pairing 2026-11-01 (thrahg)** — exposed a missing `.stlocal` on fresh folders, fixed |
| Timecode | `bin/vgstrip.py` decoder, `tmcd` + sidecar in the sweep, `/dock/clock/` strip page, Go Live band composite, portal crop | server clock is the reference | **live, verified** (OBS: frame-accurate, 0 gaps) | | Timecode | `bin/vgstrip.py` decoder, `tmcd` + sidecar in the sweep, `/dock/clock/` strip page, Go Live band composite, portal crop | server clock is the reference | **live, verified** (OBS: frame-accurate, 0 gaps) |
| Syncthing | clip intake, UI at `sync.` | UI behind Authentik + `media-admins`, own GUI auth off | live | | Syncthing | clip intake, UI at `sync.` | UI behind Authentik + `media-admins`, own GUI auth off | live |
| normalize sweep | editing standard, one copy per clip | live | | normalize sweep | editing standard, one copy per clip | live |

View File

@@ -6,5 +6,6 @@ cd "$(dirname "$0")"
u="${1:-}"; [[ $u =~ ^[a-z0-9_.-]{2,32}$ ]] || { echo "usage: $0 <username> (lowercase letters, digits, _ . -)"; exit 1; } u="${1:-}"; [[ $u =~ ^[a-z0-9_.-]{2,32}$ ]] || { echo "usage: $0 <username> (lowercase letters, digits, _ . -)"; exit 1; }
sudo install -d -o 1000 -g 1000 "/srv/media/clips/$u" sudo install -d -o 1000 -g 1000 "/srv/media/clips/$u"
sudo install -m 0644 -o 1000 -g 1000 syncthing/stignore "/srv/media/clips/$u/.stignore" sudo install -m 0644 -o 1000 -g 1000 syncthing/stignore "/srv/media/clips/$u/.stignore"
[[ -e "/srv/media/clips/$u/.stlocal" ]] || sudo install -m 0644 -o 1000 -g 1000 /dev/null "/srv/media/clips/$u/.stlocal" # #include'd by .stignore
echo "ready: /srv/media/clips/$u (Syncthing path: /var/syncthing/clips/$u)" echo "ready: /srv/media/clips/$u (Syncthing path: /var/syncthing/clips/$u)"
echo "next: pair their device in https://$(grep -E '^# vanguard:main' -A1 Caddyfile 2>/dev/null | tail -1 | awk '{print $1}')/sync/ and accept their folder at that path, Receive Only, min free 300 GB" echo "next: the gamer pairs at the clips host (self-service), or you accept their folder in the Syncthing UI at that path, Receive Only, min free 300 GB"

View File

@@ -222,6 +222,9 @@ def clips_setup(user, device_id, device_name=None):
ign = d / ".stignore" ign = d / ".stignore"
if not ign.exists() and STIGNORE_SRC.exists(): if not ign.exists() and STIGNORE_SRC.exists():
ign.write_text(STIGNORE_SRC.read_text()); shutil.chown(ign, 1000, 1000); ign.chmod(0o644) ign.write_text(STIGNORE_SRC.read_text()); shutil.chown(ign, 1000, 1000); ign.chmod(0o644)
loc = d / ".stlocal" # #include'd by .stignore; Syncthing refuses to scan while it is missing
if not loc.exists():
loc.write_text(""); shutil.chown(loc, 1000, 1000); loc.chmod(0o644)
# 2. their device # 2. their device
my_id = st("GET", "/rest/system/status")["myID"] my_id = st("GET", "/rest/system/status")["myID"]
if device_id == my_id: raise ValueError("that is the server's own Device ID — paste yours (your Syncthing → Actions → Show ID)") if device_id == my_id: raise ValueError("that is the server's own Device ID — paste yours (your Syncthing → Actions → Show ID)")

View File

@@ -45,6 +45,7 @@ install -d -o "$OWNER" /srv/live # live portal static build (dep
install -d -o 1000 -g 1000 /srv/media/streams/{techy,diceofire} /srv/media/clips/{techy,diceofire} install -d -o 1000 -g 1000 /srv/media/streams/{techy,diceofire} /srv/media/clips/{techy,diceofire}
for d in /srv/media/clips/*/; do for d in /srv/media/clips/*/; do
[[ -e "$d/.stignore" ]] || install -m 0644 -o 1000 -g 1000 syncthing/stignore "$d/.stignore" [[ -e "$d/.stignore" ]] || install -m 0644 -o 1000 -g 1000 syncthing/stignore "$d/.stignore"
[[ -e "$d/.stlocal" ]] || install -m 0644 -o 1000 -g 1000 /dev/null "$d/.stlocal" # #include'd by .stignore
done done
echo "== host scripts + units" echo "== host scripts + units"

View File

@@ -1,5 +1,5 @@
// Server-side ignore list for a clips receive folder (clips/<user>): pull video only. // Server-side ignore list for a clips receive folder (clips/<user>): pull video only.
// .stlocal is appended to by the sweep: raws it converted (then deleted locally) and the standard // .stlocal must exist (created empty with the folder) and is appended to by the sweep: raws it converted (then deleted locally) and the standard
// files it produced. Ignored = not tracked, not flagged, never re-pulled, never sent back. // files it produced. Ignored = not tracked, not flagged, never re-pulled, never sent back.
#include .stlocal #include .stlocal
// Ignored files are never downloaded from the sender. Subfolders are still traversed // Ignored files are never downloaded from the sender. Subfolders are still traversed