crabidy/docs/src/providers/fs.md

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 — an http(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 = false counts 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.

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.)