Show More
@@ -615,9 +615,12 b' class DisplayObject(object):' | |||
|
615 | 615 | filename = data |
|
616 | 616 | data = None |
|
617 | 617 | |
|
618 | self.data = data | |
|
619 | 618 | self.url = url |
|
620 | 619 | self.filename = filename |
|
620 | # because of @data.setter methods in | |
|
621 | # subclasses ensure url and filename are set | |
|
622 | # before assigning to self.data | |
|
623 | self.data = data | |
|
621 | 624 | |
|
622 | 625 | if metadata is not None: |
|
623 | 626 | self.metadata = metadata |
@@ -652,23 +655,36 b' class DisplayObject(object):' | |||
|
652 | 655 | with open(self.filename, self._read_flags) as f: |
|
653 | 656 | self.data = f.read() |
|
654 | 657 | elif self.url is not None: |
|
655 | try: | |
|
656 | 658 |
|
|
657 | 659 |
|
|
658 | 660 |
|
|
659 |
|
|
|
661 | data = response.read() | |
|
660 | 662 |
|
|
661 | 663 |
|
|
664 | if 'content-type' in response.headers: | |
|
662 | 665 | for sub in response.headers['content-type'].split(';'): |
|
663 | 666 | sub = sub.strip() |
|
664 | 667 | if sub.startswith('charset'): |
|
665 | 668 | encoding = sub.split('=')[-1].strip() |
|
666 | 669 | break |
|
670 | if 'content-encoding' in response.headers: | |
|
671 | # TODO: do deflate? | |
|
672 | if 'gzip' in response.headers['content-encoding']: | |
|
673 | import gzip | |
|
674 | from io import BytesIO | |
|
675 | with gzip.open(BytesIO(data), 'rt', encoding=encoding) as fp: | |
|
676 | encoding = None | |
|
677 | data = fp.read() | |
|
678 | ||
|
667 | 679 |
|
|
680 | # We only touch self.data once since | |
|
681 | # subclasses such as SVG have @data.setter methods | |
|
682 | # that transform self.data into ... well svg. | |
|
668 | 683 |
|
|
669 |
|
|
|
670 |
e |
|
|
671 |
self.data = |
|
|
684 | self.data = data.decode(encoding, 'replace') | |
|
685 | else: | |
|
686 | self.data = data | |
|
687 | ||
|
672 | 688 | |
|
673 | 689 | class TextDisplayObject(DisplayObject): |
|
674 | 690 | """Validate that display data is text""" |
@@ -736,6 +752,11 b' class Latex(TextDisplayObject):' | |||
|
736 | 752 | |
|
737 | 753 | |
|
738 | 754 | class SVG(DisplayObject): |
|
755 | """Embed an SVG into the display. | |
|
756 | ||
|
757 | Note if you just want to view a svg image via a URL use `:class:Image` with | |
|
758 | a url=URL keyword argument. | |
|
759 | """ | |
|
739 | 760 | |
|
740 | 761 | _read_flags = 'rb' |
|
741 | 762 | # wrap data in a property, which extracts the <svg> tag, discarding |
@@ -879,7 +900,7 b' class JSON(DisplayObject):' | |||
|
879 | 900 | data = str(data) |
|
880 | 901 | |
|
881 | 902 | if isinstance(data, str): |
|
882 |
if |
|
|
903 | if self.filename is None and self.url is None: | |
|
883 | 904 | warnings.warn("JSON expects JSONable dict or list, not JSON strings") |
|
884 | 905 | data = json.loads(data) |
|
885 | 906 | self._data = data |
@@ -72,6 +72,45 b' def test_retina_png():' | |||
|
72 | 72 | nt.assert_equal(md['width'], 1) |
|
73 | 73 | nt.assert_equal(md['height'], 1) |
|
74 | 74 | |
|
75 | def test_embed_svg_url(): | |
|
76 | import gzip | |
|
77 | from io import BytesIO | |
|
78 | svg_data = b'<svg><circle x="0" y="0" r="1"/></svg>' | |
|
79 | url = 'http://test.com/circle.svg' | |
|
80 | ||
|
81 | gzip_svg = BytesIO() | |
|
82 | with gzip.open(gzip_svg, 'wb') as fp: | |
|
83 | fp.write(svg_data) | |
|
84 | gzip_svg = gzip_svg.getvalue() | |
|
85 | ||
|
86 | def mocked_urlopen(*args, **kwargs): | |
|
87 | class MockResponse: | |
|
88 | def __init__(self, svg): | |
|
89 | self._svg_data = svg | |
|
90 | self.headers = {'content-type': 'image/svg+xml'} | |
|
91 | ||
|
92 | def read(self): | |
|
93 | return self._svg_data | |
|
94 | ||
|
95 | if args[0] == url: | |
|
96 | return MockResponse(svg_data) | |
|
97 | elif args[0] == url + 'z': | |
|
98 | ret= MockResponse(gzip_svg) | |
|
99 | ret.headers['content-encoding']= 'gzip' | |
|
100 | return ret | |
|
101 | return MockResponse(None) | |
|
102 | ||
|
103 | with mock.patch('urllib.request.urlopen', side_effect=mocked_urlopen): | |
|
104 | svg = display.SVG(url=url) | |
|
105 | nt.assert_true(svg._repr_svg_().startswith('<svg')) | |
|
106 | svg = display.SVG(url=url + 'z') | |
|
107 | nt.assert_true(svg._repr_svg_().startswith('<svg')) | |
|
108 | ||
|
109 | # do it for real: 6.1kB of data | |
|
110 | url = "https://upload.wikimedia.org/wikipedia/commons/3/30/Vector-based_example.svg" | |
|
111 | svg = display.SVG(url=url) | |
|
112 | nt.assert_true(svg._repr_svg_().startswith('<svg')) | |
|
113 | ||
|
75 | 114 | def test_retina_jpeg(): |
|
76 | 115 | here = os.path.dirname(__file__) |
|
77 | 116 | img = display.Image(os.path.join(here, "2x2.jpg"), retina=True) |
General Comments 0
You need to be logged in to leave comments.
Login now