fix: add server streaming support, fix pre-existing compilation errors
Server changes for client mode streaming:
- POST /api/item/ now streams body via async channel → ChannelReader
→ save_item_raw_streaming when compress=false or meta=false
- Add POST /api/item/{id}/meta endpoint for client-side metadata
- Add save_item_raw_streaming<R: Read> to SyncDataService
- Add add_item_meta to AsyncDataService
Fix pre-existing issues that were hidden behind swagger cfg gate:
- Remove #[cfg(feature = "swagger")] from item module so it compiles
with just the server feature
- Fix parse_comma_tags usage (returns Vec, not Result)
- Fix TextDiff temporary value lifetime issue
- Fix io::Error::new → io::Error::other
- Fix ok_or_else → ok_or for Copy types
- Inline format args throughout server code
- Fix empty line after doc comment in pages.rs
- Add cfg_attr for unused_mut where mcp feature gates mutation
- Add type_complexity allow on create_auth_middleware
- Distinguish task error vs save error in spawn_blocking handlers
Co-Authored-By: andrew/openrouter/hunter-alpha <noreply@opencode.ai>
This commit is contained in:
@@ -47,12 +47,6 @@ fn default_count() -> usize {
|
||||
1000
|
||||
}
|
||||
|
||||
/// Provides the default number of items to display per page.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// The default count: 1000.
|
||||
|
||||
/// Adds the web page routes to the Axum router.
|
||||
///
|
||||
/// This function configures the routes for the web interface, including the
|
||||
@@ -96,7 +90,7 @@ async fn list_items(
|
||||
.map_err(|_| Html("<html><body>Internal Server Error</body></html>".to_string()))?;
|
||||
Ok(response)
|
||||
}
|
||||
Err(e) => Err(Html(format!("<html><body>Error: {}</body></html>", e))),
|
||||
Err(e) => Err(Html(format!("<html><body>Error: {e}</body></html>"))),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,8 +184,7 @@ fn build_item_list(
|
||||
html.push_str("<p>");
|
||||
for tag in recent_tags {
|
||||
html.push_str(&format!(
|
||||
"<a href=\"/?tags={}\" style=\"margin-right: 8px;\">{}</a>",
|
||||
tag, tag
|
||||
"<a href=\"/?tags={tag}\" style=\"margin-right: 8px;\">{tag}</a>"
|
||||
));
|
||||
}
|
||||
html.push_str("</p>");
|
||||
@@ -228,7 +221,7 @@ fn build_item_list(
|
||||
"id" => {
|
||||
let id_value = item.id.map(|id| id.to_string()).unwrap_or_default();
|
||||
// Make the ID a link to the item details page
|
||||
format!("<a href=\"/item/{}\">{}</a>", item_id, id_value)
|
||||
format!("<a href=\"/item/{item_id}\">{id_value}</a>")
|
||||
}
|
||||
"time" => item.ts.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||
"size" => item.size.map(|s| s.to_string()).unwrap_or_default(),
|
||||
@@ -257,7 +250,7 @@ fn build_item_list(
|
||||
if let Ok(max_len) = max_len_str.parse::<usize>() {
|
||||
if value.chars().count() > max_len {
|
||||
let truncated: String = value.chars().take(max_len).collect();
|
||||
format!("{}...", truncated)
|
||||
format!("{truncated}...")
|
||||
} else {
|
||||
value
|
||||
}
|
||||
@@ -275,16 +268,12 @@ fn build_item_list(
|
||||
crate::config::ColumnAlignment::Center => "text-align: center;",
|
||||
};
|
||||
|
||||
html.push_str(&format!(
|
||||
"<td style=\"{}\">{}</td>",
|
||||
align_style, display_value
|
||||
));
|
||||
html.push_str(&format!("<td style=\"{align_style}\">{display_value}</td>"));
|
||||
}
|
||||
|
||||
// Actions column
|
||||
html.push_str(&format!(
|
||||
"<td><a href=\"/item/{}\">View</a> | <a href=\"/api/item/{}/content\">Download</a></td>",
|
||||
item_id, item_id
|
||||
"<td><a href=\"/item/{item_id}\">View</a> | <a href=\"/api/item/{item_id}/content\">Download</a></td>"
|
||||
));
|
||||
|
||||
html.push_str("</tr>");
|
||||
@@ -372,7 +361,7 @@ async fn show_item(
|
||||
.map_err(|_| Html("<html><body>Internal Server Error</body></html>".to_string()))?;
|
||||
Ok(response)
|
||||
}
|
||||
Err(e) => Err(Html(format!("<html><body>Error: {}</body></html>", e))),
|
||||
Err(e) => Err(Html(format!("<html><body>Error: {e}</body></html>"))),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,10 +375,10 @@ fn build_item_details(conn: &Connection, id: i64) -> Result<String> {
|
||||
let metas = db::get_item_meta(conn, &item)?;
|
||||
|
||||
let mut html = String::new();
|
||||
html.push_str(&format!("<html><head><title>Keep - Item #{}</title>", id));
|
||||
html.push_str(&format!("<html><head><title>Keep - Item #{id}</title>"));
|
||||
html.push_str("<link rel=\"stylesheet\" href=\"/style.css\">");
|
||||
html.push_str("</head><body>");
|
||||
html.push_str(&format!("<h1>Item #{}</h1>", id));
|
||||
html.push_str(&format!("<h1>Item #{id}</h1>"));
|
||||
|
||||
// Single table for all details
|
||||
html.push_str("<table>");
|
||||
@@ -439,8 +428,7 @@ fn build_item_details(conn: &Connection, id: i64) -> Result<String> {
|
||||
// Links
|
||||
html.push_str("<h2>Actions</h2>");
|
||||
html.push_str(&format!(
|
||||
"<p><a href=\"/api/item/{}/content\">Download Content</a></p>",
|
||||
id
|
||||
"<p><a href=\"/api/item/{id}/content\">Download Content</a></p>"
|
||||
));
|
||||
html.push_str("<p><a href=\"/\">Back to list</a></p>");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user