forked from kirbs-/hide_code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhide_code.py
More file actions
206 lines (175 loc) · 7.38 KB
/
Copy pathhide_code.py
File metadata and controls
206 lines (175 loc) · 7.38 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
import os
from os import path
import shutil
import jupyter_core.paths as j_path
from notebook.utils import url_path_join
from notebook.base.handlers import IPythonHandler
import nbformat
from traitlets.config import Config
from .hide_code_html_exporter import HideCodeHTMLExporter
from .hide_code_pdf_exporter import HideCodePDFExporter
import pdfkit
from notebook.services.config import ConfigManager
from .hide_code_config import HideCodeConfig as hc_config
from .utils import Utils
notebook_dir = ""
base_url = ""
class HideCodeHTMLExportHandler(IPythonHandler):
def get(self, *args):
self.log.info("hide_code: Starting HTML export for {}".format(args[-1]))
with open(ipynb_file_name(args)) as f:
nb = nbformat.reads(f.read(), as_version=4)
exporter = HideCodeHTMLExporter()
output_html, resources = exporter.from_notebook_node(nb)
self.set_header('Content-Type', 'text/html')
self.set_header('Content-Disposition', 'attachment; filename=' + notebook_name(args) + '.html')
self.flush()
self.write(output_html)
self.log.info("hide_code: Finished HTML export for {}".format(args[-1]))
self.finish()
class HideCodePDFExportHandler(IPythonHandler):
def get(self, *args):
self.log.info("hide_code: Starting PDF export for {}".format(args[-1]))
with open(ipynb_file_name(args)) as f:
nb = nbformat.reads(f.read(), as_version=4)
exporter = HideCodeHTMLExporter()
output_html, resources = exporter.from_notebook_node(nb)
output = pdfkit.from_string(output_html, False)
self.set_header('Content-Type', 'application/pdf')
self.set_header('Content-Disposition', 'attachment; filename=' + notebook_name(args) + '.pdf')
self.flush()
self.write(output)
self.log.info("hide_code: Finished PDF export for {}".format(args[-1]))
self.finish()
class HideCodeLatexPDFExportHandler(IPythonHandler):
def get(self, *args):
self.log.info("hide_code: Starting Latex PDF export for {}".format(args[-1]))
with open(ipynb_file_name(args)) as f:
nb = nbformat.reads(f.read(), as_version=4)
exporter = HideCodePDFExporter()
output, resources = exporter.from_notebook_node(nb, resources={"metadata": {"name": notebook_name(args)}})
self.set_header('Content-Disposition', 'attachment; filename=' + notebook_name(args) + '.pdf')
self.flush()
self.write(output)
self.log.info("hide_code: Finished Latex PDF export for {}".format(args[-1]))
self.finish()
def __main__():
install()
def load_jupyter_server_extension(nb_app):
nb_app.log.info("hide_code: Attempting to load hid_code export handler extensions.")
web_app = nb_app.web_app
notebook_dir = nb_app.notebook_dir
host_pattern = '.*$'
global base_url
base_url = web_app.settings['base_url']
base_url = web_app.settings['base_url']
web_app.add_handlers(host_pattern, [
(route_pattern_for('html'), HideCodeHTMLExportHandler),
(route_pattern_for('pdf'), HideCodePDFExportHandler),
(route_pattern_for('latexpdf'), HideCodeLatexPDFExportHandler)
])
nb_app.log.info("hide_code: Hide_code export handler extensions loaded.")
def install(nb_path=None, server_config=True, DEBUG=False):
install_path = None
print('Starting hide_code.js install...')
current_dir = path.abspath(path.dirname(__file__))
config_dirs = j_path.jupyter_config_path()
site_packages_path = Utils.get_site_package_dir()
# check for config directory with a "custom" folder
# TODO update this logic to check if custom.js file exists
for dir in config_dirs:
custom_dir = path.join(dir, "custom")
if path.isdir(custom_dir):
install_path = custom_dir
break
# last ditch effort in case jupyter config directories don't contain custom/custom.js
if install_path == None:
print("No config directories contain \"custom\" folder. Trying site-packages...")
install_path = path.join(site_packages_path, "notebook", "static", "custom")
if nb_path != None:
install_path = nb_path
print("Using argument supplied path: " + install_path)
if DEBUG:
print(install_path)
# copy js into static/custom directory in Jupyter/iPython directory
if path.isdir(install_path):
shutil.copyfile(path.join(current_dir, "hide_code.js"), path.join(install_path, "hide_code.js"))
print('Copying hide_code.js to ' + install_path)
# add require to end of custom.js to auto-load on notebook startup
print("Attempting to configure custom.js to auto-load hide_code.js...")
try:
with open(path.join(current_dir, "auto-load.txt")) as auto:
auto_load_txt = auto.read();
auto_loaded = False
# check if auto-load.txt is already in custom.js
with open(path.join(install_path, "custom.js"), 'r') as customJS:
if auto_load_txt in customJS.read():
auto_loaded = True
print("Custom.js already configured to auto-load hide_code.js.")
if not auto_loaded: # append auto load require to end of custom.js
with open(path.join(install_path, "custom.js"), 'a') as customJS:
customJS.write(auto_load_txt)
print("Configured custom.js to auto-load hide_code.js.")
except:
print("Custom.js not in custom directory.")
else:
print('Unable to install into ' + install_path)
print('Directory doesn\'t exist.')
print('Make sure Jupyter is installed.')
if server_config:
print("Attempting to configure auto-loading for hide_code export handlers.")
try:
# Activate the Python server extension
server_cm = ConfigManager(config_dir=j_path.jupyter_config_dir())
cfg = server_cm.get('jupyter_notebook_config')
server_extensions = (cfg.setdefault('NotebookApp', {})
.setdefault('server_extensions', [])
)
extension = 'hide_code.hide_code'
if extension not in server_extensions:
cfg['NotebookApp']['server_extensions'] += [extension]
server_cm.update('jupyter_notebook_config', cfg)
print('Configured jupyter to auto-load hide_code export handlers.')
else:
print("Jupyter already configured to auto-load export handlers.")
except:
print('Unable to install server extension.')
def route_pattern_for(exporter):
pattern = ''
for i in range(1, hc_config.get('nested_params_depth')):
pattern += '(/[^/]*)?'
return url_path_join(base_url, 'notebooks/([^/]+)' + pattern, 'export', exporter)
def notebook_name(params):
"""
Returns notebook name without .ipynb extension.
"""
args = [param.replace('/','') for param in params if param is not None]
return args[-1][:-6]
def ipynb_file_name(params):
"""
Returns OS path to notebook based on route parameters.
"""
p = [param.replace('/','') for param in params if param is not None]
return path.join(*p)
def setup_info():
server_cm = ConfigManager(config_dir=j_path.jupyter_config_dir())
cfg = server_cm.get('jupyter_notebook_config')
server_extensions = (cfg.setdefault('NotebookApp', {})
.setdefault('server_extensions', [])
)
extension = 'hide_code.hide_code'
if extension not in server_extensions:
ext = 'Not loaded'
else:
ext = 'Loaded'
files = []
for (dirpath, dirnames, filenames) in os.walk(path.join(Utils.get_site_package_dir(), 'hide_code')):
files.extend(filenames)
break
custom_js = ''
with open(path.join(Utils.get_site_package_dir(), 'notebook','static','custom','custom.js'), 'r') as f:
for line in iter(f):
if not line.startswith(' *') and not line.startswith('/'):
custom_js = custom_js + line + ' '
return ("Installation dir: {0}\nConfiguration dir: {1}\nExport handler extensions: {2}\nHide Code files: {3}\nCustom JS contents: {4}"
.format(Utils.get_site_package_dir(), j_path.jupyter_config_dir(), ext, files, custom_js))