Skip to content

Commit f731d17

Browse files
authored
Merge pull request #5 from mariobuikhuizen/jupyter-data-dirs
feat: use jupyter data dirs to load snippets
2 parents 9785774 + f52dbf9 commit f731d17

File tree

7 files changed

+54
-35
lines changed

7 files changed

+54
-35
lines changed

README.md

+2-6
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,11 @@ jupyter lab build
2222

2323
## Usage
2424

25-
In `jupyter_notebook_config.py`:
26-
27-
```python
28-
c.JupyterLabCodeSnippets.snippet_dir = "/path/to/snippets"
29-
```
25+
Add snippets in `[jupyter_data_dir]/code_snippets` (see: https://jupyter.readthedocs.io/en/latest/projects/jupyter-directories.html#id2)
3026

3127
In JupyterLab, use the "Code Snippets" menu to select the snippet:
3228

33-
![screenshot](./screenshot.png)
29+
<img width="398" alt="Schermafbeelding 2020-03-26 om 13 16 34" src="https://user-images.githubusercontent.com/46192475/77646139-40a21c00-6f64-11ea-9073-fe2d1052928f.png">
3430

3531

3632
## Troubleshoot

jupyterlab-code-snippets/__init__.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ def load_jupyter_server_extension(nb_app):
1616
nb_app: notebook.notebookapp.NotebookApp
1717
Notebook application instance
1818
"""
19-
snippet_dir = nb_app.config.get('JupyterLabCodeSnippets', {}).get('snippet_dir', '')
20-
# TODO: add snippets from jupyter paths?
2119

22-
loader = SnippetsLoader(snippet_dir)
20+
loader = SnippetsLoader()
2321
setup_handlers(nb_app.web_app, loader)

jupyterlab-code-snippets/loader.py

+25-14
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,40 @@
22

33
from pathlib import PurePath
44

5+
from jupyter_core.paths import jupyter_path
6+
7+
import tornado
8+
59

610
class SnippetsLoader:
7-
def __init__(self, snippet_dir):
8-
self.snippet_dir = snippet_dir
11+
def __init__(self):
12+
self.snippet_paths = jupyter_path("code_snippets")
913

1014
def collect_snippets(self):
11-
# TODO: handle multiple directories
12-
root = self.snippet_dir
1315
snippets = []
14-
for dirpath, dirnames, filenames in os.walk(root):
15-
for f in filenames:
16-
fullpath = PurePath(dirpath).relative_to(root).joinpath(f)
17-
snippets.append(fullpath.parts)
16+
for root_path in self.snippet_paths:
17+
for dirpath, dirnames, filenames in os.walk(root_path):
18+
for f in filenames:
19+
fullpath = PurePath(dirpath).relative_to(root_path).joinpath(f)
20+
21+
if fullpath.parts not in snippets:
22+
snippets.append(fullpath.parts)
23+
1824
snippets.sort()
1925
return snippets
2026

2127
def get_snippet_content(self, snippet):
2228
try:
23-
path = os.path.join(self.snippet_dir, *snippet)
24-
with open(path) as f:
25-
content = f.read()
26-
except:
27-
content = ''
29+
for root_path in self.snippet_paths:
30+
path = os.path.join(root_path, *snippet)
31+
32+
# Prevent access to the entire file system when the path contains '..'
33+
accessible = os.path.realpath(path).startswith(root_path)
2834

29-
return content
35+
if accessible and os.path.isfile(path):
36+
with open(path) as f:
37+
return f.read()
38+
except:
39+
raise tornado.web.HTTPError(status_code=500)
3040

41+
raise tornado.web.HTTPError(status_code=404)

package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@
3737
"watch": "tsc -w"
3838
},
3939
"dependencies": {
40-
"@jupyterlab/application": "^2.0.0-rc.0",
41-
"@jupyterlab/apputils": "^2.0.0-rc.0",
42-
"@jupyterlab/coreutils": "^4.0.0-rc.0",
43-
"@jupyterlab/mainmenu": "^2.0.0-rc.0",
44-
"@jupyterlab/notebook": "^2.0.0-rc.0",
45-
"@jupyterlab/services": "^5.0.0-rc.0",
40+
"@jupyterlab/application": "^2.0.2",
41+
"@jupyterlab/apputils": "^2.0.2",
42+
"@jupyterlab/coreutils": "^4.0.2",
43+
"@jupyterlab/mainmenu": "^2.0.2",
44+
"@jupyterlab/notebook": "^2.0.2",
45+
"@jupyterlab/services": "^5.0.2",
4646
"@lumino/commands": "^1.9.2",
4747
"@lumino/widgets": "^1.10.0"
4848
},

screenshot.png

-44.3 KB
Binary file not shown.

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
# Representative files that should exist after a successful build
2626
jstargets = [
27-
os.path.join(HERE, "lib", "jupyterlab-code-snippets.js"),
27+
os.path.join(HERE, "lib", "snippets.js"),
2828
]
2929

3030
package_data_spec = {

src/index.ts

+19-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ import { INotebookTracker, NotebookActions } from "@jupyterlab/notebook";
1111

1212
import { CommandRegistry } from '@lumino/commands';
1313

14-
import { Menu } from '@lumino/widgets';
14+
import {
15+
MenuSvg,
16+
pythonIcon,
17+
terminalIcon,
18+
textEditorIcon,
19+
folderIcon,
20+
} from '@jupyterlab/ui-components';
1521

1622
import { listSnippets, Snippet, fetchSnippet } from "./snippets";
1723

@@ -52,7 +58,7 @@ function toTree(snippets: Snippet[]) {
5258
* @param path The current path in the tree.
5359
*/
5460
function createMenu(commands: CommandRegistry , tree: Tree, path: string[] = []) {
55-
const menu = new Menu({ commands });
61+
const menu = new MenuSvg({ commands });
5662
for (const [name, map] of tree.entries()) {
5763
const fullpath = path.concat(name);
5864
if (map.size === 0) {
@@ -63,6 +69,7 @@ function createMenu(commands: CommandRegistry , tree: Tree, path: string[] = [])
6369
} else {
6470
const submenu = createMenu(commands, map, path.concat(name));
6571
submenu.title.label = name;
72+
submenu.title.icon = folderIcon;
6673
menu.addItem({type: 'submenu', submenu});
6774
}
6875
}
@@ -91,9 +98,16 @@ const extension: JupyterFrontEndPlugin<void> = {
9198
}
9299

93100
commands.addCommand(CommandIDs.open, {
94-
label: args => {
95-
const label = args['label'] as string;
96-
return PathExt.basename(label, PathExt.extname(label));
101+
label: args => args['label'] as string,
102+
icon: args => {
103+
const ext = PathExt.extname(args['label'] as string);
104+
if (ext === '.py') {
105+
return pythonIcon;
106+
}
107+
if (ext === '.sh') {
108+
return terminalIcon;
109+
}
110+
return textEditorIcon;
97111
},
98112
execute: async args => {
99113
const path = args['path'] as string[];

0 commit comments

Comments
 (0)