##// END OF EJS Templates
fix base64 code in nbformat.v2...
MinRK -
Show More
@@ -1,62 +1,62 b''
1 """Read and write notebooks in JSON format.
1 """Read and write notebooks in JSON format.
2
2
3 Authors:
3 Authors:
4
4
5 * Brian Granger
5 * Brian Granger
6 """
6 """
7
7
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2008-2011 The IPython Development Team
9 # Copyright (C) 2008-2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 from base64 import encodestring
20 from .nbbase import from_dict
19 from .nbbase import from_dict
21 from .rwbase import NotebookReader, NotebookWriter, base64_decode
20 from .rwbase import NotebookReader, NotebookWriter, restore_bytes
22 import json
21 import json
23
22
24 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
25 # Code
24 # Code
26 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
27
26
28 class BytesEncoder(json.JSONEncoder):
27 class BytesEncoder(json.JSONEncoder):
28 """A JSON encoder that accepts b64 (and other *ascii*) bytestrings."""
29 def default(self, obj):
29 def default(self, obj):
30 if isinstance(obj, bytes):
30 if isinstance(obj, bytes):
31 return encodestring(obj).decode('ascii')
31 return obj.decode('ascii')
32 return json.JSONEncoder.default(self, obj)
32 return json.JSONEncoder.default(self, obj)
33
33
34
34
35 class JSONReader(NotebookReader):
35 class JSONReader(NotebookReader):
36
36
37 def reads(self, s, **kwargs):
37 def reads(self, s, **kwargs):
38 nb = json.loads(s, **kwargs)
38 nb = json.loads(s, **kwargs)
39 nb = self.to_notebook(nb, **kwargs)
39 nb = self.to_notebook(nb, **kwargs)
40 return nb
40 return nb
41
41
42 def to_notebook(self, d, **kwargs):
42 def to_notebook(self, d, **kwargs):
43 return base64_decode(from_dict(d))
43 return restore_bytes(from_dict(d))
44
44
45
45
46 class JSONWriter(NotebookWriter):
46 class JSONWriter(NotebookWriter):
47
47
48 def writes(self, nb, **kwargs):
48 def writes(self, nb, **kwargs):
49 kwargs['cls'] = BytesEncoder
49 kwargs['cls'] = BytesEncoder
50 kwargs['indent'] = 4
50 kwargs['indent'] = 4
51 return json.dumps(nb, **kwargs)
51 return json.dumps(nb, **kwargs)
52
52
53
53
54 _reader = JSONReader()
54 _reader = JSONReader()
55 _writer = JSONWriter()
55 _writer = JSONWriter()
56
56
57 reads = _reader.reads
57 reads = _reader.reads
58 read = _reader.read
58 read = _reader.read
59 to_notebook = _reader.to_notebook
59 to_notebook = _reader.to_notebook
60 write = _writer.write
60 write = _writer.write
61 writes = _writer.writes
61 writes = _writer.writes
62
62
@@ -1,74 +1,110 b''
1 """Base classes and utilities for readers and writers.
1 """Base classes and utilities for readers and writers.
2
2
3 Authors:
3 Authors:
4
4
5 * Brian Granger
5 * Brian Granger
6 """
6 """
7
7
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2008-2011 The IPython Development Team
9 # Copyright (C) 2008-2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 from base64 import encodestring, decodestring
19 from base64 import encodestring, decodestring
20 import pprint
20 import pprint
21
21
22 from IPython.utils.py3compat import str_to_bytes
23
22 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
23 # Code
25 # Code
24 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
25
27
28 def restore_bytes(nb):
29 """Restore bytes of image data from unicode-only formats.
30
31 Base64 encoding is handled elsewhere. Bytes objects in the notebook are
32 always b64-encoded. We DO NOT encode/decode around file formats.
33 """
34 for ws in nb.worksheets:
35 for cell in ws.cells:
36 if cell.cell_type == 'code':
37 for output in cell.outputs:
38 if 'png' in output:
39 output.png = str_to_bytes(output.png, 'ascii')
40 if 'jpeg' in output:
41 output.jpeg = str_to_bytes(output.jpeg, 'ascii')
42 return nb
43
44
45 # b64 encode/decode are never actually used, because all bytes objects in
46 # the notebook are already b64-encoded, and we don't need/want to double-encode
47
26 def base64_decode(nb):
48 def base64_decode(nb):
27 """Base64 encode all bytes objects in the notebook."""
49 """Restore all bytes objects in the notebook from base64-encoded strings.
50
51 Note: This is never used
52 """
28 for ws in nb.worksheets:
53 for ws in nb.worksheets:
29 for cell in ws.cells:
54 for cell in ws.cells:
30 if cell.cell_type == 'code':
55 if cell.cell_type == 'code':
31 if 'png' in cell:
56 for output in cell.outputs:
32 cell.png = bytes(decodestring(cell.png))
57 if 'png' in output:
33 if 'jpeg' in cell:
58 if isinstance(output.png, unicode):
34 cell.jpeg = bytes(decodestring(cell.jpeg))
59 output.png = output.png.encode('ascii')
60 output.png = decodestring(output.png)
61 if 'jpeg' in output:
62 if isinstance(output.jpeg, unicode):
63 output.jpeg = output.jpeg.encode('ascii')
64 output.jpeg = decodestring(output.jpeg)
35 return nb
65 return nb
36
66
37
67
38 def base64_encode(nb):
68 def base64_encode(nb):
39 """Base64 decode all binary objects in the notebook."""
69 """Base64 encode all bytes objects in the notebook.
70
71 These will be b64-encoded unicode strings
72
73 Note: This is never used
74 """
40 for ws in nb.worksheets:
75 for ws in nb.worksheets:
41 for cell in ws.cells:
76 for cell in ws.cells:
42 if cell.cell_type == 'code':
77 if cell.cell_type == 'code':
43 if 'png' in cell:
78 for output in cell.outputs:
44 cell.png = unicode(encodestring(cell.png))
79 if 'png' in output:
45 if 'jpeg' in cell:
80 output.png = encodestring(output.png).decode('ascii')
46 cell.jpeg = unicode(encodestring(cell.jpeg))
81 if 'jpeg' in output:
82 output.jpeg = encodestring(output.jpeg).decode('ascii')
47 return nb
83 return nb
48
84
49
85
50 class NotebookReader(object):
86 class NotebookReader(object):
51 """A class for reading notebooks."""
87 """A class for reading notebooks."""
52
88
53 def reads(self, s, **kwargs):
89 def reads(self, s, **kwargs):
54 """Read a notebook from a string."""
90 """Read a notebook from a string."""
55 raise NotImplementedError("loads must be implemented in a subclass")
91 raise NotImplementedError("loads must be implemented in a subclass")
56
92
57 def read(self, fp, **kwargs):
93 def read(self, fp, **kwargs):
58 """Read a notebook from a file like object"""
94 """Read a notebook from a file like object"""
59 return self.read(fp.read(), **kwargs)
95 return self.read(fp.read(), **kwargs)
60
96
61
97
62 class NotebookWriter(object):
98 class NotebookWriter(object):
63 """A class for writing notebooks."""
99 """A class for writing notebooks."""
64
100
65 def writes(self, nb, **kwargs):
101 def writes(self, nb, **kwargs):
66 """Write a notebook to a string."""
102 """Write a notebook to a string."""
67 raise NotImplementedError("loads must be implemented in a subclass")
103 raise NotImplementedError("loads must be implemented in a subclass")
68
104
69 def write(self, nb, fp, **kwargs):
105 def write(self, nb, fp, **kwargs):
70 """Write a notebook to a file like object"""
106 """Write a notebook to a file like object"""
71 return fp.write(self.writes(nb,**kwargs))
107 return fp.write(self.writes(nb,**kwargs))
72
108
73
109
74
110
@@ -1,103 +1,108 b''
1 import os
2 from base64 import encodestring
3
1 from ..nbbase import (
4 from ..nbbase import (
2 NotebookNode,
5 NotebookNode,
3 new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output,
6 new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output,
4 new_metadata, new_author
7 new_metadata, new_author
5 )
8 )
6
9
7
10 # some random base64-encoded *bytes*
11 png = encodestring(os.urandom(5))
12 jpeg = encodestring(os.urandom(6))
8
13
9 ws = new_worksheet(name='worksheet1')
14 ws = new_worksheet(name='worksheet1')
10
15
11 ws.cells.append(new_text_cell(
16 ws.cells.append(new_text_cell(
12 u'html',
17 u'html',
13 source='Some NumPy Examples',
18 source='Some NumPy Examples',
14 rendered='Some NumPy Examples'
19 rendered='Some NumPy Examples'
15 ))
20 ))
16
21
17
22
18 ws.cells.append(new_code_cell(
23 ws.cells.append(new_code_cell(
19 input='import numpy',
24 input='import numpy',
20 prompt_number=1,
25 prompt_number=1,
21 collapsed=False
26 collapsed=False
22 ))
27 ))
23
28
24 ws.cells.append(new_text_cell(
29 ws.cells.append(new_text_cell(
25 u'markdown',
30 u'markdown',
26 source='A random array',
31 source='A random array',
27 rendered='A random array'
32 rendered='A random array'
28 ))
33 ))
29
34
30 ws.cells.append(new_code_cell(
35 ws.cells.append(new_code_cell(
31 input='a = numpy.random.rand(100)',
36 input='a = numpy.random.rand(100)',
32 prompt_number=2,
37 prompt_number=2,
33 collapsed=True
38 collapsed=True
34 ))
39 ))
35
40
36 ws.cells.append(new_code_cell(
41 ws.cells.append(new_code_cell(
37 input='print a',
42 input='print a',
38 prompt_number=3,
43 prompt_number=3,
39 collapsed=False,
44 collapsed=False,
40 outputs=[new_output(
45 outputs=[new_output(
41 output_type=u'pyout',
46 output_type=u'pyout',
42 output_text=u'<array a>',
47 output_text=u'<array a>',
43 output_html=u'The HTML rep',
48 output_html=u'The HTML rep',
44 output_latex=u'$a$',
49 output_latex=u'$a$',
45 output_png=b'data',
50 output_png=png,
46 output_jpeg=b'data',
51 output_jpeg=jpeg,
47 output_svg=u'<svg>',
52 output_svg=u'<svg>',
48 output_json=u'json data',
53 output_json=u'json data',
49 output_javascript=u'var i=0;',
54 output_javascript=u'var i=0;',
50 prompt_number=3
55 prompt_number=3
51 ),new_output(
56 ),new_output(
52 output_type=u'display_data',
57 output_type=u'display_data',
53 output_text=u'<array a>',
58 output_text=u'<array a>',
54 output_html=u'The HTML rep',
59 output_html=u'The HTML rep',
55 output_latex=u'$a$',
60 output_latex=u'$a$',
56 output_png=b'data',
61 output_png=png,
57 output_jpeg=b'data',
62 output_jpeg=jpeg,
58 output_svg=u'<svg>',
63 output_svg=u'<svg>',
59 output_json=u'json data',
64 output_json=u'json data',
60 output_javascript=u'var i=0;'
65 output_javascript=u'var i=0;'
61 ),new_output(
66 ),new_output(
62 output_type=u'pyerr',
67 output_type=u'pyerr',
63 etype=u'NameError',
68 etype=u'NameError',
64 evalue=u'NameError was here',
69 evalue=u'NameError was here',
65 traceback=[u'frame 0', u'frame 1', u'frame 2']
70 traceback=[u'frame 0', u'frame 1', u'frame 2']
66 )]
71 )]
67 ))
72 ))
68
73
69 authors = [new_author(name='Bart Simpson',email='bsimpson@fox.com',
74 authors = [new_author(name='Bart Simpson',email='bsimpson@fox.com',
70 affiliation=u'Fox',url=u'http://www.fox.com')]
75 affiliation=u'Fox',url=u'http://www.fox.com')]
71 md = new_metadata(name=u'My Notebook',license=u'BSD',created=u'8601_goes_here',
76 md = new_metadata(name=u'My Notebook',license=u'BSD',created=u'8601_goes_here',
72 modified=u'8601_goes_here',gistid=u'21341231',authors=authors)
77 modified=u'8601_goes_here',gistid=u'21341231',authors=authors)
73
78
74 nb0 = new_notebook(
79 nb0 = new_notebook(
75 worksheets=[ws, new_worksheet(name='worksheet2')],
80 worksheets=[ws, new_worksheet(name='worksheet2')],
76 metadata=md
81 metadata=md
77 )
82 )
78
83
79 nb0_py = """# <nbformat>2</nbformat>
84 nb0_py = """# <nbformat>2</nbformat>
80
85
81 # <htmlcell>
86 # <htmlcell>
82
87
83 # Some NumPy Examples
88 # Some NumPy Examples
84
89
85 # <codecell>
90 # <codecell>
86
91
87 import numpy
92 import numpy
88
93
89 # <markdowncell>
94 # <markdowncell>
90
95
91 # A random array
96 # A random array
92
97
93 # <codecell>
98 # <codecell>
94
99
95 a = numpy.random.rand(100)
100 a = numpy.random.rand(100)
96
101
97 # <codecell>
102 # <codecell>
98
103
99 print a
104 print a
100
105
101 """
106 """
102
107
103
108
General Comments 0
You need to be logged in to leave comments. Login now