##// END OF EJS Templates
allow ContentsManager methods to return Futures...
Min RK -
Show More
@@ -19,10 +19,9 b' except ImportError:'
19 19 from jinja2 import TemplateNotFound
20 20 from tornado import web
21 21
22 try:
22 from tornado import gen
23 23 from tornado.log import app_log
24 except ImportError:
25 app_log = logging.getLogger()
24
26 25
27 26 import IPython
28 27 from IPython.utils.sysinfo import get_sys_info
@@ -355,9 +354,10 b' def json_errors(method):'
355 354 the error in a human readable form.
356 355 """
357 356 @functools.wraps(method)
357 @gen.coroutine
358 358 def wrapper(self, *args, **kwargs):
359 359 try:
360 result = method(self, *args, **kwargs)
360 result = yield gen.maybe_future(method(self, *args, **kwargs))
361 361 except web.HTTPError as e:
362 362 status = e.status_code
363 363 message = e.log_message
@@ -5,7 +5,7 b''
5 5
6 6 import json
7 7
8 from tornado import web
8 from tornado import gen, web
9 9
10 10 from IPython.html.utils import url_path_join, url_escape
11 11 from IPython.utils.jsonutil import date_default
@@ -102,6 +102,7 b' class ContentsHandler(IPythonHandler):'
102 102
103 103 @web.authenticated
104 104 @json_errors
105 @gen.coroutine
105 106 def get(self, path=''):
106 107 """Return a model for a file or directory.
107 108
@@ -117,7 +118,7 b' class ContentsHandler(IPythonHandler):'
117 118 if format not in {None, 'text', 'base64'}:
118 119 raise web.HTTPError(400, u'Format %r is invalid' % format)
119 120
120 model = self.contents_manager.get(path=path, type=type, format=format)
121 model = yield gen.maybe_future(self.contents_manager.get(path=path, type=type, format=format))
121 122 if model['type'] == 'directory':
122 123 # group listing by type, then by name (case-insensitive)
123 124 # FIXME: sorting should be done in the frontends
@@ -127,52 +128,58 b' class ContentsHandler(IPythonHandler):'
127 128
128 129 @web.authenticated
129 130 @json_errors
131 @gen.coroutine
130 132 def patch(self, path=''):
131 133 """PATCH renames a file or directory without re-uploading content."""
132 134 cm = self.contents_manager
133 135 model = self.get_json_body()
134 136 if model is None:
135 137 raise web.HTTPError(400, u'JSON body missing')
136 model = cm.update(model, path)
138 model = yield gen.maybe_future(cm.update(model, path))
137 139 validate_model(model, expect_content=False)
138 140 self._finish_model(model)
139 141
142 @gen.coroutine
140 143 def _copy(self, copy_from, copy_to=None):
141 144 """Copy a file, optionally specifying a target directory."""
142 145 self.log.info(u"Copying {copy_from} to {copy_to}".format(
143 146 copy_from=copy_from,
144 147 copy_to=copy_to or '',
145 148 ))
146 model = self.contents_manager.copy(copy_from, copy_to)
149 model = yield gen.maybe_future(self.contents_manager.copy(copy_from, copy_to))
147 150 self.set_status(201)
148 151 validate_model(model, expect_content=False)
149 152 self._finish_model(model)
150 153
154 @gen.coroutine
151 155 def _upload(self, model, path):
152 156 """Handle upload of a new file to path"""
153 157 self.log.info(u"Uploading file to %s", path)
154 model = self.contents_manager.new(model, path)
158 model = yield gen.maybe_future(self.contents_manager.new(model, path))
155 159 self.set_status(201)
156 160 validate_model(model, expect_content=False)
157 161 self._finish_model(model)
158 162
163 @gen.coroutine
159 164 def _new_untitled(self, path, type='', ext=''):
160 165 """Create a new, empty untitled entity"""
161 166 self.log.info(u"Creating new %s in %s", type or 'file', path)
162 model = self.contents_manager.new_untitled(path=path, type=type, ext=ext)
167 model = yield gen.maybe_future(self.contents_manager.new_untitled(path=path, type=type, ext=ext))
163 168 self.set_status(201)
164 169 validate_model(model, expect_content=False)
165 170 self._finish_model(model)
166 171
172 @gen.coroutine
167 173 def _save(self, model, path):
168 174 """Save an existing file."""
169 175 self.log.info(u"Saving file at %s", path)
170 model = self.contents_manager.save(model, path)
176 model = yield gen.maybe_future(self.contents_manager.save(model, path))
171 177 validate_model(model, expect_content=False)
172 178 self._finish_model(model)
173 179
174 180 @web.authenticated
175 181 @json_errors
182 @gen.coroutine
176 183 def post(self, path=''):
177 184 """Create a new file in the specified path.
178 185
@@ -200,14 +207,15 b' class ContentsHandler(IPythonHandler):'
200 207 ext = model.get('ext', '')
201 208 type = model.get('type', '')
202 209 if copy_from:
203 self._copy(copy_from, path)
210 yield self._copy(copy_from, path)
204 211 else:
205 self._new_untitled(path, type=type, ext=ext)
212 yield self._new_untitled(path, type=type, ext=ext)
206 213 else:
207 self._new_untitled(path)
214 yield self._new_untitled(path)
208 215
209 216 @web.authenticated
210 217 @json_errors
218 @gen.coroutine
211 219 def put(self, path=''):
212 220 """Saves the file in the location specified by name and path.
213 221
@@ -223,20 +231,22 b' class ContentsHandler(IPythonHandler):'
223 231 if model:
224 232 if model.get('copy_from'):
225 233 raise web.HTTPError(400, "Cannot copy with PUT, only POST")
226 if self.contents_manager.file_exists(path):
227 self._save(model, path)
234 exists = yield gen.maybe_future(self.contents_manager.file_exists(path))
235 if exists:
236 yield gen.maybe_future(self._save(model, path))
228 237 else:
229 self._upload(model, path)
238 yield gen.maybe_future(self._upload(model, path))
230 239 else:
231 self._new_untitled(path)
240 yield gen.maybe_future(self._new_untitled(path))
232 241
233 242 @web.authenticated
234 243 @json_errors
244 @gen.coroutine
235 245 def delete(self, path=''):
236 246 """delete a file in the given path"""
237 247 cm = self.contents_manager
238 248 self.log.warn('delete %s', path)
239 cm.delete(path)
249 yield gen.maybe_future(cm.delete(path))
240 250 self.set_status(204)
241 251 self.finish()
242 252
@@ -247,19 +257,21 b' class CheckpointsHandler(IPythonHandler):'
247 257
248 258 @web.authenticated
249 259 @json_errors
260 @gen.coroutine
250 261 def get(self, path=''):
251 262 """get lists checkpoints for a file"""
252 263 cm = self.contents_manager
253 checkpoints = cm.list_checkpoints(path)
264 checkpoints = yield gen.maybe_future(cm.list_checkpoints(path))
254 265 data = json.dumps(checkpoints, default=date_default)
255 266 self.finish(data)
256 267
257 268 @web.authenticated
258 269 @json_errors
270 @gen.coroutine
259 271 def post(self, path=''):
260 272 """post creates a new checkpoint"""
261 273 cm = self.contents_manager
262 checkpoint = cm.create_checkpoint(path)
274 checkpoint = yield gen.maybe_future(cm.create_checkpoint(path))
263 275 data = json.dumps(checkpoint, default=date_default)
264 276 location = url_path_join(self.base_url, 'api/contents',
265 277 path, 'checkpoints', checkpoint['id'])
@@ -274,19 +286,21 b' class ModifyCheckpointsHandler(IPythonHandler):'
274 286
275 287 @web.authenticated
276 288 @json_errors
289 @gen.coroutine
277 290 def post(self, path, checkpoint_id):
278 291 """post restores a file from a checkpoint"""
279 292 cm = self.contents_manager
280 cm.restore_checkpoint(checkpoint_id, path)
293 yield gen.maybe_future(cm.restore_checkpoint(checkpoint_id, path))
281 294 self.set_status(204)
282 295 self.finish()
283 296
284 297 @web.authenticated
285 298 @json_errors
299 @gen.coroutine
286 300 def delete(self, path, checkpoint_id):
287 301 """delete clears a checkpoint for a given file"""
288 302 cm = self.contents_manager
289 cm.delete_checkpoint(checkpoint_id, path)
303 yield gen.maybe_future(cm.delete_checkpoint(checkpoint_id, path))
290 304 self.set_status(204)
291 305 self.finish()
292 306
General Comments 0
You need to be logged in to leave comments. Login now