Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I4c4815ad145650a07f108614034d2e996a6a6964
127 lines
3.1 KiB
Rust
127 lines
3.1 KiB
Rust
use uuid::Uuid;
|
|
|
|
use crate::{error::Result, model::*, storage::DynStorageBackend};
|
|
|
|
/// Creates a new collection.
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `storage` - Storage backend
|
|
/// * `name` - Collection name
|
|
/// * `kind` - Manual or virtual collection
|
|
/// * `description` - Optional description
|
|
/// * `filter_query` - For virtual collections, the search query
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// The created collection
|
|
pub async fn create_collection(
|
|
storage: &DynStorageBackend,
|
|
name: &str,
|
|
kind: CollectionKind,
|
|
description: Option<&str>,
|
|
filter_query: Option<&str>,
|
|
) -> Result<Collection> {
|
|
storage
|
|
.create_collection(name, kind, description, filter_query)
|
|
.await
|
|
}
|
|
|
|
/// Adds a media item to a collection.
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `storage` - Storage backend
|
|
/// * `collection_id` - Target collection
|
|
/// * `media_id` - Media item to add
|
|
/// * `position` - Position in the collection order
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// `Ok(())` on success
|
|
pub async fn add_member(
|
|
storage: &DynStorageBackend,
|
|
collection_id: Uuid,
|
|
media_id: MediaId,
|
|
position: i32,
|
|
) -> Result<()> {
|
|
storage
|
|
.add_to_collection(collection_id, media_id, position)
|
|
.await?;
|
|
crate::audit::record_action(
|
|
storage,
|
|
Some(media_id),
|
|
AuditAction::AddedToCollection,
|
|
Some(format!("collection_id={collection_id}")),
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Removes a media item from a collection.
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `storage` - Storage backend
|
|
/// * `collection_id` - Target collection
|
|
/// * `media_id` - Media item to remove
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// `Ok(())` on success
|
|
pub async fn remove_member(
|
|
storage: &DynStorageBackend,
|
|
collection_id: Uuid,
|
|
media_id: MediaId,
|
|
) -> Result<()> {
|
|
storage
|
|
.remove_from_collection(collection_id, media_id)
|
|
.await?;
|
|
crate::audit::record_action(
|
|
storage,
|
|
Some(media_id),
|
|
AuditAction::RemovedFromCollection,
|
|
Some(format!("collection_id={collection_id}")),
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Returns all media items in a collection.
|
|
///
|
|
/// Virtual collections are evaluated dynamically using their filter query.
|
|
/// Manual collections return stored members.
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `storage` - Storage backend
|
|
/// * `collection_id` - Collection to query
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// List of media items in the collection
|
|
pub async fn get_members(
|
|
storage: &DynStorageBackend,
|
|
collection_id: Uuid,
|
|
) -> Result<Vec<MediaItem>> {
|
|
let collection = storage.get_collection(collection_id).await?;
|
|
|
|
match collection.kind {
|
|
CollectionKind::Virtual => {
|
|
// Virtual collections evaluate their filter_query dynamically
|
|
if let Some(ref query_str) = collection.filter_query {
|
|
let query = crate::search::parse_search_query(query_str)?;
|
|
let request = crate::search::SearchRequest {
|
|
query,
|
|
sort: crate::search::SortOrder::DateDesc,
|
|
pagination: Pagination::new(0, 10000, None),
|
|
};
|
|
let results = storage.search(&request).await?;
|
|
Ok(results.items)
|
|
} else {
|
|
Ok(Vec::new())
|
|
}
|
|
},
|
|
CollectionKind::Manual => {
|
|
storage.get_collection_members(collection_id).await
|
|
},
|
|
}
|
|
}
|