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