##// END OF EJS Templates
Proper error handling for nbformat versions in client code....
Brian Granger -
Show More
@@ -106,8 +106,10 b' var IPython = (function (IPython) {'
106 resizable: false,
106 resizable: false,
107 modal: true,
107 modal: true,
108 title: "Websocket closed",
108 title: "Websocket closed",
109 closeText: "",
110 close: function(event, ui) {$(this).dialog('destroy').remove();},
109 buttons : {
111 buttons : {
110 "Okay": function () {
112 "OK": function () {
111 $(this).dialog('close');
113 $(this).dialog('close');
112 }
114 }
113 }
115 }
@@ -29,6 +29,7 b' var IPython = (function (IPython) {'
29 this.notebook_id = null;
29 this.notebook_id = null;
30 this.notebook_name = null;
30 this.notebook_name = null;
31 this.notebook_name_blacklist_re = /[\/\\]/;
31 this.notebook_name_blacklist_re = /[\/\\]/;
32 this.nbformat = 3 // Increment this when changing the nbformat
32 this.style();
33 this.style();
33 this.create_elements();
34 this.create_elements();
34 this.bind_events();
35 this.bind_events();
@@ -1222,7 +1223,7 b' var IPython = (function (IPython) {'
1222 // We may want to move the name/id/nbformat logic inside toJSON?
1223 // We may want to move the name/id/nbformat logic inside toJSON?
1223 var data = this.toJSON();
1224 var data = this.toJSON();
1224 data.metadata.name = this.notebook_name;
1225 data.metadata.name = this.notebook_name;
1225 data.nbformat = 3;
1226 data.nbformat = this.nbformat;
1226 // We do the call with settings so we can set cache to false.
1227 // We do the call with settings so we can set cache to false.
1227 var settings = {
1228 var settings = {
1228 processData : false,
1229 processData : false,
@@ -1230,8 +1231,8 b' var IPython = (function (IPython) {'
1230 type : "PUT",
1231 type : "PUT",
1231 data : JSON.stringify(data),
1232 data : JSON.stringify(data),
1232 headers : {'Content-Type': 'application/json'},
1233 headers : {'Content-Type': 'application/json'},
1233 success : $.proxy(this.notebook_save_success,this),
1234 success : $.proxy(this.save_notebook_success,this),
1234 error : $.proxy(this.notebook_save_failed,this)
1235 error : $.proxy(this.save_notebook_error,this)
1235 };
1236 };
1236 $([IPython.events]).trigger('notebook_saving.Notebook');
1237 $([IPython.events]).trigger('notebook_saving.Notebook');
1237 var url = $('body').data('baseProjectUrl') + 'notebooks/' + this.notebook_id;
1238 var url = $('body').data('baseProjectUrl') + 'notebooks/' + this.notebook_id;
@@ -1239,13 +1240,13 b' var IPython = (function (IPython) {'
1239 };
1240 };
1240
1241
1241
1242
1242 Notebook.prototype.notebook_save_success = function (data, status, xhr) {
1243 Notebook.prototype.save_notebook_success = function (data, status, xhr) {
1243 this.dirty = false;
1244 this.dirty = false;
1244 $([IPython.events]).trigger('notebook_saved.Notebook');
1245 $([IPython.events]).trigger('notebook_saved.Notebook');
1245 };
1246 };
1246
1247
1247
1248
1248 Notebook.prototype.notebook_save_failed = function (xhr, status, error_msg) {
1249 Notebook.prototype.save_notebook_error = function (xhr, status, error_msg) {
1249 $([IPython.events]).trigger('notebook_save_failed.Notebook');
1250 $([IPython.events]).trigger('notebook_save_failed.Notebook');
1250 };
1251 };
1251
1252
@@ -1259,9 +1260,8 b' var IPython = (function (IPython) {'
1259 cache : false,
1260 cache : false,
1260 type : "GET",
1261 type : "GET",
1261 dataType : "json",
1262 dataType : "json",
1262 success : function (data, status, xhr) {
1263 success : $.proxy(this.load_notebook_success,this),
1263 that.load_notebook_success(data, status, xhr);
1264 error : $.proxy(this.load_notebook_error,this),
1264 }
1265 };
1265 };
1266 $([IPython.events]).trigger('notebook_loading.Notebook');
1266 $([IPython.events]).trigger('notebook_loading.Notebook');
1267 var url = $('body').data('baseProjectUrl') + 'notebooks/' + this.notebook_id;
1267 var url = $('body').data('baseProjectUrl') + 'notebooks/' + this.notebook_id;
@@ -1280,9 +1280,59 b' var IPython = (function (IPython) {'
1280 }
1280 }
1281 this.select(0);
1281 this.select(0);
1282 this.scroll_to_top();
1282 this.scroll_to_top();
1283 if (data.orig_nbformat !== undefined && data.nbformat !== data.orig_nbformat) {
1284 msg = "This notebook has been converted from an older " +
1285 "notebook format (v"+data.orig_nbformat+") to the current notebook " +
1286 "format (v"+data.nbformat+"). The next time you save this notebook, the " +
1287 "newer notebook format will be used and older verions of IPython " +
1288 "may not be able to read it. To keep the older version, close the " +
1289 "notebook without saving it.";
1290 var dialog = $('<div/>');
1291 dialog.html(msg);
1292 this.element.append(dialog);
1293 dialog.dialog({
1294 resizable: false,
1295 modal: true,
1296 title: "Notebook converted",
1297 closeText: "",
1298 close: function(event, ui) {$(this).dialog('destroy').remove();},
1299 buttons : {
1300 "OK": function () {
1301 $(this).dialog('close');
1302 }
1303 },
1304 width: 400
1305 });
1306 }
1283 $([IPython.events]).trigger('notebook_loaded.Notebook');
1307 $([IPython.events]).trigger('notebook_loaded.Notebook');
1284 };
1308 };
1285
1309
1310
1311 Notebook.prototype.load_notebook_error = function (xhr, textStatus, errorThrow) {
1312 if (xhr.status === 500) {
1313 msg = "An error occurred while loading this notebook. Most likely " +
1314 "this notebook is in a newer format than is supported by this " +
1315 "version of IPython. This version can load notebook formats " +
1316 "v"+this.nbformat+" or earlier.";
1317 var dialog = $('<div/>');
1318 dialog.html(msg);
1319 this.element.append(dialog);
1320 dialog.dialog({
1321 resizable: false,
1322 modal: true,
1323 title: "Error loading notebook",
1324 closeText: "",
1325 close: function(event, ui) {$(this).dialog('destroy').remove();},
1326 buttons : {
1327 "OK": function () {
1328 $(this).dialog('close');
1329 }
1330 },
1331 width: 400
1332 });
1333 }
1334 }
1335
1286 IPython.Notebook = Notebook;
1336 IPython.Notebook = Notebook;
1287
1337
1288
1338
@@ -28,14 +28,14 b' from IPython.nbformat import v1'
28 from IPython.nbformat.v3 import (
28 from IPython.nbformat.v3 import (
29 NotebookNode,
29 NotebookNode,
30 new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet,
30 new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet,
31 parse_filename, new_metadata, new_author, new_heading_cell
31 parse_filename, new_metadata, new_author, new_heading_cell, nbformat
32 )
32 )
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Code
35 # Code
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38 current_nbformat = 3
38 current_nbformat = nbformat
39
39
40
40
41 class NBFormatError(Exception):
41 class NBFormatError(Exception):
@@ -45,8 +45,8 b' class NBFormatError(Exception):'
45 def parse_json(s, **kwargs):
45 def parse_json(s, **kwargs):
46 """Parse a string into a (nbformat, dict) tuple."""
46 """Parse a string into a (nbformat, dict) tuple."""
47 d = json.loads(s, **kwargs)
47 d = json.loads(s, **kwargs)
48 nbformat = d.get('nbformat',1)
48 nbf = d.get('nbformat',1)
49 return nbformat, d
49 return nbf, d
50
50
51
51
52 def parse_py(s, **kwargs):
52 def parse_py(s, **kwargs):
@@ -54,25 +54,25 b' def parse_py(s, **kwargs):'
54 pattern = r'# <nbformat>(?P<nbformat>\d+)</nbformat>'
54 pattern = r'# <nbformat>(?P<nbformat>\d+)</nbformat>'
55 m = re.search(pattern,s)
55 m = re.search(pattern,s)
56 if m is not None:
56 if m is not None:
57 nbformat = int(m.group('nbformat'))
57 nbf = int(m.group('nbformat'))
58 else:
58 else:
59 nbformat = 3
59 nbf = current_nbformat
60 return nbformat, s
60 return nbf, s
61
61
62
62
63 def reads_json(s, **kwargs):
63 def reads_json(s, **kwargs):
64 """Read a JSON notebook from a string and return the NotebookNode object."""
64 """Read a JSON notebook from a string and return the NotebookNode object."""
65 nbformat, d = parse_json(s, **kwargs)
65 nbf, d = parse_json(s, **kwargs)
66 if nbformat == 1:
66 if nbf == 1:
67 nb = v1.to_notebook_json(d, **kwargs)
67 nb = v1.to_notebook_json(d, **kwargs)
68 nb = v3.convert_to_this_nbformat(nb, orig_version=1)
68 nb = v3.convert_to_this_nbformat(nb, orig_version=1)
69 elif nbformat == 2:
69 elif nbf == 2:
70 nb = v2.to_notebook_json(d, **kwargs)
70 nb = v2.to_notebook_json(d, **kwargs)
71 nb = v3.convert_to_this_nbformat(nb, orig_version=2)
71 nb = v3.convert_to_this_nbformat(nb, orig_version=2)
72 elif nbformat == 3:
72 elif nbf == 3:
73 nb = v3.to_notebook_json(d, **kwargs)
73 nb = v3.to_notebook_json(d, **kwargs)
74 else:
74 else:
75 raise NBFormatError('Unsupported JSON nbformat version: %i' % nbformat)
75 raise NBFormatError('Unsupported JSON nbformat version: %i' % nbf)
76 return nb
76 return nb
77
77
78
78
@@ -82,13 +82,13 b' def writes_json(nb, **kwargs):'
82
82
83 def reads_py(s, **kwargs):
83 def reads_py(s, **kwargs):
84 """Read a .py notebook from a string and return the NotebookNode object."""
84 """Read a .py notebook from a string and return the NotebookNode object."""
85 nbformat, s = parse_py(s, **kwargs)
85 nbf, s = parse_py(s, **kwargs)
86 if nbformat == 2:
86 if nbf == 2:
87 nb = v2.to_notebook_py(s, **kwargs)
87 nb = v2.to_notebook_py(s, **kwargs)
88 elif nbformat == 3:
88 elif nbf == 3:
89 nb = v3.to_notebook_py(s, **kwargs)
89 nb = v3.to_notebook_py(s, **kwargs)
90 else:
90 else:
91 raise NBFormatError('Unsupported PY nbformat version: %i' % nbformat)
91 raise NBFormatError('Unsupported PY nbformat version: %i' % nbf)
92 return nb
92 return nb
93
93
94
94
@@ -40,6 +40,9 b' def convert_to_this_nbformat(nb, orig_version=2):'
40 nb = v2.convert_to_this_nbformat(nb)
40 nb = v2.convert_to_this_nbformat(nb)
41 orig_version = 2
41 orig_version = 2
42 if orig_version == 2:
42 if orig_version == 2:
43 # Mark the original nbformat so consumers know it has been converted.
44 nb.nbformat = 3
45 nb.orig_nbformat = 2
43 return nb
46 return nb
44 elif orig_version == 3:
47 elif orig_version == 3:
45 return nb
48 return nb
General Comments 0
You need to be logged in to leave comments. Login now