Upload a new soundtrack through the API #33

Open
opened 2026-10-09 16:04:08 +02:00 by Sansan · 0 comments
Owner

Let a client add a new soundtrack: it uploads the songs, the server writes them to a new folder in the music folder and adds them to the database, without waiting for the next sync.

Feasibility

Yes. SyncService already has syncSoundtrack(ctx, name) and syncSongs for one folder, so after writing the files the server can sync just that folder.

Plan

  • Endpoints (token required):
    1. POST /api/v1/soundtracks/uploads with {"name": "Chrono Trigger"} starts an upload.
      • It checks that the name is a safe folder name (no /, .. or hidden names) and that no soundtrack or folder of that name exists (409).
      • It returns an upload ID. Files go to a temporary folder, e.g. MUSIC_PATH/.uploads/<id>/. Hidden folders are skipped by the sync.
    2. PUT /api/v1/soundtracks/uploads/{id}/files/{file name} sends one song as the raw body. One request per song keeps requests small, and a failed song can be retried.
      • Only audio types the sync accepts.
      • Size limit per file (configurable).
      • The file name is sanitized.
    3. POST /api/v1/soundtracks/uploads/{id}/finish moves the folder to MUSIC_PATH/<name>, runs syncSoundtrack for it, reloads the search cache and returns the new soundtrack (UUID, songs).
    4. DELETE /api/v1/soundtracks/uploads/{id} cancels the upload. Uploads left unfinished are cleaned up after a day.
  • Syncing. Refuse uploads while a sync runs (IsSyncing()), and the other way around, so the two never touch the same folder.
  • Limits. Echo body limit for these routes; a total size cap per upload.
  • Tests. Integration tests like sync_integration_test.go: upload, finish, the soundtrack and songs are in the database; bad names; duplicate names; a cancelled upload leaves nothing behind.

Questions

  • The music folder is mounted from ResilioSync in compose.yaml. Is it mounted read-only in production? The server needs write access, and the new folder will then also be synced by Resilio to your other devices. Is that what you want?
  • Subfolders in an upload (discs) — keep them like the sync does today, or flatten them?
  • Should the frontend get an upload page too, or only MusicPlayer?

Used by

Let a client add a new soundtrack: it uploads the songs, the server writes them to a new folder in the music folder and adds them to the database, without waiting for the next sync. ## Feasibility Yes. `SyncService` already has `syncSoundtrack(ctx, name)` and `syncSongs` for one folder, so after writing the files the server can sync just that folder. ## Plan - **Endpoints** (token required): 1. `POST /api/v1/soundtracks/uploads` with `{"name": "Chrono Trigger"}` starts an upload. - It checks that the name is a safe folder name (no `/`, `..` or hidden names) and that no soundtrack or folder of that name exists (409). - It returns an upload ID. Files go to a temporary folder, e.g. `MUSIC_PATH/.uploads/<id>/`. Hidden folders are skipped by the sync. 2. `PUT /api/v1/soundtracks/uploads/{id}/files/{file name}` sends one song as the raw body. One request per song keeps requests small, and a failed song can be retried. - Only audio types the sync accepts. - Size limit per file (configurable). - The file name is sanitized. 3. `POST /api/v1/soundtracks/uploads/{id}/finish` moves the folder to `MUSIC_PATH/<name>`, runs `syncSoundtrack` for it, reloads the search cache and returns the new soundtrack (UUID, songs). 4. `DELETE /api/v1/soundtracks/uploads/{id}` cancels the upload. Uploads left unfinished are cleaned up after a day. - **Syncing.** Refuse uploads while a sync runs (`IsSyncing()`), and the other way around, so the two never touch the same folder. - **Limits.** Echo body limit for these routes; a total size cap per upload. - **Tests.** Integration tests like `sync_integration_test.go`: upload, finish, the soundtrack and songs are in the database; bad names; duplicate names; a cancelled upload leaves nothing behind. ## Questions - The music folder is mounted from ResilioSync in `compose.yaml`. Is it mounted read-only in production? The server needs write access, and the new folder will then also be synced by Resilio to your other devices. Is that what you want? - Subfolders in an upload (discs) — keep them like the sync does today, or flatten them? - Should the frontend get an upload page too, or only MusicPlayer? ## Used by - MusicPlayer: upload from the app, Sansan/MusicPlayer#50.
Sansan added the feature label 2026-10-09 16:04:08 +02:00
Sansan added the area/library label 2026-10-15 21:56:58 +02:00
Sign in to join this conversation.