##// END OF EJS Templates
Fix talk about image embeding in the Audio class....
David Österberg -
Show More
@@ -1,487 +1,487 b''
1 """Various display related classes.
1 """Various display related classes.
2
2
3 Authors : MinRK, gregcaporaso, dannystaple
3 Authors : MinRK, gregcaporaso, dannystaple
4 """
4 """
5 from os.path import exists, isfile, splitext, abspath, join, isdir
5 from os.path import exists, isfile, splitext, abspath, join, isdir
6 from os import walk, sep
6 from os import walk, sep
7
7
8 from IPython.core.display import DisplayObject
8 from IPython.core.display import DisplayObject
9
9
10
10
11 class Audio(DisplayObject):
11 class Audio(DisplayObject):
12 """Create an audio object.
12 """Create an audio object.
13
13
14 When this object is returned by an input cell or passed to the
14 When this object is returned by an input cell or passed to the
15 display function, it will result in Audio controls being displayed
15 display function, it will result in Audio controls being displayed
16 in the frontend (only works in the notebook).
16 in the frontend (only works in the notebook).
17
17
18 Parameters
18 Parameters
19 ----------
19 ----------
20 data : numpy array, unicode, str or bytes
20 data : numpy array, unicode, str or bytes
21 Can be a
21 Can be a
22 * Numpy array containing the desired waveform,
22 * Numpy array containing the desired waveform,
23 * String containing the filename
23 * String containing the filename
24 * Bytestring containing raw PCM data or
24 * Bytestring containing raw PCM data or
25 * URL pointing to a file on the web.
25 * URL pointing to a file on the web.
26
26
27 If the array option is used the waveform will be normalized.
27 If the array option is used the waveform will be normalized.
28
28
29 If a filename or url is used the format support will be browser
29 If a filename or url is used the format support will be browser
30 dependent.
30 dependent.
31 url : unicode
31 url : unicode
32 A URL to download the data from.
32 A URL to download the data from.
33 filename : unicode
33 filename : unicode
34 Path to a local file to load the data from.
34 Path to a local file to load the data from.
35 embed : boolean
35 embed : boolean
36 Should the image data be embedded using a data URI (True) or be
36 Should the image data be embedded using a data URI (True) or should
37 loaded using an <img> tag. Set this to True if you want the image
37 the original source be referenced. Set this to True if you want the
38 to be viewable later with no internet connection in the notebook.
38 audio to playable later with no internet connection in the notebook.
39
39
40 Default is `True`, unless the keyword argument `url` is set, then
40 Default is `True`, unless the keyword argument `url` is set, then
41 default value is `False`.
41 default value is `False`.
42 rate : integer
42 rate : integer
43 The sampling rate of the raw data.
43 The sampling rate of the raw data.
44 Only required when data parameter is being used as an array
44 Only required when data parameter is being used as an array
45 autoplay : bool
45 autoplay : bool
46 Set to True if the audio should immediately start playing.
46 Set to True if the audio should immediately start playing.
47 Default is `False`.
47 Default is `False`.
48
48
49 Examples
49 Examples
50 --------
50 --------
51
51
52 # Generate a sound
52 # Generate a sound
53 import numpy as np
53 import numpy as np
54 framerate = 44100
54 framerate = 44100
55 t = np.linspace(0,5,framerate*5)
55 t = np.linspace(0,5,framerate*5)
56 data = np.sin(2*np.pi*440*np.sin(10*t**2))
56 data = np.sin(2*np.pi*440*np.sin(10*t**2))
57 Audio(data,rate=framerate)
57 Audio(data,rate=framerate)
58
58
59 Audio("http://www.nch.com.au/acm/8k16bitpcm.wav")
59 Audio("http://www.nch.com.au/acm/8k16bitpcm.wav")
60 Audio(url="http://media.bradsucks.net/albums/ooi-128/01_-_Brad_Sucks_-_Dropping_out_of_School.mp3")
60 Audio(url="http://media.bradsucks.net/albums/ooi-128/01_-_Brad_Sucks_-_Dropping_out_of_School.mp3")
61 Audio(url="http://www.w3schools.com/html/horse.ogg", embed=True)
61 Audio(url="http://www.w3schools.com/html/horse.ogg", embed=True)
62
62
63 Audio('/path/to/sound.wav')
63 Audio('/path/to/sound.wav')
64 Audio(filename='/path/to/sound.ogg')
64 Audio(filename='/path/to/sound.ogg')
65
65
66 Audio(b'RAW_WAV_DATA..)
66 Audio(b'RAW_WAV_DATA..)
67 Audio(data=b'RAW_WAV_DATA..)
67 Audio(data=b'RAW_WAV_DATA..)
68
68
69 """
69 """
70
70
71 def __init__(self, data=None, filename=None, url=None, embed=None, rate=None, autoplay=False):
71 def __init__(self, data=None, filename=None, url=None, embed=None, rate=None, autoplay=False):
72 if filename is None and url is None and data is None:
72 if filename is None and url is None and data is None:
73 raise ValueError("No image data found. Expecting filename, url, or data.")
73 raise ValueError("No image data found. Expecting filename, url, or data.")
74 if embed is False and url is None:
74 if embed is False and url is None:
75 raise ValueError("No url found. Expecting url when embed=False")
75 raise ValueError("No url found. Expecting url when embed=False")
76
76
77 if url is not None and embed is not True:
77 if url is not None and embed is not True:
78 self.embed = False
78 self.embed = False
79 else:
79 else:
80 self.embed = True
80 self.embed = True
81 self.autoplay = autoplay
81 self.autoplay = autoplay
82 super(Audio, self).__init__(data=data, url=url, filename=filename)
82 super(Audio, self).__init__(data=data, url=url, filename=filename)
83
83
84 if self.data is not None and not isinstance(self.data, bytes):
84 if self.data is not None and not isinstance(self.data, bytes):
85 self.data = self._make_wav(data,rate)
85 self.data = self._make_wav(data,rate)
86
86
87 def reload(self):
87 def reload(self):
88 """Reload the raw data from file or URL."""
88 """Reload the raw data from file or URL."""
89 import mimetypes
89 import mimetypes
90 if self.embed:
90 if self.embed:
91 super(Audio, self).reload()
91 super(Audio, self).reload()
92
92
93 if self.filename is not None:
93 if self.filename is not None:
94 self.mimetype = mimetypes.guess_type(self.filename)[0]
94 self.mimetype = mimetypes.guess_type(self.filename)[0]
95 elif self.url is not None:
95 elif self.url is not None:
96 self.mimetype = mimetypes.guess_type(self.url)[0]
96 self.mimetype = mimetypes.guess_type(self.url)[0]
97 else:
97 else:
98 self.mimetype = "audio/wav"
98 self.mimetype = "audio/wav"
99
99
100
100
101 def _make_wav(self,data,rate):
101 def _make_wav(self,data,rate):
102 """ Transform a numpy array to a PCM bytestring """
102 """ Transform a numpy array to a PCM bytestring """
103 import struct
103 import struct
104 from io import BytesIO
104 from io import BytesIO
105 import wave
105 import wave
106 maxabsvalue = max(map(abs,data))
106 maxabsvalue = max(map(abs,data))
107 scaled = map(lambda x: int(x/maxabsvalue*32767), data)
107 scaled = map(lambda x: int(x/maxabsvalue*32767), data)
108 fp = BytesIO()
108 fp = BytesIO()
109 waveobj = wave.open(fp,mode='wb')
109 waveobj = wave.open(fp,mode='wb')
110 waveobj.setnchannels(1)
110 waveobj.setnchannels(1)
111 waveobj.setframerate(rate)
111 waveobj.setframerate(rate)
112 waveobj.setsampwidth(2)
112 waveobj.setsampwidth(2)
113 waveobj.setcomptype('NONE','NONE')
113 waveobj.setcomptype('NONE','NONE')
114 waveobj.writeframes(b''.join([struct.pack('<h',x) for x in scaled]))
114 waveobj.writeframes(b''.join([struct.pack('<h',x) for x in scaled]))
115 val = fp.getvalue()
115 val = fp.getvalue()
116 waveobj.close()
116 waveobj.close()
117 return val
117 return val
118
118
119 def _data_and_metadata(self):
119 def _data_and_metadata(self):
120 """shortcut for returning metadata with url information, if defined"""
120 """shortcut for returning metadata with url information, if defined"""
121 md = {}
121 md = {}
122 if self.url:
122 if self.url:
123 md['url'] = self.url
123 md['url'] = self.url
124 if md:
124 if md:
125 return self.data, md
125 return self.data, md
126 else:
126 else:
127 return self.data
127 return self.data
128
128
129 def _repr_html_(self):
129 def _repr_html_(self):
130 src = """
130 src = """
131 <audio controls="controls" {autoplay}>
131 <audio controls="controls" {autoplay}>
132 <source src="{src}" type="{type}" />
132 <source src="{src}" type="{type}" />
133 Your browser does not support the audio element.
133 Your browser does not support the audio element.
134 </audio>
134 </audio>
135 """
135 """
136 return src.format(src=self.src_attr(),type=self.mimetype, autoplay=self.autoplay_attr())
136 return src.format(src=self.src_attr(),type=self.mimetype, autoplay=self.autoplay_attr())
137
137
138 def src_attr(self):
138 def src_attr(self):
139 import base64
139 import base64
140 if self.embed and (self.data is not None):
140 if self.embed and (self.data is not None):
141 return """data:{type};base64,{base64}""".format(type=self.mimetype, base64=base64.encodestring(self.data))
141 return """data:{type};base64,{base64}""".format(type=self.mimetype, base64=base64.encodestring(self.data))
142 elif self.url is not None:
142 elif self.url is not None:
143 return self.url
143 return self.url
144 else:
144 else:
145 return ""
145 return ""
146
146
147 def autoplay_attr(self):
147 def autoplay_attr(self):
148 if(self.autoplay):
148 if(self.autoplay):
149 return 'autoplay="autoplay"'
149 return 'autoplay="autoplay"'
150 else:
150 else:
151 return ''
151 return ''
152
152
153 class IFrame(object):
153 class IFrame(object):
154 """
154 """
155 Generic class to embed an iframe in an IPython notebook
155 Generic class to embed an iframe in an IPython notebook
156 """
156 """
157
157
158 iframe = """
158 iframe = """
159 <iframe
159 <iframe
160 width="{width}"
160 width="{width}"
161 height={height}"
161 height={height}"
162 src="{src}{params}"
162 src="{src}{params}"
163 frameborder="0"
163 frameborder="0"
164 allowfullscreen
164 allowfullscreen
165 ></iframe>
165 ></iframe>
166 """
166 """
167
167
168 def __init__(self, src, width, height, **kwargs):
168 def __init__(self, src, width, height, **kwargs):
169 self.src = src
169 self.src = src
170 self.width = width
170 self.width = width
171 self.height = height
171 self.height = height
172 self.params = kwargs
172 self.params = kwargs
173
173
174 def _repr_html_(self):
174 def _repr_html_(self):
175 """return the embed iframe"""
175 """return the embed iframe"""
176 if self.params:
176 if self.params:
177 from urllib import urlencode
177 from urllib import urlencode
178 params = "?" + urlencode(self.params)
178 params = "?" + urlencode(self.params)
179 else:
179 else:
180 params = ""
180 params = ""
181 return self.iframe.format(src=self.src,
181 return self.iframe.format(src=self.src,
182 width=self.width,
182 width=self.width,
183 height=self.height,
183 height=self.height,
184 params=params)
184 params=params)
185
185
186 class YouTubeVideo(IFrame):
186 class YouTubeVideo(IFrame):
187 """Class for embedding a YouTube Video in an IPython session, based on its video id.
187 """Class for embedding a YouTube Video in an IPython session, based on its video id.
188
188
189 e.g. to embed the video on this page:
189 e.g. to embed the video on this page:
190
190
191 http://www.youtube.com/watch?v=foo
191 http://www.youtube.com/watch?v=foo
192
192
193 you would do:
193 you would do:
194
194
195 vid = YouTubeVideo("foo")
195 vid = YouTubeVideo("foo")
196 display(vid)
196 display(vid)
197
197
198 To start from 30 seconds:
198 To start from 30 seconds:
199
199
200 vid = YouTubeVideo("abc", start=30)
200 vid = YouTubeVideo("abc", start=30)
201 display(vid)
201 display(vid)
202
202
203 To calculate seconds from time as hours, minutes, seconds use:
203 To calculate seconds from time as hours, minutes, seconds use:
204 start=int(timedelta(hours=1, minutes=46, seconds=40).total_seconds())
204 start=int(timedelta(hours=1, minutes=46, seconds=40).total_seconds())
205
205
206 Other parameters can be provided as documented at
206 Other parameters can be provided as documented at
207 https://developers.google.com/youtube/player_parameters#parameter-subheader
207 https://developers.google.com/youtube/player_parameters#parameter-subheader
208 """
208 """
209
209
210 def __init__(self, id, width=400, height=300, **kwargs):
210 def __init__(self, id, width=400, height=300, **kwargs):
211 src = "http://www.youtube.com/embed/{0}".format(id)
211 src = "http://www.youtube.com/embed/{0}".format(id)
212 super(YouTubeVideo, self).__init__(src, width, height, **kwargs)
212 super(YouTubeVideo, self).__init__(src, width, height, **kwargs)
213
213
214 class VimeoVideo(IFrame):
214 class VimeoVideo(IFrame):
215 """
215 """
216 Class for embedding a Vimeo video in an IPython session, based on its video id.
216 Class for embedding a Vimeo video in an IPython session, based on its video id.
217 """
217 """
218
218
219 def __init__(self, id, width=400, height=300, **kwargs):
219 def __init__(self, id, width=400, height=300, **kwargs):
220 src="http://player.vimeo.com/video/{0}".format(id)
220 src="http://player.vimeo.com/video/{0}".format(id)
221 super(VimeoVideo, self).__init__(src, width, height, **kwargs)
221 super(VimeoVideo, self).__init__(src, width, height, **kwargs)
222
222
223 class ScribdDocument(IFrame):
223 class ScribdDocument(IFrame):
224 """
224 """
225 Class for embedding a Scribd document in an IPython session
225 Class for embedding a Scribd document in an IPython session
226
226
227 Use the start_page params to specify a starting point in the document
227 Use the start_page params to specify a starting point in the document
228 Use the view_mode params to specify display type one off scroll | slideshow | book
228 Use the view_mode params to specify display type one off scroll | slideshow | book
229
229
230 e.g to Display Wes' foundational paper about PANDAS in book mode from page 3
230 e.g to Display Wes' foundational paper about PANDAS in book mode from page 3
231
231
232 ScribdDocument(71048089, width=800, height=400, start_page=3, view_mode="book")
232 ScribdDocument(71048089, width=800, height=400, start_page=3, view_mode="book")
233 """
233 """
234
234
235 def __init__(self, id, width=400, height=300, **kwargs):
235 def __init__(self, id, width=400, height=300, **kwargs):
236 src="http://www.scribd.com/embeds/{0}/content".format(id)
236 src="http://www.scribd.com/embeds/{0}/content".format(id)
237 super(ScribdDocument, self).__init__(src, width, height, **kwargs)
237 super(ScribdDocument, self).__init__(src, width, height, **kwargs)
238
238
239 class FileLink(object):
239 class FileLink(object):
240 """Class for embedding a local file link in an IPython session, based on path
240 """Class for embedding a local file link in an IPython session, based on path
241
241
242 e.g. to embed a link that was generated in the IPython notebook as my/data.txt
242 e.g. to embed a link that was generated in the IPython notebook as my/data.txt
243
243
244 you would do::
244 you would do::
245
245
246 local_file = FileLink("my/data.txt")
246 local_file = FileLink("my/data.txt")
247 display(local_file)
247 display(local_file)
248
248
249 or in the HTML notebook, just::
249 or in the HTML notebook, just::
250
250
251 FileLink("my/data.txt")
251 FileLink("my/data.txt")
252 """
252 """
253
253
254 html_link_str = "<a href='%s' target='_blank'>%s</a>"
254 html_link_str = "<a href='%s' target='_blank'>%s</a>"
255
255
256 def __init__(self,
256 def __init__(self,
257 path,
257 path,
258 url_prefix='files/',
258 url_prefix='files/',
259 result_html_prefix='',
259 result_html_prefix='',
260 result_html_suffix='<br>'):
260 result_html_suffix='<br>'):
261 """
261 """
262 Parameters
262 Parameters
263 ----------
263 ----------
264 path : str
264 path : str
265 path to the file or directory that should be formatted
265 path to the file or directory that should be formatted
266 directory_prefix : str
266 directory_prefix : str
267 prefix to be prepended to all files to form a working link [default:
267 prefix to be prepended to all files to form a working link [default:
268 'files']
268 'files']
269 result_html_prefix : str
269 result_html_prefix : str
270 text to append to beginning to link [default: none]
270 text to append to beginning to link [default: none]
271 result_html_suffix : str
271 result_html_suffix : str
272 text to append at the end of link [default: '<br>']
272 text to append at the end of link [default: '<br>']
273 """
273 """
274 if isdir(path):
274 if isdir(path):
275 raise ValueError,\
275 raise ValueError,\
276 ("Cannot display a directory using FileLink. "
276 ("Cannot display a directory using FileLink. "
277 "Use FileLinks to display '%s'." % path)
277 "Use FileLinks to display '%s'." % path)
278 self.path = path
278 self.path = path
279 self.url_prefix = url_prefix
279 self.url_prefix = url_prefix
280 self.result_html_prefix = result_html_prefix
280 self.result_html_prefix = result_html_prefix
281 self.result_html_suffix = result_html_suffix
281 self.result_html_suffix = result_html_suffix
282
282
283 def _format_path(self):
283 def _format_path(self):
284 fp = ''.join([self.url_prefix,self.path])
284 fp = ''.join([self.url_prefix,self.path])
285 return ''.join([self.result_html_prefix,
285 return ''.join([self.result_html_prefix,
286 self.html_link_str % (fp, self.path),
286 self.html_link_str % (fp, self.path),
287 self.result_html_suffix])
287 self.result_html_suffix])
288
288
289 def _repr_html_(self):
289 def _repr_html_(self):
290 """return html link to file
290 """return html link to file
291 """
291 """
292 if not exists(self.path):
292 if not exists(self.path):
293 return ("Path (<tt>%s</tt>) doesn't exist. "
293 return ("Path (<tt>%s</tt>) doesn't exist. "
294 "It may still be in the process of "
294 "It may still be in the process of "
295 "being generated, or you may have the "
295 "being generated, or you may have the "
296 "incorrect path." % self.path)
296 "incorrect path." % self.path)
297
297
298 return self._format_path()
298 return self._format_path()
299
299
300 def __repr__(self):
300 def __repr__(self):
301 """return absolute path to file
301 """return absolute path to file
302 """
302 """
303 return abspath(self.path)
303 return abspath(self.path)
304
304
305 class FileLinks(FileLink):
305 class FileLinks(FileLink):
306 """Class for embedding local file links in an IPython session, based on path
306 """Class for embedding local file links in an IPython session, based on path
307
307
308 e.g. to embed links to files that were generated in the IPython notebook under my/data
308 e.g. to embed links to files that were generated in the IPython notebook under my/data
309
309
310 you would do:
310 you would do:
311
311
312 local_files = FileLinks("my/data")
312 local_files = FileLinks("my/data")
313 display(local_files)
313 display(local_files)
314
314
315 or in the HTML notebook, just
315 or in the HTML notebook, just
316
316
317 FileLinks("my/data")
317 FileLinks("my/data")
318
318
319 """
319 """
320 def __init__(self,
320 def __init__(self,
321 path,
321 path,
322 url_prefix='files/',
322 url_prefix='files/',
323 included_suffixes=None,
323 included_suffixes=None,
324 result_html_prefix='',
324 result_html_prefix='',
325 result_html_suffix='<br>',
325 result_html_suffix='<br>',
326 notebook_display_formatter=None,
326 notebook_display_formatter=None,
327 terminal_display_formatter=None):
327 terminal_display_formatter=None):
328 """
328 """
329 included_suffixes : list of filename suffixes to include when
329 included_suffixes : list of filename suffixes to include when
330 formatting output [default: include all files]
330 formatting output [default: include all files]
331
331
332 See the FileLink (baseclass of LocalDirectory) docstring for
332 See the FileLink (baseclass of LocalDirectory) docstring for
333 information on additional parameters.
333 information on additional parameters.
334
334
335 notebook_display_formatter : func used to format links for display
335 notebook_display_formatter : func used to format links for display
336 in the notebook. See discussion of formatter function below.
336 in the notebook. See discussion of formatter function below.
337
337
338 terminal_display_formatter : func used to format links for display
338 terminal_display_formatter : func used to format links for display
339 in the terminal. See discussion of formatter function below.
339 in the terminal. See discussion of formatter function below.
340
340
341
341
342 Passing custom formatter functions
342 Passing custom formatter functions
343 ----------------------------------
343 ----------------------------------
344 Formatter functions must be of the form:
344 Formatter functions must be of the form:
345 f(dirname, fnames, included_suffixes)
345 f(dirname, fnames, included_suffixes)
346 dirname : the name of a directory (a string),
346 dirname : the name of a directory (a string),
347 fnames : a list of the files in that directory
347 fnames : a list of the files in that directory
348 included_suffixes : a list of the file suffixes that should be
348 included_suffixes : a list of the file suffixes that should be
349 included in the output (passing None means
349 included in the output (passing None means
350 to include all suffixes in the output in
350 to include all suffixes in the output in
351 the built-in formatters)
351 the built-in formatters)
352
352
353 returns a list of lines that should will be print in the
353 returns a list of lines that should will be print in the
354 notebook (if passing notebook_display_formatter) or the terminal
354 notebook (if passing notebook_display_formatter) or the terminal
355 (if passing terminal_display_formatter). This function is iterated
355 (if passing terminal_display_formatter). This function is iterated
356 over for each directory in self.path. Default formatters are in
356 over for each directory in self.path. Default formatters are in
357 place, can be passed here to support alternative formatting.
357 place, can be passed here to support alternative formatting.
358
358
359 """
359 """
360 if isfile(path):
360 if isfile(path):
361 raise ValueError,\
361 raise ValueError,\
362 ("Cannot display a file using FileLinks. "
362 ("Cannot display a file using FileLinks. "
363 "Use FileLink to display '%s'." % path)
363 "Use FileLink to display '%s'." % path)
364 self.included_suffixes = included_suffixes
364 self.included_suffixes = included_suffixes
365 # remove trailing slashs for more consistent output formatting
365 # remove trailing slashs for more consistent output formatting
366 path = path.rstrip('/')
366 path = path.rstrip('/')
367
367
368 self.path = path
368 self.path = path
369 self.url_prefix = url_prefix
369 self.url_prefix = url_prefix
370 self.result_html_prefix = result_html_prefix
370 self.result_html_prefix = result_html_prefix
371 self.result_html_suffix = result_html_suffix
371 self.result_html_suffix = result_html_suffix
372
372
373 self.notebook_display_formatter = \
373 self.notebook_display_formatter = \
374 notebook_display_formatter or self._get_notebook_display_formatter()
374 notebook_display_formatter or self._get_notebook_display_formatter()
375 self.terminal_display_formatter = \
375 self.terminal_display_formatter = \
376 terminal_display_formatter or self._get_terminal_display_formatter()
376 terminal_display_formatter or self._get_terminal_display_formatter()
377
377
378 def _get_display_formatter(self,
378 def _get_display_formatter(self,
379 dirname_output_format,
379 dirname_output_format,
380 fname_output_format,
380 fname_output_format,
381 fp_format,
381 fp_format,
382 fp_cleaner=None):
382 fp_cleaner=None):
383 """ generate built-in formatter function
383 """ generate built-in formatter function
384
384
385 this is used to define both the notebook and terminal built-in
385 this is used to define both the notebook and terminal built-in
386 formatters as they only differ by some wrapper text for each entry
386 formatters as they only differ by some wrapper text for each entry
387
387
388 dirname_output_format: string to use for formatting directory
388 dirname_output_format: string to use for formatting directory
389 names, dirname will be substituted for a single "%s" which
389 names, dirname will be substituted for a single "%s" which
390 must appear in this string
390 must appear in this string
391 fname_output_format: string to use for formatting file names,
391 fname_output_format: string to use for formatting file names,
392 if a single "%s" appears in the string, fname will be substituted
392 if a single "%s" appears in the string, fname will be substituted
393 if two "%s" appear in the string, the path to fname will be
393 if two "%s" appear in the string, the path to fname will be
394 substituted for the first and fname will be substituted for the
394 substituted for the first and fname will be substituted for the
395 second
395 second
396 fp_format: string to use for formatting filepaths, must contain
396 fp_format: string to use for formatting filepaths, must contain
397 exactly two "%s" and the dirname will be subsituted for the first
397 exactly two "%s" and the dirname will be subsituted for the first
398 and fname will be substituted for the second
398 and fname will be substituted for the second
399 """
399 """
400 def f(dirname, fnames, included_suffixes=None):
400 def f(dirname, fnames, included_suffixes=None):
401 result = []
401 result = []
402 # begin by figuring out which filenames, if any,
402 # begin by figuring out which filenames, if any,
403 # are going to be displayed
403 # are going to be displayed
404 display_fnames = []
404 display_fnames = []
405 for fname in fnames:
405 for fname in fnames:
406 if (isfile(join(dirname,fname)) and
406 if (isfile(join(dirname,fname)) and
407 (included_suffixes == None or
407 (included_suffixes == None or
408 splitext(fname)[1] in included_suffixes)):
408 splitext(fname)[1] in included_suffixes)):
409 display_fnames.append(fname)
409 display_fnames.append(fname)
410
410
411 if len(display_fnames) == 0:
411 if len(display_fnames) == 0:
412 # if there are no filenames to display, don't print anything
412 # if there are no filenames to display, don't print anything
413 # (not even the directory name)
413 # (not even the directory name)
414 pass
414 pass
415 else:
415 else:
416 # otherwise print the formatted directory name followed by
416 # otherwise print the formatted directory name followed by
417 # the formatted filenames
417 # the formatted filenames
418 dirname_output_line = dirname_output_format % dirname
418 dirname_output_line = dirname_output_format % dirname
419 result.append(dirname_output_line)
419 result.append(dirname_output_line)
420 for fname in display_fnames:
420 for fname in display_fnames:
421 fp = fp_format % (dirname,fname)
421 fp = fp_format % (dirname,fname)
422 if fp_cleaner is not None:
422 if fp_cleaner is not None:
423 fp = fp_cleaner(fp)
423 fp = fp_cleaner(fp)
424 try:
424 try:
425 # output can include both a filepath and a filename...
425 # output can include both a filepath and a filename...
426 fname_output_line = fname_output_format % (fp, fname)
426 fname_output_line = fname_output_format % (fp, fname)
427 except TypeError:
427 except TypeError:
428 # ... or just a single filepath
428 # ... or just a single filepath
429 fname_output_line = fname_output_format % fname
429 fname_output_line = fname_output_format % fname
430 result.append(fname_output_line)
430 result.append(fname_output_line)
431 return result
431 return result
432 return f
432 return f
433
433
434 def _get_notebook_display_formatter(self,
434 def _get_notebook_display_formatter(self,
435 spacer="&nbsp;&nbsp;"):
435 spacer="&nbsp;&nbsp;"):
436 """ generate function to use for notebook formatting
436 """ generate function to use for notebook formatting
437 """
437 """
438 dirname_output_format = \
438 dirname_output_format = \
439 self.result_html_prefix + "%s/" + self.result_html_suffix
439 self.result_html_prefix + "%s/" + self.result_html_suffix
440 fname_output_format = \
440 fname_output_format = \
441 self.result_html_prefix + spacer + self.html_link_str + self.result_html_suffix
441 self.result_html_prefix + spacer + self.html_link_str + self.result_html_suffix
442 fp_format = self.url_prefix + '%s/%s'
442 fp_format = self.url_prefix + '%s/%s'
443 if sep == "\\":
443 if sep == "\\":
444 # Working on a platform where the path separator is "\", so
444 # Working on a platform where the path separator is "\", so
445 # must convert these to "/" for generating a URI
445 # must convert these to "/" for generating a URI
446 def fp_cleaner(fp):
446 def fp_cleaner(fp):
447 # Replace all occurences of backslash ("\") with a forward
447 # Replace all occurences of backslash ("\") with a forward
448 # slash ("/") - this is necessary on windows when a path is
448 # slash ("/") - this is necessary on windows when a path is
449 # provided as input, but we must link to a URI
449 # provided as input, but we must link to a URI
450 return fp.replace('\\','/')
450 return fp.replace('\\','/')
451 else:
451 else:
452 fp_cleaner = None
452 fp_cleaner = None
453
453
454 return self._get_display_formatter(dirname_output_format,
454 return self._get_display_formatter(dirname_output_format,
455 fname_output_format,
455 fname_output_format,
456 fp_format,
456 fp_format,
457 fp_cleaner)
457 fp_cleaner)
458
458
459 def _get_terminal_display_formatter(self,
459 def _get_terminal_display_formatter(self,
460 spacer=" "):
460 spacer=" "):
461 """ generate function to use for terminal formatting
461 """ generate function to use for terminal formatting
462 """
462 """
463 dirname_output_format = "%s/"
463 dirname_output_format = "%s/"
464 fname_output_format = spacer + "%s"
464 fname_output_format = spacer + "%s"
465 fp_format = '%s/%s'
465 fp_format = '%s/%s'
466
466
467 return self._get_display_formatter(dirname_output_format,
467 return self._get_display_formatter(dirname_output_format,
468 fname_output_format,
468 fname_output_format,
469 fp_format)
469 fp_format)
470
470
471 def _format_path(self):
471 def _format_path(self):
472 result_lines = []
472 result_lines = []
473 walked_dir = list(walk(self.path))
473 walked_dir = list(walk(self.path))
474 walked_dir.sort()
474 walked_dir.sort()
475 for dirname, subdirs, fnames in walked_dir:
475 for dirname, subdirs, fnames in walked_dir:
476 result_lines += self.notebook_display_formatter(dirname, fnames, self.included_suffixes)
476 result_lines += self.notebook_display_formatter(dirname, fnames, self.included_suffixes)
477 return '\n'.join(result_lines)
477 return '\n'.join(result_lines)
478
478
479 def __repr__(self):
479 def __repr__(self):
480 """return newline-separated absolute paths
480 """return newline-separated absolute paths
481 """
481 """
482 result_lines = []
482 result_lines = []
483 walked_dir = list(walk(self.path))
483 walked_dir = list(walk(self.path))
484 walked_dir.sort()
484 walked_dir.sort()
485 for dirname, subdirs, fnames in walked_dir:
485 for dirname, subdirs, fnames in walked_dir:
486 result_lines += self.terminal_display_formatter(dirname, fnames, self.included_suffixes)
486 result_lines += self.terminal_display_formatter(dirname, fnames, self.included_suffixes)
487 return '\n'.join(result_lines)
487 return '\n'.join(result_lines)
General Comments 0
You need to be logged in to leave comments. Login now