4.5 KiB
Filesystem — /fs
The filesystem provider (crate fsdy) serves a single local music
folder under /fs. It does not read audio tags: instead it walks the
directory tree and treats small TOML files with a well-known suffix as
serialized track nodes — each one carries a track's metadata and a
reference to the thing that actually plays.
Folders become library nodes; *.cbd-track.toml files become tracks.
Everything else in the tree (other files, hidden entries, symlinks) is
ignored.
Configuration — ~/.config/crabidy/fsdy.toml
The file has a single field:
# Absolute path of the directory exposed under /fs. When unset, the
# platform music directory (dirs::audio_dir(), e.g. ~/Music) is used.
root = "/home/me/Music"
A missing or empty file is fine — the default root is used. A root that does not exist yet is accepted; listing it simply fails until it appears. If neither a configured root nor a platform music directory is available, the provider disables itself with a warning rather than taking the server down.
The track-file format
A file named <anything>.cbd-track.toml inside the root is a track. The
schema is:
# Required.
title = "We Will Rock You"
# Optional; empty when omitted (web radio streams often have no artist).
artist = "Queen"
# Optional, in seconds.
duration = 122
# Optional.
[album]
title = "News of the World"
release_date = "1977-10-28"
# Required: exactly one playable (see below).
[playable]
file = "../flac/we-will-rock-you.flac"
The [playable] table must set exactly one of five fields:
file— a local audio file (see resolution below).url— anhttp(s)URL streamed by the player.link— an absolute crabidy path owned by another provider, e.g./tidal/artists/3634161/536243361.store— the bare name of an entry in the content-addressed store, written by download captures (see The crabidy store).skipped = true— the track has no playable audio; playback skips it. (skipped = falsecounts as unset.)
A file that is not valid TOML, or that sets zero or several playables,
is **skipped with a warning** at listing time. It never panics and never
poisons its sibling files — the rest of the directory still lists.
How a file playable resolves
- An absolute path is used as-is.
- A relative path is joined onto the directory containing the track file, so a whole music folder stays relocatable.
Existence is not checked while listing; a dead reference surfaces at play time as the player's normal "cannot open" warning, and playback moves on.
How a link playable resolves
When the provider builds a track from a link file, it sets the track's
path to the link target, not to the /fs path. From then on the
track is a track of the target's provider as far as the queue and
playback are concerned — the orchestrator's prefix routing does the rest.
Links resolve exactly one hop: get_urls_for_track on an /fs path
never follows a link, so a link whose target is itself a link file dies
at play time with a warning, and cycles cannot recurse. The metadata
shown is what the file says, not the target's live metadata.
Path-to-disk mapping
Library paths mirror the directory tree: /fs/<seg>/<seg>/…, where each
segment is the percent-encoded file name (the same encoding search terms
use), so names with spaces, %, or unicode survive the path scheme.
Mapping a path back to disk is a safe descent: each segment is
decoded and rejected if it is empty, ., .., or contains a path
separator. The joined path is always a pure descent from the root, so a
client-supplied path cannot escape the configured folder. Symlinks are
skipped during listing, so they cannot lead out of the root either.
Listing behavior
- Directories and track files are each sorted case-insensitively by file
name — a deterministic queueing order. Prefix file names with
01,02, … to order an album. - Directories are queueable nodes; queueing one resolves its whole subtree, one chunk per directory.
- Nothing is cached. Every navigation reads the directory fresh, so edits made with an ordinary file manager appear on the next visit — there is no file watching and no reload step.
Creating track files through the library is not supported here; they are
made and edited with normal file tools. (Other instances of the same
crate — the /crabidy saves — do support renaming and deleting; see
The crabidy store.)