##// END OF EJS Templates
move _encode_binary to jsonutil.encode_images...
MinRK -
Show More
@@ -14,6 +14,7 b''
14 import re
14 import re
15 import sys
15 import sys
16 import types
16 import types
17 from base64 import encodestring
17 from datetime import datetime
18 from datetime import datetime
18
19
19 from IPython.utils import py3compat
20 from IPython.utils import py3compat
@@ -89,6 +90,24 b' def date_default(obj):'
89 raise TypeError("%r is not JSON serializable"%obj)
90 raise TypeError("%r is not JSON serializable"%obj)
90
91
91
92
93 # constants for identifying png/jpeg data
94 PNG = b'\x89PNG\r\n\x1a\n'
95 JPEG = b'\xff\xd8'
96
97 def encode_images(format_dict):
98 """b64-encodes images in a displaypub format dict
99
100 Perhaps this should be handled in json_clean itself?
101 """
102 encoded = format_dict.copy()
103 pngdata = format_dict.get('image/png')
104 if isinstance(pngdata, bytes) and pngdata[:8] == PNG:
105 encoded['image/png'] = encodestring(pngdata).decode('ascii')
106 jpegdata = format_dict.get('image/jpeg')
107 if isinstance(jpegdata, bytes) and jpegdata[:2] == JPEG:
108 encoded['image/jpeg'] = encodestring(jpegdata).decode('ascii')
109 return encoded
110
92
111
93 def json_clean(obj):
112 def json_clean(obj):
94 """Clean an object to ensure it's safe to encode in JSON.
113 """Clean an object to ensure it's safe to encode in JSON.
@@ -12,12 +12,15 b''
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # stdlib
13 # stdlib
14 import json
14 import json
15 from base64 import decodestring
15
16
16 # third party
17 # third party
17 import nose.tools as nt
18 import nose.tools as nt
18
19
19 # our own
20 # our own
20 from ..jsonutil import json_clean
21 from IPython.testing import decorators as dec
22 from ..jsonutil import json_clean, encode_images
23 from ..py3compat import unicode_to_str, str_to_bytes
21
24
22 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
23 # Test functions
26 # Test functions
@@ -56,6 +59,35 b' def test():'
56 json.loads(json.dumps(out))
59 json.loads(json.dumps(out))
57
60
58
61
62
63 @dec.parametric
64 def test_encode_images():
65 # invalid data, but the header and footer are from real files
66 pngdata = b'\x89PNG\r\n\x1a\nblahblahnotactuallyvalidIEND\xaeB`\x82'
67 jpegdata = b'\xff\xd8\xff\xe0\x00\x10JFIFblahblahjpeg(\xa0\x0f\xff\xd9'
68
69 fmt = {
70 'image/png' : pngdata,
71 'image/jpeg' : jpegdata,
72 }
73 encoded = encode_images(fmt)
74 for key, value in fmt.iteritems():
75 # encoded has unicode, want bytes
76 decoded = decodestring(encoded[key].encode('ascii'))
77 yield nt.assert_equal(decoded, value)
78 encoded2 = encode_images(encoded)
79 yield nt.assert_equal(encoded, encoded2)
80
81 b64_str = {}
82 for key, encoded in encoded.iteritems():
83 b64_str[key] = unicode_to_str(encoded)
84 encoded3 = encode_images(b64_str)
85 yield nt.assert_equal(encoded3, b64_str)
86 for key, value in fmt.iteritems():
87 # encoded3 has str, want bytes
88 decoded = decodestring(str_to_bytes(encoded3[key]))
89 yield nt.assert_equal(decoded, value)
90
59 def test_lambda():
91 def test_lambda():
60 jc = json_clean(lambda : 1)
92 jc = json_clean(lambda : 1)
61 assert isinstance(jc, str)
93 assert isinstance(jc, str)
@@ -1,8 +1,8 b''
1 import __builtin__
1 import __builtin__
2 import sys
2 import sys
3 from base64 import encodestring
4
3
5 from IPython.core.displayhook import DisplayHook
4 from IPython.core.displayhook import DisplayHook
5 from IPython.utils.jsonutil import encode_images
6 from IPython.utils.traitlets import Instance, Dict
6 from IPython.utils.traitlets import Instance, Dict
7 from session import extract_header, Session
7 from session import extract_header, Session
8
8
@@ -30,18 +30,6 b' class ZMQDisplayHook(object):'
30 self.parent_header = extract_header(parent)
30 self.parent_header = extract_header(parent)
31
31
32
32
33 def _encode_binary(format_dict):
34 encoded = format_dict.copy()
35 pngdata = format_dict.get('image/png')
36 if isinstance(pngdata, bytes):
37 encoded['image/png'] = encodestring(pngdata).decode('ascii')
38 jpegdata = format_dict.get('image/jpeg')
39 if isinstance(jpegdata, bytes):
40 encoded['image/jpeg'] = encodestring(jpegdata).decode('ascii')
41
42 return encoded
43
44
45 class ZMQShellDisplayHook(DisplayHook):
33 class ZMQShellDisplayHook(DisplayHook):
46 """A displayhook subclass that publishes data using ZeroMQ. This is intended
34 """A displayhook subclass that publishes data using ZeroMQ. This is intended
47 to work with an InteractiveShell instance. It sends a dict of different
35 to work with an InteractiveShell instance. It sends a dict of different
@@ -64,7 +52,7 b' class ZMQShellDisplayHook(DisplayHook):'
64 self.msg['content']['execution_count'] = self.prompt_count
52 self.msg['content']['execution_count'] = self.prompt_count
65
53
66 def write_format_data(self, format_dict):
54 def write_format_data(self, format_dict):
67 self.msg['content']['data'] = _encode_binary(format_dict)
55 self.msg['content']['data'] = encode_images(format_dict)
68
56
69 def finish_displayhook(self):
57 def finish_displayhook(self):
70 """Finish up all displayhook activities."""
58 """Finish up all displayhook activities."""
@@ -38,12 +38,12 b' from IPython.lib.kernel import ('
38 )
38 )
39 from IPython.testing.skipdoctest import skip_doctest
39 from IPython.testing.skipdoctest import skip_doctest
40 from IPython.utils import io
40 from IPython.utils import io
41 from IPython.utils.jsonutil import json_clean
41 from IPython.utils.jsonutil import json_clean, encode_images
42 from IPython.utils.process import arg_split
42 from IPython.utils.process import arg_split
43 from IPython.utils import py3compat
43 from IPython.utils import py3compat
44 from IPython.utils.traitlets import Instance, Type, Dict, CBool, CBytes
44 from IPython.utils.traitlets import Instance, Type, Dict, CBool, CBytes
45 from IPython.utils.warn import warn, error
45 from IPython.utils.warn import warn, error
46 from IPython.zmq.displayhook import ZMQShellDisplayHook, _encode_binary
46 from IPython.zmq.displayhook import ZMQShellDisplayHook
47 from IPython.zmq.session import extract_header
47 from IPython.zmq.session import extract_header
48 from session import Session
48 from session import Session
49
49
@@ -75,7 +75,7 b' class ZMQDisplayPublisher(DisplayPublisher):'
75 self._validate_data(source, data, metadata)
75 self._validate_data(source, data, metadata)
76 content = {}
76 content = {}
77 content['source'] = source
77 content['source'] = source
78 content['data'] = _encode_binary(data)
78 content['data'] = encode_images(data)
79 content['metadata'] = metadata
79 content['metadata'] = metadata
80 self.session.send(
80 self.session.send(
81 self.pub_socket, u'display_data', json_clean(content),
81 self.pub_socket, u'display_data', json_clean(content),
General Comments 0
You need to be logged in to leave comments. Login now