mirror of
https://github.com/jupyter/notebook.git
synced 2025-02-05 12:19:58 +08:00
update upload and copy
adds 'notebook.ipynb/copy' url handler because we were putting too many things in a single POST handler.
This commit is contained in:
parent
75e14424c6
commit
b33ffa7068
@ -71,8 +71,7 @@ class NotebookHandler(IPythonHandler):
|
||||
@web.authenticated
|
||||
@json_errors
|
||||
def patch(self, path='', name=None):
|
||||
"""patch is currently used strictly for notebook renaming.
|
||||
Changes the notebook name to the name given in data."""
|
||||
"""PATCH renames a notebook without re-uploading content."""
|
||||
nbm = self.notebook_manager
|
||||
if name is None:
|
||||
raise web.HTTPError(400, u'Notebook name missing')
|
||||
@ -90,10 +89,31 @@ class NotebookHandler(IPythonHandler):
|
||||
@web.authenticated
|
||||
@json_errors
|
||||
def post(self, path='', name=None):
|
||||
"""Create a new notebook in the location given by 'notebook_path'."""
|
||||
"""Create a new notebook in the specified path.
|
||||
|
||||
POST creates new notebooks.
|
||||
|
||||
POST /api/notebooks/path : new untitled notebook in path
|
||||
POST /api/notebooks/path/notebook.ipynb : new notebook with name in path
|
||||
If content specified upload notebook, otherwise start empty.
|
||||
"""
|
||||
nbm = self.notebook_manager
|
||||
model = self.get_json_body()
|
||||
model = nbm.create_notebook_model(model, path)
|
||||
if name is None:
|
||||
# creating new notebook, model doesn't make sense
|
||||
if model is not None:
|
||||
raise web.HTTPError(400, "Model not valid when creating untitled notebooks.")
|
||||
model = nbm.create_notebook_model(path=path)
|
||||
else:
|
||||
if model is None:
|
||||
self.log.info("Creating new Notebook at %s/%s", path, name)
|
||||
model = {}
|
||||
else:
|
||||
self.log.info("Uploading Notebook to %s/%s", path, name)
|
||||
# set the model name from the URL
|
||||
model['name'] = name
|
||||
model = nbm.create_notebook_model(model, path)
|
||||
|
||||
location = self.notebook_location(model[u'name'], model[u'path'])
|
||||
self.set_header(u'Location', location)
|
||||
self.set_header(u'Last-Modified', model[u'last_modified'])
|
||||
@ -120,6 +140,29 @@ class NotebookHandler(IPythonHandler):
|
||||
self.set_status(204)
|
||||
self.finish()
|
||||
|
||||
class NotebookCopyHandler(IPythonHandler):
|
||||
|
||||
SUPPORTED_METHODS = ('POST')
|
||||
|
||||
@web.authenticated
|
||||
@json_errors
|
||||
def post(self, path='', name=None):
|
||||
"""Copy an existing notebook."""
|
||||
nbm = self.notebook_manager
|
||||
model = self.get_json_body()
|
||||
if name is None:
|
||||
raise web.HTTPError(400, "Notebook name required")
|
||||
self.log.info("Copying Notebook %s/%s", path, name)
|
||||
model = nbm.copy_notebook(name, path)
|
||||
location = url_path_join(
|
||||
self.base_project_url, 'api', 'notebooks',
|
||||
model['path'], model['name'],
|
||||
)
|
||||
self.set_header(u'Location', location)
|
||||
self.set_header(u'Last-Modified', model[u'last_modified'])
|
||||
self.set_status(201)
|
||||
self.finish(json.dumps(model, default=date_default))
|
||||
|
||||
|
||||
class NotebookCheckpointsHandler(IPythonHandler):
|
||||
|
||||
@ -180,6 +223,7 @@ _notebook_name_regex = r"(?P<name>[^/]+\.ipynb)"
|
||||
_notebook_path_regex = "%s/%s" % (_path_regex, _notebook_name_regex)
|
||||
|
||||
default_handlers = [
|
||||
(r"/api/notebooks/?%s/copy" % _notebook_path_regex, NotebookCopyHandler),
|
||||
(r"/api/notebooks/?%s/checkpoints" % _notebook_path_regex, NotebookCheckpointsHandler),
|
||||
(r"/api/notebooks/?%s/checkpoints/%s" % (_notebook_path_regex, _checkpoint_id_regex),
|
||||
ModifyNotebookCheckpointsHandler),
|
||||
|
@ -87,7 +87,7 @@ class NotebookManager(LoggingConfigurable):
|
||||
"""
|
||||
return basename
|
||||
|
||||
def list_notebooks(self):
|
||||
def list_notebooks(self, path=''):
|
||||
"""Return a list of notebook dicts without content.
|
||||
|
||||
This returns a list of dicts, each of the form::
|
||||
@ -112,53 +112,51 @@ class NotebookManager(LoggingConfigurable):
|
||||
"""Update the notebook model and return the model with no content."""
|
||||
raise NotImplementedError('must be implemented in a subclass')
|
||||
|
||||
def delete_notebook_model(self, name, path):
|
||||
def delete_notebook_model(self, name, path=''):
|
||||
"""Delete notebook by name and path."""
|
||||
raise NotImplementedError('must be implemented in a subclass')
|
||||
|
||||
def create_notebook_model(self, model=None, path=''):
|
||||
"""Create a new untitled notebook and return its model with no content."""
|
||||
untitled = self.increment_filename('Untitled', path)
|
||||
if model is None:
|
||||
model = {}
|
||||
if 'content' not in model:
|
||||
metadata = current.new_metadata(name=u'')
|
||||
nb = current.new_notebook(metadata=metadata)
|
||||
model['content'] = nb
|
||||
model['name'] = name = untitled
|
||||
model['path'] = path
|
||||
else:
|
||||
name = model.setdefault('name', untitled)
|
||||
model['path'] = path
|
||||
model = self.save_notebook_model(model, name, path)
|
||||
model['content'] = current.new_notebook(metadata=metadata)
|
||||
if 'name' not in model:
|
||||
model['name'] = self.increment_filename('Untitled', path)
|
||||
|
||||
model['path'] = path
|
||||
model = self.save_notebook_model(model, model['name'], model['path'])
|
||||
return model
|
||||
|
||||
def copy_notebook(self, name, path='/', content=False):
|
||||
def copy_notebook(self, name, path=''):
|
||||
"""Copy an existing notebook and return its new model."""
|
||||
model = self.get_notebook_model(name, path)
|
||||
name = os.path.splitext(name)[0] + '-Copy'
|
||||
name = self.increment_filename(name, path) + self.filename_ext
|
||||
model['name'] = name
|
||||
model = self.save_notebook_model(model, name, path, content=content)
|
||||
model = self.save_notebook_model(model, name, path)
|
||||
return model
|
||||
|
||||
# Checkpoint-related
|
||||
|
||||
def create_checkpoint(self, name, path='/'):
|
||||
def create_checkpoint(self, name, path=''):
|
||||
"""Create a checkpoint of the current state of a notebook
|
||||
|
||||
Returns a checkpoint_id for the new checkpoint.
|
||||
"""
|
||||
raise NotImplementedError("must be implemented in a subclass")
|
||||
|
||||
def list_checkpoints(self, name, path='/'):
|
||||
def list_checkpoints(self, name, path=''):
|
||||
"""Return a list of checkpoints for a given notebook"""
|
||||
return []
|
||||
|
||||
def restore_checkpoint(self, checkpoint_id, name, path='/'):
|
||||
def restore_checkpoint(self, checkpoint_id, name, path=''):
|
||||
"""Restore a notebook from one of its checkpoints"""
|
||||
raise NotImplementedError("must be implemented in a subclass")
|
||||
|
||||
def delete_checkpoint(self, checkpoint_id, name, path='/'):
|
||||
def delete_checkpoint(self, checkpoint_id, name, path=''):
|
||||
"""delete a checkpoint for a notebook"""
|
||||
raise NotImplementedError("must be implemented in a subclass")
|
||||
|
||||
|
@ -1768,15 +1768,12 @@ var IPython = (function (IPython) {
|
||||
|
||||
Notebook.prototype.copy_notebook = function(){
|
||||
var path = this.notebookPath();
|
||||
var name = {'name': this.notebook_name}
|
||||
var settings = {
|
||||
processData : false,
|
||||
cache : false,
|
||||
type : "POST",
|
||||
data: JSON.stringify(name),
|
||||
dataType : "json",
|
||||
success:$.proxy(function (data, status, xhr){
|
||||
notebook_name = data.name;
|
||||
var notebook_name = data.name;
|
||||
window.open(utils.url_path_join(
|
||||
this._baseProjectUrl,
|
||||
'notebooks',
|
||||
@ -1787,8 +1784,10 @@ var IPython = (function (IPython) {
|
||||
};
|
||||
var url = utils.url_path_join(
|
||||
this._baseProjectUrl,
|
||||
'notebooks',
|
||||
path
|
||||
'api/notebooks',
|
||||
path,
|
||||
this.notebook_name,
|
||||
'copy'
|
||||
);
|
||||
$.ajax(url,settings);
|
||||
};
|
||||
|
@ -312,7 +312,7 @@ var IPython = (function (IPython) {
|
||||
var upload_button = $('<button/>').text("Upload")
|
||||
.addClass('btn btn-primary btn-mini upload_button')
|
||||
.click(function (e) {
|
||||
var nbname = item.find('.item_name > input').attr('value');
|
||||
var nbname = item.find('.item_name > input').val();
|
||||
var nbformat = item.data('nbformat');
|
||||
var nbdata = item.data('nbdata');
|
||||
var content_type = 'application/json';
|
||||
@ -323,8 +323,6 @@ var IPython = (function (IPython) {
|
||||
}
|
||||
var model = {
|
||||
content : JSON.parse(nbdata),
|
||||
name : nbname,
|
||||
path : that.notebookPath()
|
||||
};
|
||||
var settings = {
|
||||
processData : false,
|
||||
@ -345,7 +343,8 @@ var IPython = (function (IPython) {
|
||||
var url = utils.url_path_join(
|
||||
that.baseProjectUrl(),
|
||||
'api/notebooks',
|
||||
that.notebookPath()
|
||||
that.notebookPath(),
|
||||
nbname + '.ipynb'
|
||||
);
|
||||
$.ajax(url, settings);
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user