From d164edf87c889908ca4ccb783582572685610216 Mon Sep 17 00:00:00 2001 From: Priec Date: Sun, 17 May 2026 18:15:22 +0200 Subject: [PATCH] audio --- Cargo.lock | 1 + Cargo.toml | 3 +- REWRITE_SPEC.md | 10 +- assets/views/admin/audio/albums.html | 63 ++ assets/views/admin/audio/new_album.html | 56 ++ assets/views/admin/audio/tracks.html | 70 ++ assets/views/admin/audio/upload_track.html | 46 ++ assets/views/admin/base.html | 4 + assets/views/admin/images/index.html | 38 ++ assets/views/admin/index.html | 26 + assets/views/audio/album.html | 48 ++ assets/views/audio/albums.html | 42 ++ assets/views/base.html | 2 + config/development.yaml | 1 + config/test.yaml | 1 + src/app.rs | 17 +- src/controllers/media.rs | 737 +++++++++++++++++++++ src/controllers/mod.rs | 1 + 18 files changed, 1159 insertions(+), 7 deletions(-) create mode 100644 assets/views/admin/audio/albums.html create mode 100644 assets/views/admin/audio/new_album.html create mode 100644 assets/views/admin/audio/tracks.html create mode 100644 assets/views/admin/audio/upload_track.html create mode 100644 assets/views/admin/images/index.html create mode 100644 assets/views/audio/album.html create mode 100644 assets/views/audio/albums.html create mode 100644 src/controllers/media.rs diff --git a/Cargo.lock b/Cargo.lock index abfe2db..574405c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5059,6 +5059,7 @@ dependencies = [ "async-trait", "axum", "axum-extra", + "bytes", "chrono", "dotenvy", "fluent-templates", diff --git a/Cargo.toml b/Cargo.toml index af50745..8b9a81e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ tokio = { version = "1.45", default-features = false, features = [ "rt-multi-thread", ] } async-trait = { version = "0.1" } -axum = { version = "0.8" } +axum = { version = "0.8", features = ["multipart"] } tracing = { version = "0.1" } tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] } regex = { version = "1.11" } @@ -42,6 +42,7 @@ fluent-templates = { version = "0.13", features = ["tera"] } unic-langid = { version = "0.9" } # /view engine axum-extra = { version = "0.10", features = ["form"] } +bytes = { version = "1" } [[bin]] name = "universal_web-cli" diff --git a/REWRITE_SPEC.md b/REWRITE_SPEC.md index 708fb68..5a4148d 100644 --- a/REWRITE_SPEC.md +++ b/REWRITE_SPEC.md @@ -41,11 +41,11 @@ The old app ships these feature modules. Each must exist in the rewrite: - [ ] **Admin** — dashboard, user management, role assignment, audit log - [ ] **Blog** — articles CRUD, publish workflow, public listing, view counts - [ ] **Audio dashboard** — albums + tracks + tags CRUD, publish workflow -- [ ] **Audio streaming** — range-aware track/file streaming, raw upload +- [x] **Audio streaming** — range-aware track/file streaming, raw upload - [ ] **Audio player** — persistent bottom-bar player (frontend) -- [ ] **Images** — upload + serve, used as cover/featured images +- [x] **Images** — upload + serve, used as cover/featured images - [ ] **Theme** — per-user light/dark preference -- [ ] **Storage** — pluggable backend (fs default, S3/Azure/GCS capable) +- [x] **Storage** — pluggable backend (fs default, S3/Azure/GCS capable) - [ ] **Home + layout** — landing page, dynamic navbar, footer - [ ] **Swagger/OpenAPI** — API docs (optional, lower priority) @@ -366,11 +366,11 @@ Already generated in this directory — reuse, don't rebuild: 2. **Auth + sessions** — settle §3.1, get register/login/logout/me working, including admin-bootstrap. 3. **RBAC** — roles/permissions, the permission-loading middleware, guard helpers. -4. **Storage + images** — storage backend, image upload/serve (unblocks blog/audio +4. **Storage + images** — DONE: storage backend, image upload/serve (unblocks blog/audio cover images). 5. **Blog** — CRUD + publish + public pages. 6. **Audio dashboard** — albums, tracks (multipart upload), tags. -7. **Audio streaming + player** — range-aware endpoints, then the player in the GUI. +7. **Audio streaming + player** — DONE for range-aware endpoints; player remains GUI work. 8. **Admin** — dashboard, user management, role UI, audit log. 9. **Theme**, **home/layout/navbar**. 10. **Swagger/OpenAPI** (optional), tests, polish. diff --git a/assets/views/admin/audio/albums.html b/assets/views/admin/audio/albums.html new file mode 100644 index 0000000..dabd4ac --- /dev/null +++ b/assets/views/admin/audio/albums.html @@ -0,0 +1,63 @@ +{% extends "admin/base.html" %} + +{% block title %}Audio Albums{% endblock title %} + +{% block content %} +
+
+
+

