Show More
@@ -76,15 +76,12 b' class NbconvertFileHandler(IPythonHandler):' | |||
|
76 | 76 | exporter = get_exporter(format, config=self.config) |
|
77 | 77 | |
|
78 | 78 | path = path.strip('/') |
|
79 |
|
|
|
80 | if not os.path.isfile(os_path): | |
|
81 | raise web.HTTPError(404, u'Notebook does not exist: %s' % name) | |
|
79 | model = self.notebook_manager.get_notebook(name=name, path=path) | |
|
82 | 80 | |
|
83 | info = os.stat(os_path) | |
|
84 | self.set_header('Last-Modified', tz.utcfromtimestamp(info.st_mtime)) | |
|
81 | self.set_header('Last-Modified', model['last_modified']) | |
|
85 | 82 | |
|
86 | 83 | try: |
|
87 |
output, resources = exporter.from_ |
|
|
84 | output, resources = exporter.from_notebook_node(model['content']) | |
|
88 | 85 | except Exception as e: |
|
89 | 86 | raise web.HTTPError(500, "nbconvert failed: %s" % e) |
|
90 | 87 |
@@ -88,7 +88,7 b' from IPython.utils.localinterfaces import localhost' | |||
|
88 | 88 | from IPython.utils import submodule |
|
89 | 89 | from IPython.utils.traitlets import ( |
|
90 | 90 | Dict, Unicode, Integer, List, Bool, Bytes, |
|
91 | DottedObjectName | |
|
91 | DottedObjectName, TraitError, | |
|
92 | 92 | ) |
|
93 | 93 | from IPython.utils import py3compat |
|
94 | 94 | from IPython.utils.path import filefind, get_ipython_dir |
@@ -201,8 +201,11 b' class NotebookWebApplication(web.Application):' | |||
|
201 | 201 | handlers.extend(load_handlers('services.clusters.handlers')) |
|
202 | 202 | handlers.extend(load_handlers('services.sessions.handlers')) |
|
203 | 203 | handlers.extend(load_handlers('services.nbconvert.handlers')) |
|
204 | handlers.extend([ | |
|
205 | (r"/files/(.*)", AuthenticatedFileHandler, {'path' : settings['notebook_manager'].notebook_dir}), | |
|
204 | # FIXME: /files/ should be handled by the Contents service when it exists | |
|
205 | nbm = settings['notebook_manager'] | |
|
206 | if hasattr(nbm, 'notebook_dir'): | |
|
207 | handlers.extend([ | |
|
208 | (r"/files/(.*)", AuthenticatedFileHandler, {'path' : nbm.notebook_dir}), | |
|
206 | 209 | (r"/nbextensions/(.*)", FileFindHandler, {'path' : settings['nbextensions_path']}), |
|
207 | 210 | ]) |
|
208 | 211 | # prepend base_url onto the patterns that we match |
@@ -278,7 +281,7 b' aliases.update({' | |||
|
278 | 281 | 'transport': 'KernelManager.transport', |
|
279 | 282 | 'keyfile': 'NotebookApp.keyfile', |
|
280 | 283 | 'certfile': 'NotebookApp.certfile', |
|
281 |
'notebook-dir': 'Notebook |
|
|
284 | 'notebook-dir': 'NotebookApp.notebook_dir', | |
|
282 | 285 | 'browser': 'NotebookApp.browser', |
|
283 | 286 | }) |
|
284 | 287 | |
@@ -507,6 +510,24 b' class NotebookApp(BaseIPythonApplication):' | |||
|
507 | 510 | def _info_file_default(self): |
|
508 | 511 | info_file = "nbserver-%s.json"%os.getpid() |
|
509 | 512 | return os.path.join(self.profile_dir.security_dir, info_file) |
|
513 | ||
|
514 | notebook_dir = Unicode(py3compat.getcwd(), config=True, | |
|
515 | help="The directory to use for notebooks and kernels." | |
|
516 | ) | |
|
517 | ||
|
518 | def _notebook_dir_changed(self, name, old, new): | |
|
519 | """Do a bit of validation of the notebook dir.""" | |
|
520 | if not os.path.isabs(new): | |
|
521 | # If we receive a non-absolute path, make it absolute. | |
|
522 | self.notebook_dir = os.path.abspath(new) | |
|
523 | return | |
|
524 | if not os.path.isdir(new): | |
|
525 | raise TraitError("No such notebook dir: %r" % new) | |
|
526 | ||
|
527 | # setting App.notebook_dir implies setting notebook and kernel dirs as well | |
|
528 | self.config.FileNotebookManager.notebook_dir = new | |
|
529 | self.config.MappingKernelManager.root_dir = new | |
|
530 | ||
|
510 | 531 | |
|
511 | 532 | def parse_command_line(self, argv=None): |
|
512 | 533 | super(NotebookApp, self).parse_command_line(argv) |
@@ -519,7 +540,7 b' class NotebookApp(BaseIPythonApplication):' | |||
|
519 | 540 | self.log.critical("No such file or directory: %s", f) |
|
520 | 541 | self.exit(1) |
|
521 | 542 | if os.path.isdir(f): |
|
522 |
self |
|
|
543 | self.notebook_dir = f | |
|
523 | 544 | elif os.path.isfile(f): |
|
524 | 545 | self.file_to_run = f |
|
525 | 546 | |
@@ -730,7 +751,7 b' class NotebookApp(BaseIPythonApplication):' | |||
|
730 | 751 | 'port': self.port, |
|
731 | 752 | 'secure': bool(self.certfile), |
|
732 | 753 | 'base_url': self.base_url, |
|
733 |
'notebook_dir': os.path.abspath(self. |
|
|
754 | 'notebook_dir': os.path.abspath(self.notebook_dir), | |
|
734 | 755 | } |
|
735 | 756 | |
|
736 | 757 | def write_server_info_file(self): |
@@ -16,6 +16,8 b' Authors:' | |||
|
16 | 16 | # Imports |
|
17 | 17 | #----------------------------------------------------------------------------- |
|
18 | 18 | |
|
19 | import os | |
|
20 | ||
|
19 | 21 | from tornado import web |
|
20 | 22 | |
|
21 | 23 | from IPython.kernel.multikernelmanager import MultiKernelManager |
@@ -23,6 +25,9 b' from IPython.utils.traitlets import (' | |||
|
23 | 25 | Dict, List, Unicode, |
|
24 | 26 | ) |
|
25 | 27 | |
|
28 | from IPython.html.utils import to_os_path | |
|
29 | from IPython.utils.py3compat import getcwd | |
|
30 | ||
|
26 | 31 | #----------------------------------------------------------------------------- |
|
27 | 32 | # Classes |
|
28 | 33 | #----------------------------------------------------------------------------- |
@@ -35,6 +40,17 b' class MappingKernelManager(MultiKernelManager):' | |||
|
35 | 40 | return "IPython.kernel.ioloop.IOLoopKernelManager" |
|
36 | 41 | |
|
37 | 42 | kernel_argv = List(Unicode) |
|
43 | ||
|
44 | root_dir = Unicode(getcwd(), config=True) | |
|
45 | ||
|
46 | def _root_dir_changed(self, name, old, new): | |
|
47 | """Do a bit of validation of the root dir.""" | |
|
48 | if not os.path.isabs(new): | |
|
49 | # If we receive a non-absolute path, make it absolute. | |
|
50 | self.root_dir = os.path.abspath(new) | |
|
51 | return | |
|
52 | if not os.path.exists(new) or not os.path.isdir(new): | |
|
53 | raise TraitError("kernel root dir %r is not a directory" % new) | |
|
38 | 54 | |
|
39 | 55 | #------------------------------------------------------------------------- |
|
40 | 56 | # Methods for managing kernels and sessions |
@@ -44,8 +60,17 b' class MappingKernelManager(MultiKernelManager):' | |||
|
44 | 60 | """notice that a kernel died""" |
|
45 | 61 | self.log.warn("Kernel %s died, removing from map.", kernel_id) |
|
46 | 62 | self.remove_kernel(kernel_id) |
|
47 | ||
|
48 | def start_kernel(self, kernel_id=None, **kwargs): | |
|
63 | ||
|
64 | def cwd_for_path(self, path): | |
|
65 | """Turn API path into absolute OS path.""" | |
|
66 | os_path = to_os_path(path, self.root_dir) | |
|
67 | # in the case of notebooks and kernels not being on the same filesystem, | |
|
68 | # walk up to root_dir if the paths don't exist | |
|
69 | while not os.path.exists(os_path) and os_path != self.root_dir: | |
|
70 | os_path = os.path.dirname(os_path) | |
|
71 | return os_path | |
|
72 | ||
|
73 | def start_kernel(self, kernel_id=None, path=None, **kwargs): | |
|
49 | 74 | """Start a kernel for a session an return its kernel_id. |
|
50 | 75 | |
|
51 | 76 | Parameters |
@@ -54,9 +79,14 b' class MappingKernelManager(MultiKernelManager):' | |||
|
54 | 79 | The uuid to associate the new kernel with. If this |
|
55 | 80 | is not None, this kernel will be persistent whenever it is |
|
56 | 81 | requested. |
|
82 | path : API path | |
|
83 | The API path (unicode, '/' delimited) for the cwd. | |
|
84 | Will be transformed to an OS path relative to root_dir. | |
|
57 | 85 | """ |
|
58 | 86 | if kernel_id is None: |
|
59 | 87 | kwargs['extra_arguments'] = self.kernel_argv |
|
88 | if path is not None: | |
|
89 | kwargs['cwd'] = self.cwd_for_path(path) | |
|
60 | 90 | kernel_id = super(MappingKernelManager, self).start_kernel(**kwargs) |
|
61 | 91 | self.log.info("Kernel started: %s" % kernel_id) |
|
62 | 92 | self.log.debug("Kernel args: %r" % kwargs) |
@@ -18,7 +18,6 b' Authors:' | |||
|
18 | 18 | #----------------------------------------------------------------------------- |
|
19 | 19 | |
|
20 | 20 | import io |
|
21 | import itertools | |
|
22 | 21 | import os |
|
23 | 22 | import glob |
|
24 | 23 | import shutil |
@@ -28,8 +27,9 b' from tornado import web' | |||
|
28 | 27 | from .nbmanager import NotebookManager |
|
29 | 28 | from IPython.nbformat import current |
|
30 | 29 | from IPython.utils.traitlets import Unicode, Dict, Bool, TraitError |
|
30 | from IPython.utils.py3compat import getcwd | |
|
31 | 31 | from IPython.utils import tz |
|
32 | from IPython.html.utils import is_hidden | |
|
32 | from IPython.html.utils import is_hidden, to_os_path | |
|
33 | 33 | |
|
34 | 34 | #----------------------------------------------------------------------------- |
|
35 | 35 | # Classes |
@@ -46,7 +46,17 b' class FileNotebookManager(NotebookManager):' | |||
|
46 | 46 | short `--script` flag. |
|
47 | 47 | """ |
|
48 | 48 | ) |
|
49 | notebook_dir = Unicode(getcwd(), config=True) | |
|
49 | 50 | |
|
51 | def _notebook_dir_changed(self, name, old, new): | |
|
52 | """Do a bit of validation of the notebook dir.""" | |
|
53 | if not os.path.isabs(new): | |
|
54 | # If we receive a non-absolute path, make it absolute. | |
|
55 | self.notebook_dir = os.path.abspath(new) | |
|
56 | return | |
|
57 | if not os.path.exists(new) or not os.path.isdir(new): | |
|
58 | raise TraitError("notebook dir %r is not a directory" % new) | |
|
59 | ||
|
50 | 60 | checkpoint_dir = Unicode(config=True, |
|
51 | 61 | help="""The location in which to keep notebook checkpoints |
|
52 | 62 | |
@@ -75,9 +85,9 b' class FileNotebookManager(NotebookManager):' | |||
|
75 | 85 | def get_notebook_names(self, path=''): |
|
76 | 86 | """List all notebook names in the notebook dir and path.""" |
|
77 | 87 | path = path.strip('/') |
|
78 | if not os.path.isdir(self.get_os_path(path=path)): | |
|
88 | if not os.path.isdir(self._get_os_path(path=path)): | |
|
79 | 89 | raise web.HTTPError(404, 'Directory not found: ' + path) |
|
80 | names = glob.glob(self.get_os_path('*'+self.filename_ext, path)) | |
|
90 | names = glob.glob(self._get_os_path('*'+self.filename_ext, path)) | |
|
81 | 91 | names = [os.path.basename(name) |
|
82 | 92 | for name in names] |
|
83 | 93 | return names |
@@ -97,7 +107,7 b' class FileNotebookManager(NotebookManager):' | |||
|
97 | 107 | Whether the path is indeed a directory. |
|
98 | 108 | """ |
|
99 | 109 | path = path.strip('/') |
|
100 | os_path = self.get_os_path(path=path) | |
|
110 | os_path = self._get_os_path(path=path) | |
|
101 | 111 | return os.path.isdir(os_path) |
|
102 | 112 | |
|
103 | 113 | def is_hidden(self, path): |
@@ -116,10 +126,10 b' class FileNotebookManager(NotebookManager):' | |||
|
116 | 126 | |
|
117 | 127 | """ |
|
118 | 128 | path = path.strip('/') |
|
119 | os_path = self.get_os_path(path=path) | |
|
129 | os_path = self._get_os_path(path=path) | |
|
120 | 130 | return is_hidden(os_path, self.notebook_dir) |
|
121 | 131 | |
|
122 | def get_os_path(self, name=None, path=''): | |
|
132 | def _get_os_path(self, name=None, path=''): | |
|
123 | 133 | """Given a notebook name and a URL path, return its file system |
|
124 | 134 | path. |
|
125 | 135 | |
@@ -138,12 +148,9 b' class FileNotebookManager(NotebookManager):' | |||
|
138 | 148 | server started), the relative path, and the filename with the |
|
139 | 149 | current operating system's url. |
|
140 | 150 | """ |
|
141 | parts = path.strip('/').split('/') | |
|
142 | parts = [p for p in parts if p != ''] # remove duplicate splits | |
|
143 | 151 | if name is not None: |
|
144 |
pa |
|
|
145 |
path |
|
|
146 | return path | |
|
152 | path = path + '/' + name | |
|
153 | return to_os_path(path, self.notebook_dir) | |
|
147 | 154 | |
|
148 | 155 | def notebook_exists(self, name, path=''): |
|
149 | 156 | """Returns a True if the notebook exists. Else, returns False. |
@@ -160,7 +167,7 b' class FileNotebookManager(NotebookManager):' | |||
|
160 | 167 | bool |
|
161 | 168 | """ |
|
162 | 169 | path = path.strip('/') |
|
163 | nbpath = self.get_os_path(name, path=path) | |
|
170 | nbpath = self._get_os_path(name, path=path) | |
|
164 | 171 | return os.path.isfile(nbpath) |
|
165 | 172 | |
|
166 | 173 | # TODO: Remove this after we create the contents web service and directories are |
@@ -168,13 +175,13 b' class FileNotebookManager(NotebookManager):' | |||
|
168 | 175 | def list_dirs(self, path): |
|
169 | 176 | """List the directories for a given API style path.""" |
|
170 | 177 | path = path.strip('/') |
|
171 | os_path = self.get_os_path('', path) | |
|
178 | os_path = self._get_os_path('', path) | |
|
172 | 179 | if not os.path.isdir(os_path) or is_hidden(os_path, self.notebook_dir): |
|
173 | 180 | raise web.HTTPError(404, u'directory does not exist: %r' % os_path) |
|
174 | 181 | dir_names = os.listdir(os_path) |
|
175 | 182 | dirs = [] |
|
176 | 183 | for name in dir_names: |
|
177 | os_path = self.get_os_path(name, path) | |
|
184 | os_path = self._get_os_path(name, path) | |
|
178 | 185 | if os.path.isdir(os_path) and not is_hidden(os_path, self.notebook_dir): |
|
179 | 186 | try: |
|
180 | 187 | model = self.get_dir_model(name, path) |
@@ -189,7 +196,7 b' class FileNotebookManager(NotebookManager):' | |||
|
189 | 196 | def get_dir_model(self, name, path=''): |
|
190 | 197 | """Get the directory model given a directory name and its API style path""" |
|
191 | 198 | path = path.strip('/') |
|
192 | os_path = self.get_os_path(name, path) | |
|
199 | os_path = self._get_os_path(name, path) | |
|
193 | 200 | if not os.path.isdir(os_path): |
|
194 | 201 | raise IOError('directory does not exist: %r' % os_path) |
|
195 | 202 | info = os.stat(os_path) |
@@ -245,7 +252,7 b' class FileNotebookManager(NotebookManager):' | |||
|
245 | 252 | path = path.strip('/') |
|
246 | 253 | if not self.notebook_exists(name=name, path=path): |
|
247 | 254 | raise web.HTTPError(404, u'Notebook does not exist: %s' % name) |
|
248 | os_path = self.get_os_path(name, path) | |
|
255 | os_path = self._get_os_path(name, path) | |
|
249 | 256 | info = os.stat(os_path) |
|
250 | 257 | last_modified = tz.utcfromtimestamp(info.st_mtime) |
|
251 | 258 | created = tz.utcfromtimestamp(info.st_ctime) |
@@ -284,7 +291,7 b' class FileNotebookManager(NotebookManager):' | |||
|
284 | 291 | self.rename_notebook(name, path, new_name, new_path) |
|
285 | 292 | |
|
286 | 293 | # Save the notebook file |
|
287 | os_path = self.get_os_path(new_name, new_path) | |
|
294 | os_path = self._get_os_path(new_name, new_path) | |
|
288 | 295 | nb = current.to_notebook_json(model['content']) |
|
289 | 296 | |
|
290 | 297 | self.check_and_sign(nb, new_path, new_name) |
@@ -324,7 +331,7 b' class FileNotebookManager(NotebookManager):' | |||
|
324 | 331 | def delete_notebook(self, name, path=''): |
|
325 | 332 | """Delete notebook by name and path.""" |
|
326 | 333 | path = path.strip('/') |
|
327 | os_path = self.get_os_path(name, path) | |
|
334 | os_path = self._get_os_path(name, path) | |
|
328 | 335 | if not os.path.isfile(os_path): |
|
329 | 336 | raise web.HTTPError(404, u'Notebook does not exist: %s' % os_path) |
|
330 | 337 | |
@@ -346,8 +353,8 b' class FileNotebookManager(NotebookManager):' | |||
|
346 | 353 | if new_name == old_name and new_path == old_path: |
|
347 | 354 | return |
|
348 | 355 | |
|
349 | new_os_path = self.get_os_path(new_name, new_path) | |
|
350 | old_os_path = self.get_os_path(old_name, old_path) | |
|
356 | new_os_path = self._get_os_path(new_name, new_path) | |
|
357 | old_os_path = self._get_os_path(old_name, old_path) | |
|
351 | 358 | |
|
352 | 359 | # Should we proceed with the move? |
|
353 | 360 | if os.path.isfile(new_os_path): |
@@ -409,7 +416,7 b' class FileNotebookManager(NotebookManager):' | |||
|
409 | 416 | def create_checkpoint(self, name, path=''): |
|
410 | 417 | """Create a checkpoint from the current state of a notebook""" |
|
411 | 418 | path = path.strip('/') |
|
412 | nb_path = self.get_os_path(name, path) | |
|
419 | nb_path = self._get_os_path(name, path) | |
|
413 | 420 | # only the one checkpoint ID: |
|
414 | 421 | checkpoint_id = u"checkpoint" |
|
415 | 422 | cp_path = self.get_checkpoint_path(checkpoint_id, name, path) |
@@ -439,7 +446,7 b' class FileNotebookManager(NotebookManager):' | |||
|
439 | 446 | """restore a notebook to a checkpointed state""" |
|
440 | 447 | path = path.strip('/') |
|
441 | 448 | self.log.info("restoring Notebook %s from checkpoint %s", name, checkpoint_id) |
|
442 | nb_path = self.get_os_path(name, path) | |
|
449 | nb_path = self._get_os_path(name, path) | |
|
443 | 450 | cp_path = self.get_checkpoint_path(checkpoint_id, name, path) |
|
444 | 451 | if not os.path.isfile(cp_path): |
|
445 | 452 | self.log.debug("checkpoint file does not exist: %s", cp_path) |
@@ -22,8 +22,7 b' import os' | |||
|
22 | 22 | |
|
23 | 23 | from IPython.config.configurable import LoggingConfigurable |
|
24 | 24 | from IPython.nbformat import current, sign |
|
25 |
from IPython.utils import |
|
|
26 | from IPython.utils.traitlets import Instance, Unicode, TraitError | |
|
25 | from IPython.utils.traitlets import Instance, Unicode | |
|
27 | 26 | |
|
28 | 27 | #----------------------------------------------------------------------------- |
|
29 | 28 | # Classes |
@@ -31,16 +30,6 b' from IPython.utils.traitlets import Instance, Unicode, TraitError' | |||
|
31 | 30 | |
|
32 | 31 | class NotebookManager(LoggingConfigurable): |
|
33 | 32 | |
|
34 | # Todo: | |
|
35 | # The notebook_dir attribute is used to mean a couple of different things: | |
|
36 | # 1. Where the notebooks are stored if FileNotebookManager is used. | |
|
37 | # 2. The cwd of the kernel for a project. | |
|
38 | # Right now we use this attribute in a number of different places and | |
|
39 | # we are going to have to disentangle all of this. | |
|
40 | notebook_dir = Unicode(py3compat.getcwd(), config=True, help=""" | |
|
41 | The directory to use for notebooks. | |
|
42 | """) | |
|
43 | ||
|
44 | 33 | filename_ext = Unicode(u'.ipynb') |
|
45 | 34 | |
|
46 | 35 | notary = Instance(sign.NotebookNotary) |
@@ -251,19 +240,4 b' class NotebookManager(LoggingConfigurable):' | |||
|
251 | 240 | if not trusted: |
|
252 | 241 | self.log.warn("Notebook %s/%s is not trusted", path, name) |
|
253 | 242 | self.notary.mark_cells(nb, trusted) |
|
254 | ||
|
255 | def _notebook_dir_changed(self, name, old, new): | |
|
256 | """Do a bit of validation of the notebook dir.""" | |
|
257 | if not os.path.isabs(new): | |
|
258 | # If we receive a non-absolute path, make it absolute. | |
|
259 | self.notebook_dir = os.path.abspath(new) | |
|
260 | return | |
|
261 | if os.path.exists(new) and not os.path.isdir(new): | |
|
262 | raise TraitError("notebook dir %r is not a directory" % new) | |
|
263 | if not os.path.exists(new): | |
|
264 | self.log.info("Creating notebook dir %s", new) | |
|
265 | try: | |
|
266 | os.mkdir(new) | |
|
267 | except: | |
|
268 | raise TraitError("Couldn't create notebook dir %r" % new) | |
|
269 | 243 |
@@ -23,12 +23,6 b' class TestFileNotebookManager(TestCase):' | |||
|
23 | 23 | fm = FileNotebookManager(notebook_dir=td) |
|
24 | 24 | self.assertEqual(fm.notebook_dir, td) |
|
25 | 25 | |
|
26 | def test_create_nb_dir(self): | |
|
27 | with TemporaryDirectory() as td: | |
|
28 | nbdir = os.path.join(td, 'notebooks') | |
|
29 | fm = FileNotebookManager(notebook_dir=nbdir) | |
|
30 | self.assertEqual(fm.notebook_dir, nbdir) | |
|
31 | ||
|
32 | 26 | def test_missing_nb_dir(self): |
|
33 | 27 | with TemporaryDirectory() as td: |
|
34 | 28 | nbdir = os.path.join(td, 'notebook', 'dir', 'is', 'missing') |
@@ -42,20 +36,20 b' class TestFileNotebookManager(TestCase):' | |||
|
42 | 36 | # full filesystem path should be returned with correct operating system |
|
43 | 37 | # separators. |
|
44 | 38 | with TemporaryDirectory() as td: |
|
45 |
nbdir = |
|
|
39 | nbdir = td | |
|
46 | 40 | fm = FileNotebookManager(notebook_dir=nbdir) |
|
47 | path = fm.get_os_path('test.ipynb', '/path/to/notebook/') | |
|
41 | path = fm._get_os_path('test.ipynb', '/path/to/notebook/') | |
|
48 | 42 | rel_path_list = '/path/to/notebook/test.ipynb'.split('/') |
|
49 | 43 | fs_path = os.path.join(fm.notebook_dir, *rel_path_list) |
|
50 | 44 | self.assertEqual(path, fs_path) |
|
51 | 45 | |
|
52 | 46 | fm = FileNotebookManager(notebook_dir=nbdir) |
|
53 | path = fm.get_os_path('test.ipynb') | |
|
47 | path = fm._get_os_path('test.ipynb') | |
|
54 | 48 | fs_path = os.path.join(fm.notebook_dir, 'test.ipynb') |
|
55 | 49 | self.assertEqual(path, fs_path) |
|
56 | 50 | |
|
57 | 51 | fm = FileNotebookManager(notebook_dir=nbdir) |
|
58 | path = fm.get_os_path('test.ipynb', '////') | |
|
52 | path = fm._get_os_path('test.ipynb', '////') | |
|
59 | 53 | fs_path = os.path.join(fm.notebook_dir, 'test.ipynb') |
|
60 | 54 | self.assertEqual(path, fs_path) |
|
61 | 55 |
@@ -62,7 +62,7 b' class SessionRootHandler(IPythonHandler):' | |||
|
62 | 62 | if sm.session_exists(name=name, path=path): |
|
63 | 63 | model = sm.get_session(name=name, path=path) |
|
64 | 64 | else: |
|
65 |
kernel_id = km.start_kernel( |
|
|
65 | kernel_id = km.start_kernel(path=path) | |
|
66 | 66 | model = sm.create_session(name=name, path=path, kernel_id=kernel_id) |
|
67 | 67 | location = url_path_join(self.base_url, 'api', 'sessions', model['id']) |
|
68 | 68 | self.set_header('Location', url_escape(location)) |
@@ -11,10 +11,16 b'' | |||
|
11 | 11 | # Imports |
|
12 | 12 | #----------------------------------------------------------------------------- |
|
13 | 13 | |
|
14 | import os | |
|
15 | from tempfile import NamedTemporaryFile | |
|
16 | ||
|
14 | 17 | import nose.tools as nt |
|
15 | 18 | |
|
19 | from IPython.utils.tempdir import TemporaryDirectory | |
|
20 | from IPython.utils.traitlets import TraitError | |
|
16 | 21 | import IPython.testing.tools as tt |
|
17 | 22 | from IPython.html import notebookapp |
|
23 | NotebookApp = notebookapp.NotebookApp | |
|
18 | 24 | |
|
19 | 25 | #----------------------------------------------------------------------------- |
|
20 | 26 | # Test functions |
@@ -25,7 +31,7 b' def test_help_output():' | |||
|
25 | 31 | tt.help_all_output_test('notebook') |
|
26 | 32 | |
|
27 | 33 | def test_server_info_file(): |
|
28 |
nbapp = |
|
|
34 | nbapp = NotebookApp(profile='nbserver_file_test') | |
|
29 | 35 | def get_servers(): |
|
30 | 36 | return list(notebookapp.list_running_servers(profile='nbserver_file_test')) |
|
31 | 37 | nbapp.initialize(argv=[]) |
@@ -38,4 +44,30 b' def test_server_info_file():' | |||
|
38 | 44 | nt.assert_equal(get_servers(), []) |
|
39 | 45 | |
|
40 | 46 | # The ENOENT error should be silenced. |
|
41 | nbapp.remove_server_info_file() No newline at end of file | |
|
47 | nbapp.remove_server_info_file() | |
|
48 | ||
|
49 | def test_nb_dir(): | |
|
50 | with TemporaryDirectory() as td: | |
|
51 | app = NotebookApp(notebook_dir=td) | |
|
52 | nt.assert_equal(app.notebook_dir, td) | |
|
53 | ||
|
54 | def test_no_create_nb_dir(): | |
|
55 | with TemporaryDirectory() as td: | |
|
56 | nbdir = os.path.join(td, 'notebooks') | |
|
57 | app = NotebookApp() | |
|
58 | with nt.assert_raises(TraitError): | |
|
59 | app.notebook_dir = nbdir | |
|
60 | ||
|
61 | def test_missing_nb_dir(): | |
|
62 | with TemporaryDirectory() as td: | |
|
63 | nbdir = os.path.join(td, 'notebook', 'dir', 'is', 'missing') | |
|
64 | app = NotebookApp() | |
|
65 | with nt.assert_raises(TraitError): | |
|
66 | app.notebook_dir = nbdir | |
|
67 | ||
|
68 | def test_invalid_nb_dir(): | |
|
69 | with NamedTemporaryFile() as tf: | |
|
70 | app = NotebookApp() | |
|
71 | with nt.assert_raises(TraitError): | |
|
72 | app.notebook_dir = tf | |
|
73 |
@@ -81,7 +81,7 b' def url_unescape(path):' | |||
|
81 | 81 | ]) |
|
82 | 82 | |
|
83 | 83 | def is_hidden(abs_path, abs_root=''): |
|
84 |
"""Is a file |
|
|
84 | """Is a file hidden or contained in a hidden directory? | |
|
85 | 85 | |
|
86 | 86 | This will start with the rightmost path element and work backwards to the |
|
87 | 87 | given root to see if a path is hidden or in a hidden directory. Hidden is |
@@ -112,3 +112,14 b" def is_hidden(abs_path, abs_root=''):" | |||
|
112 | 112 | |
|
113 | 113 | return False |
|
114 | 114 | |
|
115 | def to_os_path(path, root=''): | |
|
116 | """Convert an API path to a filesystem path | |
|
117 | ||
|
118 | If given, root will be prepended to the path. | |
|
119 | root must be a filesystem path already. | |
|
120 | """ | |
|
121 | parts = path.strip('/').split('/') | |
|
122 | parts = [p for p in parts if p != ''] # remove duplicate splits | |
|
123 | path = os.path.join(root, *parts) | |
|
124 | return path | |
|
125 |
General Comments 0
You need to be logged in to leave comments.
Login now