Skip to content

Commit 03f3784

Browse files
committed
Filesystem navigation tree implementation on backend
1 parent 1469931 commit 03f3784

File tree

2 files changed

+78
-5
lines changed

2 files changed

+78
-5
lines changed

solid_node/viewers/web/app/src/node.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export abstract class Node {
9999
return;
100100
}
101101
const response = await fetch(
102-
`/root${this.path}`,
102+
`/node${this.path}`,
103103
{
104104
method: 'POST',
105105
headers: {

solid_node/viewers/web/viewer.py

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,18 @@ def __init__(self, path, dev=True):
4848

4949
self.stl_index = {}
5050
self.app = FastAPI()
51-
self.root = NodeAPI(self.node,
51+
root_node = NodeAPI(self.node,
5252
self.repo,
5353
self.stl_index,
5454
f'/{self.node.name}',
5555
)
5656

57-
self.broker = BrokerClient()
57+
root_fs = FilesystemAPI(root_node.basedir)
58+
59+
self.app.mount(f'/node', root_node.app)
60+
self.app.mount(f'/file', root_fs.app)
5861

59-
self.app.mount(f'/root', self.root.app)
62+
self.broker = BrokerClient()
6063

6164
self._setup_build_error()
6265

@@ -162,7 +165,7 @@ def __init__(self, node, repo, stl_index, prefix):
162165
for child in children:
163166
child_path = f'/{child.name}'
164167
subapp = NodeAPI(child, self.repo, stl_index, child_path)
165-
logger.info(f'Mounting {child_path}')
168+
logger.info(f'Mounting node {child_path}')
166169
self.app.mount(child_path, subapp.app)
167170
self.subapps.append(subapp)
168171
self.children.append(child.name)
@@ -223,3 +226,73 @@ async def wait_for_file(self, file_path):
223226
if os.path.exists(file_path):
224227
return
225228
await asyncio.sleep(0.1)
229+
230+
231+
class FilesystemAPI:
232+
233+
def __init__(self, basedir, path=None):
234+
basedir = os.path.abspath(basedir)
235+
if path is None:
236+
parts = basedir.split('/')
237+
path = parts[-1]
238+
basedir = os.path.abspath(
239+
'/'.join(parts[:-1])
240+
)
241+
242+
self.basedir = basedir
243+
self.path = path
244+
self.full_path = os.path.join(self.basedir, path)
245+
self.is_dir = os.path.isdir(self.full_path)
246+
self.is_file = os.path.isfile(self.full_path)
247+
self.name = os.path.basename(self.path)
248+
self.valid = self.is_valid()
249+
250+
if not self.valid:
251+
return
252+
253+
self.app = FastAPI()
254+
self.subapps = []
255+
256+
if self.is_file:
257+
file_path = f'/{self.name}'
258+
self.app.add_api_route(file_path, self.tree, methods=['GET'])
259+
return
260+
261+
self.app.add_api_route('/', self.tree, methods=['GET'])
262+
263+
for child in os.listdir(self.full_path):
264+
child_path = os.path.join(self.path, child)
265+
subapp = FilesystemAPI(self.basedir, child_path)
266+
logger.info(f'Mounting tree {child_path}')
267+
if subapp.valid:
268+
self.app.mount(f'/{child}', subapp.app)
269+
self.subapps.append(subapp)
270+
271+
272+
def tree(self, request: Request):
273+
return JSONResponse(content=self.build_tree())
274+
275+
def build_tree(self):
276+
result = []
277+
tree = {
278+
'name': self.name,
279+
'path': self.path,
280+
'isFile': self.is_file,
281+
}
282+
if self.is_file:
283+
return tree
284+
tree['children'] = [
285+
subapp.build_tree()
286+
for subapp in self.subapps
287+
]
288+
return tree
289+
290+
def is_valid(self):
291+
if self.is_dir == self.is_file:
292+
return False
293+
if self.is_dir and self.name.startswith('__'):
294+
return False
295+
if self.is_file and not self.name.endswith('.py'):
296+
return False
297+
298+
return True

0 commit comments

Comments
 (0)