feat: implemented episode actions GET route

This commit is contained in:
Jef Roosens 2025-03-04 16:44:30 +01:00
parent bcfb8805eb
commit 029eb95382
No known key found for this signature in database
GPG key ID: 21FD3D77D56BAF49
7 changed files with 180 additions and 15 deletions

View file

@ -1,9 +1,10 @@
use axum::{
extract::{Path, State},
extract::{Path, Query, State},
middleware,
routing::post,
Extension, Json, Router,
};
use serde::{Deserialize, Serialize};
use crate::{
gpodder::{self, EpisodeActionRepository},
@ -20,7 +21,10 @@ use crate::{
pub fn router(ctx: Context) -> Router<Context> {
Router::new()
.route("/{username}", post(post_episode_actions))
.route(
"/{username}",
post(post_episode_actions).get(get_episode_actions),
)
.layer(middleware::from_fn_with_state(ctx.clone(), auth_middleware))
}
@ -50,3 +54,46 @@ async fn post_episode_actions(
})?,
)
}
#[derive(Deserialize, Default)]
#[serde(default)]
struct FilterQuery {
podcast: Option<String>,
device: Option<String>,
since: Option<i64>,
aggregated: bool,
}
#[derive(Serialize)]
struct EpisodeActionsResponse {
timestamp: i64,
actions: Vec<gpodder::EpisodeAction>,
}
async fn get_episode_actions(
State(ctx): State<Context>,
Path(username): Path<StringWithFormat>,
Extension(user): Extension<gpodder::User>,
Query(filter): Query<FilterQuery>,
) -> AppResult<Json<EpisodeActionsResponse>> {
if username.format != Format::Json {
return Err(AppError::NotFound);
}
if *username != user.username {
return Err(AppError::BadRequest);
}
Ok(tokio::task::spawn_blocking(move || {
ctx.repo.episode_actions_for_user(
&user,
filter.since,
filter.podcast,
filter.device,
filter.aggregated,
)
})
.await
.unwrap()
.map(|(timestamp, actions)| Json(EpisodeActionsResponse { timestamp, actions }))?)
}