##// END OF EJS Templates
this should address the failure in #2732...
Greg Caporaso -
Show More
@@ -1,287 +1,301 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 from os import walk
8 from os import walk, sep
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 if isdir(path):
89 89 raise ValueError,\
90 90 ("Cannot display a directory using FileLink. "
91 91 "Use FileLinks to display '%s'." % path)
92 92 self.path = path
93 93 self.url_prefix = url_prefix
94 94 self.result_html_prefix = result_html_prefix
95 95 self.result_html_suffix = result_html_suffix
96 96
97 97 def _format_path(self):
98 98 fp = ''.join([self.url_prefix,self.path])
99 99 return ''.join([self.result_html_prefix,
100 100 self.html_link_str % (fp, self.path),
101 101 self.result_html_suffix])
102 102
103 103 def _repr_html_(self):
104 104 """return html link to file
105 105 """
106 106 if not exists(self.path):
107 107 return ("Path (<tt>%s</tt>) doesn't exist. "
108 108 "It may still be in the process of "
109 109 "being generated, or you may have the "
110 110 "incorrect path." % self.path)
111 111
112 112 return self._format_path()
113 113
114 114 def __repr__(self):
115 115 """return absolute path to file
116 116 """
117 117 return abspath(self.path)
118 118
119 119 class FileLinks(FileLink):
120 120 """Class for embedding local file links in an IPython session, based on path
121 121
122 122 e.g. to embed links to files that were generated in the IPython notebook under my/data
123 123
124 124 you would do:
125 125
126 126 local_files = FileLinks("my/data")
127 127 display(local_files)
128 128
129 129 or in the HTML notebook, just
130 130
131 131 FileLinks("my/data")
132 132
133 133 """
134 134 def __init__(self,
135 135 path,
136 136 url_prefix='files/',
137 137 included_suffixes=None,
138 138 result_html_prefix='',
139 139 result_html_suffix='<br>',
140 140 notebook_display_formatter=None,
141 141 terminal_display_formatter=None):
142 142 """
143 143 included_suffixes : list of filename suffixes to include when
144 144 formatting output [default: include all files]
145 145
146 146 See the FileLink (baseclass of LocalDirectory) docstring for
147 147 information on additional parameters.
148 148
149 149 notebook_display_formatter : func used to format links for display
150 150 in the notebook. See discussion of formatter function below.
151 151
152 152 terminal_display_formatter : func used to format links for display
153 153 in the terminal. See discussion of formatter function below.
154 154
155 155
156 156 Passing custom formatter functions
157 157 ----------------------------------
158 158 Formatter functions must be of the form:
159 159 f(dirname, fnames, included_suffixes)
160 160 dirname : the name of a directory (a string),
161 161 fnames : a list of the files in that directory
162 162 included_suffixes : a list of the file suffixes that should be
163 163 included in the output (passing None means
164 164 to include all suffixes in the output in
165 165 the built-in formatters)
166 166
167 167 returns a list of lines that should will be print in the
168 168 notebook (if passing notebook_display_formatter) or the terminal
169 169 (if passing terminal_display_formatter). This function is iterated
170 170 over for each directory in self.path. Default formatters are in
171 171 place, can be passed here to support alternative formatting.
172 172
173 173 """
174 174 if isfile(path):
175 175 raise ValueError,\
176 176 ("Cannot display a file using FileLinks. "
177 177 "Use FileLink to display '%s'." % path)
178 178 self.included_suffixes = included_suffixes
179 179 # remove trailing slashs for more consistent output formatting
180 180 path = path.rstrip('/')
181 181
182 182 self.path = path
183 183 self.url_prefix = url_prefix
184 184 self.result_html_prefix = result_html_prefix
185 185 self.result_html_suffix = result_html_suffix
186 186
187 187 self.notebook_display_formatter = \
188 188 notebook_display_formatter or self._get_notebook_display_formatter()
189 189 self.terminal_display_formatter = \
190 190 terminal_display_formatter or self._get_terminal_display_formatter()
191 191
192 192 def _get_display_formatter(self,
193 193 dirname_output_format,
194 194 fname_output_format,
195 fp_format):
195 fp_format,
196 fp_cleaner=None):
196 197 """ generate built-in formatter function
197 198
198 199 this is used to define both the notebook and terminal built-in
199 200 formatters as they only differ by some wrapper text for each entry
200 201
201 202 dirname_output_format: string to use for formatting directory
202 203 names, dirname will be substituted for a single "%s" which
203 204 must appear in this string
204 205 fname_output_format: string to use for formatting file names,
205 206 if a single "%s" appears in the string, fname will be substituted
206 207 if two "%s" appear in the string, the path to fname will be
207 208 substituted for the first and fname will be substituted for the
208 209 second
209 210 fp_format: string to use for formatting filepaths, must contain
210 211 exactly two "%s" and the dirname will be subsituted for the first
211 212 and fname will be substituted for the second
212 213 """
213 214 def f(dirname, fnames, included_suffixes=None):
214 215 result = []
215 216 # begin by figuring out which filenames, if any,
216 217 # are going to be displayed
217 218 display_fnames = []
218 219 for fname in fnames:
219 220 if (isfile(join(dirname,fname)) and
220 221 (included_suffixes == None or
221 222 splitext(fname)[1] in included_suffixes)):
222 223 display_fnames.append(fname)
223 224
224 225 if len(display_fnames) == 0:
225 226 # if there are no filenames to display, don't print anything
226 227 # (not even the directory name)
227 228 pass
228 229 else:
229 230 # otherwise print the formatted directory name followed by
230 231 # the formatted filenames
231 232 dirname_output_line = dirname_output_format % dirname
232 233 result.append(dirname_output_line)
233 234 for fname in display_fnames:
234 235 fp = fp_format % (dirname,fname)
236 if fp_cleaner != None:
237 fp = fp_cleaner(fp)
235 238 try:
236 239 # output can include both a filepath and a filename...
237 240 fname_output_line = fname_output_format % (fp, fname)
238 241 except TypeError:
239 242 # ... or just a single filepath
240 243 fname_output_line = fname_output_format % fname
241 244 result.append(fname_output_line)
242 245 return result
243 246 return f
244 247
245 248 def _get_notebook_display_formatter(self,
246 249 spacer="&nbsp;&nbsp;"):
247 250 """ generate function to use for notebook formatting
248 251 """
249 252 dirname_output_format = \
250 253 self.result_html_prefix + "%s/" + self.result_html_suffix
251 254 fname_output_format = \
252 255 self.result_html_prefix + spacer + self.html_link_str + self.result_html_suffix
253 256 fp_format = self.url_prefix + '%s/%s'
257 if sep == "\\":
258 # Working on a platform where the path separator is "\", so
259 # must convert these to "/" for generating a URI
260 def fp_cleaner(fp):
261 # Replace all occurences of backslash ("\") with a forward
262 # slash ("/") - this is necessary on windows when a path is
263 # provided as input, but we must link to a URI
264 return fp.replace('\\','/')
265 else:
266 fp_cleaner = None
254 267
255 268 return self._get_display_formatter(dirname_output_format,
256 269 fname_output_format,
257 fp_format)
270 fp_format,
271 fp_cleaner)
258 272
259 273 def _get_terminal_display_formatter(self,
260 274 spacer=" "):
261 275 """ generate function to use for terminal formatting
262 276 """
263 277 dirname_output_format = "%s/"
264 278 fname_output_format = spacer + "%s"
265 279 fp_format = '%s/%s'
266 280
267 281 return self._get_display_formatter(dirname_output_format,
268 282 fname_output_format,
269 283 fp_format)
270 284
271 285 def _format_path(self):
272 286 result_lines = []
273 287 walked_dir = list(walk(self.path))
274 288 walked_dir.sort()
275 289 for dirname, subdirs, fnames in walked_dir:
276 290 result_lines += self.notebook_display_formatter(dirname, fnames, self.included_suffixes)
277 291 return '\n'.join(result_lines)
278 292
279 293 def __repr__(self):
280 294 """return newline-separated absolute paths
281 295 """
282 296 result_lines = []
283 297 walked_dir = list(walk(self.path))
284 298 walked_dir.sort()
285 299 for dirname, subdirs, fnames in walked_dir:
286 300 result_lines += self.terminal_display_formatter(dirname, fnames, self.included_suffixes)
287 301 return '\n'.join(result_lines)
@@ -1,153 +1,158 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 from os import sep
18 19
19 20 # Third-party imports
20 21 import nose.tools as nt
21 22
22 23 # Our own imports
23 24 from IPython.lib import display
24 25
25 26 #-----------------------------------------------------------------------------
26 27 # Classes and functions
27 28 #-----------------------------------------------------------------------------
28 29
29 30 #--------------------------
30 31 # FileLink tests
31 32 #--------------------------
32 33
33 34 def test_instantiation_FileLink():
34 35 """FileLink: Test class can be instantiated"""
35 36 fl = display.FileLink('example.txt')
36 37
37 38 def test_warning_on_non_existant_path_FileLink():
38 39 """FileLink: Calling _repr_html_ on non-existant files returns a warning
39 40 """
40 41 fl = display.FileLink('example.txt')
41 42 nt.assert_true(fl._repr_html_().startswith('Path (<tt>example.txt</tt>)'))
42 43
43 44 def test_existing_path_FileLink():
44 45 """FileLink: Calling _repr_html_ functions as expected on existing filepath
45 46 """
46 47 tf = NamedTemporaryFile()
47 48 fl = display.FileLink(tf.name)
48 49 actual = fl._repr_html_()
49 50 expected = "<a href='files/%s' target='_blank'>%s</a><br>" % (tf.name,tf.name)
50 51 nt.assert_equal(actual,expected)
51 52
52 53 def test_existing_path_FileLink_repr():
53 54 """FileLink: Calling repr() functions as expected on existing filepath
54 55 """
55 56 tf = NamedTemporaryFile()
56 57 fl = display.FileLink(tf.name)
57 58 actual = repr(fl)
58 59 expected = tf.name
59 60 nt.assert_equal(actual,expected)
60 61
61 62 def test_error_on_directory_to_FileLink():
62 63 """FileLink: Raises error when passed directory
63 64 """
64 65 td = mkdtemp()
65 66 nt.assert_raises(ValueError,display.FileLink,td)
66 67
67 68 #--------------------------
68 69 # FileLinks tests
69 70 #--------------------------
70 71
71 72 def test_instantiation_FileLinks():
72 73 """FileLinks: Test class can be instantiated
73 74 """
74 75 fls = display.FileLinks('example')
75 76
76 77 def test_warning_on_non_existant_path_FileLinks():
77 78 """FileLinks: Calling _repr_html_ on non-existant files returns a warning
78 79 """
79 80 fls = display.FileLinks('example')
80 81 nt.assert_true(fls._repr_html_().startswith('Path (<tt>example</tt>)'))
81 82
82 83 def test_existing_path_FileLinks():
83 84 """FileLinks: Calling _repr_html_ functions as expected on existing dir
84 85 """
85 86 td = mkdtemp()
86 87 tf1 = NamedTemporaryFile(dir=td)
87 88 tf2 = NamedTemporaryFile(dir=td)
88 89 fl = display.FileLinks(td)
89 90 actual = fl._repr_html_()
90 91 actual = actual.split('\n')
91 92 actual.sort()
93 # the links should always have forward slashes, even on windows, so replace
94 # backslashes with forward slashes here
92 95 expected = ["%s/<br>" % td,
93 "&nbsp;&nbsp;<a href='files/%s' target='_blank'>%s</a><br>" % (tf2.name,split(tf2.name)[1]),
94 "&nbsp;&nbsp;<a href='files/%s' target='_blank'>%s</a><br>" % (tf1.name,split(tf1.name)[1])]
96 "&nbsp;&nbsp;<a href='files/%s' target='_blank'>%s</a><br>" %\
97 (tf2.name.replace("\\","/"),split(tf2.name)[1]),
98 "&nbsp;&nbsp;<a href='files/%s' target='_blank'>%s</a><br>" %\
99 (tf1.name.replace("\\","/"),split(tf1.name)[1])]
95 100 expected.sort()
96 101 # We compare the sorted list of links here as that's more reliable
97 102 nt.assert_equal(actual,expected)
98 103
99 104 def test_existing_path_FileLinks_alt_formatter():
100 105 """FileLinks: Calling _repr_html_ functions as expected w/ an alt formatter
101 106 """
102 107 td = mkdtemp()
103 108 tf1 = NamedTemporaryFile(dir=td)
104 109 tf2 = NamedTemporaryFile(dir=td)
105 110 def fake_formatter(dirname,fnames,included_suffixes):
106 111 return ["hello","world"]
107 112 fl = display.FileLinks(td,notebook_display_formatter=fake_formatter)
108 113 actual = fl._repr_html_()
109 114 actual = actual.split('\n')
110 115 actual.sort()
111 116 expected = ["hello","world"]
112 117 expected.sort()
113 118 # We compare the sorted list of links here as that's more reliable
114 119 nt.assert_equal(actual,expected)
115 120
116 121 def test_existing_path_FileLinks_repr():
117 122 """FileLinks: Calling repr() functions as expected on existing directory """
118 123 td = mkdtemp()
119 124 tf1 = NamedTemporaryFile(dir=td)
120 125 tf2 = NamedTemporaryFile(dir=td)
121 126 fl = display.FileLinks(td)
122 127 actual = repr(fl)
123 128 actual = actual.split('\n')
124 129 actual.sort()
125 130 expected = ['%s/' % td, ' %s' % split(tf1.name)[1],' %s' % split(tf2.name)[1]]
126 131 expected.sort()
127 132 # We compare the sorted list of links here as that's more reliable
128 133 nt.assert_equal(actual,expected)
129 134
130 135 def test_existing_path_FileLinks_repr_alt_formatter():
131 136 """FileLinks: Calling repr() functions as expected w/ alt formatter
132 137 """
133 138 td = mkdtemp()
134 139 tf1 = NamedTemporaryFile(dir=td)
135 140 tf2 = NamedTemporaryFile(dir=td)
136 141 def fake_formatter(dirname,fnames,included_suffixes):
137 142 return ["hello","world"]
138 143 fl = display.FileLinks(td,terminal_display_formatter=fake_formatter)
139 144 actual = repr(fl)
140 145 actual = actual.split('\n')
141 146 actual.sort()
142 147 expected = ["hello","world"]
143 148 expected.sort()
144 149 # We compare the sorted list of links here as that's more reliable
145 150 nt.assert_equal(actual,expected)
146 151
147 152 def test_error_on_file_to_FileLinks():
148 153 """FileLinks: Raises error when passed file
149 154 """
150 155 td = mkdtemp()
151 156 tf1 = NamedTemporaryFile(dir=td)
152 157 nt.assert_raises(ValueError,display.FileLinks,tf1.name)
153 158
General Comments 0
You need to be logged in to leave comments. Login now