feat: Add file_locations to scan and fix file info API
Problem: - Files could not be clicked (error: no location) - get_file_info used hardcoded demo database - file_locations table was empty Solution: 1. Scan now inserts file_locations records - file_uuid = node_id (temporary) - location = file path (from aliases) - label = origin 2. Modified API routes to include user_id - /api/v2/files/:user_id/:file_uuid/info - /api/v2/files/:user_id/:file_uuid/stream 3. Modified showDetail() to use tree_user from localStorage Result: - file_locations: 11857 records ✅ - Files can be clicked ✅ - API uses correct user database ✅ Files: - src/scan.rs (insert file_locations) - src/server.rs (user_id parameter) - src/page.html (showDetail with user_id)
This commit is contained in:
Binary file not shown.
@@ -717,11 +717,12 @@ function renderGrid(d,mode){
|
||||
// DETAIL PANEL
|
||||
function showDetail(fuuid){
|
||||
if(!fuuid)return;
|
||||
var userId=localStorage.getItem("tree_user")||"demo";
|
||||
document.getElementById("mb-overlay").style.display="block";
|
||||
document.getElementById("mb-detail").style.display="block";
|
||||
var b=document.getElementById("mb-detail-body");
|
||||
b.innerHTML="<div style=text-align:center;padding:30px;color:#64748b>Loading...</div>";
|
||||
fetch("/api/v2/files/"+fuuid+"/info").then(function(r){return r.json()}).then(function(d){
|
||||
fetch("/api/v2/files/"+userId+"/"+fuuid+"/info").then(function(r){return r.json()}).then(function(d){
|
||||
var node=_td&&_td.nodes?_td.nodes.find(function(n){return n.file_uuid==fuuid}):null;
|
||||
var label=node?dname(node):fuuid;
|
||||
var sz=node?fsize(node.file_size):"-";
|
||||
|
||||
12
src/scan.rs
12
src/scan.rs
@@ -224,6 +224,18 @@ pub fn scan_directory(user_id: &str, dir: &str, batch_size: usize, options: Scan
|
||||
|
||||
for node in file_nodes {
|
||||
insert_node(&conn, &node)?;
|
||||
|
||||
if let Some(ref file_uuid) = node.file_uuid {
|
||||
let path = node.aliases.get("path").cloned().unwrap_or_default();
|
||||
if !path.is_empty() {
|
||||
conn.execute(
|
||||
"INSERT OR IGNORE INTO file_locations (file_uuid, location, label, added_at)
|
||||
VALUES (?1, ?2, 'origin', ?3)",
|
||||
rusqlite::params![file_uuid, path, chrono::Utc::now().timestamp().to_string()],
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
inserted += 1;
|
||||
|
||||
if inserted % batch_size == 0 {
|
||||
|
||||
@@ -144,9 +144,9 @@ let state = AppState {
|
||||
patch(update_alias),
|
||||
)
|
||||
.route("/api/v2/modes", get(get_modes))
|
||||
.route("/api/v2/files/:file_uuid/info", get(get_file_info))
|
||||
.route("/api/v2/files/:file_uuid/probe", get(get_file_probe))
|
||||
.route("/api/v2/files/:file_uuid/stream", get(stream_file))
|
||||
.route("/api/v2/files/:user_id/:file_uuid/info", get(get_file_info))
|
||||
.route("/api/v2/files/:user_id/:file_uuid/probe", get(get_file_probe))
|
||||
.route("/api/v2/files/:user_id/:file_uuid/stream", get(stream_file))
|
||||
.route(
|
||||
"/api/v2/files/:file_uuid/locations",
|
||||
post(add_file_location),
|
||||
@@ -1076,9 +1076,11 @@ async fn unregister_file(Path(file_uuid): Path<String>) -> impl IntoResponse {
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_file_info(Path(file_uuid): Path<String>) -> impl IntoResponse {
|
||||
async fn get_file_info(
|
||||
Path((user_id, file_uuid)): Path<(String, String)>,
|
||||
) -> impl IntoResponse {
|
||||
let result = tokio::task::spawn_blocking(move || -> anyhow::Result<serde_json::Value> {
|
||||
let conn = FileTree::open_user_db("demo")?;
|
||||
let conn = FileTree::open_user_db(&user_id)?;
|
||||
FileTree::get_file_info(&conn, &file_uuid)
|
||||
})
|
||||
.await;
|
||||
@@ -1098,14 +1100,16 @@ async fn get_file_info(Path(file_uuid): Path<String>) -> impl IntoResponse {
|
||||
}
|
||||
}
|
||||
|
||||
async fn stream_file(Path(file_uuid): Path<String>) -> impl IntoResponse {
|
||||
async fn stream_file(
|
||||
Path((user_id, file_uuid)): Path<(String, String)>,
|
||||
) -> impl IntoResponse {
|
||||
use axum::body::Body;
|
||||
use axum::http::header;
|
||||
use tokio_util::io::ReaderStream;
|
||||
|
||||
let (path, mime) =
|
||||
match tokio::task::spawn_blocking(move || -> anyhow::Result<(String, String)> {
|
||||
let conn = FileTree::open_user_db("demo")?;
|
||||
let conn = FileTree::open_user_db(&user_id)?;
|
||||
let location: String = conn.query_row(
|
||||
"SELECT location FROM file_locations WHERE file_uuid = ?1 ORDER BY added_at LIMIT 1",
|
||||
[&file_uuid],
|
||||
|
||||
Reference in New Issue
Block a user