diff --git a/README.md b/README.md index 4d38999..522a653 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,117 @@ # Furumi-ng -Remote filesystem over encrypted gRPC. Mount a directory from a remote server as a local folder via FUSE. +A music platform consisting of a remote filesystem, an AI-powered metadata agent, and a database-backed web player. -Designed for streaming media (video, music) over the network. +## Components + +``` +furumi-server gRPC remote filesystem with TLS and auth +furumi-client-core Cross-platform gRPC client library +furumi-mount-linux FUSE mount for Linux +furumi-mount-macos NFS mount for macOS +furumi-agent AI metadata agent (LLM-powered ingest pipeline + admin UI) +furumi-web-player Database-backed web music player with OIDC auth +``` + +### furumi-server + +Exposes a local directory over encrypted gRPC. Supports Bearer token auth, OIDC/SSO, Prometheus metrics, and a built-in web player for direct filesystem browsing. + +### furumi-agent + +Background service that watches an inbox folder for new music files, extracts metadata, normalizes it using a local LLM (via Ollama), and stores canonical metadata in PostgreSQL. Features: + +- Automatic metadata extraction (Symphonia) and file path parsing +- LLM normalization with RAG (queries existing artists/albums in DB for consistency) +- Featured artist detection (`feat.`, `п.у.`, `&`, etc.) +- Album cover image processing +- Auto-approval for high-confidence results, review queue for uncertain ones +- Admin web UI with batch operations, inline editing, album grouping +- Organized file storage (`Artist/Album/Track.ext`) +- Configurable system prompt (built-in default or external file) +- Database migrations via sqlx + +### furumi-web-player + +Web music player that reads exclusively from the database populated by the agent. Features: + +- Browse by Artists, Albums, Tracks +- Full-text search across the library +- Audio streaming with HTTP Range request support +- Album cover art (from DB or embedded in audio files) +- Queue management with shuffle, repeat, drag-and-drop reorder +- Media Session API (hardware controls, lock screen integration) +- OIDC/SSO authentication +- Deep linking (`?t=`) +- Relative URL paths (works behind any reverse proxy prefix) ## Architecture ``` -furumi-server (gRPC + TLS) ←→ furumi-client-core ←→ furumi-mount-{linux,macos} (FUSE / NFS) + ┌─────────────────┐ + │ Ollama (LLM) │ + └────────┬────────┘ + │ +┌──────────┐ ┌────────────┴────────────┐ ┌──────────────────┐ +│ Inbox │───→│ furumi-agent │───→│ Storage (files) │ +│ folder │ │ (ingest + admin UI) │ └────────┬─────────┘ +└──────────┘ └────────────┬────────────┘ │ + │ │ + ┌──────┴──────┐ ┌───────┴────────┐ + │ PostgreSQL │←──────────│ furumi-web- │ + │ (metadata) │ │ player │ + └─────────────┘ └────────────────┘ ``` -- **furumi-server** — exposes a directory over gRPC with auto-TLS, Bearer token auth, and Prometheus metrics -- **furumi-client-core** — cross-platform gRPC client library with attribute caching -- **furumi-mount-linux** — mounts the remote directory locally via FUSE (read-only) -- **furumi-mount-macos** — mounts the remote directory locally via a local NFS server (read-only) - ## Quick Start +### Remote Filesystem (FUSE/NFS mount) + ```bash -# Build cargo build --release --workspace -# Server — auto-generates TLS certificate, saves it for client +# Server ./target/release/furumi-server \ --root /path/to/media \ - --token mysecrettoken \ - --tls-cert-out /tmp/furumi-ca.pem + --token mysecrettoken -# Client -./target/release/furumi-mount-macos \ +# Client (Linux) +./target/release/furumi-mount-linux \ --server server-ip:50051 \ --token mysecrettoken \ - --mount /Volumes/remote - -# Use it -ls /mnt/remote -mpv /mnt/remote/video.mkv + --mount /mnt/remote ``` -### Linux FUSE3 -Linux client uses FUSE. Install with: -``` -sudo add-apt-repository universe -sudo apt install libfuse3-dev -``` -## Encryption +### Music Platform (Agent + Player) -TLS is enabled by default. The server auto-generates a self-signed certificate on each start — no manual cert management required. The client automatically trusts the server's certificate for encryption. +Requires PostgreSQL with `pg_trgm` extension and Ollama for LLM. -To disable TLS (not recommended): `--no-tls` on both server and client. +```bash +# 1. Start PostgreSQL +docker run -d --name furumi-pg \ + -e POSTGRES_DB=furumi -e POSTGRES_USER=furumi -e POSTGRES_PASSWORD=furumi \ + -p 5432:5432 postgres:17 + +# 2. Create directories +mkdir -p /music/inbox /music/storage + +# 3. Start the agent (runs migrations automatically) +./target/release/furumi-agent \ + --inbox-dir /music/inbox \ + --storage-dir /music/storage \ + --database-url "postgres://furumi:furumi@localhost:5432/furumi" \ + --ollama-url "http://localhost:11434" \ + --ollama-model "qwen3:14b" + +# 4. Start the web player +./target/release/furumi-web-player \ + --storage-dir /music/storage \ + --database-url "postgres://furumi:furumi@localhost:5432/furumi" + +# 5. Drop music files into /music/inbox — agent processes them automatically +# 6. Open http://localhost:8080 to play music +# 7. Open http://localhost:8090 for the agent admin UI +``` ## Configuration @@ -62,9 +125,11 @@ All options can be set via CLI flags or environment variables. | `--root` | `FURUMI_ROOT` | `.` | Directory to expose | | `--token` | `FURUMI_TOKEN` | *(empty, auth off)* | Bearer token | | `--metrics-bind` | `FURUMI_METRICS_BIND` | `0.0.0.0:9090` | Prometheus endpoint | +| `--web-bind` | `FURUMI_WEB_BIND` | `0.0.0.0:8080` | Built-in web player | +| `--no-web` | — | `false` | Disable built-in web player | | `--no-tls` | — | `false` | Disable TLS | -### Client +### Client (Linux / macOS) | Flag | Env | Default | Description | |------|-----|---------|-------------| @@ -73,22 +138,58 @@ All options can be set via CLI flags or environment variables. | `--mount` | `FURUMI_MOUNT` | — | Mount point directory | | `--no-tls` | — | `false` | Disable TLS | +### Metadata Agent + +| Flag | Env | Default | Description | +|------|-----|---------|-------------| +| `--bind` | `FURUMI_AGENT_BIND` | `0.0.0.0:8090` | Admin UI address | +| `--inbox-dir` | `FURUMI_AGENT_INBOX_DIR` | — | Watch folder for new files | +| `--storage-dir` | `FURUMI_AGENT_STORAGE_DIR` | — | Permanent storage folder | +| `--database-url` | `FURUMI_AGENT_DATABASE_URL` | — | PostgreSQL URL | +| `--ollama-url` | `FURUMI_AGENT_OLLAMA_URL` | `http://localhost:11434` | Ollama API endpoint | +| `--ollama-model` | `FURUMI_AGENT_OLLAMA_MODEL` | `qwen3:14b` | LLM model name | +| `--poll-interval-secs` | `FURUMI_AGENT_POLL_INTERVAL_SECS` | `30` | Inbox scan interval | +| `--confidence-threshold` | `FURUMI_AGENT_CONFIDENCE_THRESHOLD` | `0.85` | Auto-approve threshold | +| `--system-prompt-file` | `FURUMI_AGENT_SYSTEM_PROMPT_FILE` | *(built-in)* | Custom LLM prompt | + +### Web Player + +| Flag | Env | Default | Description | +|------|-----|---------|-------------| +| `--bind` | `FURUMI_PLAYER_BIND` | `0.0.0.0:8080` | Player address | +| `--database-url` | `FURUMI_PLAYER_DATABASE_URL` | — | PostgreSQL URL | +| `--storage-dir` | `FURUMI_PLAYER_STORAGE_DIR` | — | Storage folder (for streaming) | +| `--oidc-issuer-url` | `FURUMI_PLAYER_OIDC_ISSUER_URL` | *(disabled)* | OIDC issuer | +| `--oidc-client-id` | `FURUMI_PLAYER_OIDC_CLIENT_ID` | — | OIDC client ID | +| `--oidc-client-secret` | `FURUMI_PLAYER_OIDC_CLIENT_SECRET` | — | OIDC client secret | +| `--oidc-redirect-url` | `FURUMI_PLAYER_OIDC_REDIRECT_URL` | — | OIDC redirect URL | +| `--oidc-session-secret` | `FURUMI_PLAYER_OIDC_SESSION_SECRET` | *(random)* | Session HMAC secret | + +## Docker + +Pre-built images are available on Docker Hub: + +```bash +docker pull /furumi-server +docker pull /furumi-web-player +docker pull /furumi-metadata-agent +``` + ## Prometheus Metrics -Available at `http:///metrics`: +Available at `http:///metrics` (server only): - `furumi_grpc_requests_total` — request count by method and status - `furumi_grpc_request_duration_seconds` — request latency histogram - `furumi_bytes_read_total` — total bytes streamed - `furumi_active_streams` — current streaming connections -- `furumi_file_open_errors_total` — file access errors -- `furumi_auth_failures_total` — authentication failures ## Requirements -- Linux with `libfuse3-dev` and `pkg-config` (for client) -- macOS (uses built-in NFS client) - Rust 2024 edition +- PostgreSQL 14+ with `pg_trgm` extension (for agent and web player) +- Ollama with a local LLM (for agent) +- Linux with `libfuse3-dev` (for FUSE client only) ## License