-
Notifications
You must be signed in to change notification settings - Fork 15
/
handler.py
87 lines (75 loc) · 2.79 KB
/
handler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import os
import time
from fnmatch import fnmatch
from jupyter_server.base.handlers import APIHandler
from tornado import web
from tornado.escape import json_encode
class QuickOpenHandler(APIHandler):
@property
def contents_manager(self):
"""Currently configured jupyter server ContentsManager."""
return self.settings["contents_manager"]
@property
def root_dir(self):
"""Root directory to scan."""
return self.contents_manager.root_dir
async def should_hide(self, entry, excludes):
"""Decides if a file or directory should be hidden from the search results based on
the `allow_hidden` and `hide_globs` properties of the ContentsManager, as well as a
set of exclude patterns included in the client request.
Parameters
----------
entry: DirEntry
From os.scandir
excludes: set of str
Exclude patterns
Returns
-------
bool
"""
return (
any(fnmatch(entry.name, glob) for glob in excludes)
or not self.contents_manager.should_list(entry.name)
or (
await self.contents_manager.is_hidden(entry.path)
and not self.contents_manager.allow_hidden
)
)
async def scan_disk(self, path, excludes, on_disk=None):
if on_disk is None:
on_disk = {}
for entry in os.scandir(path):
if await self.should_hide(entry, excludes):
continue
elif entry.is_dir():
await self.scan_disk(entry.path, excludes, on_disk)
elif entry.is_file():
parent = os.path.relpath(os.path.dirname(entry.path), self.root_dir)
on_disk.setdefault(parent, []).append(entry.name)
return on_disk
@web.authenticated
async def get(self):
"""Gets the name of every file under the root notebooks directory binned by parent
folder relative to the root notebooks dir.
Arguments
---------
exclude: str
Comma-separated set of file name patterns to exclude
Responds
--------
JSON
scan_seconds: Time in seconds to collect all file names
contents: File names binned by parent directory
"""
excludes = set(self.get_arguments("excludes"))
current_path = self.get_argument("path")
start_ts = time.time()
if current_path:
full_path = os.path.join(self.root_dir, current_path)
else:
full_path = self.root_dir
contents_by_path = await self.scan_disk(full_path, excludes)
delta_ts = time.time() - start_ts
self.write(
json_encode({"scan_seconds": delta_ts, "contents": contents_by_path})
)