Ugh
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use anyhow::{Result, anyhow};
|
||||
use log::debug;
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use log::{debug};
|
||||
|
||||
use crate::modes::server::common::AppState;
|
||||
use crate::services::async_item_service::AsyncItemService;
|
||||
@@ -35,7 +35,8 @@ impl KeepTools {
|
||||
}
|
||||
|
||||
pub async fn save_item(&self, args: Option<Value>) -> Result<String, ToolError> {
|
||||
let args = args.ok_or_else(|| ToolError::InvalidArguments("Missing arguments".to_string()))?;
|
||||
let args =
|
||||
args.ok_or_else(|| ToolError::InvalidArguments("Missing arguments".to_string()))?;
|
||||
|
||||
let content = args
|
||||
.get("content")
|
||||
@@ -70,11 +71,11 @@ impl KeepTools {
|
||||
);
|
||||
|
||||
let service = AsyncItemService::new(
|
||||
self.state.data_dir.clone(),
|
||||
self.state.db.clone(),
|
||||
self.state.data_dir.clone(),
|
||||
self.state.db.clone(),
|
||||
self.state.item_service.clone(),
|
||||
self.state.cmd.clone(),
|
||||
self.state.settings.clone()
|
||||
self.state.settings.clone(),
|
||||
);
|
||||
let item_with_meta = service
|
||||
.save_item_from_mcp(content.as_bytes().to_vec(), tags, metadata)
|
||||
@@ -90,28 +91,39 @@ impl KeepTools {
|
||||
}
|
||||
|
||||
pub async fn get_item(&self, args: Option<Value>) -> Result<String, ToolError> {
|
||||
let args = args.ok_or_else(|| ToolError::InvalidArguments("Missing arguments".to_string()))?;
|
||||
|
||||
let item_id = args.get("id")
|
||||
.and_then(|v| v.as_i64())
|
||||
.ok_or_else(|| ToolError::InvalidArguments("Missing or invalid 'id' field".to_string()))?;
|
||||
let args =
|
||||
args.ok_or_else(|| ToolError::InvalidArguments("Missing arguments".to_string()))?;
|
||||
|
||||
let item_id = args.get("id").and_then(|v| v.as_i64()).ok_or_else(|| {
|
||||
ToolError::InvalidArguments("Missing or invalid 'id' field".to_string())
|
||||
})?;
|
||||
|
||||
let service = AsyncItemService::new(
|
||||
self.state.data_dir.clone(),
|
||||
self.state.db.clone(),
|
||||
self.state.data_dir.clone(),
|
||||
self.state.db.clone(),
|
||||
self.state.item_service.clone(),
|
||||
self.state.cmd.clone(),
|
||||
self.state.settings.clone()
|
||||
self.state.settings.clone(),
|
||||
);
|
||||
|
||||
let item_with_content = match service.get_item_content(item_id).await {
|
||||
Ok(iwc) => iwc,
|
||||
Err(CoreError::ItemNotFound(_)) => return Err(ToolError::InvalidArguments(format!("Item {} not found", item_id))),
|
||||
Err(CoreError::ItemNotFound(_)) => {
|
||||
return Err(ToolError::InvalidArguments(format!(
|
||||
"Item {} not found",
|
||||
item_id
|
||||
)));
|
||||
}
|
||||
Err(e) => return Err(ToolError::Other(anyhow::Error::from(e))),
|
||||
};
|
||||
|
||||
let content = String::from_utf8_lossy(&item_with_content.content).to_string();
|
||||
let tags: Vec<String> = item_with_content.item_with_meta.tags.iter().map(|t| t.name.clone()).collect();
|
||||
let tags: Vec<String> = item_with_content
|
||||
.item_with_meta
|
||||
.tags
|
||||
.iter()
|
||||
.map(|t| t.name.clone())
|
||||
.collect();
|
||||
let metadata = item_with_content.item_with_meta.meta_as_map();
|
||||
let item = item_with_content.item_with_meta.item;
|
||||
|
||||
@@ -124,7 +136,7 @@ impl KeepTools {
|
||||
"tags": tags,
|
||||
"metadata": metadata,
|
||||
});
|
||||
|
||||
|
||||
Ok(serde_json::to_string_pretty(&response)?)
|
||||
}
|
||||
|
||||
@@ -133,28 +145,45 @@ impl KeepTools {
|
||||
.as_ref()
|
||||
.and_then(|v| v.get("tags"))
|
||||
.and_then(|v| v.as_array())
|
||||
.map(|arr| arr.iter().filter_map(|v| v.as_str().map(|s| s.to_string())).collect())
|
||||
.map(|arr| {
|
||||
arr.iter()
|
||||
.filter_map(|v| v.as_str().map(|s| s.to_string()))
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let service = AsyncItemService::new(
|
||||
self.state.data_dir.clone(),
|
||||
self.state.db.clone(),
|
||||
self.state.data_dir.clone(),
|
||||
self.state.db.clone(),
|
||||
self.state.item_service.clone(),
|
||||
self.state.cmd.clone(),
|
||||
self.state.settings.clone()
|
||||
self.state.settings.clone(),
|
||||
);
|
||||
|
||||
let item_with_meta = match service.find_item(vec![], tags, HashMap::new()).await {
|
||||
Ok(iwm) => iwm,
|
||||
Err(CoreError::ItemNotFoundGeneric) => return Err(ToolError::InvalidArguments("No items found".to_string())),
|
||||
Err(CoreError::ItemNotFoundGeneric) => {
|
||||
return Err(ToolError::InvalidArguments("No items found".to_string()));
|
||||
}
|
||||
Err(e) => return Err(ToolError::Other(anyhow::Error::from(e))),
|
||||
};
|
||||
|
||||
let item_id = item_with_meta.item.id.ok_or_else(|| anyhow!("Item missing ID after find"))?;
|
||||
let item_with_content = service.get_item_content(item_id).await.map_err(|e| ToolError::Other(anyhow::Error::from(e)))?;
|
||||
|
||||
|
||||
let item_id = item_with_meta
|
||||
.item
|
||||
.id
|
||||
.ok_or_else(|| anyhow!("Item missing ID after find"))?;
|
||||
let item_with_content = service
|
||||
.get_item_content(item_id)
|
||||
.await
|
||||
.map_err(|e| ToolError::Other(anyhow::Error::from(e)))?;
|
||||
|
||||
let content = String::from_utf8_lossy(&item_with_content.content).to_string();
|
||||
let tags: Vec<String> = item_with_content.item_with_meta.tags.iter().map(|t| t.name.clone()).collect();
|
||||
let tags: Vec<String> = item_with_content
|
||||
.item_with_meta
|
||||
.tags
|
||||
.iter()
|
||||
.map(|t| t.name.clone())
|
||||
.collect();
|
||||
let metadata = item_with_content.item_with_meta.meta_as_map();
|
||||
let item = item_with_content.item_with_meta.item;
|
||||
|
||||
@@ -167,7 +196,7 @@ impl KeepTools {
|
||||
"tags": tags,
|
||||
"metadata": metadata,
|
||||
});
|
||||
|
||||
|
||||
Ok(serde_json::to_string_pretty(&response)?)
|
||||
}
|
||||
|
||||
@@ -176,40 +205,52 @@ impl KeepTools {
|
||||
let tags: Vec<String> = args_ref
|
||||
.and_then(|v| v.get("tags"))
|
||||
.and_then(|v| v.as_array())
|
||||
.map(|arr| arr.iter().filter_map(|v| v.as_str().map(|s| s.to_string())).collect())
|
||||
.map(|arr| {
|
||||
arr.iter()
|
||||
.filter_map(|v| v.as_str().map(|s| s.to_string()))
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
|
||||
let limit = args_ref
|
||||
.and_then(|v| v.get("limit"))
|
||||
.and_then(|v| v.as_u64())
|
||||
.unwrap_or(10) as usize;
|
||||
|
||||
|
||||
let offset = args_ref
|
||||
.and_then(|v| v.get("offset"))
|
||||
.and_then(|v| v.as_u64())
|
||||
.unwrap_or(0) as usize;
|
||||
|
||||
let service = AsyncItemService::new(
|
||||
self.state.data_dir.clone(),
|
||||
self.state.db.clone(),
|
||||
self.state.data_dir.clone(),
|
||||
self.state.db.clone(),
|
||||
self.state.item_service.clone(),
|
||||
self.state.cmd.clone(),
|
||||
self.state.settings.clone()
|
||||
self.state.settings.clone(),
|
||||
);
|
||||
let mut items_with_meta = service.list_items(tags, HashMap::new()).await.map_err(|e| ToolError::Other(anyhow::Error::from(e)))?;
|
||||
let mut items_with_meta = service
|
||||
.list_items(tags, HashMap::new())
|
||||
.await
|
||||
.map_err(|e| ToolError::Other(anyhow::Error::from(e)))?;
|
||||
|
||||
// Sort by timestamp (newest first) and apply pagination
|
||||
items_with_meta.sort_by(|a, b| b.item.ts.cmp(&a.item.ts));
|
||||
let items_with_meta: Vec<_> = items_with_meta.into_iter().skip(offset).take(limit).collect();
|
||||
|
||||
let items_with_meta: Vec<_> = items_with_meta
|
||||
.into_iter()
|
||||
.skip(offset)
|
||||
.take(limit)
|
||||
.collect();
|
||||
|
||||
let items_info: Vec<_> = items_with_meta
|
||||
.into_iter()
|
||||
.map(|item_with_meta| {
|
||||
let item_tags: Vec<String> = item_with_meta.tags.iter().map(|t| t.name.clone()).collect();
|
||||
let item_tags: Vec<String> =
|
||||
item_with_meta.tags.iter().map(|t| t.name.clone()).collect();
|
||||
let item_meta = item_with_meta.meta_as_map();
|
||||
let item = item_with_meta.item;
|
||||
let item_id = item.id.unwrap_or(0);
|
||||
|
||||
|
||||
serde_json::json!({
|
||||
"id": item_id,
|
||||
"timestamp": item.ts.to_rfc3339(),
|
||||
@@ -220,14 +261,14 @@ impl KeepTools {
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
let response = serde_json::json!({
|
||||
"items": items_info,
|
||||
"count": items_info.len(),
|
||||
"offset": offset,
|
||||
"limit": limit
|
||||
});
|
||||
|
||||
|
||||
Ok(serde_json::to_string_pretty(&response)?)
|
||||
}
|
||||
|
||||
@@ -236,38 +277,48 @@ impl KeepTools {
|
||||
.as_ref()
|
||||
.and_then(|v| v.get("tags"))
|
||||
.and_then(|v| v.as_array())
|
||||
.map(|arr| arr.iter().filter_map(|v| v.as_str().map(|s| s.to_string())).collect())
|
||||
.map(|arr| {
|
||||
arr.iter()
|
||||
.filter_map(|v| v.as_str().map(|s| s.to_string()))
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
|
||||
let metadata: HashMap<String, String> = args
|
||||
.as_ref()
|
||||
.and_then(|v| v.get("metadata"))
|
||||
.and_then(|v| v.as_object())
|
||||
.map(|obj| obj.iter().filter_map(|(k, v)| {
|
||||
v.as_str().map(|s| (k.clone(), s.to_string()))
|
||||
}).collect())
|
||||
.map(|obj| {
|
||||
obj.iter()
|
||||
.filter_map(|(k, v)| v.as_str().map(|s| (k.clone(), s.to_string())))
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let service = AsyncItemService::new(
|
||||
self.state.data_dir.clone(),
|
||||
self.state.db.clone(),
|
||||
self.state.data_dir.clone(),
|
||||
self.state.db.clone(),
|
||||
self.state.item_service.clone(),
|
||||
self.state.cmd.clone(),
|
||||
self.state.settings.clone()
|
||||
self.state.settings.clone(),
|
||||
);
|
||||
let mut items_with_meta = service.list_items(tags.clone(), metadata.clone()).await.map_err(|e| ToolError::Other(anyhow::Error::from(e)))?;
|
||||
let mut items_with_meta = service
|
||||
.list_items(tags.clone(), metadata.clone())
|
||||
.await
|
||||
.map_err(|e| ToolError::Other(anyhow::Error::from(e)))?;
|
||||
|
||||
// Sort by timestamp (newest first)
|
||||
items_with_meta.sort_by(|a, b| b.item.ts.cmp(&a.item.ts));
|
||||
|
||||
|
||||
let items_info: Vec<_> = items_with_meta
|
||||
.into_iter()
|
||||
.map(|item_with_meta| {
|
||||
let item_tags: Vec<String> = item_with_meta.tags.iter().map(|t| t.name.clone()).collect();
|
||||
let item_tags: Vec<String> =
|
||||
item_with_meta.tags.iter().map(|t| t.name.clone()).collect();
|
||||
let item_meta = item_with_meta.meta_as_map();
|
||||
let item = item_with_meta.item;
|
||||
let item_id = item.id.unwrap_or(0);
|
||||
|
||||
|
||||
serde_json::json!({
|
||||
"id": item_id,
|
||||
"timestamp": item.ts.to_rfc3339(),
|
||||
@@ -278,7 +329,7 @@ impl KeepTools {
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
let response = serde_json::json!({
|
||||
"items": items_info,
|
||||
"count": items_info.len(),
|
||||
@@ -287,7 +338,7 @@ impl KeepTools {
|
||||
"metadata": metadata
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Ok(serde_json::to_string_pretty(&response)?)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user