Ugh
This commit is contained in:
@@ -44,15 +44,15 @@ impl AsyncItemService {
|
||||
///
|
||||
/// A new `AsyncItemService`.
|
||||
pub fn new(
|
||||
data_dir: PathBuf,
|
||||
db: Arc<Mutex<Connection>>,
|
||||
data_dir: PathBuf,
|
||||
db: Arc<Mutex<Connection>>,
|
||||
item_service: Arc<ItemService>,
|
||||
cmd: Arc<Mutex<Command>>,
|
||||
settings: Arc<Settings>,
|
||||
) -> Self {
|
||||
Self {
|
||||
data_dir,
|
||||
db,
|
||||
Self {
|
||||
data_dir,
|
||||
db,
|
||||
item_service,
|
||||
cmd,
|
||||
settings,
|
||||
@@ -82,7 +82,7 @@ impl AsyncItemService {
|
||||
{
|
||||
let db = self.db.clone();
|
||||
let item_service = self.item_service.clone();
|
||||
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let conn = db.blocking_lock();
|
||||
f(&conn, &item_service)
|
||||
@@ -92,11 +92,13 @@ impl AsyncItemService {
|
||||
}
|
||||
|
||||
pub async fn get_item(&self, id: i64) -> Result<ItemWithMeta, CoreError> {
|
||||
self.execute_blocking(move |conn, item_service| item_service.get_item(conn, id)).await
|
||||
self.execute_blocking(move |conn, item_service| item_service.get_item(conn, id))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_item_content(&self, id: i64) -> Result<ItemWithContent, CoreError> {
|
||||
self.execute_blocking(move |conn, item_service| item_service.get_item_content(conn, id)).await
|
||||
self.execute_blocking(move |conn, item_service| item_service.get_item_content(conn, id))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_item_content_info(
|
||||
@@ -104,7 +106,10 @@ impl AsyncItemService {
|
||||
id: i64,
|
||||
filter: Option<String>,
|
||||
) -> Result<(Vec<u8>, String, bool), CoreError> {
|
||||
self.execute_blocking(move |conn, item_service| item_service.get_item_content_info(conn, id, filter)).await
|
||||
self.execute_blocking(move |conn, item_service| {
|
||||
item_service.get_item_content_info(conn, id, filter)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn stream_item_content_by_id(
|
||||
@@ -113,11 +118,25 @@ impl AsyncItemService {
|
||||
allow_binary: bool,
|
||||
offset: u64,
|
||||
length: u64,
|
||||
) -> Result<(std::pin::Pin<Box<dyn tokio_stream::Stream<Item = Result<tokio_util::bytes::Bytes, std::io::Error>> + Send>>, String), CoreError> {
|
||||
let content = self.execute_blocking(move |conn, item_service| {
|
||||
let item_with_content = item_service.get_item_content(conn, item_id)?;
|
||||
Ok::<_, CoreError>(item_with_content.content)
|
||||
}).await?;
|
||||
) -> Result<
|
||||
(
|
||||
std::pin::Pin<
|
||||
Box<
|
||||
dyn tokio_stream::Stream<
|
||||
Item = Result<tokio_util::bytes::Bytes, std::io::Error>,
|
||||
> + Send,
|
||||
>,
|
||||
>,
|
||||
String,
|
||||
),
|
||||
CoreError,
|
||||
> {
|
||||
let content = self
|
||||
.execute_blocking(move |conn, item_service| {
|
||||
let item_with_content = item_service.get_item_content(conn, item_id)?;
|
||||
Ok::<_, CoreError>(item_with_content.content)
|
||||
})
|
||||
.await?;
|
||||
|
||||
// Clone content for use in the binary check closure
|
||||
let content_clone = content.clone();
|
||||
@@ -150,7 +169,9 @@ impl AsyncItemService {
|
||||
|
||||
// Check if content is binary when allow_binary is false
|
||||
if !allow_binary && is_binary {
|
||||
return Err(CoreError::InvalidInput("Binary content not allowed".to_string()));
|
||||
return Err(CoreError::InvalidInput(
|
||||
"Binary content not allowed".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
// Create a stream that reads only the requested portion
|
||||
@@ -165,7 +186,8 @@ impl AsyncItemService {
|
||||
};
|
||||
|
||||
let stream = if start < content_len {
|
||||
let chunk = tokio_util::bytes::Bytes::from(content[start as usize..end as usize].to_vec());
|
||||
let chunk =
|
||||
tokio_util::bytes::Bytes::from(content[start as usize..end as usize].to_vec());
|
||||
Box::pin(tokio_stream::iter(vec![Ok(chunk)]))
|
||||
} else {
|
||||
Box::pin(tokio_stream::iter(vec![]))
|
||||
@@ -182,7 +204,19 @@ impl AsyncItemService {
|
||||
offset: u64,
|
||||
length: u64,
|
||||
filter: Option<String>,
|
||||
) -> Result<(std::pin::Pin<Box<dyn tokio_stream::Stream<Item = Result<tokio_util::bytes::Bytes, std::io::Error>> + Send>>, String), CoreError> {
|
||||
) -> Result<
|
||||
(
|
||||
std::pin::Pin<
|
||||
Box<
|
||||
dyn tokio_stream::Stream<
|
||||
Item = Result<tokio_util::bytes::Bytes, std::io::Error>,
|
||||
> + Send,
|
||||
>,
|
||||
>,
|
||||
String,
|
||||
),
|
||||
CoreError,
|
||||
> {
|
||||
// Use provided metadata to determine MIME type and binary status
|
||||
let mime_type = metadata
|
||||
.get("mime_type")
|
||||
@@ -195,15 +229,14 @@ impl AsyncItemService {
|
||||
text_val == "false"
|
||||
} else {
|
||||
// Get binary status using streaming approach
|
||||
let (_, _, is_binary) = self.get_item_content_info_streaming(
|
||||
item_id,
|
||||
None
|
||||
).await?;
|
||||
let (_, _, is_binary) = self.get_item_content_info_streaming(item_id, None).await?;
|
||||
is_binary
|
||||
};
|
||||
|
||||
if is_binary {
|
||||
return Err(CoreError::InvalidInput("Binary content not allowed".to_string()));
|
||||
return Err(CoreError::InvalidInput(
|
||||
"Binary content not allowed".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,11 +248,9 @@ impl AsyncItemService {
|
||||
let filter = filter.clone();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let conn = db.blocking_lock();
|
||||
item_service.get_item_content_info_streaming(
|
||||
&conn,
|
||||
item_id,
|
||||
filter
|
||||
).map(|(reader, _, _)| reader)
|
||||
item_service
|
||||
.get_item_content_info_streaming(&conn, item_id, filter)
|
||||
.map(|(reader, _, _)| reader)
|
||||
})
|
||||
.await
|
||||
.map_err(|e| CoreError::Other(anyhow::anyhow!("Blocking task failed: {}", e)))?
|
||||
@@ -302,7 +333,10 @@ impl AsyncItemService {
|
||||
item_id: i64,
|
||||
filter: Option<String>,
|
||||
) -> Result<(Box<dyn Read + Send>, String, bool), CoreError> {
|
||||
self.execute_blocking(move |conn, item_service| item_service.get_item_content_info_streaming(conn, item_id, filter)).await
|
||||
self.execute_blocking(move |conn, item_service| {
|
||||
item_service.get_item_content_info_streaming(conn, item_id, filter)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn find_item(
|
||||
@@ -314,7 +348,10 @@ impl AsyncItemService {
|
||||
let ids_clone = ids.clone();
|
||||
let tags_clone = tags.clone();
|
||||
let meta_clone = meta.clone();
|
||||
self.execute_blocking(move |conn, item_service| item_service.find_item(conn, &ids_clone, &tags_clone, &meta_clone)).await
|
||||
self.execute_blocking(move |conn, item_service| {
|
||||
item_service.find_item(conn, &ids_clone, &tags_clone, &meta_clone)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn list_items(
|
||||
@@ -324,13 +361,16 @@ impl AsyncItemService {
|
||||
) -> Result<Vec<ItemWithMeta>, CoreError> {
|
||||
let tags_clone = tags.clone();
|
||||
let meta_clone = meta.clone();
|
||||
self.execute_blocking(move |conn, item_service| item_service.list_items(conn, &tags_clone, &meta_clone)).await
|
||||
self.execute_blocking(move |conn, item_service| {
|
||||
item_service.list_items(conn, &tags_clone, &meta_clone)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn delete_item(&self, id: i64) -> Result<(), CoreError> {
|
||||
let db = self.db.clone();
|
||||
let item_service = self.item_service.clone();
|
||||
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let mut conn = db.blocking_lock();
|
||||
item_service.delete_item(&mut conn, id)
|
||||
@@ -354,7 +394,8 @@ impl AsyncItemService {
|
||||
let mut conn = db.blocking_lock();
|
||||
let mut cmd = cmd.blocking_lock();
|
||||
let settings = settings.as_ref();
|
||||
item_service.save_item_from_mcp(&content, &tags, &metadata, &mut cmd, settings, &mut conn)
|
||||
item_service
|
||||
.save_item_from_mcp(&content, &tags, &metadata, &mut cmd, settings, &mut conn)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
||||
Reference in New Issue
Block a user