Skip to content

Commit

Permalink
Improvements to file uploaded, mime types and .py reader.
Browse files Browse the repository at this point in the history
* The .py notebook reader now uses that ast module to split
  a plain python file into blocks. These blocks become cells in
  the notebook.
* Proper mime types are used for xml (application/xml), json
  (application/json) and python (application/x-python).
* Other fixes to file uploading.
  • Loading branch information
ellisonbg committed Aug 7, 2011
1 parent 53c7ec7 commit 8f4eb62
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 16 deletions.
13 changes: 7 additions & 6 deletions IPython/frontend/html/notebook/handlers.py
Expand Up @@ -41,12 +41,12 @@ def get(self, notebook_id):
class KernelHandler(web.RequestHandler):

def get(self):
self.write(json.dumps(self.application.kernel_ids))
self.finish(json.dumps(self.application.kernel_ids))

def post(self):
kernel_id = self.application.start_kernel()
self.set_header('Location', '/'+kernel_id)
self.write(json.dumps(kernel_id))
self.finish(json.dumps(kernel_id))


class KernelActionHandler(web.RequestHandler):
Expand All @@ -58,6 +58,7 @@ def post(self, kernel_id, action):
if action == 'restart':
new_kernel_id = self.application.restart_kernel(kernel_id)
self.write(json.dumps(new_kernel_id))
self.finish()


class ZMQStreamHandler(websocket.WebSocketHandler):
Expand All @@ -83,7 +84,7 @@ class NotebookRootHandler(web.RequestHandler):
def get(self):
nbm = self.application.notebook_manager
files = nbm.list_notebooks()
self.write(json.dumps(files))
self.finish(json.dumps(files))

def post(self):
nbm = self.application.notebook_manager
Expand All @@ -95,7 +96,7 @@ def post(self):
else:
notebook_id = nbm.new_notebook()
self.set_header('Location', '/'+notebook_id)
self.write(json.dumps(notebook_id))
self.finish(json.dumps(notebook_id))


class NotebookHandler(web.RequestHandler):
Expand All @@ -110,10 +111,10 @@ def get(self, notebook_id):
self.set_header('Content-Type', 'application/json')
self.set_header('Content-Disposition','attachment; filename=%s.json' % name)
elif format == u'xml':
self.set_header('Content-Type', 'text/xml')
self.set_header('Content-Type', 'application/xml')
self.set_header('Content-Disposition','attachment; filename=%s.ipynb' % name)
elif format == u'py':
self.set_header('Content-Type', 'text/plain')
self.set_header('Content-Type', 'application/x-python')
self.set_header('Content-Disposition','attachment; filename=%s.py' % name)
self.set_header('Last-Modified', last_mod)
self.finish(data)
Expand Down
11 changes: 6 additions & 5 deletions IPython/frontend/html/notebook/static/js/notebook.js
Expand Up @@ -559,11 +559,12 @@ var IPython = (function (IPython) {
data.id = notebook_id
// We do the call with settings so we can set cache to false.
var settings = {
processData : false,
cache : false,
type : "PUT",
data : JSON.stringify(data),
success : $.proxy(this.notebook_saved,this)
processData : false,
cache : false,
type : "PUT",
data : JSON.stringify(data),
headers : {'Content-Type': 'application/json'},
success : $.proxy(this.notebook_saved,this)
};
IPython.save_widget.status_saving();
$.ajax("/notebooks/" + notebook_id, settings);
Expand Down
15 changes: 12 additions & 3 deletions IPython/frontend/html/notebook/static/js/notebooklist.js
Expand Up @@ -191,20 +191,29 @@ var IPython = (function (IPython) {
var nbname = item.find('.item_name > input').attr('value');
var nbformat = item.data('nbformat');
var nbdata = item.data('nbdata');
var content_type = 'text/plain';
if (nbformat === 'xml') {
content_type = 'application/xml';
} else if (nbformat === 'json') {
content_type = 'application/json';
} else if (nbformat === 'py') {
content_type = 'application/x-python';
};
var settings = {
processData : false,
cache : false,
type : "POST",
dataType : "json",
type : 'POST',
dataType : 'json',
data : nbdata,
headers : {'Content-Type': content_type},
success : function (data, status, xhr) {
that.add_link(data, nbname, item);
that.add_delete_button(item);
}
};

var qs = $.param({name:nbname, format:nbformat});
$.ajax("/notebooks?" + qs, settings);
$.ajax('/notebooks?' + qs, settings);
});
var cancel_button = $('<button>Cancel</button>').button().
click(function (e) {
Expand Down
2 changes: 1 addition & 1 deletion IPython/nbformat/current.py
Expand Up @@ -43,7 +43,7 @@ def parse_py(s, **kwargs):
if m is not None:
nbformat = int(m.group('nbformat'))
else:
raise NBFormatError('No nbformat version found')
nbformat = 2
return nbformat, s


Expand Down
26 changes: 26 additions & 0 deletions IPython/nbformat/v2/nbpy.py
Expand Up @@ -4,6 +4,10 @@
from .nbbase import new_code_cell, new_worksheet, new_notebook


class PyReaderError(Exception):
pass


class PyReader(NotebookReader):

def reads(self, s, **kwargs):
Expand All @@ -13,20 +17,42 @@ def to_notebook(self, s, **kwargs):
lines = s.splitlines()
cells = []
cell_lines = []
code_cell = False
for line in lines:
if line.startswith(u'# <codecell>'):
if code_cell:
raise PyReaderError('Unexpected <codecell>')
if cell_lines:
for block in self.split_lines_into_blocks(cell_lines):
cells.append(new_code_cell(input=block))
cell_lines = []
code_cell = True
if line.startswith(u'# </codecell>'):
if not code_cell:
raise PyReaderError('Unexpected </codecell>')
code = u'\n'.join(cell_lines)
code = code.strip(u'\n')
if code:
cells.append(new_code_cell(input=code))
code_cell = False
else:
cell_lines.append(line)
# For lines we were not able to process,
for block in self.split_lines_into_blocks(cell_lines):
cells.append(new_code_cell(input=block))
ws = new_worksheet(cells=cells)
nb = new_notebook(worksheets=[ws])
return nb

def split_lines_into_blocks(self, lines):
import ast
source = '\n'.join(lines)
code = ast.parse(source)
starts = [x.lineno-1 for x in code.body]
for i in range(len(starts)-1):
yield '\n'.join(lines[starts[i]:starts[i+1]]).strip('\n')
yield '\n'.join(lines[starts[-1]:]).strip('\n')


class PyWriter(NotebookWriter):

Expand Down
1 change: 0 additions & 1 deletion IPython/nbformat/v2/tests/test_nbpy.py
Expand Up @@ -15,4 +15,3 @@ def test_write(self):
s = writes(nb0)
self.assertEquals(s,nb0_py)


0 comments on commit 8f4eb62

Please sign in to comment.