Show More
@@ -196,6 +196,7 class FileContentsManager(ContentsManager): | |||||
196 | contents.append(self.get_model(name=name, path=dir_path, content=False)) |
|
196 | contents.append(self.get_model(name=name, path=dir_path, content=False)) | |
197 |
|
197 | |||
198 | model['content'] = sorted(contents, key=sort_key) |
|
198 | model['content'] = sorted(contents, key=sort_key) | |
|
199 | model['format'] = 'json' | |||
199 |
|
200 | |||
200 | return model |
|
201 | return model | |
201 |
|
202 | |||
@@ -273,12 +274,48 class FileContentsManager(ContentsManager): | |||||
273 | model = self._file_model(name, path, content) |
|
274 | model = self._file_model(name, path, content) | |
274 | return model |
|
275 | return model | |
275 |
|
276 | |||
|
277 | def _save_notebook(self, os_path, model, name='', path=''): | |||
|
278 | # Save the notebook file | |||
|
279 | nb = current.to_notebook_json(model['content']) | |||
|
280 | ||||
|
281 | self.check_and_sign(nb, name, path) | |||
|
282 | ||||
|
283 | if 'name' in nb['metadata']: | |||
|
284 | nb['metadata']['name'] = u'' | |||
|
285 | ||||
|
286 | with io.open(os_path, 'w', encoding='utf-8') as f: | |||
|
287 | current.write(nb, f, u'json') | |||
|
288 | ||||
|
289 | def _save_file(self, os_path, model, name='', path=''): | |||
|
290 | fmt = model.get('format', None) | |||
|
291 | if fmt not in {'text', 'base64'}: | |||
|
292 | raise web.HTTPError(400, "Must specify format of file contents as 'text' or 'base64'") | |||
|
293 | try: | |||
|
294 | content = model['content'] | |||
|
295 | if fmt == 'text': | |||
|
296 | bcontent = content.encode('utf8') | |||
|
297 | else: | |||
|
298 | b64_bytes = content.encode('ascii') | |||
|
299 | bcontent = base64.decodestring(b64_bytes) | |||
|
300 | except Exception as e: | |||
|
301 | raise web.HTTPError(400, u'Encoding error saving %s: %s' % (os_path, e)) | |||
|
302 | with io.open(os_path, 'wb') as f: | |||
|
303 | f.write(bcontent) | |||
|
304 | ||||
|
305 | def _save_directory(self, os_path, model, name='', path=''): | |||
|
306 | if not os.path.exists(os_path): | |||
|
307 | os.mkdir(os_path) | |||
|
308 | elif not os.path.isdir(os_path): | |||
|
309 | raise web.HTTPError(400, u'Not a directory: %s' % (os_path)) | |||
|
310 | ||||
276 | def save(self, model, name='', path=''): |
|
311 | def save(self, model, name='', path=''): | |
277 |
"""Save the |
|
312 | """Save the file model and return the model with no content.""" | |
278 | path = path.strip('/') |
|
313 | path = path.strip('/') | |
279 |
|
314 | |||
280 | if 'content' not in model: |
|
315 | if 'content' not in model: | |
281 |
raise web.HTTPError(400, u'No |
|
316 | raise web.HTTPError(400, u'No file content provided') | |
|
317 | if 'type' not in model: | |||
|
318 | raise web.HTTPError(400, u'No file type provided') | |||
282 |
|
319 | |||
283 | # One checkpoint should always exist |
|
320 | # One checkpoint should always exist | |
284 | if self.file_exists(name, path) and not self.list_checkpoints(name, path): |
|
321 | if self.file_exists(name, path) and not self.list_checkpoints(name, path): | |
@@ -290,20 +327,21 class FileContentsManager(ContentsManager): | |||||
290 | if path != new_path or name != new_name: |
|
327 | if path != new_path or name != new_name: | |
291 | self.rename(name, path, new_name, new_path) |
|
328 | self.rename(name, path, new_name, new_path) | |
292 |
|
329 | |||
293 | # Save the notebook file |
|
|||
294 | os_path = self._get_os_path(new_name, new_path) |
|
330 | os_path = self._get_os_path(new_name, new_path) | |
295 | nb = current.to_notebook_json(model['content']) |
|
331 | self.log.debug("Saving %s", os_path) | |
296 |
|
||||
297 | self.check_and_sign(nb, new_name, new_path) |
|
|||
298 |
|
||||
299 | if 'name' in nb['metadata']: |
|
|||
300 | nb['metadata']['name'] = u'' |
|
|||
301 | try: |
|
332 | try: | |
302 | self.log.debug("Autosaving notebook %s", os_path) |
|
333 | if model['type'] == 'notebook': | |
303 | with io.open(os_path, 'w', encoding='utf-8') as f: |
|
334 | self._save_notebook(os_path, model, new_name, new_path) | |
304 | current.write(nb, f, u'json') |
|
335 | elif model['type'] == 'file': | |
|
336 | self._save_file(os_path, model, new_name, new_path) | |||
|
337 | elif model['type'] == 'directory': | |||
|
338 | self._save_directory(os_path, model, new_name, new_path) | |||
|
339 | else: | |||
|
340 | raise web.HTTPError(400, "Unhandled contents type: %s" % model['type']) | |||
|
341 | except web.HTTPError: | |||
|
342 | raise | |||
305 | except Exception as e: |
|
343 | except Exception as e: | |
306 |
raise web.HTTPError(400, u'Unexpected error while |
|
344 | raise web.HTTPError(400, u'Unexpected error while saving file: %s %s' % (os_path, e)) | |
307 |
|
345 | |||
308 | model = self.get_model(new_name, new_path, content=False) |
|
346 | model = self.get_model(new_name, new_path, content=False) | |
309 | return model |
|
347 | return model |
@@ -99,20 +99,20 class ContentsHandler(IPythonHandler): | |||||
99 | if name: |
|
99 | if name: | |
100 | model['name'] = name |
|
100 | model['name'] = name | |
101 |
|
101 | |||
102 |
model = self.contents_manager.create_ |
|
102 | model = self.contents_manager.create_file(model, path) | |
103 | self.set_status(201) |
|
103 | self.set_status(201) | |
104 | self._finish_model(model) |
|
104 | self._finish_model(model) | |
105 |
|
105 | |||
106 |
def _create_empty_ |
|
106 | def _create_empty_file(self, path, name=None, ext='.ipynb'): | |
107 |
"""Create an empty |
|
107 | """Create an empty file in path | |
108 |
|
108 | |||
109 | If name specified, create it in path/name. |
|
109 | If name specified, create it in path/name. | |
110 | """ |
|
110 | """ | |
111 |
self.log.info(u"Creating new |
|
111 | self.log.info(u"Creating new file in %s/%s", path, name or '') | |
112 | model = {} |
|
112 | model = {} | |
113 | if name: |
|
113 | if name: | |
114 | model['name'] = name |
|
114 | model['name'] = name | |
115 |
model = self.contents_manager.create_ |
|
115 | model = self.contents_manager.create_file(model, path=path, ext=ext) | |
116 | self.set_status(201) |
|
116 | self.set_status(201) | |
117 | self._finish_model(model) |
|
117 | self._finish_model(model) | |
118 |
|
118 | |||
@@ -137,7 +137,8 class ContentsHandler(IPythonHandler): | |||||
137 | POST /api/contents/path |
|
137 | POST /api/contents/path | |
138 | New untitled notebook in path. If content specified, upload a |
|
138 | New untitled notebook in path. If content specified, upload a | |
139 | notebook, otherwise start empty. |
|
139 | notebook, otherwise start empty. | |
140 |
POST /api/contents/path |
|
140 | POST /api/contents/path | |
|
141 | with body {"copy_from" : "OtherNotebook.ipynb"} | |||
141 | New copy of OtherNotebook in path |
|
142 | New copy of OtherNotebook in path | |
142 | """ |
|
143 | """ | |
143 |
|
144 | |||
@@ -156,14 +157,17 class ContentsHandler(IPythonHandler): | |||||
156 |
|
157 | |||
157 | if model is not None: |
|
158 | if model is not None: | |
158 | copy_from = model.get('copy_from') |
|
159 | copy_from = model.get('copy_from') | |
159 | if copy_from: |
|
160 | ext = model.get('ext', '.ipynb') | |
160 |
|
|
161 | if model.get('content') is not None: | |
|
162 | if copy_from: | |||
161 | raise web.HTTPError(400, "Can't upload and copy at the same time.") |
|
163 | raise web.HTTPError(400, "Can't upload and copy at the same time.") | |
|
164 | self._upload(model, path) | |||
|
165 | elif copy_from: | |||
162 | self._copy(copy_from, path) |
|
166 | self._copy(copy_from, path) | |
163 | else: |
|
167 | else: | |
164 |
self._ |
|
168 | self._create_empty_file(path, ext=ext) | |
165 | else: |
|
169 | else: | |
166 |
self._create_empty_ |
|
170 | self._create_empty_file(path) | |
167 |
|
171 | |||
168 | @web.authenticated |
|
172 | @web.authenticated | |
169 | @json_errors |
|
173 | @json_errors | |
@@ -195,7 +199,7 class ContentsHandler(IPythonHandler): | |||||
195 | else: |
|
199 | else: | |
196 | self._upload(model, path, name) |
|
200 | self._upload(model, path, name) | |
197 | else: |
|
201 | else: | |
198 |
self._create_empty_ |
|
202 | self._create_empty_file(path, name) | |
199 |
|
203 | |||
200 | @web.authenticated |
|
204 | @web.authenticated | |
201 | @json_errors |
|
205 | @json_errors |
@@ -155,16 +155,23 class ContentsManager(LoggingConfigurable): | |||||
155 | break |
|
155 | break | |
156 | return name |
|
156 | return name | |
157 |
|
157 | |||
158 |
def create_ |
|
158 | def create_file(self, model=None, path='', ext='.ipynb'): | |
159 | """Create a new notebook and return its model with no content.""" |
|
159 | """Create a new notebook and return its model with no content.""" | |
160 | path = path.strip('/') |
|
160 | path = path.strip('/') | |
161 | if model is None: |
|
161 | if model is None: | |
162 | model = {} |
|
162 | model = {} | |
163 | if 'content' not in model: |
|
163 | if 'content' not in model: | |
164 | metadata = current.new_metadata(name=u'') |
|
164 | if ext == '.ipynb': | |
165 |
|
|
165 | metadata = current.new_metadata(name=u'') | |
|
166 | model['content'] = current.new_notebook(metadata=metadata) | |||
|
167 | model.setdefault('type', 'notebook') | |||
|
168 | model.setdefault('format', 'json') | |||
|
169 | else: | |||
|
170 | model['content'] = '' | |||
|
171 | model.setdefault('type', 'file') | |||
|
172 | model.setdefault('format', 'text') | |||
166 | if 'name' not in model: |
|
173 | if 'name' not in model: | |
167 |
model['name'] = self.increment_filename('Untitled |
|
174 | model['name'] = self.increment_filename('Untitled' + ext, path) | |
168 |
|
175 | |||
169 | model['path'] = path |
|
176 | model['path'] = path | |
170 | model = self.save(model, model['name'], model['path']) |
|
177 | model = self.save(model, model['name'], model['path']) |
@@ -50,8 +50,11 class API(object): | |||||
50 | def read(self, name, path='/'): |
|
50 | def read(self, name, path='/'): | |
51 | return self._req('GET', url_path_join(path, name)) |
|
51 | return self._req('GET', url_path_join(path, name)) | |
52 |
|
52 | |||
53 | def create_untitled(self, path='/'): |
|
53 | def create_untitled(self, path='/', ext=None): | |
54 | return self._req('POST', path) |
|
54 | body = None | |
|
55 | if ext: | |||
|
56 | body = json.dumps({'ext': ext}) | |||
|
57 | return self._req('POST', path, body) | |||
55 |
|
58 | |||
56 | def upload_untitled(self, body, path='/'): |
|
59 | def upload_untitled(self, body, path='/'): | |
57 | return self._req('POST', path, body) |
|
60 | return self._req('POST', path, body) | |
@@ -267,26 +270,72 class APITest(NotebookTestBase): | |||||
267 | resp = self.api.create_untitled(path='foo/bar') |
|
270 | resp = self.api.create_untitled(path='foo/bar') | |
268 | self._check_nb_created(resp, 'Untitled0.ipynb', 'foo/bar') |
|
271 | self._check_nb_created(resp, 'Untitled0.ipynb', 'foo/bar') | |
269 |
|
272 | |||
|
273 | def test_create_untitled_txt(self): | |||
|
274 | resp = self.api.create_untitled(path='foo/bar', ext='.txt') | |||
|
275 | self._check_nb_created(resp, 'Untitled0.txt', 'foo/bar') | |||
|
276 | ||||
|
277 | resp = self.api.read(path='foo/bar', name='Untitled0.txt') | |||
|
278 | model = resp.json() | |||
|
279 | self.assertEqual(model['type'], 'file') | |||
|
280 | self.assertEqual(model['format'], 'text') | |||
|
281 | self.assertEqual(model['content'], '') | |||
|
282 | ||||
270 | def test_upload_untitled(self): |
|
283 | def test_upload_untitled(self): | |
271 | nb = new_notebook(name='Upload test') |
|
284 | nb = new_notebook(name='Upload test') | |
272 | nbmodel = {'content': nb} |
|
285 | nbmodel = {'content': nb, 'type': 'notebook'} | |
273 | resp = self.api.upload_untitled(path=u'å b', |
|
286 | resp = self.api.upload_untitled(path=u'å b', | |
274 | body=json.dumps(nbmodel)) |
|
287 | body=json.dumps(nbmodel)) | |
275 | self._check_nb_created(resp, 'Untitled0.ipynb', u'å b') |
|
288 | self._check_nb_created(resp, 'Untitled0.ipynb', u'å b') | |
276 |
|
289 | |||
277 | def test_upload(self): |
|
290 | def test_upload(self): | |
278 | nb = new_notebook(name=u'ignored') |
|
291 | nb = new_notebook(name=u'ignored') | |
279 | nbmodel = {'content': nb} |
|
292 | nbmodel = {'content': nb, 'type': 'notebook'} | |
280 | resp = self.api.upload(u'Upload tést.ipynb', path=u'å b', |
|
293 | resp = self.api.upload(u'Upload tést.ipynb', path=u'å b', | |
281 | body=json.dumps(nbmodel)) |
|
294 | body=json.dumps(nbmodel)) | |
282 | self._check_nb_created(resp, u'Upload tést.ipynb', u'å b') |
|
295 | self._check_nb_created(resp, u'Upload tést.ipynb', u'å b') | |
283 |
|
296 | |||
|
297 | def test_upload_txt(self): | |||
|
298 | body = u'ünicode téxt' | |||
|
299 | model = { | |||
|
300 | 'content' : body, | |||
|
301 | 'format' : 'text', | |||
|
302 | 'type' : 'file', | |||
|
303 | } | |||
|
304 | resp = self.api.upload(u'Upload tést.txt', path=u'å b', | |||
|
305 | body=json.dumps(model)) | |||
|
306 | ||||
|
307 | # check roundtrip | |||
|
308 | resp = self.api.read(path=u'å b', name=u'Upload tést.txt') | |||
|
309 | model = resp.json() | |||
|
310 | self.assertEqual(model['type'], 'file') | |||
|
311 | self.assertEqual(model['format'], 'text') | |||
|
312 | self.assertEqual(model['content'], body) | |||
|
313 | ||||
|
314 | def test_upload_b64(self): | |||
|
315 | body = b'\xFFblob' | |||
|
316 | b64body = base64.encodestring(body).decode('ascii') | |||
|
317 | model = { | |||
|
318 | 'content' : b64body, | |||
|
319 | 'format' : 'base64', | |||
|
320 | 'type' : 'file', | |||
|
321 | } | |||
|
322 | resp = self.api.upload(u'Upload tést.blob', path=u'å b', | |||
|
323 | body=json.dumps(model)) | |||
|
324 | ||||
|
325 | # check roundtrip | |||
|
326 | resp = self.api.read(path=u'å b', name=u'Upload tést.blob') | |||
|
327 | model = resp.json() | |||
|
328 | self.assertEqual(model['type'], 'file') | |||
|
329 | self.assertEqual(model['format'], 'base64') | |||
|
330 | decoded = base64.decodestring(model['content'].encode('ascii')) | |||
|
331 | self.assertEqual(decoded, body) | |||
|
332 | ||||
284 | def test_upload_v2(self): |
|
333 | def test_upload_v2(self): | |
285 | nb = v2.new_notebook() |
|
334 | nb = v2.new_notebook() | |
286 | ws = v2.new_worksheet() |
|
335 | ws = v2.new_worksheet() | |
287 | nb.worksheets.append(ws) |
|
336 | nb.worksheets.append(ws) | |
288 | ws.cells.append(v2.new_code_cell(input='print("hi")')) |
|
337 | ws.cells.append(v2.new_code_cell(input='print("hi")')) | |
289 | nbmodel = {'content': nb} |
|
338 | nbmodel = {'content': nb, 'type': 'notebook'} | |
290 | resp = self.api.upload(u'Upload tést.ipynb', path=u'å b', |
|
339 | resp = self.api.upload(u'Upload tést.ipynb', path=u'å b', | |
291 | body=json.dumps(nbmodel)) |
|
340 | body=json.dumps(nbmodel)) | |
292 | self._check_nb_created(resp, u'Upload tést.ipynb', u'å b') |
|
341 | self._check_nb_created(resp, u'Upload tést.ipynb', u'å b') | |
@@ -335,7 +384,7 class APITest(NotebookTestBase): | |||||
335 | nb.worksheets = [ws] |
|
384 | nb.worksheets = [ws] | |
336 | ws.cells.append(new_heading_cell(u'Created by test ³')) |
|
385 | ws.cells.append(new_heading_cell(u'Created by test ³')) | |
337 |
|
386 | |||
338 | nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb} |
|
387 | nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb, 'type': 'notebook'} | |
339 | resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel)) |
|
388 | resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel)) | |
340 |
|
389 | |||
341 | nbfile = pjoin(self.notebook_dir.name, 'foo', 'a.ipynb') |
|
390 | nbfile = pjoin(self.notebook_dir.name, 'foo', 'a.ipynb') | |
@@ -349,7 +398,7 class APITest(NotebookTestBase): | |||||
349 | u'Created by test ³') |
|
398 | u'Created by test ³') | |
350 |
|
399 | |||
351 | # Save and rename |
|
400 | # Save and rename | |
352 | nbmodel= {'name': 'a2.ipynb', 'path':'foo/bar', 'content': nb} |
|
401 | nbmodel= {'name': 'a2.ipynb', 'path':'foo/bar', 'content': nb, 'type': 'notebook'} | |
353 | resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel)) |
|
402 | resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel)) | |
354 | saved = resp.json() |
|
403 | saved = resp.json() | |
355 | self.assertEqual(saved['name'], 'a2.ipynb') |
|
404 | self.assertEqual(saved['name'], 'a2.ipynb') | |
@@ -375,7 +424,7 class APITest(NotebookTestBase): | |||||
375 | hcell = new_heading_cell('Created by test') |
|
424 | hcell = new_heading_cell('Created by test') | |
376 | ws.cells.append(hcell) |
|
425 | ws.cells.append(hcell) | |
377 | # Save |
|
426 | # Save | |
378 | nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb} |
|
427 | nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb, 'type': 'notebook'} | |
379 | resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel)) |
|
428 | resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel)) | |
380 |
|
429 | |||
381 | # List checkpoints |
|
430 | # List checkpoints |
@@ -101,7 +101,7 class TestContentsManager(TestCase): | |||||
101 |
|
101 | |||
102 | def new_notebook(self): |
|
102 | def new_notebook(self): | |
103 | cm = self.contents_manager |
|
103 | cm = self.contents_manager | |
104 |
model = cm.create_ |
|
104 | model = cm.create_file() | |
105 | name = model['name'] |
|
105 | name = model['name'] | |
106 | path = model['path'] |
|
106 | path = model['path'] | |
107 |
|
107 | |||
@@ -112,10 +112,10 class TestContentsManager(TestCase): | |||||
112 | cm.save(full_model, name, path) |
|
112 | cm.save(full_model, name, path) | |
113 | return nb, name, path |
|
113 | return nb, name, path | |
114 |
|
114 | |||
115 |
def test_create_ |
|
115 | def test_create_file(self): | |
116 | cm = self.contents_manager |
|
116 | cm = self.contents_manager | |
117 | # Test in root directory |
|
117 | # Test in root directory | |
118 |
model = cm.create_ |
|
118 | model = cm.create_file() | |
119 | assert isinstance(model, dict) |
|
119 | assert isinstance(model, dict) | |
120 | self.assertIn('name', model) |
|
120 | self.assertIn('name', model) | |
121 | self.assertIn('path', model) |
|
121 | self.assertIn('path', model) | |
@@ -125,7 +125,7 class TestContentsManager(TestCase): | |||||
125 | # Test in sub-directory |
|
125 | # Test in sub-directory | |
126 | sub_dir = '/foo/' |
|
126 | sub_dir = '/foo/' | |
127 | self.make_dir(cm.root_dir, 'foo') |
|
127 | self.make_dir(cm.root_dir, 'foo') | |
128 |
model = cm.create_ |
|
128 | model = cm.create_file(None, sub_dir) | |
129 | assert isinstance(model, dict) |
|
129 | assert isinstance(model, dict) | |
130 | self.assertIn('name', model) |
|
130 | self.assertIn('name', model) | |
131 | self.assertIn('path', model) |
|
131 | self.assertIn('path', model) | |
@@ -135,7 +135,7 class TestContentsManager(TestCase): | |||||
135 | def test_get(self): |
|
135 | def test_get(self): | |
136 | cm = self.contents_manager |
|
136 | cm = self.contents_manager | |
137 | # Create a notebook |
|
137 | # Create a notebook | |
138 |
model = cm.create_ |
|
138 | model = cm.create_file() | |
139 | name = model['name'] |
|
139 | name = model['name'] | |
140 | path = model['path'] |
|
140 | path = model['path'] | |
141 |
|
141 | |||
@@ -150,7 +150,7 class TestContentsManager(TestCase): | |||||
150 | # Test in sub-directory |
|
150 | # Test in sub-directory | |
151 | sub_dir = '/foo/' |
|
151 | sub_dir = '/foo/' | |
152 | self.make_dir(cm.root_dir, 'foo') |
|
152 | self.make_dir(cm.root_dir, 'foo') | |
153 |
model = cm.create_ |
|
153 | model = cm.create_file(None, sub_dir) | |
154 | model2 = cm.get_model(name, sub_dir) |
|
154 | model2 = cm.get_model(name, sub_dir) | |
155 | assert isinstance(model2, dict) |
|
155 | assert isinstance(model2, dict) | |
156 | self.assertIn('name', model2) |
|
156 | self.assertIn('name', model2) | |
@@ -162,7 +162,7 class TestContentsManager(TestCase): | |||||
162 | def test_update(self): |
|
162 | def test_update(self): | |
163 | cm = self.contents_manager |
|
163 | cm = self.contents_manager | |
164 | # Create a notebook |
|
164 | # Create a notebook | |
165 |
model = cm.create_ |
|
165 | model = cm.create_file() | |
166 | name = model['name'] |
|
166 | name = model['name'] | |
167 | path = model['path'] |
|
167 | path = model['path'] | |
168 |
|
168 | |||
@@ -181,7 +181,7 class TestContentsManager(TestCase): | |||||
181 | # Create a directory and notebook in that directory |
|
181 | # Create a directory and notebook in that directory | |
182 | sub_dir = '/foo/' |
|
182 | sub_dir = '/foo/' | |
183 | self.make_dir(cm.root_dir, 'foo') |
|
183 | self.make_dir(cm.root_dir, 'foo') | |
184 |
model = cm.create_ |
|
184 | model = cm.create_file(None, sub_dir) | |
185 | name = model['name'] |
|
185 | name = model['name'] | |
186 | path = model['path'] |
|
186 | path = model['path'] | |
187 |
|
187 | |||
@@ -200,7 +200,7 class TestContentsManager(TestCase): | |||||
200 | def test_save(self): |
|
200 | def test_save(self): | |
201 | cm = self.contents_manager |
|
201 | cm = self.contents_manager | |
202 | # Create a notebook |
|
202 | # Create a notebook | |
203 |
model = cm.create_ |
|
203 | model = cm.create_file() | |
204 | name = model['name'] |
|
204 | name = model['name'] | |
205 | path = model['path'] |
|
205 | path = model['path'] | |
206 |
|
206 | |||
@@ -219,7 +219,7 class TestContentsManager(TestCase): | |||||
219 | # Create a directory and notebook in that directory |
|
219 | # Create a directory and notebook in that directory | |
220 | sub_dir = '/foo/' |
|
220 | sub_dir = '/foo/' | |
221 | self.make_dir(cm.root_dir, 'foo') |
|
221 | self.make_dir(cm.root_dir, 'foo') | |
222 |
model = cm.create_ |
|
222 | model = cm.create_file(None, sub_dir) | |
223 | name = model['name'] |
|
223 | name = model['name'] | |
224 | path = model['path'] |
|
224 | path = model['path'] | |
225 | model = cm.get_model(name, path) |
|
225 | model = cm.get_model(name, path) | |
@@ -248,7 +248,7 class TestContentsManager(TestCase): | |||||
248 | path = u'å b' |
|
248 | path = u'å b' | |
249 | name = u'nb √.ipynb' |
|
249 | name = u'nb √.ipynb' | |
250 | os.mkdir(os.path.join(cm.root_dir, path)) |
|
250 | os.mkdir(os.path.join(cm.root_dir, path)) | |
251 |
orig = cm.create_ |
|
251 | orig = cm.create_file({'name' : name}, path=path) | |
252 |
|
252 | |||
253 | # copy with unspecified name |
|
253 | # copy with unspecified name | |
254 | copy = cm.copy(name, path=path) |
|
254 | copy = cm.copy(name, path=path) |
@@ -1885,6 +1885,8 define([ | |||||
1885 | var model = {}; |
|
1885 | var model = {}; | |
1886 | model.name = this.notebook_name; |
|
1886 | model.name = this.notebook_name; | |
1887 | model.path = this.notebook_path; |
|
1887 | model.path = this.notebook_path; | |
|
1888 | model.type = 'notebook'; | |||
|
1889 | model.format = 'json'; | |||
1888 | model.content = this.toJSON(); |
|
1890 | model.content = this.toJSON(); | |
1889 | model.content.nbformat = this.nbformat; |
|
1891 | model.content.nbformat = this.nbformat; | |
1890 | model.content.nbformat_minor = this.nbformat_minor; |
|
1892 | model.content.nbformat_minor = this.nbformat_minor; |
General Comments 0
You need to be logged in to leave comments.
Login now