##// END OF EJS Templates
removing spurious import
Nicholas Bollweg -
Show More
@@ -1,162 +1,161 b''
1 """Tornado handlers for nbconvert."""
1 """Tornado handlers for nbconvert."""
2
2
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 import io
6 import io
7 import os
7 import os
8 import zipfile
8 import zipfile
9 import collections
10
9
11 from tornado import web
10 from tornado import web
12
11
13 from ..base.handlers import (
12 from ..base.handlers import (
14 IPythonHandler, FilesRedirectHandler,
13 IPythonHandler, FilesRedirectHandler,
15 path_regex,
14 path_regex,
16 )
15 )
17 from IPython.nbformat import from_dict
16 from IPython.nbformat import from_dict
18
17
19 from IPython.utils.py3compat import cast_bytes
18 from IPython.utils.py3compat import cast_bytes
20 from IPython.utils import text
19 from IPython.utils import text
21
20
22 def find_resource_files(output_files_dir):
21 def find_resource_files(output_files_dir):
23 files = []
22 files = []
24 for dirpath, dirnames, filenames in os.walk(output_files_dir):
23 for dirpath, dirnames, filenames in os.walk(output_files_dir):
25 files.extend([os.path.join(dirpath, f) for f in filenames])
24 files.extend([os.path.join(dirpath, f) for f in filenames])
26 return files
25 return files
27
26
28 def respond_zip(handler, name, output, resources):
27 def respond_zip(handler, name, output, resources):
29 """Zip up the output and resource files and respond with the zip file.
28 """Zip up the output and resource files and respond with the zip file.
30
29
31 Returns True if it has served a zip file, False if there are no resource
30 Returns True if it has served a zip file, False if there are no resource
32 files, in which case we serve the plain output file.
31 files, in which case we serve the plain output file.
33 """
32 """
34 # Check if we have resource files we need to zip
33 # Check if we have resource files we need to zip
35 output_files = resources.get('outputs', None)
34 output_files = resources.get('outputs', None)
36 if not output_files:
35 if not output_files:
37 return False
36 return False
38
37
39 # Headers
38 # Headers
40 zip_filename = os.path.splitext(name)[0] + '.zip'
39 zip_filename = os.path.splitext(name)[0] + '.zip'
41 handler.set_header('Content-Disposition',
40 handler.set_header('Content-Disposition',
42 'attachment; filename="%s"' % zip_filename)
41 'attachment; filename="%s"' % zip_filename)
43 handler.set_header('Content-Type', 'application/zip')
42 handler.set_header('Content-Type', 'application/zip')
44
43
45 # Prepare the zip file
44 # Prepare the zip file
46 buffer = io.BytesIO()
45 buffer = io.BytesIO()
47 zipf = zipfile.ZipFile(buffer, mode='w', compression=zipfile.ZIP_DEFLATED)
46 zipf = zipfile.ZipFile(buffer, mode='w', compression=zipfile.ZIP_DEFLATED)
48 output_filename = os.path.splitext(name)[0] + resources['output_extension']
47 output_filename = os.path.splitext(name)[0] + resources['output_extension']
49 zipf.writestr(output_filename, cast_bytes(output, 'utf-8'))
48 zipf.writestr(output_filename, cast_bytes(output, 'utf-8'))
50 for filename, data in output_files.items():
49 for filename, data in output_files.items():
51 zipf.writestr(os.path.basename(filename), data)
50 zipf.writestr(os.path.basename(filename), data)
52 zipf.close()
51 zipf.close()
53
52
54 handler.finish(buffer.getvalue())
53 handler.finish(buffer.getvalue())
55 return True
54 return True
56
55
57 def get_exporter(format, **kwargs):
56 def get_exporter(format, **kwargs):
58 """get an exporter, raising appropriate errors"""
57 """get an exporter, raising appropriate errors"""
59 # if this fails, will raise 500
58 # if this fails, will raise 500
60 try:
59 try:
61 from IPython.nbconvert.exporters.export import exporter_map
60 from IPython.nbconvert.exporters.export import exporter_map
62 except ImportError as e:
61 except ImportError as e:
63 raise web.HTTPError(500, "Could not import nbconvert: %s" % e)
62 raise web.HTTPError(500, "Could not import nbconvert: %s" % e)
64
63
65 try:
64 try:
66 Exporter = exporter_map[format]
65 Exporter = exporter_map[format]
67 except KeyError:
66 except KeyError:
68 # should this be 400?
67 # should this be 400?
69 raise web.HTTPError(404, u"No exporter for format: %s" % format)
68 raise web.HTTPError(404, u"No exporter for format: %s" % format)
70
69
71 try:
70 try:
72 return Exporter(**kwargs)
71 return Exporter(**kwargs)
73 except Exception as e:
72 except Exception as e:
74 raise web.HTTPError(500, "Could not construct Exporter: %s" % e)
73 raise web.HTTPError(500, "Could not construct Exporter: %s" % e)
75
74
76 class NbconvertFileHandler(IPythonHandler):
75 class NbconvertFileHandler(IPythonHandler):
77
76
78 SUPPORTED_METHODS = ('GET',)
77 SUPPORTED_METHODS = ('GET',)
79
78
80 @web.authenticated
79 @web.authenticated
81 def get(self, format, path):
80 def get(self, format, path):
82
81
83 exporter = get_exporter(format, config=self.config, log=self.log)
82 exporter = get_exporter(format, config=self.config, log=self.log)
84
83
85 path = path.strip('/')
84 path = path.strip('/')
86 model = self.contents_manager.get(path=path)
85 model = self.contents_manager.get(path=path)
87 name = model['name']
86 name = model['name']
88 if model['type'] != 'notebook':
87 if model['type'] != 'notebook':
89 raise web.HTTPError(400, "Not a notebook: %s" % path)
88 raise web.HTTPError(400, "Not a notebook: %s" % path)
90
89
91 self.set_header('Last-Modified', model['last_modified'])
90 self.set_header('Last-Modified', model['last_modified'])
92
91
93 try:
92 try:
94 output, resources = exporter.from_notebook_node(
93 output, resources = exporter.from_notebook_node(
95 model['content'],
94 model['content'],
96 resources={
95 resources={
97 "metadata": {
96 "metadata": {
98 "name": name[:name.rfind('.')],
97 "name": name[:name.rfind('.')],
99 "modified_date": (model['last_modified']
98 "modified_date": (model['last_modified']
100 .strftime(text.date_format))
99 .strftime(text.date_format))
101 }
100 }
102 }
101 }
103 )
102 )
104 except Exception as e:
103 except Exception as e:
105 raise web.HTTPError(500, "nbconvert failed: %s" % e)
104 raise web.HTTPError(500, "nbconvert failed: %s" % e)
106
105
107 if respond_zip(self, name, output, resources):
106 if respond_zip(self, name, output, resources):
108 return
107 return
109
108
110 # Force download if requested
109 # Force download if requested
111 if self.get_argument('download', 'false').lower() == 'true':
110 if self.get_argument('download', 'false').lower() == 'true':
112 filename = os.path.splitext(name)[0] + resources['output_extension']
111 filename = os.path.splitext(name)[0] + resources['output_extension']
113 self.set_header('Content-Disposition',
112 self.set_header('Content-Disposition',
114 'attachment; filename="%s"' % filename)
113 'attachment; filename="%s"' % filename)
115
114
116 # MIME type
115 # MIME type
117 if exporter.output_mimetype:
116 if exporter.output_mimetype:
118 self.set_header('Content-Type',
117 self.set_header('Content-Type',
119 '%s; charset=utf-8' % exporter.output_mimetype)
118 '%s; charset=utf-8' % exporter.output_mimetype)
120
119
121 self.finish(output)
120 self.finish(output)
122
121
123 class NbconvertPostHandler(IPythonHandler):
122 class NbconvertPostHandler(IPythonHandler):
124 SUPPORTED_METHODS = ('POST',)
123 SUPPORTED_METHODS = ('POST',)
125
124
126 @web.authenticated
125 @web.authenticated
127 def post(self, format):
126 def post(self, format):
128 exporter = get_exporter(format, config=self.config)
127 exporter = get_exporter(format, config=self.config)
129
128
130 model = self.get_json_body()
129 model = self.get_json_body()
131 name = model.get('name', 'notebook.ipynb')
130 name = model.get('name', 'notebook.ipynb')
132 nbnode = from_dict(model['content'])
131 nbnode = from_dict(model['content'])
133
132
134 try:
133 try:
135 output, resources = exporter.from_notebook_node(nbnode)
134 output, resources = exporter.from_notebook_node(nbnode)
136 except Exception as e:
135 except Exception as e:
137 raise web.HTTPError(500, "nbconvert failed: %s" % e)
136 raise web.HTTPError(500, "nbconvert failed: %s" % e)
138
137
139 if respond_zip(self, name, output, resources):
138 if respond_zip(self, name, output, resources):
140 return
139 return
141
140
142 # MIME type
141 # MIME type
143 if exporter.output_mimetype:
142 if exporter.output_mimetype:
144 self.set_header('Content-Type',
143 self.set_header('Content-Type',
145 '%s; charset=utf-8' % exporter.output_mimetype)
144 '%s; charset=utf-8' % exporter.output_mimetype)
146
145
147 self.finish(output)
146 self.finish(output)
148
147
149
148
150 #-----------------------------------------------------------------------------
149 #-----------------------------------------------------------------------------
151 # URL to handler mappings
150 # URL to handler mappings
152 #-----------------------------------------------------------------------------
151 #-----------------------------------------------------------------------------
153
152
154 _format_regex = r"(?P<format>\w+)"
153 _format_regex = r"(?P<format>\w+)"
155
154
156
155
157 default_handlers = [
156 default_handlers = [
158 (r"/nbconvert/%s" % _format_regex, NbconvertPostHandler),
157 (r"/nbconvert/%s" % _format_regex, NbconvertPostHandler),
159 (r"/nbconvert/%s%s" % (_format_regex, path_regex),
158 (r"/nbconvert/%s%s" % (_format_regex, path_regex),
160 NbconvertFileHandler),
159 NbconvertFileHandler),
161 (r"/nbconvert/html%s" % path_regex, FilesRedirectHandler),
160 (r"/nbconvert/html%s" % path_regex, FilesRedirectHandler),
162 ]
161 ]
General Comments 0
You need to be logged in to leave comments. Login now