Audio Albums

+

Create albums and upload audio tracks.

+
+ New album +
+ +
+
+ {% if albums | length > 0 %} +
+ + + + + + + + + + + {% for row in albums %} + + + + + + + {% endfor %} + +
AlbumStatusTracksActions
{{ row.album.title }} + {% if row.album.published %} + Published + {% else %} + Draft + {% endif %} + {{ row.track_count }} +
+ Tracks + View +
+
+
+ {% else %} +
+

No albums yet.

+

Create an album before uploading tracks.

+
+ New album +
+
+ {% endif %} +
+
+
+{% endblock content %} diff --git a/assets/views/admin/audio/new_album.html b/assets/views/admin/audio/new_album.html new file mode 100644 index 0000000..5694bd4 --- /dev/null +++ b/assets/views/admin/audio/new_album.html @@ -0,0 +1,56 @@ +{% extends "admin/base.html" %} + +{% block title %}New Audio Album{% endblock title %} + +{% block content %} +
+
+
+

New Audio Album

+

Create a container for uploaded tracks.

+
+ Back to albums +
+ +
+
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + + +
+ + Cancel +
+
+
+
+
+{% endblock content %} diff --git a/assets/views/admin/audio/tracks.html b/assets/views/admin/audio/tracks.html new file mode 100644 index 0000000..3d750c6 --- /dev/null +++ b/assets/views/admin/audio/tracks.html @@ -0,0 +1,70 @@ +{% extends "admin/base.html" %} + +{% block title %}{{ album.title }} Tracks{% endblock title %} + +{% block content %} +
+
+
+

{{ album.title }}

+

Uploaded tracks for this album.

+
+ +
+ +
+
+ {% if tracks | length > 0 %} +
+ + + + + + + + + + + {% for track in tracks %} + + + + + + + {% endfor %} + +
TrackFileFeaturedActions
+ {% if track.track_number %}{{ track.track_number }}. {% endif %}{{ track.title }} + {{ track.audio_file_id }} + {% if track.featured %} + Yes + {% else %} + No + {% endif %} + +
+ Play +
+ +
+
+
+
+ {% else %} +
+

No tracks yet.

+

Upload the first audio file for this album.

+ +
+ {% endif %} +
+
+
+{% endblock content %} diff --git a/assets/views/admin/audio/upload_track.html b/assets/views/admin/audio/upload_track.html new file mode 100644 index 0000000..7f35310 --- /dev/null +++ b/assets/views/admin/audio/upload_track.html @@ -0,0 +1,46 @@ +{% extends "admin/base.html" %} + +{% block title %}Upload Track{% endblock title %} + +{% block content %} +
+
+
+

Upload Track

+

{{ album.title }}

+
+ Back to tracks +
+ +
+
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ + + +
+ + Cancel +
+
+
+
+
+{% endblock content %} diff --git a/assets/views/admin/base.html b/assets/views/admin/base.html index c3fe292..d85f0c4 100644 --- a/assets/views/admin/base.html +++ b/assets/views/admin/base.html @@ -65,6 +65,8 @@