forked from jerry-git/learn-python3
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpost_save_hook.py
More file actions
97 lines (77 loc) · 3.52 KB
/
post_save_hook.py
File metadata and controls
97 lines (77 loc) · 3.52 KB
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
88
89
90
91
92
93
94
95
96
97
"""
Jupyter post_save_hook script for generating .py/.html files automatically when .ipynb file is saved.
Add the content to your jupyter_notebook_config.py. The location is usually $HOME/.jupyter/jupyter_notebook_config.py.
If you don't have one yet, you can generate the file: jupyter notebook --generate-config
"""
import json
import os
from subprocess import check_call
SAVE_PY = False # Save .py files (location is <dir of original>/py/)
SAVE_HTML = True # Save .html files (location is <dir of original>/html/)
# Run notebook before saving py/html. Note: this won't affect to the state of the .ipynb file.
RUN_NB_BEFORE_SAVE = True
# Skip saving of files which name contains of the following
DONT_SAVE = {'exercise', 'copy', 'untitled'}
# Add beatufil "Toggle output" button at the top of html page
USE_TOGGLE_BTN_IN_HTML = True
TOGGLE_OUTPUT_BTN = {
"cell_type":
"raw",
"metadata": {},
"source": [
"<script>\n", " function toggle() {\n",
" show ? $('div.output').hide('200') : $('div.output').show('200')\n",
" show = !show\n", " }\n", "\n",
" $( document ).ready(function(){\n", "show=false;\n",
" $('div.output').hide()\n", " });\n", "</script>\n", "\n",
"<form action=\"javascript:toggle()\" style=\"text-align:center;\">\n",
" <input type=\"submit\" id=\"toggleButton\" value=\"Toggle output 🐍\" \n",
" style=\"\n", " font-size: 20px;\n",
" text-align: center;\n", " color: green;\n",
" border-radius: 12px;\n", " width: 200px;\n",
" height: 50px;\n", " margin-bottom: 20px;\n",
" margin-top: 20px;\">\n", "\n", "</form>"
]
}
def _run_cmd(cmd, cwd=None):
check_call(cmd.split(), cwd=cwd)
def post_save(model, os_path, contents_manager):
if model['type'] != 'notebook' or not (SAVE_PY or SAVE_HTML):
return
dir_, fname = os.path.split(os_path)
for word in DONT_SAVE:
if word.lower() in fname.lower():
return
source, tmp_name = fname, None
out_file_base, _ = os.path.splitext(fname)
if RUN_NB_BEFORE_SAVE:
tmp_name = 'tmp_{}'.format(fname)
cmd = 'jupyter nbconvert --to notebook --execute --ExecutePreprocessor.timeout=30 --output {} {}'.format(
tmp_name, os_path)
_run_cmd(cmd, cwd=dir_)
source = tmp_name
if SAVE_PY:
out_dir_py = os.path.join(os.path.dirname(dir_), 'py')
os.makedirs(out_dir_py, exist_ok=True)
cmd = 'jupyter nbconvert --to python --output-dir {} --output {}.py {}'.format(
out_dir_py, out_file_base, source)
_run_cmd(cmd, cwd=dir_)
if SAVE_HTML:
if USE_TOGGLE_BTN_IN_HTML and RUN_NB_BEFORE_SAVE:
with open(os.path.join(dir_, source), 'r+') as tmp_source:
content = json.loads(tmp_source.read())
content['cells'] = [TOGGLE_OUTPUT_BTN] + content.get(
'cells', [])
tmp_source.seek(0)
tmp_source.write(json.dumps(content))
tmp_source.truncate()
out_dir_html = os.path.join(os.path.dirname(dir_), 'html')
os.makedirs(out_dir_html, exist_ok=True)
cmd = 'jupyter nbconvert --to html --output-dir {} --output {}.html {}'.format(
out_dir_html, out_file_base, source)
_run_cmd(cmd, cwd=dir_)
if tmp_name:
tmp_file = os.path.join(dir_, tmp_name)
if os.path.exists(tmp_file):
os.remove(tmp_file)
c.FileContentsManager.post_save_hook = post_save