##// END OF EJS Templates
don't 'restore_bytes' in from_JSON...
MinRK -
Show More
@@ -1,215 +1,215 b''
1 """The basic dict based notebook format.
1 """The basic dict based notebook format.
2
2
3 The Python representation of a notebook is a nested structure of
3 The Python representation of a notebook is a nested structure of
4 dictionary subclasses that support attribute access
4 dictionary subclasses that support attribute access
5 (IPython.utils.ipstruct.Struct). The functions in this module are merely
5 (IPython.utils.ipstruct.Struct). The functions in this module are merely
6 helpers to build the structs in the right form.
6 helpers to build the structs in the right form.
7
7
8 Authors:
8 Authors:
9
9
10 * Brian Granger
10 * Brian Granger
11 """
11 """
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008-2011 The IPython Development Team
14 # Copyright (C) 2008-2011 The IPython Development Team
15 #
15 #
16 # Distributed under the terms of the BSD License. The full license is in
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
17 # the file COPYING, distributed as part of this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 import pprint
24 import pprint
25 import uuid
25 import uuid
26
26
27 from IPython.utils.ipstruct import Struct
27 from IPython.utils.ipstruct import Struct
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Code
30 # Code
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33 # Change this when incrementing the nbformat version
33 # Change this when incrementing the nbformat version
34 nbformat = 3
34 nbformat = 3
35 nbformat_minor = 0
35 nbformat_minor = 0
36
36
37 class NotebookNode(Struct):
37 class NotebookNode(Struct):
38 pass
38 pass
39
39
40
40
41 def from_dict(d):
41 def from_dict(d):
42 if isinstance(d, dict):
42 if isinstance(d, dict):
43 newd = NotebookNode()
43 newd = NotebookNode()
44 for k,v in d.items():
44 for k,v in d.items():
45 newd[k] = from_dict(v)
45 newd[k] = from_dict(v)
46 return newd
46 return newd
47 elif isinstance(d, (tuple, list)):
47 elif isinstance(d, (tuple, list)):
48 return [from_dict(i) for i in d]
48 return [from_dict(i) for i in d]
49 else:
49 else:
50 return d
50 return d
51
51
52
52
53 def new_output(output_type=None, output_text=None, output_png=None,
53 def new_output(output_type=None, output_text=None, output_png=None,
54 output_html=None, output_svg=None, output_latex=None, output_json=None,
54 output_html=None, output_svg=None, output_latex=None, output_json=None,
55 output_javascript=None, output_jpeg=None, prompt_number=None,
55 output_javascript=None, output_jpeg=None, prompt_number=None,
56 ename=None, evalue=None, traceback=None, stream=None, metadata=None):
56 ename=None, evalue=None, traceback=None, stream=None, metadata=None):
57 """Create a new code cell with input and output"""
57 """Create a new code cell with input and output"""
58 output = NotebookNode()
58 output = NotebookNode()
59 if output_type is not None:
59 if output_type is not None:
60 output.output_type = unicode(output_type)
60 output.output_type = unicode(output_type)
61
61
62 if metadata is None:
62 if metadata is None:
63 metadata = {}
63 metadata = {}
64 if not isinstance(metadata, dict):
64 if not isinstance(metadata, dict):
65 raise TypeError("metadata must be dict")
65 raise TypeError("metadata must be dict")
66 output.metadata = metadata
66 output.metadata = metadata
67
67
68 if output_type != 'pyerr':
68 if output_type != 'pyerr':
69 if output_text is not None:
69 if output_text is not None:
70 output.text = unicode(output_text)
70 output.text = unicode(output_text)
71 if output_png is not None:
71 if output_png is not None:
72 output.png = bytes(output_png)
72 output.png = unicode(output_png)
73 if output_jpeg is not None:
73 if output_jpeg is not None:
74 output.jpeg = bytes(output_jpeg)
74 output.jpeg = unicode(output_jpeg)
75 if output_html is not None:
75 if output_html is not None:
76 output.html = unicode(output_html)
76 output.html = unicode(output_html)
77 if output_svg is not None:
77 if output_svg is not None:
78 output.svg = unicode(output_svg)
78 output.svg = unicode(output_svg)
79 if output_latex is not None:
79 if output_latex is not None:
80 output.latex = unicode(output_latex)
80 output.latex = unicode(output_latex)
81 if output_json is not None:
81 if output_json is not None:
82 output.json = unicode(output_json)
82 output.json = unicode(output_json)
83 if output_javascript is not None:
83 if output_javascript is not None:
84 output.javascript = unicode(output_javascript)
84 output.javascript = unicode(output_javascript)
85
85
86 if output_type == u'pyout':
86 if output_type == u'pyout':
87 if prompt_number is not None:
87 if prompt_number is not None:
88 output.prompt_number = int(prompt_number)
88 output.prompt_number = int(prompt_number)
89
89
90 if output_type == u'pyerr':
90 if output_type == u'pyerr':
91 if ename is not None:
91 if ename is not None:
92 output.ename = unicode(ename)
92 output.ename = unicode(ename)
93 if evalue is not None:
93 if evalue is not None:
94 output.evalue = unicode(evalue)
94 output.evalue = unicode(evalue)
95 if traceback is not None:
95 if traceback is not None:
96 output.traceback = [unicode(frame) for frame in list(traceback)]
96 output.traceback = [unicode(frame) for frame in list(traceback)]
97
97
98 if output_type == u'stream':
98 if output_type == u'stream':
99 output.stream = 'stdout' if stream is None else unicode(stream)
99 output.stream = 'stdout' if stream is None else unicode(stream)
100
100
101 return output
101 return output
102
102
103
103
104 def new_code_cell(input=None, prompt_number=None, outputs=None,
104 def new_code_cell(input=None, prompt_number=None, outputs=None,
105 language=u'python', collapsed=False, metadata=None):
105 language=u'python', collapsed=False, metadata=None):
106 """Create a new code cell with input and output"""
106 """Create a new code cell with input and output"""
107 cell = NotebookNode()
107 cell = NotebookNode()
108 cell.cell_type = u'code'
108 cell.cell_type = u'code'
109 if language is not None:
109 if language is not None:
110 cell.language = unicode(language)
110 cell.language = unicode(language)
111 if input is not None:
111 if input is not None:
112 cell.input = unicode(input)
112 cell.input = unicode(input)
113 if prompt_number is not None:
113 if prompt_number is not None:
114 cell.prompt_number = int(prompt_number)
114 cell.prompt_number = int(prompt_number)
115 if outputs is None:
115 if outputs is None:
116 cell.outputs = []
116 cell.outputs = []
117 else:
117 else:
118 cell.outputs = outputs
118 cell.outputs = outputs
119 if collapsed is not None:
119 if collapsed is not None:
120 cell.collapsed = bool(collapsed)
120 cell.collapsed = bool(collapsed)
121 cell.metadata = NotebookNode(metadata or {})
121 cell.metadata = NotebookNode(metadata or {})
122
122
123 return cell
123 return cell
124
124
125 def new_text_cell(cell_type, source=None, rendered=None, metadata=None):
125 def new_text_cell(cell_type, source=None, rendered=None, metadata=None):
126 """Create a new text cell."""
126 """Create a new text cell."""
127 cell = NotebookNode()
127 cell = NotebookNode()
128 # VERSIONHACK: plaintext -> raw
128 # VERSIONHACK: plaintext -> raw
129 # handle never-released plaintext name for raw cells
129 # handle never-released plaintext name for raw cells
130 if cell_type == 'plaintext':
130 if cell_type == 'plaintext':
131 cell_type = 'raw'
131 cell_type = 'raw'
132 if source is not None:
132 if source is not None:
133 cell.source = unicode(source)
133 cell.source = unicode(source)
134 if rendered is not None:
134 if rendered is not None:
135 cell.rendered = unicode(rendered)
135 cell.rendered = unicode(rendered)
136 cell.metadata = NotebookNode(metadata or {})
136 cell.metadata = NotebookNode(metadata or {})
137 cell.cell_type = cell_type
137 cell.cell_type = cell_type
138 return cell
138 return cell
139
139
140
140
141 def new_heading_cell(source=None, rendered=None, level=1, metadata=None):
141 def new_heading_cell(source=None, rendered=None, level=1, metadata=None):
142 """Create a new section cell with a given integer level."""
142 """Create a new section cell with a given integer level."""
143 cell = NotebookNode()
143 cell = NotebookNode()
144 cell.cell_type = u'heading'
144 cell.cell_type = u'heading'
145 if source is not None:
145 if source is not None:
146 cell.source = unicode(source)
146 cell.source = unicode(source)
147 if rendered is not None:
147 if rendered is not None:
148 cell.rendered = unicode(rendered)
148 cell.rendered = unicode(rendered)
149 cell.level = int(level)
149 cell.level = int(level)
150 cell.metadata = NotebookNode(metadata or {})
150 cell.metadata = NotebookNode(metadata or {})
151 return cell
151 return cell
152
152
153
153
154 def new_worksheet(name=None, cells=None, metadata=None):
154 def new_worksheet(name=None, cells=None, metadata=None):
155 """Create a worksheet by name with with a list of cells."""
155 """Create a worksheet by name with with a list of cells."""
156 ws = NotebookNode()
156 ws = NotebookNode()
157 if name is not None:
157 if name is not None:
158 ws.name = unicode(name)
158 ws.name = unicode(name)
159 if cells is None:
159 if cells is None:
160 ws.cells = []
160 ws.cells = []
161 else:
161 else:
162 ws.cells = list(cells)
162 ws.cells = list(cells)
163 ws.metadata = NotebookNode(metadata or {})
163 ws.metadata = NotebookNode(metadata or {})
164 return ws
164 return ws
165
165
166
166
167 def new_notebook(name=None, metadata=None, worksheets=None):
167 def new_notebook(name=None, metadata=None, worksheets=None):
168 """Create a notebook by name, id and a list of worksheets."""
168 """Create a notebook by name, id and a list of worksheets."""
169 nb = NotebookNode()
169 nb = NotebookNode()
170 nb.nbformat = nbformat
170 nb.nbformat = nbformat
171 nb.nbformat_minor = nbformat_minor
171 nb.nbformat_minor = nbformat_minor
172 if worksheets is None:
172 if worksheets is None:
173 nb.worksheets = []
173 nb.worksheets = []
174 else:
174 else:
175 nb.worksheets = list(worksheets)
175 nb.worksheets = list(worksheets)
176 if metadata is None:
176 if metadata is None:
177 nb.metadata = new_metadata()
177 nb.metadata = new_metadata()
178 else:
178 else:
179 nb.metadata = NotebookNode(metadata)
179 nb.metadata = NotebookNode(metadata)
180 if name is not None:
180 if name is not None:
181 nb.metadata.name = unicode(name)
181 nb.metadata.name = unicode(name)
182 return nb
182 return nb
183
183
184
184
185 def new_metadata(name=None, authors=None, license=None, created=None,
185 def new_metadata(name=None, authors=None, license=None, created=None,
186 modified=None, gistid=None):
186 modified=None, gistid=None):
187 """Create a new metadata node."""
187 """Create a new metadata node."""
188 metadata = NotebookNode()
188 metadata = NotebookNode()
189 if name is not None:
189 if name is not None:
190 metadata.name = unicode(name)
190 metadata.name = unicode(name)
191 if authors is not None:
191 if authors is not None:
192 metadata.authors = list(authors)
192 metadata.authors = list(authors)
193 if created is not None:
193 if created is not None:
194 metadata.created = unicode(created)
194 metadata.created = unicode(created)
195 if modified is not None:
195 if modified is not None:
196 metadata.modified = unicode(modified)
196 metadata.modified = unicode(modified)
197 if license is not None:
197 if license is not None:
198 metadata.license = unicode(license)
198 metadata.license = unicode(license)
199 if gistid is not None:
199 if gistid is not None:
200 metadata.gistid = unicode(gistid)
200 metadata.gistid = unicode(gistid)
201 return metadata
201 return metadata
202
202
203 def new_author(name=None, email=None, affiliation=None, url=None):
203 def new_author(name=None, email=None, affiliation=None, url=None):
204 """Create a new author."""
204 """Create a new author."""
205 author = NotebookNode()
205 author = NotebookNode()
206 if name is not None:
206 if name is not None:
207 author.name = unicode(name)
207 author.name = unicode(name)
208 if email is not None:
208 if email is not None:
209 author.email = unicode(email)
209 author.email = unicode(email)
210 if affiliation is not None:
210 if affiliation is not None:
211 author.affiliation = unicode(affiliation)
211 author.affiliation = unicode(affiliation)
212 if url is not None:
212 if url is not None:
213 author.url = unicode(url)
213 author.url = unicode(url)
214 return author
214 return author
215
215
@@ -1,72 +1,72 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 import copy
19 import copy
20 import json
20 import json
21
21
22 from .nbbase import from_dict
22 from .nbbase import from_dict
23 from .rwbase import (
23 from .rwbase import (
24 NotebookReader, NotebookWriter, restore_bytes, rejoin_lines, split_lines
24 NotebookReader, NotebookWriter, restore_bytes, rejoin_lines, split_lines
25 )
25 )
26
26
27 from IPython.utils import py3compat
27 from IPython.utils import py3compat
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Code
30 # Code
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33 class BytesEncoder(json.JSONEncoder):
33 class BytesEncoder(json.JSONEncoder):
34 """A JSON encoder that accepts b64 (and other *ascii*) bytestrings."""
34 """A JSON encoder that accepts b64 (and other *ascii*) bytestrings."""
35 def default(self, obj):
35 def default(self, obj):
36 if isinstance(obj, bytes):
36 if isinstance(obj, bytes):
37 return obj.decode('ascii')
37 return obj.decode('ascii')
38 return json.JSONEncoder.default(self, obj)
38 return json.JSONEncoder.default(self, obj)
39
39
40
40
41 class JSONReader(NotebookReader):
41 class JSONReader(NotebookReader):
42
42
43 def reads(self, s, **kwargs):
43 def reads(self, s, **kwargs):
44 nb = json.loads(s, **kwargs)
44 nb = json.loads(s, **kwargs)
45 nb = self.to_notebook(nb, **kwargs)
45 nb = self.to_notebook(nb, **kwargs)
46 return nb
46 return nb
47
47
48 def to_notebook(self, d, **kwargs):
48 def to_notebook(self, d, **kwargs):
49 return restore_bytes(rejoin_lines(from_dict(d)))
49 return rejoin_lines(from_dict(d))
50
50
51
51
52 class JSONWriter(NotebookWriter):
52 class JSONWriter(NotebookWriter):
53
53
54 def writes(self, nb, **kwargs):
54 def writes(self, nb, **kwargs):
55 kwargs['cls'] = BytesEncoder
55 kwargs['cls'] = BytesEncoder
56 kwargs['indent'] = 1
56 kwargs['indent'] = 1
57 kwargs['sort_keys'] = True
57 kwargs['sort_keys'] = True
58 kwargs['separators'] = (',',': ')
58 kwargs['separators'] = (',',': ')
59 if kwargs.pop('split_lines', True):
59 if kwargs.pop('split_lines', True):
60 nb = split_lines(copy.deepcopy(nb))
60 nb = split_lines(copy.deepcopy(nb))
61 return py3compat.str_to_unicode(json.dumps(nb, **kwargs), 'utf-8')
61 return py3compat.str_to_unicode(json.dumps(nb, **kwargs), 'utf-8')
62
62
63
63
64 _reader = JSONReader()
64 _reader = JSONReader()
65 _writer = JSONWriter()
65 _writer = JSONWriter()
66
66
67 reads = _reader.reads
67 reads = _reader.reads
68 read = _reader.read
68 read = _reader.read
69 to_notebook = _reader.to_notebook
69 to_notebook = _reader.to_notebook
70 write = _writer.write
70 write = _writer.write
71 writes = _writer.writes
71 writes = _writer.writes
72
72
General Comments 0
You need to be logged in to leave comments. Login now