##// END OF EJS Templates
Add method notebook_exists to NotebookManager....
Konrad Hinsen -
Show More
@@ -1,235 +1,251 b''
1 1 """A base class notebook manager.
2 2
3 3 Authors:
4 4
5 5 * Brian Granger
6 6 * Zach Sailer
7 7 """
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (C) 2011 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19
20 20 import os
21 21
22 22 from IPython.config.configurable import LoggingConfigurable
23 23 from IPython.nbformat import current, sign
24 24 from IPython.utils import py3compat
25 25 from IPython.utils.traitlets import Instance, Unicode, TraitError
26 26
27 27 #-----------------------------------------------------------------------------
28 28 # Classes
29 29 #-----------------------------------------------------------------------------
30 30
31 31 class NotebookManager(LoggingConfigurable):
32 32
33 33 # Todo:
34 34 # The notebook_dir attribute is used to mean a couple of different things:
35 35 # 1. Where the notebooks are stored if FileNotebookManager is used.
36 36 # 2. The cwd of the kernel for a project.
37 37 # Right now we use this attribute in a number of different places and
38 38 # we are going to have to disentangle all of this.
39 39 notebook_dir = Unicode(py3compat.getcwd(), config=True, help="""
40 40 The directory to use for notebooks.
41 41 """)
42 42
43 43 filename_ext = Unicode(u'.ipynb')
44 44
45 45 notary = Instance(sign.NotebookNotary)
46 46 def _notary_default(self):
47 47 return sign.NotebookNotary(parent=self)
48 48
49 49 def check_and_sign(self, nb, path, name):
50 50 """Check for trusted cells, and sign the notebook.
51 51
52 52 Called as a part of saving notebooks.
53 53 """
54 54 if self.notary.check_cells(nb):
55 55 self.notary.sign(nb)
56 56 else:
57 57 self.log.warn("Saving untrusted notebook %s/%s", path, name)
58 58
59 59 def mark_trusted_cells(self, nb, path, name):
60 60 """Mark cells as trusted if the notebook signature matches.
61 61
62 62 Called as a part of loading notebooks.
63 63 """
64 64 trusted = self.notary.check_signature(nb)
65 65 if not trusted:
66 66 self.log.warn("Notebook %s/%s is not trusted", path, name)
67 67 self.notary.mark_cells(nb, trusted)
68 68
69 69 def path_exists(self, path):
70 70 """Does the API-style path (directory) actually exist?
71 71
72 72 Override this method in subclasses.
73 73
74 74 Parameters
75 75 ----------
76 76 path : string
77 77 The
78 78
79 79 Returns
80 80 -------
81 81 exists : bool
82 82 Whether the path does indeed exist.
83 83 """
84 84 raise NotImplementedError
85 85
86 86 def is_hidden(self, path):
87 87 """Does the API style path correspond to a hidden directory or file?
88 88
89 89 Parameters
90 90 ----------
91 91 path : string
92 92 The path to check. This is an API path (`/` separated,
93 93 relative to base notebook-dir).
94 94
95 95 Returns
96 96 -------
97 97 exists : bool
98 98 Whether the path is hidden.
99 99
100 100 """
101 101 raise NotImplementedError
102 102
103 103 def _notebook_dir_changed(self, name, old, new):
104 104 """Do a bit of validation of the notebook dir."""
105 105 if not os.path.isabs(new):
106 106 # If we receive a non-absolute path, make it absolute.
107 107 self.notebook_dir = os.path.abspath(new)
108 108 return
109 109 if os.path.exists(new) and not os.path.isdir(new):
110 110 raise TraitError("notebook dir %r is not a directory" % new)
111 111 if not os.path.exists(new):
112 112 self.log.info("Creating notebook dir %s", new)
113 113 try:
114 114 os.mkdir(new)
115 115 except:
116 116 raise TraitError("Couldn't create notebook dir %r" % new)
117 117
118 118 # Main notebook API
119 119
120 120 def increment_filename(self, basename, path=''):
121 121 """Increment a notebook filename without the .ipynb to make it unique.
122 122
123 123 Parameters
124 124 ----------
125 125 basename : unicode
126 126 The name of a notebook without the ``.ipynb`` file extension.
127 127 path : unicode
128 128 The URL path of the notebooks directory
129 129 """
130 130 return basename
131 131
132 def notebook_exists(self, name, path=''):
133 """Returns a True if the notebook exists. Else, returns False.
134
135 Parameters
136 ----------
137 name : string
138 The name of the notebook you are checking.
139 path : string
140 The relative path to the notebook (with '/' as separator)
141
142 Returns
143 -------
144 bool
145 """
146 raise NotImplementedError('must be implemented in a subclass')
147
132 148 # TODO: Remove this after we create the contents web service and directories are
133 149 # no longer listed by the notebook web service.
134 150 def list_dirs(self, path):
135 151 """List the directory models for a given API style path."""
136 152 raise NotImplementedError('must be implemented in a subclass')
137 153
138 154 # TODO: Remove this after we create the contents web service and directories are
139 155 # no longer listed by the notebook web service.
140 156 def get_dir_model(self, name, path=''):
141 157 """Get the directory model given a directory name and its API style path.
142 158
143 159 The keys in the model should be:
144 160 * name
145 161 * path
146 162 * last_modified
147 163 * created
148 164 * type='directory'
149 165 """
150 166 raise NotImplementedError('must be implemented in a subclass')
151 167
152 168 def list_notebooks(self, path=''):
153 169 """Return a list of notebook dicts without content.
154 170
155 171 This returns a list of dicts, each of the form::
156 172
157 173 dict(notebook_id=notebook,name=name)
158 174
159 175 This list of dicts should be sorted by name::
160 176
161 177 data = sorted(data, key=lambda item: item['name'])
162 178 """
163 179 raise NotImplementedError('must be implemented in a subclass')
164 180
165 181 def get_notebook(self, name, path='', content=True):
166 182 """Get the notebook model with or without content."""
167 183 raise NotImplementedError('must be implemented in a subclass')
168 184
169 185 def save_notebook(self, model, name, path=''):
170 186 """Save the notebook and return the model with no content."""
171 187 raise NotImplementedError('must be implemented in a subclass')
172 188
173 189 def update_notebook(self, model, name, path=''):
174 190 """Update the notebook and return the model with no content."""
175 191 raise NotImplementedError('must be implemented in a subclass')
176 192
177 193 def delete_notebook(self, name, path=''):
178 194 """Delete notebook by name and path."""
179 195 raise NotImplementedError('must be implemented in a subclass')
180 196
181 197 def create_notebook(self, model=None, path=''):
182 198 """Create a new notebook and return its model with no content."""
183 199 path = path.strip('/')
184 200 if model is None:
185 201 model = {}
186 202 if 'content' not in model:
187 203 metadata = current.new_metadata(name=u'')
188 204 model['content'] = current.new_notebook(metadata=metadata)
189 205 if 'name' not in model:
190 206 model['name'] = self.increment_filename('Untitled', path)
191 207
192 208 model['path'] = path
193 209 model = self.save_notebook(model, model['name'], model['path'])
194 210 return model
195 211
196 212 def copy_notebook(self, from_name, to_name=None, path=''):
197 213 """Copy an existing notebook and return its new model.
198 214
199 215 If to_name not specified, increment `from_name-Copy#.ipynb`.
200 216 """
201 217 path = path.strip('/')
202 218 model = self.get_notebook(from_name, path)
203 219 if not to_name:
204 220 base = os.path.splitext(from_name)[0] + '-Copy'
205 221 to_name = self.increment_filename(base, path)
206 222 model['name'] = to_name
207 223 model = self.save_notebook(model, to_name, path)
208 224 return model
209 225
210 226 # Checkpoint-related
211 227
212 228 def create_checkpoint(self, name, path=''):
213 229 """Create a checkpoint of the current state of a notebook
214 230
215 231 Returns a checkpoint_id for the new checkpoint.
216 232 """
217 233 raise NotImplementedError("must be implemented in a subclass")
218 234
219 235 def list_checkpoints(self, name, path=''):
220 236 """Return a list of checkpoints for a given notebook"""
221 237 return []
222 238
223 239 def restore_checkpoint(self, checkpoint_id, name, path=''):
224 240 """Restore a notebook from one of its checkpoints"""
225 241 raise NotImplementedError("must be implemented in a subclass")
226 242
227 243 def delete_checkpoint(self, checkpoint_id, name, path=''):
228 244 """delete a checkpoint for a notebook"""
229 245 raise NotImplementedError("must be implemented in a subclass")
230 246
231 247 def log_info(self):
232 248 self.log.info(self.info_string())
233 249
234 250 def info_string(self):
235 251 return "Serving notebooks"
General Comments 0
You need to be logged in to leave comments. Login now