pinakes-server: fix api key timing, notification scoping, and validate progress inputs
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Ieb342b4b48034de0a2184cdf89d068316a6a6964
This commit is contained in:
parent
52f0b5defc
commit
2b2c1830a1
7 changed files with 334 additions and 179 deletions
|
|
@ -8,11 +8,41 @@ use pinakes_core::{
|
|||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{dto::*, error::ApiError, state::AppState};
|
||||
use crate::{
|
||||
dto::{
|
||||
BatchCollectionRequest,
|
||||
BatchDeleteRequest,
|
||||
BatchImportItemResult,
|
||||
BatchImportRequest,
|
||||
BatchImportResponse,
|
||||
BatchMoveRequest,
|
||||
BatchOperationResponse,
|
||||
BatchTagRequest,
|
||||
BatchUpdateRequest,
|
||||
DirectoryImportRequest,
|
||||
DirectoryPreviewFile,
|
||||
DirectoryPreviewResponse,
|
||||
EmptyTrashResponse,
|
||||
ImportRequest,
|
||||
ImportResponse,
|
||||
ImportWithOptionsRequest,
|
||||
MediaCountResponse,
|
||||
MediaResponse,
|
||||
MoveMediaRequest,
|
||||
PaginationParams,
|
||||
RenameMediaRequest,
|
||||
SetCustomFieldRequest,
|
||||
TrashInfoResponse,
|
||||
TrashResponse,
|
||||
UpdateMediaRequest,
|
||||
},
|
||||
error::ApiError,
|
||||
state::AppState,
|
||||
};
|
||||
|
||||
/// Apply tags and add to collection after a successful import.
|
||||
/// Shared logic used by import_with_options, batch_import, and
|
||||
/// import_directory_endpoint.
|
||||
/// Shared logic used by `import_with_options`, `batch_import`, and
|
||||
/// `import_directory_endpoint`.
|
||||
async fn apply_import_post_processing(
|
||||
storage: &DynStorageBackend,
|
||||
media_id: MediaId,
|
||||
|
|
@ -59,6 +89,17 @@ pub async fn import_media(
|
|||
) -> Result<Json<ImportResponse>, ApiError> {
|
||||
let result =
|
||||
pinakes_core::import::import_file(&state.storage, &req.path).await?;
|
||||
|
||||
if let Some(ref dispatcher) = state.webhook_dispatcher {
|
||||
let id = result.media_id.0.to_string();
|
||||
dispatcher.dispatch(pinakes_core::webhooks::WebhookEvent::MediaCreated {
|
||||
media_id: id.clone(),
|
||||
});
|
||||
dispatcher.dispatch(
|
||||
pinakes_core::webhooks::WebhookEvent::ImportCompleted { media_id: id },
|
||||
);
|
||||
}
|
||||
|
||||
Ok(Json(ImportResponse {
|
||||
media_id: result.media_id.0.to_string(),
|
||||
was_duplicate: result.was_duplicate,
|
||||
|
|
@ -150,6 +191,12 @@ pub async fn update_media(
|
|||
)
|
||||
.await?;
|
||||
|
||||
if let Some(ref dispatcher) = state.webhook_dispatcher {
|
||||
dispatcher.dispatch(pinakes_core::webhooks::WebhookEvent::MediaUpdated {
|
||||
media_id: item.id.0.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(Json(MediaResponse::from(item)))
|
||||
}
|
||||
|
||||
|
|
@ -473,7 +520,7 @@ pub async fn preview_directory(
|
|||
})?;
|
||||
let recursive = req
|
||||
.get("recursive")
|
||||
.and_then(|v| v.as_bool())
|
||||
.and_then(serde_json::Value::as_bool)
|
||||
.unwrap_or(true);
|
||||
let dir = std::path::PathBuf::from(path_str);
|
||||
if !dir.is_dir() {
|
||||
|
|
@ -515,8 +562,7 @@ pub async fn preview_directory(
|
|||
// Skip hidden files/dirs
|
||||
if path
|
||||
.file_name()
|
||||
.map(|n| n.to_string_lossy().starts_with('.'))
|
||||
.unwrap_or(false)
|
||||
.is_some_and(|n| n.to_string_lossy().starts_with('.'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -528,7 +574,7 @@ pub async fn preview_directory(
|
|||
&& let Some(mt) =
|
||||
pinakes_core::media_type::MediaType::from_path(&path)
|
||||
{
|
||||
let size = entry.metadata().ok().map(|m| m.len()).unwrap_or(0);
|
||||
let size = entry.metadata().ok().map_or(0, |m| m.len());
|
||||
let file_name = path
|
||||
.file_name()
|
||||
.map(|n| n.to_string_lossy().to_string())
|
||||
|
|
@ -579,8 +625,7 @@ pub async fn set_custom_field(
|
|||
if req.value.len() > MAX_LONG_TEXT {
|
||||
return Err(ApiError(
|
||||
pinakes_core::error::PinakesError::InvalidOperation(format!(
|
||||
"field value exceeds {} characters",
|
||||
MAX_LONG_TEXT
|
||||
"field value exceeds {MAX_LONG_TEXT} characters"
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
|
@ -747,7 +792,7 @@ pub async fn batch_add_to_collection(
|
|||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => processed += 1,
|
||||
Ok(()) => processed += 1,
|
||||
Err(e) => errors.push(format!("{media_id}: {e}")),
|
||||
}
|
||||
}
|
||||
|
|
@ -1113,10 +1158,7 @@ pub async fn permanent_delete_media(
|
|||
Query(params): Query<std::collections::HashMap<String, String>>,
|
||||
) -> Result<Json<serde_json::Value>, ApiError> {
|
||||
let media_id = MediaId(id);
|
||||
let permanent = params
|
||||
.get("permanent")
|
||||
.map(|v| v == "true")
|
||||
.unwrap_or(false);
|
||||
let permanent = params.get("permanent").is_some_and(|v| v == "true");
|
||||
|
||||
if permanent {
|
||||
// Get item info before delete
|
||||
|
|
@ -1161,6 +1203,12 @@ pub async fn permanent_delete_media(
|
|||
tracing::warn!(path = %thumb_path.display(), error = %e, "failed to remove thumbnail");
|
||||
}
|
||||
|
||||
if let Some(ref dispatcher) = state.webhook_dispatcher {
|
||||
dispatcher.dispatch(pinakes_core::webhooks::WebhookEvent::MediaDeleted {
|
||||
media_id: id.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(Json(
|
||||
serde_json::json!({"deleted": true, "permanent": true}),
|
||||
))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue