tsk-170: API documentation (#178)

* tsk-170: Added utopia crates for API documentation

* tsk-170: Adding code to document API

* tsk-170: icarus_models version bump

Added schema capabilities

* tsk-170: crate changes

* tsk-170: Added documentation for song queue endpoint

* tsk-170: Swagger openapi docs are now up

Well, at least one

* tsk-170: Some documentation

* tsk-170: Code formatting

* tsk-170: Saving changes

* tsk-170: Added more documentation

* tsk-170: Added the rest of the documentation

* tsk-170: Formatting

* tsk-170: icarus_models version bump
This commit was merged in pull request #178.
This commit is contained in:
KD
2025-08-24 19:58:38 -04:00
committed by GitHub
parent 598996cb8d
commit 805df87f5b
6 changed files with 580 additions and 43 deletions
+129 -15
View File
@@ -1,14 +1,26 @@
// TODO: Separate queue and coverart endpoints
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct CoverArtQueue {
pub id: uuid::Uuid,
pub song_queue_id: uuid::Uuid,
}
pub mod request {
pub mod queue {
#[derive(utoipa::ToSchema)]
pub struct Request {
/// Filename
pub file: String,
#[schema(rename = "type")]
/// File type. Should be a file and not a value
pub file_type: String,
/// Raw data of the cover art file
pub value: Vec<u8>,
}
}
pub mod link {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Request {
pub coverart_id: uuid::Uuid,
pub song_queue_id: uuid::Uuid,
@@ -16,7 +28,7 @@ pub mod request {
}
pub mod fetch_coverart_no_data {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Params {
pub id: Option<uuid::Uuid>,
pub song_queue_id: Option<uuid::Uuid>,
@@ -24,7 +36,7 @@ pub mod request {
}
pub mod fetch_coverart_with_data {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
#[derive(Debug, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Params {
pub id: Option<uuid::Uuid>,
pub song_queue_id: Option<uuid::Uuid>,
@@ -32,7 +44,7 @@ pub mod request {
}
pub mod create_coverart {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
#[derive(Debug, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Request {
pub song_id: uuid::Uuid,
pub coverart_queue_id: uuid::Uuid,
@@ -40,14 +52,14 @@ pub mod request {
}
pub mod wipe_data_from_coverart_queue {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
#[derive(Debug, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Request {
pub coverart_queue_id: uuid::Uuid,
}
}
pub mod get_coverart {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
#[derive(Debug, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Params {
pub id: Option<uuid::Uuid>,
}
@@ -55,20 +67,20 @@ pub mod request {
}
pub mod response {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<uuid::Uuid>,
}
pub mod link {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
#[derive(Debug, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Id {
pub coverart_id: uuid::Uuid,
pub song_queue_id: uuid::Uuid,
}
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<Id>,
@@ -76,7 +88,7 @@ pub mod response {
}
pub mod fetch_coverart_no_data {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<super::super::CoverArtQueue>,
@@ -84,7 +96,7 @@ pub mod response {
}
pub mod fetch_coverart_with_data {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<Vec<u8>>,
@@ -92,7 +104,7 @@ pub mod response {
}
pub mod create_coverart {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<icarus_models::coverart::CoverArt>,
@@ -100,7 +112,7 @@ pub mod response {
}
pub mod wipe_data_from_coverart_queue {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<uuid::Uuid>,
@@ -108,7 +120,7 @@ pub mod response {
}
pub mod get_coverart {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<icarus_models::coverart::CoverArt>,
@@ -465,6 +477,18 @@ pub mod endpoint {
use axum::response::IntoResponse;
/// Endpoint to queue cover art
#[utoipa::path(
post,
path = super::super::endpoints::QUEUECOVERART,
request_body(
content = super::request::queue::Request,
),
responses(
(status = 200, description = "Successful", body = super::response::Response),
(status = 400, description = "Error queueing cover art", body = super::response::Response)
)
)]
pub async fn queue(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
mut multipart: axum::extract::Multipart,
@@ -510,6 +534,20 @@ pub mod endpoint {
}
}
/// Endpoint to link queued cover art
#[utoipa::path(
post,
path = super::super::endpoints::QUEUECOVERARTLINK,
request_body(
content = super::request::link::Request,
description = "Linking queued cover art to queued song",
content_type = "application/json"
),
responses(
(status = 200, description = "Queued cover art linked", body = super::response::link::Response),
(status = 400, description = "Linkage failed", body = super::response::link::Response)
)
)]
pub async fn link(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::Json(payload): axum::Json<super::request::link::Request>,
@@ -537,6 +575,19 @@ pub mod endpoint {
}
}
/// Endpoint to fetch cover art details
#[utoipa::path(
get,
path = super::super::endpoints::QUEUECOVERART,
params(
("id" = uuid::Uuid, Path, description = "Queued cover art Id"),
("song_queue_id" = uuid::Uuid, Path, description = "Queued song Id")
),
responses(
(status = 200, description = "Queued song linked", body = super::response::fetch_coverart_no_data::Response),
(status = 400, description = "Linkage failed", body = super::response::fetch_coverart_no_data::Response)
)
)]
pub async fn fetch_coverart_no_data(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::extract::Query(params): axum::extract::Query<
@@ -584,6 +635,16 @@ pub mod endpoint {
}
}
/// Endpoint to fetch the queued cover art data
#[utoipa::path(
get,
path = super::super::endpoints::QUEUECOVERARTDATA,
params(("id" = uuid::Uuid, Path, description = "Queued cover art Id")),
responses(
(status = 200, description = "Queued cover art data", body = Vec<u8>),
(status = 400, description = "Error fetching queued cover art data", body = Vec<u8>)
)
)]
pub async fn fetch_coverart_with_data(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::extract::Path(id): axum::extract::Path<uuid::Uuid>,
@@ -612,6 +673,20 @@ pub mod endpoint {
}
}
/// Endpoint to create cover art
#[utoipa::path(
post,
path = super::super::endpoints::CREATECOVERART,
request_body(
content = super::request::create_coverart::Request,
description = "Data required to create cover art",
content_type = "application/json"
),
responses(
(status = 200, description = "Cover art created", body = super::response::create_coverart::Response),
(status = 400, description = "Failure in creating cover art", body = super::response::create_coverart::Response)
)
)]
pub async fn create_coverart(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::Json(payload): axum::Json<super::request::create_coverart::Request>,
@@ -672,6 +747,21 @@ pub mod endpoint {
}
}
/// Endpoint to wipe data from the cover art queue
#[utoipa::path(
patch,
path = super::super::endpoints::QUEUECOVERARTDATAWIPE,
request_body(
content = super::request::wipe_data_from_coverart_queue::Request,
description = "Data required to wipe the data from the cover art queue",
content_type = "application/json"
),
responses(
(status = 200, description = "Data wiped from cover art queue", body = super::response::wipe_data_from_coverart_queue::Response),
(status = 400, description = "Error wiping the data", body = super::response::wipe_data_from_coverart_queue::Response),
(status = 404, description = "Cover art not found", body = super::response::wipe_data_from_coverart_queue::Response)
)
)]
pub async fn wipe_data_from_coverart_queue(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::Json(payload): axum::Json<super::request::wipe_data_from_coverart_queue::Request>,
@@ -701,6 +791,18 @@ pub mod endpoint {
}
}
/// Endpoint to get cover art with criteria
#[utoipa::path(
get,
path = super::super::endpoints::GETCOVERART,
params(
("id" = uuid::Uuid, Path, description = "Cover art Id")
),
responses(
(status = 200, description = "Cover art retrieved", body = super::response::get_coverart::Response),
(status = 400, description = "Error retrieving cover art", body = super::response::get_coverart::Response)
)
)]
pub async fn get_coverart(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::extract::Query(params): axum::extract::Query<super::request::get_coverart::Params>,
@@ -729,6 +831,18 @@ pub mod endpoint {
}
}
/// Endpoint to download cover art
#[utoipa::path(
get,
path = super::super::endpoints::DOWNLOADCOVERART,
params(
("id" = uuid::Uuid, Path, description = "Cover art Id")
),
responses(
(status = 200, description = "Cover art downloading", body = Vec<u8>),
(status = 404, description = "Cover art not found", body = Vec<u8>)
)
)]
pub async fn download_coverart(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::extract::Path(id): axum::extract::Path<uuid::Uuid>,
+40 -8
View File
@@ -1,10 +1,9 @@
// TODO: Explicitly make this module target queueing a song's metadata
pub mod request {
pub mod queue_metadata {
use serde::{Deserialize, Serialize};
#[derive(Debug, Default, Deserialize, Serialize, sqlx::FromRow)]
#[derive(Debug, Default, Deserialize, Serialize, sqlx::FromRow, utoipa::ToSchema)]
pub struct Request {
pub song_queue_id: uuid::Uuid,
pub album: String,
@@ -43,7 +42,13 @@ pub mod request {
pub mod fetch_metadata {
#[derive(
Debug, Default, serde::Deserialize, serde::Serialize, sqlx::FromRow, sqlx::Decode,
Debug,
Default,
serde::Deserialize,
serde::Serialize,
sqlx::FromRow,
sqlx::Decode,
utoipa::ToSchema,
)]
pub struct Params {
pub id: Option<uuid::Uuid>,
@@ -53,11 +58,10 @@ pub mod request {
}
pub mod response {
pub mod queue_metadata {
use serde::{Deserialize, Serialize};
#[derive(Default, Deserialize, Serialize)]
#[derive(Default, Deserialize, Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<uuid::Uuid>,
@@ -67,7 +71,7 @@ pub mod response {
pub mod fetch_metadata {
use serde::{Deserialize, Serialize};
#[derive(Default, Deserialize, Serialize)]
#[derive(Default, Deserialize, Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<crate::callers::metadata::metadata_queue::MetadataQueue>,
@@ -83,7 +87,7 @@ pub mod metadata_queue {
pub id: uuid::Uuid,
}
#[derive(Debug, serde::Deserialize, serde::Serialize, sqlx::FromRow)]
#[derive(Debug, serde::Deserialize, serde::Serialize, sqlx::FromRow, utoipa::ToSchema)]
pub struct MetadataQueue {
pub id: uuid::Uuid,
pub metadata: serde_json::Value,
@@ -204,9 +208,24 @@ pub mod metadata_queue {
}
}
/// Module for metadata related endpoints
pub mod endpoint {
use axum::{Json, http::StatusCode};
/// Endpoint to create queued metadata
#[utoipa::path(
post,
path = super::super::endpoints::QUEUEMETADATA,
request_body(
content = super::request::queue_metadata::Request,
description = "Data required to create queued metadata",
content_type = "application/json"
),
responses(
(status = 200, description = "Queued metadata created", body = super::response::queue_metadata::Response),
(status = 400, description = "Error creating queued metadata", body = super::response::queue_metadata::Response)
)
)]
pub async fn queue_metadata(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
Json(payload): Json<super::request::queue_metadata::Request>,
@@ -221,7 +240,7 @@ pub mod endpoint {
response.message = if response.data.is_empty() {
String::from("Error")
} else {
String::from("Success")
String::from(super::super::response::SUCCESSFUL)
};
(StatusCode::OK, Json(response))
@@ -233,6 +252,19 @@ pub mod endpoint {
}
}
/// Endpoint to get queued metadata
#[utoipa::path(
get,
path = super::super::endpoints::QUEUEMETADATA,
params(
("id" = uuid::Uuid, Path, description = "Id of queued metadata"),
("song_queue_id" = uuid::Uuid, Path, description = "Id of queued song")
),
responses(
(status = 200, description = "Queued metadata retrieved", body = super::response::fetch_metadata::Response),
(status = 400, description = "Error retrieving queued metadata", body = super::response::fetch_metadata::Response)
)
)]
pub async fn fetch_metadata(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::extract::Query(params): axum::extract::Query<super::request::fetch_metadata::Params>,
+193 -17
View File
@@ -7,8 +7,21 @@ pub mod request {
pub message: String,
}
pub mod song_queue {
#[derive(utoipa::ToSchema)]
pub struct SongQueueRequest {
/// Filename
pub file: String,
#[schema(rename = "type")]
/// File type. Should be a file and not a value
pub file_type: String,
/// Raw data of the flac file
pub value: Vec<u8>,
}
}
pub mod update_status {
#[derive(Default, serde::Deserialize, serde::Serialize)]
#[derive(Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Request {
pub id: uuid::Uuid,
pub status: String,
@@ -16,7 +29,7 @@ pub mod request {
}
pub mod create_metadata {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
#[derive(Debug, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Request {
pub title: String,
pub artist: String,
@@ -79,14 +92,14 @@ pub mod request {
}
pub mod wipe_data_from_song_queue {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
#[derive(Debug, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Request {
pub song_queue_id: uuid::Uuid,
}
}
pub mod link_user_id {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
#[derive(Debug, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Request {
pub song_queue_id: uuid::Uuid,
pub user_id: uuid::Uuid,
@@ -94,7 +107,7 @@ pub mod request {
}
pub mod get_songs {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Params {
pub id: Option<uuid::Uuid>,
}
@@ -104,16 +117,18 @@ pub mod request {
pub mod response {
use serde::{Deserialize, Serialize};
#[derive(Default, Deserialize, Serialize)]
/// Song queue response
#[derive(Default, Deserialize, Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
/// Id of the queued song
pub data: Vec<uuid::Uuid>,
}
pub mod fetch_queue_song {
use serde::{Deserialize, Serialize};
#[derive(Default, Deserialize, Serialize)]
#[derive(Default, Deserialize, Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<crate::callers::song::song_queue::SongQueue>,
@@ -121,13 +136,13 @@ pub mod response {
}
pub mod update_status {
#[derive(serde::Deserialize, serde::Serialize)]
#[derive(serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct ChangedStatus {
pub old_status: String,
pub new_status: String,
}
#[derive(Default, serde::Deserialize, serde::Serialize)]
#[derive(Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<ChangedStatus>,
@@ -135,7 +150,7 @@ pub mod response {
}
pub mod update_song_queue {
#[derive(Default, serde::Deserialize, serde::Serialize)]
#[derive(Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<uuid::Uuid>,
@@ -143,7 +158,7 @@ pub mod response {
}
pub mod create_metadata {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<icarus_models::song::Song>,
@@ -151,7 +166,7 @@ pub mod response {
}
pub mod wipe_data_from_song_queue {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<uuid::Uuid>,
@@ -159,7 +174,7 @@ pub mod response {
}
pub mod link_user_id {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<uuid::Uuid>,
@@ -167,7 +182,7 @@ pub mod response {
}
pub mod get_songs {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<icarus_models::song::Song>,
@@ -175,13 +190,13 @@ pub mod response {
}
pub mod delete_song {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct SongAndCoverArt {
pub song: icarus_models::song::Song,
pub coverart: icarus_models::coverart::CoverArt,
}
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct Response {
pub message: String,
pub data: Vec<SongAndCoverArt>,
@@ -561,7 +576,8 @@ mod song_queue {
pub id: uuid::Uuid,
}
#[derive(Debug, serde::Deserialize, serde::Serialize, sqlx::FromRow)]
// TODO: Move this somewhere else at some point
#[derive(Debug, serde::Deserialize, serde::Serialize, sqlx::FromRow, utoipa::ToSchema)]
pub struct SongQueue {
pub id: uuid::Uuid,
pub filename: String,
@@ -854,12 +870,27 @@ mod song_queue {
}
}
/// Module for song related endpoints
pub mod endpoint {
use axum::{Json, http::StatusCode, response::IntoResponse};
use std::io::Write;
use crate::callers::song::song_queue;
/// Endpoint to queue a song. Starts the process and places the song in a queue
#[utoipa::path(
post,
path = super::super::endpoints::QUEUESONG,
request_body(
content = super::request::song_queue::SongQueueRequest,
description = "Multipart form data for uploading song",
content_type = "multipart/form-data"
),
responses(
(status = 200, description = "Song queued", body = super::response::Response)
)
)]
pub async fn queue_song(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
mut multipart: axum::extract::Multipart,
@@ -908,6 +939,20 @@ pub mod endpoint {
(StatusCode::OK, Json(response))
}
/// Endpoint to link a user id to a queued song
#[utoipa::path(
patch,
path = super::super::endpoints::QUEUESONGLINKUSERID,
request_body(
content = super::request::link_user_id::Request,
description = "User Id and queued song id",
content_type = "application/json"
),
responses(
(status = 200, description = "Queued song linked", body = super::response::link_user_id::Response),
(status = 400, description = "Linkage failed", body = super::response::link_user_id::Response)
)
)]
pub async fn link_user_id(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::Json(payload): axum::Json<super::request::link_user_id::Request>,
@@ -939,6 +984,15 @@ pub mod endpoint {
}
}
/// Endpoint to fetch the next queued song as long as it is available
#[utoipa::path(
get,
path = super::super::endpoints::NEXTQUEUESONG,
responses(
(status = 200, description = "Queued song is present and available", body = super::response::fetch_queue_song::Response),
(status = 400, description = "Linkage failed", body = super::response::fetch_queue_song::Response)
)
)]
pub async fn fetch_queue_song(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
) -> (
@@ -961,6 +1015,16 @@ pub mod endpoint {
}
// TODO: Rename
/// Endpoint to download the queued song
#[utoipa::path(
get,
path = super::super::endpoints::QUEUESONGDATA,
params(("id" = uuid::Uuid, Path, description = "Queued song Id")),
responses(
(status = 200, description = "Queued song linked", body = Vec<u8>),
(status = 400, description = "Linkage failed", body = Vec<u8>)
)
)]
pub async fn download_flac(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::extract::Path(id): axum::extract::Path<uuid::Uuid>,
@@ -989,6 +1053,20 @@ pub mod endpoint {
}
}
/// Endpoint to update the status of a queued song
#[utoipa::path(
patch,
path = super::super::endpoints::QUEUESONG,
request_body(
content = super::request::update_status::Request,
description = "Update the status of a queued song",
content_type = "application/json"
),
responses(
(status = 200, description = "Status has been updated", body = super::response::update_status::Response),
(status = 400, description = "Error updating status of queued song", body = super::response::update_status::Response)
)
)]
pub async fn update_song_queue_status(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::Json(payload): axum::Json<super::request::update_status::Request>,
@@ -1041,6 +1119,22 @@ pub mod endpoint {
}
}
/// Endpoint to update the queued song data
#[utoipa::path(
patch,
path = super::super::endpoints::QUEUESONGUPDATE,
request_body(
content = super::request::song_queue::SongQueueRequest,
description = "Multipart form data for uploading song",
content_type = "multipart/form-data"
),
params(("id" = uuid::Uuid, Path, description = "Queued song Id")),
responses(
(status = 200, description = "Queued song updated", body = super::response::update_song_queue::Response),
(status = 400, description = "Error updating queued song", body = super::response::update_song_queue::Response),
(status = 404, description = "Queued song not found", body = super::response::update_song_queue::Response)
)
)]
pub async fn update_song_queue(
axum::extract::Path(id): axum::extract::Path<uuid::Uuid>,
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
@@ -1087,6 +1181,21 @@ pub mod endpoint {
}
}
/// Endpoint to create song
#[utoipa::path(
post,
path = super::super::endpoints::QUEUEMETADATA,
request_body(
content = super::request::create_metadata::Request,
description = "Data needed to create the song and save it to the filesystem",
content_type = "application/json"
),
responses(
(status = 200, description = "Song created", body = super::response::create_metadata::Response),
(status = 400, description = "Error", body = super::response::create_metadata::Response),
(status = 505, description = "Error creating song", body = super::response::create_metadata::Response)
)
)]
pub async fn create_metadata(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::Json(payload): axum::Json<super::request::create_metadata::Request>,
@@ -1170,6 +1279,20 @@ pub mod endpoint {
}
}
/// Endpoint to wipe the data from a queued song
#[utoipa::path(
patch,
path = super::super::endpoints::QUEUESONGDATAWIPE,
request_body(
content = super::request::wipe_data_from_song_queue::Request,
description = "Pass the queued song Id to wipe the data",
content_type = "application/json"
),
responses(
(status = 200, description = "Queued song data wiped", body = super::response::wipe_data_from_song_queue::Response),
(status = 404, description = "Queued song cannot be found", body = super::response::wipe_data_from_song_queue::Response)
)
)]
pub async fn wipe_data_from_song_queue(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::Json(payload): axum::Json<super::request::wipe_data_from_song_queue::Request>,
@@ -1200,6 +1323,18 @@ pub mod endpoint {
}
}
// Endpoint to get songs
#[utoipa::path(
get,
path = super::super::endpoints::GETSONGS,
params(
("id" = uuid::Uuid, Path, description = "Id of song")
),
responses(
(status = 200, description = "Songs found", body = super::response::get_songs::Response),
(status = 400, description = "Error getting songs", body = super::response::get_songs::Response)
)
)]
pub async fn get_songs(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::extract::Query(params): axum::extract::Query<super::request::get_songs::Params>,
@@ -1228,6 +1363,15 @@ pub mod endpoint {
}
}
/// Endpoint to get all songs
#[utoipa::path(
get,
path = super::super::endpoints::GETALLSONGS,
responses(
(status = 200, description = "Getting all songs", body = super::response::get_songs::Response),
(status = 404, description = "Song not found", body = super::response::get_songs::Response)
)
)]
pub async fn get_all_songs(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
) -> (
@@ -1249,6 +1393,16 @@ pub mod endpoint {
}
}
/// Ednpoint to stream song
#[utoipa::path(
get,
path = super::super::endpoints::STREAMSONG,
params(("id" = uuid::Uuid, Path, description = "Song Id")),
responses(
(status = 200, description = "Stream song", body = Vec<u8>),
(status = 500, description = "Error streaming song", body = (u64, String))
)
)]
pub async fn stream_song(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::extract::Path(id): axum::extract::Path<uuid::Uuid>,
@@ -1296,6 +1450,17 @@ pub mod endpoint {
}
}
/// Endpoint to download song
#[utoipa::path(
get,
path = super::super::endpoints::DOWNLOADSONG,
params(("id" = uuid::Uuid, Path, description = "Song Id")),
responses(
(status = 200, description = "Download song", body = (u64, Vec<u8>)),
(status = 404, description = "Song not found", body = (u64, Vec<u8>)),
(status = 400, description = "Error downloading song", body = (u64, Vec<u8>))
)
)]
pub async fn download_song(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::extract::Path(id): axum::extract::Path<uuid::Uuid>,
@@ -1331,6 +1496,17 @@ pub mod endpoint {
}
}
/// Endpoint to delete the song
#[utoipa::path(
delete,
path = super::super::endpoints::DELETESONG,
params(("id" = uuid::Uuid, Path, description = "Song Id")),
responses(
(status = 200, description = "Song deleted", body = super::response::delete_song::Response),
(status = 404, description = "Song not found", body = super::response::delete_song::Response),
(status = 500, description = "Error deleting song", body = super::response::delete_song::Response)
)
)]
pub async fn delete_song(
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
axum::extract::Path(id): axum::extract::Path<uuid::Uuid>,
+36
View File
@@ -48,12 +48,44 @@ pub mod init {
use axum::routing::{delete, get, patch, post};
use std::time::Duration;
use tower_http::timeout::TimeoutLayer;
use utoipa::OpenApi;
use axum::http::{
HeaderValue, Method,
header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE},
};
use crate::callers::coverart as coverart_caller;
use crate::callers::metadata as metadata_caller;
use crate::callers::song as song_caller;
use coverart_caller::endpoint as coverart_endpoints;
use coverart_caller::response as coverart_responses;
use metadata_caller::endpoint as metadata_endpoints;
use metadata_caller::response as metadata_responses;
use song_caller::endpoint as song_endpoints;
use song_caller::response as song_responses;
#[derive(utoipa::OpenApi)]
#[openapi(
paths(song_endpoints::queue_song, song_endpoints::link_user_id, song_endpoints::fetch_queue_song, song_endpoints::download_flac,
song_endpoints::update_song_queue_status, song_endpoints::update_song_queue, song_endpoints::create_metadata, song_endpoints::wipe_data_from_song_queue, song_endpoints::get_songs, song_endpoints::get_all_songs, song_endpoints::stream_song, song_endpoints::download_song,
song_endpoints::delete_song, coverart_endpoints::queue, coverart_endpoints::link, coverart_endpoints::fetch_coverart_no_data,
coverart_endpoints::fetch_coverart_with_data, coverart_endpoints::create_coverart, coverart_endpoints::wipe_data_from_coverart_queue,
coverart_endpoints::get_coverart, coverart_endpoints::download_coverart,
metadata_endpoints::queue_metadata, metadata_endpoints::fetch_metadata),
components(schemas(song_responses::Response, song_responses::link_user_id::Response, song_responses::fetch_queue_song::Response,
song_responses::update_status::Response, song_responses::update_song_queue::Response, song_responses::create_metadata::Response,
song_responses::wipe_data_from_song_queue::Response, song_responses::get_songs::Response, song_responses::delete_song::Response,
coverart_responses::Response, coverart_responses::link::Response, coverart_responses::fetch_coverart_no_data::Response,
coverart_responses::fetch_coverart_with_data::Response, coverart_responses::create_coverart::Response,
coverart_responses::wipe_data_from_coverart_queue::Response, coverart_responses::get_coverart::Response,
metadata_responses::queue_metadata::Response, metadata_responses::fetch_metadata::Response)),
tags(
(name = "Icarus API", description = "Web API to manage music")
)
)]
struct ApiDoc;
pub async fn routes() -> axum::Router {
axum::Router::new()
.route(crate::ROOT, get(crate::root))
@@ -211,6 +243,10 @@ pub mod init {
routes()
.await
.merge(
utoipa_swagger_ui::SwaggerUi::new("/swagger-ui")
.url("/api-docs/openapi.json", ApiDoc::openapi()),
)
.layer(axum::Extension(pool))
.layer(axum::extract::DefaultBodyLimit::max(1024 * 1024 * 1024))
.layer(TimeoutLayer::new(Duration::from_secs(300)))