feat: add api docs and refactor AppEvent to struct variant
This commit is contained in:
@@ -4,7 +4,7 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
axum = { version = "0.7", features = ["macros", "ws"] }
|
||||
axum = { version = "0.8", features = ["macros", "ws"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tower = { version = "0.4", features = ["util", "timeout"] }
|
||||
tower-http = { version = "0.5", features = ["fs", "trace", "cors", "compression-full"] }
|
||||
@@ -24,3 +24,5 @@ mime_guess = "2.0"
|
||||
shared = { path = "../shared" }
|
||||
thiserror = "2.0.18"
|
||||
dotenvy = "0.15.7"
|
||||
utoipa = { version = "5.4.0", features = ["axum_extras"] }
|
||||
utoipa-swagger-ui = { version = "9.0.2", features = ["axum"] }
|
||||
|
||||
@@ -8,13 +8,16 @@ use axum::{
|
||||
use rust_embed::RustEmbed;
|
||||
use serde::Deserialize;
|
||||
use shared::TorrentActionRequest;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "../frontend/dist"]
|
||||
pub struct Asset;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct AddTorrentRequest {
|
||||
/// Magnet link or Torrent file URL
|
||||
#[schema(example = "magnet:?xt=urn:btih:...")]
|
||||
uri: String,
|
||||
}
|
||||
|
||||
@@ -46,6 +49,16 @@ pub async fn static_handler(uri: Uri) -> impl IntoResponse {
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a new torrent via magnet link or URL
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/torrents/add",
|
||||
request_body = AddTorrentRequest,
|
||||
responses(
|
||||
(status = 200, description = "Torrent added successfully"),
|
||||
(status = 500, description = "Internal server error or rTorrent fault")
|
||||
)
|
||||
)]
|
||||
pub async fn add_torrent_handler(
|
||||
State(state): State<AppState>,
|
||||
Json(payload): Json<AddTorrentRequest>,
|
||||
@@ -193,6 +206,18 @@ async fn delete_torrent_with_data(
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform an action on a torrent (start, stop, delete)
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/torrents/action",
|
||||
request_body = TorrentActionRequest,
|
||||
responses(
|
||||
(status = 200, description = "Action executed successfully"),
|
||||
(status = 400, description = "Invalid action or request"),
|
||||
(status = 403, description = "Forbidden: Security risk detected"),
|
||||
(status = 500, description = "Internal server error")
|
||||
)
|
||||
)]
|
||||
pub async fn handle_torrent_action(
|
||||
State(state): State<AppState>,
|
||||
Json(payload): Json<TorrentActionRequest>,
|
||||
|
||||
@@ -22,6 +22,8 @@ use tower_http::{
|
||||
cors::CorsLayer,
|
||||
trace::TraceLayer,
|
||||
};
|
||||
use utoipa::OpenApi;
|
||||
use utoipa_swagger_ui::SwaggerUi;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
@@ -47,6 +49,27 @@ struct Args {
|
||||
port: u16,
|
||||
}
|
||||
|
||||
#[derive(OpenApi)]
|
||||
#[openapi(
|
||||
paths(
|
||||
handlers::add_torrent_handler,
|
||||
handlers::handle_torrent_action
|
||||
),
|
||||
components(
|
||||
schemas(
|
||||
handlers::AddTorrentRequest,
|
||||
shared::TorrentActionRequest,
|
||||
shared::Torrent,
|
||||
shared::TorrentStatus,
|
||||
shared::Theme
|
||||
)
|
||||
),
|
||||
tags(
|
||||
(name = "vibetorrent", description = "VibeTorrent API")
|
||||
)
|
||||
)]
|
||||
struct ApiDoc;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Load .env file
|
||||
@@ -122,8 +145,10 @@ async fn main() {
|
||||
|
||||
match diff::diff_torrents(&previous_torrents, &new_torrents) {
|
||||
diff::DiffResult::FullUpdate => {
|
||||
let _ =
|
||||
event_bus_tx.send(AppEvent::FullList(new_torrents.clone(), now));
|
||||
let _ = event_bus_tx.send(AppEvent::FullList {
|
||||
torrents: new_torrents.clone(),
|
||||
timestamp: now,
|
||||
});
|
||||
}
|
||||
diff::DiffResult::Partial(updates) => {
|
||||
for update in updates {
|
||||
@@ -144,6 +169,7 @@ async fn main() {
|
||||
});
|
||||
|
||||
let app = Router::new()
|
||||
.merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", ApiDoc::openapi()))
|
||||
.route("/api/events", get(sse::sse_handler))
|
||||
.route("/api/torrents/add", post(handlers::add_torrent_handler))
|
||||
.route(
|
||||
|
||||
Reference in New Issue
Block a user