pinakes-ui: streamline sidebar design
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I0176fa480e5ba40eea5a39685a4f97896a6a6964
This commit is contained in:
parent
3e14bbe607
commit
278bcaa4b0
25 changed files with 1805 additions and 1686 deletions
|
|
@ -100,13 +100,14 @@ pub async fn update_playlist(
|
|||
Json(req): Json<UpdatePlaylistRequest>,
|
||||
) -> Result<Json<PlaylistResponse>, ApiError> {
|
||||
if let Some(ref name) = req.name
|
||||
&& (name.is_empty() || name.chars().count() > 255) {
|
||||
return Err(ApiError(
|
||||
pinakes_core::error::PinakesError::InvalidOperation(
|
||||
"playlist name must be 1-255 characters".into(),
|
||||
),
|
||||
));
|
||||
}
|
||||
&& (name.is_empty() || name.chars().count() > 255)
|
||||
{
|
||||
return Err(ApiError(
|
||||
pinakes_core::error::PinakesError::InvalidOperation(
|
||||
"playlist name must be 1-255 characters".into(),
|
||||
),
|
||||
));
|
||||
}
|
||||
let user_id = resolve_user_id(&state.storage, &username).await?;
|
||||
check_playlist_access(&state.storage, id, user_id, true).await?;
|
||||
let playlist = state
|
||||
|
|
|
|||
|
|
@ -137,14 +137,15 @@ pub async fn create_share_link(
|
|||
};
|
||||
const MAX_EXPIRY_HOURS: u64 = 8760; // 1 year
|
||||
if let Some(h) = req.expires_in_hours
|
||||
&& h > MAX_EXPIRY_HOURS {
|
||||
return Err(ApiError(
|
||||
pinakes_core::error::PinakesError::InvalidOperation(format!(
|
||||
"expires_in_hours cannot exceed {}",
|
||||
MAX_EXPIRY_HOURS
|
||||
)),
|
||||
));
|
||||
}
|
||||
&& h > MAX_EXPIRY_HOURS
|
||||
{
|
||||
return Err(ApiError(
|
||||
pinakes_core::error::PinakesError::InvalidOperation(format!(
|
||||
"expires_in_hours cannot exceed {}",
|
||||
MAX_EXPIRY_HOURS
|
||||
)),
|
||||
));
|
||||
}
|
||||
let expires_at = req
|
||||
.expires_in_hours
|
||||
.map(|h| chrono::Utc::now() + chrono::Duration::hours(h as i64));
|
||||
|
|
@ -169,13 +170,12 @@ pub async fn access_shared_media(
|
|||
let link = state.storage.get_share_link(&token).await?;
|
||||
// Check expiration
|
||||
if let Some(expires) = link.expires_at
|
||||
&& chrono::Utc::now() > expires {
|
||||
return Err(ApiError(
|
||||
pinakes_core::error::PinakesError::InvalidOperation(
|
||||
"share link has expired".into(),
|
||||
),
|
||||
));
|
||||
}
|
||||
&& chrono::Utc::now() > expires
|
||||
{
|
||||
return Err(ApiError(
|
||||
pinakes_core::error::PinakesError::InvalidOperation("share link has expired".into()),
|
||||
));
|
||||
}
|
||||
// Verify password if set
|
||||
if let Some(ref hash) = link.password_hash {
|
||||
let password = match query.password.as_deref() {
|
||||
|
|
|
|||
|
|
@ -104,30 +104,31 @@ pub async fn hls_segment(
|
|||
|
||||
// Look for an active/completed transcode session
|
||||
if let Some(transcode_service) = &state.transcode_service
|
||||
&& let Some(session) = transcode_service.find_session(media_id, &profile).await {
|
||||
let segment_path = session.cache_path.join(&segment);
|
||||
&& let Some(session) = transcode_service.find_session(media_id, &profile).await
|
||||
{
|
||||
let segment_path = session.cache_path.join(&segment);
|
||||
|
||||
if segment_path.exists() {
|
||||
let data = tokio::fs::read(&segment_path).await.map_err(|e| {
|
||||
ApiError(pinakes_core::error::PinakesError::InvalidOperation(
|
||||
format!("failed to read segment: {}", e),
|
||||
))
|
||||
})?;
|
||||
if segment_path.exists() {
|
||||
let data = tokio::fs::read(&segment_path).await.map_err(|e| {
|
||||
ApiError(pinakes_core::error::PinakesError::InvalidOperation(
|
||||
format!("failed to read segment: {}", e),
|
||||
))
|
||||
})?;
|
||||
|
||||
return Ok(axum::response::Response::builder()
|
||||
.header("Content-Type", "video/MP2T")
|
||||
.body(axum::body::Body::from(data))
|
||||
.unwrap());
|
||||
}
|
||||
|
||||
// Session exists but segment not ready yet
|
||||
return Ok(axum::response::Response::builder()
|
||||
.status(StatusCode::ACCEPTED)
|
||||
.header("Retry-After", "2")
|
||||
.body(axum::body::Body::from("segment not yet available"))
|
||||
.header("Content-Type", "video/MP2T")
|
||||
.body(axum::body::Body::from(data))
|
||||
.unwrap());
|
||||
}
|
||||
|
||||
// Session exists but segment not ready yet
|
||||
return Ok(axum::response::Response::builder()
|
||||
.status(StatusCode::ACCEPTED)
|
||||
.header("Retry-After", "2")
|
||||
.body(axum::body::Body::from("segment not yet available"))
|
||||
.unwrap());
|
||||
}
|
||||
|
||||
Err(ApiError(
|
||||
pinakes_core::error::PinakesError::InvalidOperation(
|
||||
"no transcode session found; start a transcode first via POST /media/{id}/transcode"
|
||||
|
|
@ -206,29 +207,30 @@ pub async fn dash_segment(
|
|||
let media_id = MediaId(id);
|
||||
|
||||
if let Some(transcode_service) = &state.transcode_service
|
||||
&& let Some(session) = transcode_service.find_session(media_id, &profile).await {
|
||||
let segment_path = session.cache_path.join(&segment);
|
||||
&& let Some(session) = transcode_service.find_session(media_id, &profile).await
|
||||
{
|
||||
let segment_path = session.cache_path.join(&segment);
|
||||
|
||||
if segment_path.exists() {
|
||||
let data = tokio::fs::read(&segment_path).await.map_err(|e| {
|
||||
ApiError(pinakes_core::error::PinakesError::InvalidOperation(
|
||||
format!("failed to read segment: {}", e),
|
||||
))
|
||||
})?;
|
||||
|
||||
return Ok(axum::response::Response::builder()
|
||||
.header("Content-Type", "video/mp4")
|
||||
.body(axum::body::Body::from(data))
|
||||
.unwrap());
|
||||
}
|
||||
if segment_path.exists() {
|
||||
let data = tokio::fs::read(&segment_path).await.map_err(|e| {
|
||||
ApiError(pinakes_core::error::PinakesError::InvalidOperation(
|
||||
format!("failed to read segment: {}", e),
|
||||
))
|
||||
})?;
|
||||
|
||||
return Ok(axum::response::Response::builder()
|
||||
.status(StatusCode::ACCEPTED)
|
||||
.header("Retry-After", "2")
|
||||
.body(axum::body::Body::from("segment not yet available"))
|
||||
.header("Content-Type", "video/mp4")
|
||||
.body(axum::body::Body::from(data))
|
||||
.unwrap());
|
||||
}
|
||||
|
||||
return Ok(axum::response::Response::builder()
|
||||
.status(StatusCode::ACCEPTED)
|
||||
.header("Retry-After", "2")
|
||||
.body(axum::body::Body::from("segment not yet available"))
|
||||
.unwrap());
|
||||
}
|
||||
|
||||
Err(ApiError(
|
||||
pinakes_core::error::PinakesError::InvalidOperation(
|
||||
"no transcode session found; start a transcode first via POST /media/{id}/transcode"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue