refactor: Consolidate item content filtering into a single filter string

Co-authored-by: aider (openai/andrew/openrouter/deepseek/deepseek-chat-v3.1) <aider@aider.chat>
This commit is contained in:
Andrew Phillips
2025-09-02 18:54:50 -03:00
parent d7a0ac96b3
commit 61d7dcb94e
3 changed files with 38 additions and 58 deletions

View File

@@ -392,6 +392,32 @@ pub async fn handle_get_item_content(
debug!("ITEM_API: Getting content for item {} with stream={}, allow_binary={}, offset={}, length={}", debug!("ITEM_API: Getting content for item {} with stream={}, allow_binary={}, offset={}, length={}",
item_id, params.stream, params.allow_binary, params.offset, params.length); item_id, params.stream, params.allow_binary, params.offset, params.length);
// Build filter string from query parameters
let mut filter_parts = Vec::new();
if let Some(head_bytes) = params.head_bytes {
filter_parts.push(format!("head_bytes({})", head_bytes));
}
if let Some(head_lines) = params.head_lines {
filter_parts.push(format!("head_lines({})", head_lines));
}
if let Some(tail_bytes) = params.tail_bytes {
filter_parts.push(format!("tail_bytes({})", tail_bytes));
}
if let Some(tail_lines) = params.tail_lines {
filter_parts.push(format!("tail_lines({})", tail_lines));
}
if let Some(grep) = params.grep {
filter_parts.push(format!("grep({})", grep));
}
// Note: head_words, tail_words, line_start, line_end are not implemented in the filter system yet
// You may need to add them to the filter syntax or handle them differently
let filter = if filter_parts.is_empty() {
None
} else {
Some(filter_parts.join(" | "))
};
let item_service = AsyncItemService::new( let item_service = AsyncItemService::new(
state.data_dir.clone(), state.data_dir.clone(),
state.db.clone(), state.db.clone(),
@@ -408,7 +434,7 @@ pub async fn handle_get_item_content(
} }
result result
} else { } else {
let result = stream_item_content_response(&item_service, item_id, params.allow_binary, params.offset, params.length, params.stream).await; let result = stream_item_content_response(&item_service, item_id, params.allow_binary, params.offset, params.length, params.stream, filter).await;
if let Ok(response) = &result { if let Ok(response) = &result {
debug!("ITEM_API: Response content-length: {:?}", response.headers().get("content-length")); debug!("ITEM_API: Response content-length: {:?}", response.headers().get("content-length"));
} }
@@ -423,6 +449,7 @@ async fn stream_item_content_response(
offset: u64, offset: u64,
length: u64, length: u64,
stream: bool, stream: bool,
filter: Option<String>,
) -> Result<Response, StatusCode> { ) -> Result<Response, StatusCode> {
debug!("STREAM_ITEM_CONTENT_RESPONSE: stream={}", stream); debug!("STREAM_ITEM_CONTENT_RESPONSE: stream={}", stream);
// Get the item with metadata once // Get the item with metadata once
@@ -432,7 +459,7 @@ async fn stream_item_content_response(
})?; })?;
let metadata = item_with_meta.meta_as_map(); let metadata = item_with_meta.meta_as_map();
stream_item_content_response_with_metadata(item_service, item_id, &metadata, allow_binary, offset, length, stream).await stream_item_content_response_with_metadata(item_service, item_id, &metadata, allow_binary, offset, length, stream, filter).await
} }
async fn stream_item_content_response_with_metadata( async fn stream_item_content_response_with_metadata(
@@ -443,6 +470,7 @@ async fn stream_item_content_response_with_metadata(
offset: u64, offset: u64,
length: u64, length: u64,
stream: bool, stream: bool,
filter: Option<String>,
) -> Result<Response, StatusCode> { ) -> Result<Response, StatusCode> {
debug!("STREAM_ITEM_CONTENT_RESPONSE_WITH_METADATA: stream={}", stream); debug!("STREAM_ITEM_CONTENT_RESPONSE_WITH_METADATA: stream={}", stream);
let mime_type = metadata let mime_type = metadata
@@ -481,15 +509,7 @@ async fn stream_item_content_response_with_metadata(
true, true,
offset, offset,
length, length,
None, filter
None,
None,
None,
None,
None,
None,
None,
None
).await { ).await {
Ok((stream, _)) => { Ok((stream, _)) => {
let body = axum::body::Body::from_stream(stream); let body = axum::body::Body::from_stream(stream);
@@ -508,15 +528,7 @@ async fn stream_item_content_response_with_metadata(
debug!("NON-STREAMING: Building full response in memory"); debug!("NON-STREAMING: Building full response in memory");
match item_service.get_item_content_info( match item_service.get_item_content_info(
item_id, item_id,
None, filter
None,
None,
None,
None,
None,
None,
None,
None
).await { ).await {
Ok((content, _, _)) => { Ok((content, _, _)) => {
// Apply offset and length // Apply offset and length

View File

@@ -68,15 +68,7 @@ impl AsyncItemService {
pub async fn get_item_content_info( pub async fn get_item_content_info(
&self, &self,
id: i64, id: i64,
head_bytes: Option<usize>, filter: Option<String>,
head_words: Option<usize>,
head_lines: Option<usize>,
tail_bytes: Option<usize>,
tail_words: Option<usize>,
tail_lines: Option<usize>,
line_start: Option<usize>,
line_end: Option<usize>,
grep: Option<String>,
) -> Result<(Vec<u8>, String, bool), CoreError> { ) -> Result<(Vec<u8>, String, bool), CoreError> {
let db = self.db.clone(); let db = self.db.clone();
let item_service = self.item_service.clone(); let item_service = self.item_service.clone();
@@ -86,15 +78,7 @@ impl AsyncItemService {
item_service.get_item_content_info( item_service.get_item_content_info(
&conn, &conn,
id, id,
head_bytes, filter
head_words,
head_lines,
tail_bytes,
tail_words,
tail_lines,
line_start,
line_end,
grep
) )
}) })
.await .await
@@ -182,15 +166,7 @@ impl AsyncItemService {
allow_binary: bool, allow_binary: bool,
offset: u64, offset: u64,
length: u64, length: u64,
head_bytes: Option<usize>, filter: Option<String>,
head_words: Option<usize>,
head_lines: Option<usize>,
tail_bytes: Option<usize>,
tail_words: Option<usize>,
tail_lines: Option<usize>,
line_start: Option<usize>,
line_end: Option<usize>,
grep: 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 // Use provided metadata to determine MIME type and binary status
let mime_type = metadata let mime_type = metadata
@@ -225,7 +201,7 @@ impl AsyncItemService {
item_service.get_item_content_info_streaming( item_service.get_item_content_info_streaming(
&conn, &conn,
item_id, item_id,
None filter
).map(|(reader, _, _)| reader) ).map(|(reader, _, _)| reader)
}) })
.await .await

View File

@@ -139,19 +139,11 @@ impl ItemService {
&self, &self,
conn: &Connection, conn: &Connection,
id: i64, id: i64,
head_bytes: Option<usize>, filter: Option<String>,
head_words: Option<usize>,
head_lines: Option<usize>,
tail_bytes: Option<usize>,
tail_words: Option<usize>,
tail_lines: Option<usize>,
line_start: Option<usize>,
line_end: Option<usize>,
grep: Option<String>,
) -> Result<(Vec<u8>, String, bool), CoreError> { ) -> Result<(Vec<u8>, String, bool), CoreError> {
// Use streaming approach to handle all filtering options consistently // Use streaming approach to handle all filtering options consistently
let (mut reader, mime_type, is_binary) = self.get_item_content_info_streaming( let (mut reader, mime_type, is_binary) = self.get_item_content_info_streaming(
conn, id, None conn, id, filter
)?; )?;
// Read all the filtered content into a buffer // Read all the filtered content into a buffer