diff options
| -rw-r--r-- | frontend/lib/drive_server.ts | 78 |
1 files changed, 1 insertions, 77 deletions
diff --git a/frontend/lib/drive_server.ts b/frontend/lib/drive_server.ts index 41b9c71..8af0356 100644 --- a/frontend/lib/drive_server.ts +++ b/frontend/lib/drive_server.ts | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | import { spawnSync } from 'child_process' | 1 | import { spawnSync } from 'child_process' |
| 2 | import { DriveLsEntry, DriveTreeNode, DriveTreeResponse, DriveLogEntry } from './drive_types' | 2 | import { DriveLsEntry, DriveLogEntry } from './drive_types' |
| 3 | import { Drive_split_path, Drive_basename } from './drive_shared' | 3 | import { Drive_split_path, Drive_basename } from './drive_shared' |
| 4 | 4 | ||
| 5 | /** | 5 | /** |
| @@ -120,82 +120,6 @@ export async function Drive_stat(path: string): Promise<string> { | |||
| 120 | return result.stdout.trim(); | 120 | return result.stdout.trim(); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | /// builds a filesystem tree from Drive_ls entries | ||
| 124 | export async function Drive_tree(): Promise<DriveTreeResponse> { | ||
| 125 | const entries = await Drive_ls('/', true); | ||
| 126 | |||
| 127 | const nodesMap = new Map<string, DriveTreeNode>(); | ||
| 128 | const rootNodes: DriveTreeNode[] = []; | ||
| 129 | |||
| 130 | // First pass: create all nodes | ||
| 131 | entries.forEach(entry => { | ||
| 132 | const node: DriveTreeNode = { | ||
| 133 | path: entry.path, | ||
| 134 | name: Drive_basename(entry.path), | ||
| 135 | type: entry.type, | ||
| 136 | lastmod: entry.lastmod, | ||
| 137 | blob: entry.blob, | ||
| 138 | size: entry.size, | ||
| 139 | author: entry.author, | ||
| 140 | children: entry.type === "dir" ? [] : undefined | ||
| 141 | }; | ||
| 142 | nodesMap.set(entry.path, node); | ||
| 143 | }); | ||
| 144 | |||
| 145 | // Second pass: build hierarchy | ||
| 146 | entries.forEach(entry => { | ||
| 147 | const pathParts = Drive_split_path(entry.path); | ||
| 148 | const node = nodesMap.get(entry.path)!; | ||
| 149 | |||
| 150 | if (pathParts.length === 1) { | ||
| 151 | // Root level item | ||
| 152 | rootNodes.push(node); | ||
| 153 | } else { | ||
| 154 | // Find parent path by reconstructing it | ||
| 155 | const parentParts = pathParts.slice(0, -1); | ||
| 156 | const parentPath = '/' + parentParts.join('/'); | ||
| 157 | const parent = nodesMap.get(parentPath); | ||
| 158 | |||
| 159 | if (parent && parent.children) { | ||
| 160 | parent.children.push(node); | ||
| 161 | } else { | ||
| 162 | // If parent not found, add to root | ||
| 163 | rootNodes.push(node); | ||
| 164 | } | ||
| 165 | } | ||
| 166 | }); | ||
| 167 | |||
| 168 | // Third pass: calculate directory sizes and sort all levels | ||
| 169 | const calculateSizesAndSort = (nodes: DriveTreeNode[]): DriveTreeNode[] => { | ||
| 170 | // First, recursively process children and calculate their sizes | ||
| 171 | nodes.forEach(node => { | ||
| 172 | if (node.children) { | ||
| 173 | node.children = calculateSizesAndSort(node.children); | ||
| 174 | |||
| 175 | // If this is a directory, calculate its size as sum of all children | ||
| 176 | if (node.type === "dir") { | ||
| 177 | node.size = node.children.reduce((total, child) => { | ||
| 178 | return total + (child.size || 0); | ||
| 179 | }, 0); | ||
| 180 | } | ||
| 181 | } | ||
| 182 | }); | ||
| 183 | |||
| 184 | // Then sort: directories first, then files, both alphabetically | ||
| 185 | const sorted = nodes.sort((a, b) => { | ||
| 186 | // Directories first, then files | ||
| 187 | if (a.type === "dir" && b.type === "file") return -1; | ||
| 188 | if (a.type === "file" && b.type === "dir") return 1; | ||
| 189 | |||
| 190 | // Both same type, sort alphabetically by name (case-insensitive) | ||
| 191 | return a.name.toLowerCase().localeCompare(b.name.toLowerCase()); | ||
| 192 | }); | ||
| 193 | |||
| 194 | return sorted; | ||
| 195 | }; | ||
| 196 | |||
| 197 | return { root: calculateSizesAndSort(rootNodes) }; | ||
| 198 | } | ||
| 199 | 123 | ||
| 200 | /// lists only directories (recursively) from the given path | 124 | /// lists only directories (recursively) from the given path |
| 201 | export async function Drive_ls_directories(path: string = '/'): Promise<DriveLsEntry[]> { | 125 | export async function Drive_ls_directories(path: string = '/'): Promise<DriveLsEntry[]> { |
