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