##// END OF EJS Templates
noew removes trailing slashes if they are provided in input so the output can be formatted consistently by always appending a trailing slash (which previously could result in two trailing slashes if the input path included a trailing slash)
Greg Caporaso -
Show More
@@ -1,216 +1,243 b''
1 """Various display related classes.
1 """Various display related classes.
2
2
3 Authors : MinRK, gregcaporaso
3 Authors : MinRK, gregcaporaso
4 """
4 """
5
5
6 from os.path import exists, isfile, splitext, abspath, join, isdir, walk
6 from os.path import exists, isfile, splitext, abspath, join, isdir, walk
7
7
8
8
9 class YouTubeVideo(object):
9 class YouTubeVideo(object):
10 """Class for embedding a YouTube Video in an IPython session, based on its video id.
10 """Class for embedding a YouTube Video in an IPython session, based on its video id.
11
11
12 e.g. to embed the video on this page:
12 e.g. to embed the video on this page:
13
13
14 http://www.youtube.com/watch?v=foo
14 http://www.youtube.com/watch?v=foo
15
15
16 you would do:
16 you would do:
17
17
18 vid = YouTubeVideo("foo")
18 vid = YouTubeVideo("foo")
19 display(vid)
19 display(vid)
20 """
20 """
21
21
22 def __init__(self, id, width=400, height=300):
22 def __init__(self, id, width=400, height=300):
23 self.id = id
23 self.id = id
24 self.width = width
24 self.width = width
25 self.height = height
25 self.height = height
26
26
27 def _repr_html_(self):
27 def _repr_html_(self):
28 """return YouTube embed iframe for this video id"""
28 """return YouTube embed iframe for this video id"""
29 return """
29 return """
30 <iframe
30 <iframe
31 width="%i"
31 width="%i"
32 height="%i"
32 height="%i"
33 src="http://www.youtube.com/embed/%s"
33 src="http://www.youtube.com/embed/%s"
34 frameborder="0"
34 frameborder="0"
35 allowfullscreen
35 allowfullscreen
36 ></iframe>
36 ></iframe>
37 """%(self.width, self.height, self.id)
37 """%(self.width, self.height, self.id)
38
38
39 class FileLink(object):
39 class FileLink(object):
40 """Class for embedding a local file link in an IPython session, based on path
40 """Class for embedding a local file link in an IPython session, based on path
41
41
42 e.g. to embed a link that was generated in the IPython notebook as my/data.txt
42 e.g. to embed a link that was generated in the IPython notebook as my/data.txt
43
43
44 you would do:
44 you would do:
45
45
46 local_file = FileLink("my/data.txt")
46 local_file = FileLink("my/data.txt")
47 display(local_file)
47 display(local_file)
48
48
49 or in the HTML notebook, just
49 or in the HTML notebook, just
50
50
51 FileLink("my/data.txt")
51 FileLink("my/data.txt")
52 """
52 """
53
53
54 html_link_str = "<a href='%s' target='_blank'>%s</a>"
54 html_link_str = "<a href='%s' target='_blank'>%s</a>"
55
55
56 def __init__(self,
56 def __init__(self,
57 path,
57 path,
58 url_prefix='files/',
58 url_prefix='files/',
59 result_html_prefix='',
59 result_html_prefix='',
60 result_html_suffix='<br>'):
60 result_html_suffix='<br>'):
61 """
61 """
62 path : path to the file or directory that should be formatted
62 path : path to the file or directory that should be formatted
63 directory_prefix : prefix to be prepended to all files to form a
63 directory_prefix : prefix to be prepended to all files to form a
64 working link [default: 'files']
64 working link [default: 'files']
65 result_html_prefix : text to append to beginning to link
65 result_html_prefix : text to append to beginning to link
66 [default: none]
66 [default: none]
67 result_html_suffix : text to append at the end of link
67 result_html_suffix : text to append at the end of link
68 [default: '<br>']
68 [default: '<br>']
69 """
69 """
70 self.path = path
70 self.path = path
71 self.url_prefix = url_prefix
71 self.url_prefix = url_prefix
72 self.result_html_prefix = result_html_prefix
72 self.result_html_prefix = result_html_prefix
73 self.result_html_suffix = result_html_suffix
73 self.result_html_suffix = result_html_suffix
74
74
75 def _format_path(self):
75 def _format_path(self):
76 fp = ''.join([self.url_prefix,self.path])
76 fp = ''.join([self.url_prefix,self.path])
77 return ''.join([self.result_html_prefix,
77 return ''.join([self.result_html_prefix,
78 self.html_link_str % (fp, self.path),
78 self.html_link_str % (fp, self.path),
79 self.result_html_suffix])
79 self.result_html_suffix])
80
80
81 def _repr_html_(self):
81 def _repr_html_(self):
82 """return html link to file
82 """return html link to file
83 """
83 """
84 if not exists(self.path):
84 if not exists(self.path):
85 return ("Path (<tt>%s</tt>) doesn't exist. "
85 return ("Path (<tt>%s</tt>) doesn't exist. "
86 "It may still be in the process of "
86 "It may still be in the process of "
87 "being generated, or you may have the "
87 "being generated, or you may have the "
88 "incorrect path." % self.path)
88 "incorrect path." % self.path)
89
89
90 return self._format_path()
90 return self._format_path()
91
91
92 def __repr__(self):
92 def __repr__(self):
93 """return absolute path to file
93 """return absolute path to file
94 """
94 """
95 return abspath(self.path)
95 return abspath(self.path)
96
96
97 # Create an alias for formatting a single directory name as a link.
97 # Create an alias for formatting a single directory name as a link.
98 # Right now this is the same as a formatting for a single file, but
98 # Right now this is the same as a formatting for a single file, but
99 # we'll encourage users to reference these with a different class in
99 # we'll encourage users to reference these with a different class in
100 # case we want to change this in the future.
100 # case we want to change this in the future.
101 DirectoryLink = FileLink
101 DirectoryLink = FileLink
102
102
103 class FileLinks(FileLink):
103 class FileLinks(FileLink):
104 """Class for embedding local file links in an IPython session, based on path
104 """Class for embedding local file links in an IPython session, based on path
105
105
106 e.g. to embed links to files that were generated in the IPython notebook under my/data
106 e.g. to embed links to files that were generated in the IPython notebook under my/data
107
107
108 you would do:
108 you would do:
109
109
110 local_files = FileLinks("my/data")
110 local_files = FileLinks("my/data")
111 display(local_files)
111 display(local_files)
112
112
113 or in the HTML notebook, just
113 or in the HTML notebook, just
114
114
115 FileLinks("my/data")
115 FileLinks("my/data")
116
116
117 """
117 """
118 def __init__(self,
118 def __init__(self,
119 path,
119 path,
120 url_prefix='files/',
120 url_prefix='files/',
121 included_suffixes=None,
121 included_suffixes=None,
122 result_html_prefix='',
122 result_html_prefix='',
123 result_html_suffix='<br>',
123 result_html_suffix='<br>',
124 notebook_display_formatter=None,
124 notebook_display_formatter=None,
125 terminal_display_formatter=None):
125 terminal_display_formatter=None):
126 """
126 """
127 included_suffixes : list of filename suffixes to include when
127 included_suffixes : list of filename suffixes to include when
128 formatting output [default: include all files]
128 formatting output [default: include all files]
129
129
130 See the FileLink (baseclass of LocalDirectory) docstring for
130 See the FileLink (baseclass of LocalDirectory) docstring for
131 information on additional parameters.
131 information on additional parameters.
132
133 notebook_display_formatter : func passed to os.path.walk when
134 formatting links for display in the notebook
135
136 terminal_display_formatter : func passed to os.path.walk when
137 formatting links for display in the terminal
132
138
133 """
139 """
134 self.included_suffixes = included_suffixes
140 self.included_suffixes = included_suffixes
135
141 # remove trailing slashs for more consistent output formatting
142 path = path.rstrip('/')
136 FileLink.__init__(self,
143 FileLink.__init__(self,
137 path,
144 path,
138 url_prefix,
145 url_prefix,
139 result_html_prefix,
146 result_html_prefix,
140 result_html_suffix)
147 result_html_suffix)
141
148
142 self.notebook_display_formatter = \
149 self.notebook_display_formatter = \
143 notebook_display_formatter or self._get_notebook_display_formatter()
150 notebook_display_formatter or self._get_notebook_display_formatter()
144 self.terminal_display_formatter = \
151 self.terminal_display_formatter = \
145 terminal_display_formatter or self._get_terminal_display_formatter()
152 terminal_display_formatter or self._get_terminal_display_formatter()
146
153
147 def _get_display_formatter(self,
154 def _get_display_formatter(self,
148 dirname_output_format,
155 dirname_output_format,
149 fname_output_format,
156 fname_output_format,
150 fp_format):
157 fp_format):
158 """ generate func to pass to os.path.walk
159
160 dirname_output_format: string to use for formatting directory
161 names, dirname will be substituted for a single "%s" which
162 must appear in this string
163 fname_output_format: string to use for formatting file names,
164 if a single "%s" appears in the string, fname will be substituted
165 if two "%s" appear in the string, the path to fname will be
166 substituted for the first and fname will be substituted for the
167 second
168 fp_format: string to use for formatting filepaths, must contain
169 exactly two "%s" and the dirname will be subsituted for the first
170 and fname will be substituted for the second
171 """
151
172
152 included_suffixes = self.included_suffixes
173 included_suffixes = self.included_suffixes
153
174
154 def f(output_lines, dirname, fnames):
175 def f(output_lines, dirname, fnames):
155 """ """
176 """ func to be passed to os.path.walk """
156 # begin by figuring out which filenames, if any,
177 # begin by figuring out which filenames, if any,
157 # are going to be displayed
178 # are going to be displayed
158 display_fnames = []
179 display_fnames = []
159 for fname in fnames:
180 for fname in fnames:
160 if (isfile(join(dirname,fname)) and
181 if (isfile(join(dirname,fname)) and
161 (included_suffixes == None or
182 (included_suffixes == None or
162 splitext(fname)[1] in included_suffixes)):
183 splitext(fname)[1] in included_suffixes)):
163 display_fnames.append(fname)
184 display_fnames.append(fname)
164
185
165 if len(display_fnames) == 0:
186 if len(display_fnames) == 0:
187 # if there are no filenames to display, don't print anything
188 # (not even the directory name)
166 pass
189 pass
167 else:
190 else:
191 # otherwise print the formatted directory name followed by
192 # the formatted filenames
168 dirname_output_line = dirname_output_format % dirname
193 dirname_output_line = dirname_output_format % dirname
169 output_lines.append(dirname_output_line)
194 output_lines.append(dirname_output_line)
170 for fname in display_fnames:
195 for fname in display_fnames:
171 fp = fp_format % (dirname,fname)
196 fp = fp_format % (dirname,fname)
172 try:
197 try:
173 # output can include both a filepath and a filename...
198 # output can include both a filepath and a filename...
174 fname_output_line = fname_output_format % (fp, fname)
199 fname_output_line = fname_output_format % (fp, fname)
175 except TypeError:
200 except TypeError:
176 # ... or just a single filepath
201 # ... or just a single filepath
177 fname_output_line = fname_output_format % fname
202 fname_output_line = fname_output_format % fname
178 output_lines.append(fname_output_line)
203 output_lines.append(fname_output_line)
179 return
204 return
180 return f
205 return f
181
206
182 def _get_notebook_display_formatter(self,
207 def _get_notebook_display_formatter(self,
183 spacer="&nbsp;&nbsp;"):
208 spacer="&nbsp;&nbsp;"):
184 """ """
209 """ generate func to pass to os.path.walk for notebook formatting
210 """
185 dirname_output_format = \
211 dirname_output_format = \
186 self.result_html_prefix + "%s" + self.result_html_suffix
212 self.result_html_prefix + "%s/" + self.result_html_suffix
187 fname_output_format = \
213 fname_output_format = \
188 self.result_html_prefix + spacer + self.html_link_str + self.result_html_suffix
214 self.result_html_prefix + spacer + self.html_link_str + self.result_html_suffix
189 fp_format = self.url_prefix + '%s/%s'
215 fp_format = self.url_prefix + '%s/%s'
190
216
191 return self._get_display_formatter(dirname_output_format,
217 return self._get_display_formatter(dirname_output_format,
192 fname_output_format,
218 fname_output_format,
193 fp_format)
219 fp_format)
194
220
195 def _get_terminal_display_formatter(self,
221 def _get_terminal_display_formatter(self,
196 spacer=" "):
222 spacer=" "):
197 """ """
223 """ generate func to pass to os.path.walk for terminal formatting
198 dirname_output_format = "%s"
224 """
225 dirname_output_format = "%s/"
199 fname_output_format = spacer + "%s"
226 fname_output_format = spacer + "%s"
200 fp_format = '%s/%s'
227 fp_format = '%s/%s'
201
228
202 return self._get_display_formatter(dirname_output_format,
229 return self._get_display_formatter(dirname_output_format,
203 fname_output_format,
230 fname_output_format,
204 fp_format)
231 fp_format)
205
232
206 def _format_path(self):
233 def _format_path(self):
207 result_lines = []
234 result_lines = []
208 walk(self.path, self.notebook_display_formatter, result_lines)
235 walk(self.path, self.notebook_display_formatter, result_lines)
209 return '\n'.join(result_lines)
236 return '\n'.join(result_lines)
210
237
211 def __repr__(self):
238 def __repr__(self):
212 """return newline-separated absolute paths
239 """return newline-separated absolute paths
213 """
240 """
214 result_lines = []
241 result_lines = []
215 walk(self.path, self.terminal_display_formatter, result_lines)
242 walk(self.path, self.terminal_display_formatter, result_lines)
216 return '\n'.join(result_lines) No newline at end of file
243 return '\n'.join(result_lines)
@@ -1,120 +1,120 b''
1 """Tests for IPython.lib.display.
1 """Tests for IPython.lib.display.
2
2
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2012, the IPython Development Team.
5 # Copyright (c) 2012, the IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 from __future__ import print_function
15 from __future__ import print_function
16 from tempfile import NamedTemporaryFile, mkdtemp
16 from tempfile import NamedTemporaryFile, mkdtemp
17 from os.path import split
17 from os.path import split
18
18
19 # Third-party imports
19 # Third-party imports
20 import nose.tools as nt
20 import nose.tools as nt
21
21
22 # Our own imports
22 # Our own imports
23 from IPython.lib import display
23 from IPython.lib import display
24
24
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 # Classes and functions
26 # Classes and functions
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28
28
29 #--------------------------
29 #--------------------------
30 # FileLink tests
30 # FileLink tests
31 #--------------------------
31 #--------------------------
32
32
33 def test_instantiation_FileLink():
33 def test_instantiation_FileLink():
34 """Test classes can be instantiated"""
34 """Test classes can be instantiated"""
35 fl = display.FileLink('example.txt')
35 fl = display.FileLink('example.txt')
36
36
37 def test_warning_on_non_existant_path_FileLink():
37 def test_warning_on_non_existant_path_FileLink():
38 """Calling _repr_html_ on non-existant files returns a warning"""
38 """Calling _repr_html_ on non-existant files returns a warning"""
39 fl = display.FileLink('example.txt')
39 fl = display.FileLink('example.txt')
40 nt.assert_true(fl._repr_html_().startswith('Path (<tt>example.txt</tt>)'))
40 nt.assert_true(fl._repr_html_().startswith('Path (<tt>example.txt</tt>)'))
41
41
42 def test_existing_path_FileLink():
42 def test_existing_path_FileLink():
43 """ Calling _repr_html_ functions as expected on existing filepath """
43 """ Calling _repr_html_ functions as expected on existing filepath """
44 tf = NamedTemporaryFile()
44 tf = NamedTemporaryFile()
45 fl = display.FileLink(tf.name)
45 fl = display.FileLink(tf.name)
46 actual = fl._repr_html_()
46 actual = fl._repr_html_()
47 expected = "<a href='files/%s' target='_blank'>%s</a><br>" % (tf.name,tf.name)
47 expected = "<a href='files/%s' target='_blank'>%s</a><br>" % (tf.name,tf.name)
48 nt.assert_equal(actual,expected)
48 nt.assert_equal(actual,expected)
49
49
50 def test_existing_path_FileLink_repr():
50 def test_existing_path_FileLink_repr():
51 """ Calling repr() functions as expected on existing filepath """
51 """ Calling repr() functions as expected on existing filepath """
52 tf = NamedTemporaryFile()
52 tf = NamedTemporaryFile()
53 fl = display.FileLink(tf.name)
53 fl = display.FileLink(tf.name)
54 actual = repr(fl)
54 actual = repr(fl)
55 expected = tf.name
55 expected = tf.name
56 nt.assert_equal(actual,expected)
56 nt.assert_equal(actual,expected)
57
57
58 #--------------------------
58 #--------------------------
59 # FileLinks tests
59 # FileLinks tests
60 #--------------------------
60 #--------------------------
61
61
62 def test_instantiation_FileLinks():
62 def test_instantiation_FileLinks():
63 """Test classes can be instantiated"""
63 """Test classes can be instantiated"""
64 fls = display.FileLinks('example')
64 fls = display.FileLinks('example')
65
65
66 def test_warning_on_non_existant_path_FileLinks():
66 def test_warning_on_non_existant_path_FileLinks():
67 """Calling _repr_html_ on non-existant files returns a warning"""
67 """Calling _repr_html_ on non-existant files returns a warning"""
68 fls = display.FileLinks('example')
68 fls = display.FileLinks('example')
69 nt.assert_true(fls._repr_html_().startswith('Path (<tt>example</tt>)'))
69 nt.assert_true(fls._repr_html_().startswith('Path (<tt>example</tt>)'))
70
70
71 def test_existing_path_FileLinks():
71 def test_existing_path_FileLinks():
72 """ Calling _repr_html_ functions as expected on existing directory """
72 """ Calling _repr_html_ functions as expected on existing directory """
73 td = mkdtemp()
73 td = mkdtemp()
74 tf1 = NamedTemporaryFile(dir=td)
74 tf1 = NamedTemporaryFile(dir=td)
75 tf2 = NamedTemporaryFile(dir=td)
75 tf2 = NamedTemporaryFile(dir=td)
76 fl = display.FileLinks(td)
76 fl = display.FileLinks(td)
77 actual = fl._repr_html_()
77 actual = fl._repr_html_()
78 actual = actual.split('\n')
78 actual = actual.split('\n')
79 actual.sort()
79 actual.sort()
80 expected = ["%s<br>" % td,
80 expected = ["%s/<br>" % td,
81 "&nbsp;&nbsp;<a href='files/%s' target='_blank'>%s</a><br>" % (tf2.name,split(tf2.name)[1]),
81 "&nbsp;&nbsp;<a href='files/%s' target='_blank'>%s</a><br>" % (tf2.name,split(tf2.name)[1]),
82 "&nbsp;&nbsp;<a href='files/%s' target='_blank'>%s</a><br>" % (tf1.name,split(tf1.name)[1])]
82 "&nbsp;&nbsp;<a href='files/%s' target='_blank'>%s</a><br>" % (tf1.name,split(tf1.name)[1])]
83 expected.sort()
83 expected.sort()
84 # We compare the sorted list of links here as that's more reliable
84 # We compare the sorted list of links here as that's more reliable
85 nt.assert_equal(actual,expected)
85 nt.assert_equal(actual,expected)
86
86
87 def test_existing_path_FileLinks_repr():
87 def test_existing_path_FileLinks_repr():
88 """ Calling repr() functions as expected on existing directory """
88 """ Calling repr() functions as expected on existing directory """
89 td = mkdtemp()
89 td = mkdtemp()
90 tf1 = NamedTemporaryFile(dir=td)
90 tf1 = NamedTemporaryFile(dir=td)
91 tf2 = NamedTemporaryFile(dir=td)
91 tf2 = NamedTemporaryFile(dir=td)
92 fl = display.FileLinks(td)
92 fl = display.FileLinks(td)
93 actual = repr(fl)
93 actual = repr(fl)
94 actual = actual.split('\n')
94 actual = actual.split('\n')
95 actual.sort()
95 actual.sort()
96 expected = [td, ' %s' % split(tf1.name)[1],' %s' % split(tf2.name)[1]]
96 expected = ['%s/' % td, ' %s' % split(tf1.name)[1],' %s' % split(tf2.name)[1]]
97 expected.sort()
97 expected.sort()
98 # We compare the sorted list of links here as that's more reliable
98 # We compare the sorted list of links here as that's more reliable
99 nt.assert_equal(actual,expected)
99 nt.assert_equal(actual,expected)
100
100
101 #--------------------------
101 #--------------------------
102 # DirectoryLink tests
102 # DirectoryLink tests
103 #--------------------------
103 #--------------------------
104
104
105 def test_instantiation_DirectoryLink():
105 def test_instantiation_DirectoryLink():
106 """Test classes can be instantiated"""
106 """Test classes can be instantiated"""
107 dl = display.DirectoryLink('example')
107 dl = display.DirectoryLink('example')
108
108
109 def test_warning_on_non_existant_path_DirectoryLink():
109 def test_warning_on_non_existant_path_DirectoryLink():
110 """Calling _repr_html_ on non-existant files returns a warning"""
110 """Calling _repr_html_ on non-existant files returns a warning"""
111 dl = display.DirectoryLink('example')
111 dl = display.DirectoryLink('example')
112 nt.assert_true(dl._repr_html_().startswith('Path (<tt>example</tt>)'))
112 nt.assert_true(dl._repr_html_().startswith('Path (<tt>example</tt>)'))
113
113
114 def test_existing_path_DirectoryLink():
114 def test_existing_path_DirectoryLink():
115 """ Calling _repr_html_ functions as expected on existing directory """
115 """ Calling _repr_html_ functions as expected on existing directory """
116 td = mkdtemp()
116 td = mkdtemp()
117 dl = display.DirectoryLink(td)
117 dl = display.DirectoryLink(td)
118 actual = dl._repr_html_()
118 actual = dl._repr_html_()
119 expected = "<a href='files/%s' target='_blank'>%s</a><br>" % (td,td)
119 expected = "<a href='files/%s' target='_blank'>%s</a><br>" % (td,td)
120 nt.assert_equal(actual,expected)
120 nt.assert_equal(actual,expected)
General Comments 0
You need to be logged in to leave comments. Login now