##// END OF EJS Templates
Fix extra ) syntax error
David Österberg -
Show More
@@ -1,489 +1,489 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 should
36 Should the image data be embedded using a data URI (True) or should
37 the original source be referenced. Set this to True if you want the
37 the original source be referenced. Set this to True if you want the
38 audio to playable 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 data = base64=base64.b64encode(self.data).decode('ascii'))
141 data = base64=base64.b64encode(self.data).decode('ascii')
142 return """data:{type};base64,{base64}""".format(type=self.mimetype,
142 return """data:{type};base64,{base64}""".format(type=self.mimetype,
143 base64=data)
143 base64=data)
144 elif self.url is not None:
144 elif self.url is not None:
145 return self.url
145 return self.url
146 else:
146 else:
147 return ""
147 return ""
148
148
149 def autoplay_attr(self):
149 def autoplay_attr(self):
150 if(self.autoplay):
150 if(self.autoplay):
151 return 'autoplay="autoplay"'
151 return 'autoplay="autoplay"'
152 else:
152 else:
153 return ''
153 return ''
154
154
155 class IFrame(object):
155 class IFrame(object):
156 """
156 """
157 Generic class to embed an iframe in an IPython notebook
157 Generic class to embed an iframe in an IPython notebook
158 """
158 """
159
159
160 iframe = """
160 iframe = """
161 <iframe
161 <iframe
162 width="{width}"
162 width="{width}"
163 height={height}"
163 height={height}"
164 src="{src}{params}"
164 src="{src}{params}"
165 frameborder="0"
165 frameborder="0"
166 allowfullscreen
166 allowfullscreen
167 ></iframe>
167 ></iframe>
168 """
168 """
169
169
170 def __init__(self, src, width, height, **kwargs):
170 def __init__(self, src, width, height, **kwargs):
171 self.src = src
171 self.src = src
172 self.width = width
172 self.width = width
173 self.height = height
173 self.height = height
174 self.params = kwargs
174 self.params = kwargs
175
175
176 def _repr_html_(self):
176 def _repr_html_(self):
177 """return the embed iframe"""
177 """return the embed iframe"""
178 if self.params:
178 if self.params:
179 from urllib import urlencode
179 from urllib import urlencode
180 params = "?" + urlencode(self.params)
180 params = "?" + urlencode(self.params)
181 else:
181 else:
182 params = ""
182 params = ""
183 return self.iframe.format(src=self.src,
183 return self.iframe.format(src=self.src,
184 width=self.width,
184 width=self.width,
185 height=self.height,
185 height=self.height,
186 params=params)
186 params=params)
187
187
188 class YouTubeVideo(IFrame):
188 class YouTubeVideo(IFrame):
189 """Class for embedding a YouTube Video in an IPython session, based on its video id.
189 """Class for embedding a YouTube Video in an IPython session, based on its video id.
190
190
191 e.g. to embed the video on this page:
191 e.g. to embed the video on this page:
192
192
193 http://www.youtube.com/watch?v=foo
193 http://www.youtube.com/watch?v=foo
194
194
195 you would do:
195 you would do:
196
196
197 vid = YouTubeVideo("foo")
197 vid = YouTubeVideo("foo")
198 display(vid)
198 display(vid)
199
199
200 To start from 30 seconds:
200 To start from 30 seconds:
201
201
202 vid = YouTubeVideo("abc", start=30)
202 vid = YouTubeVideo("abc", start=30)
203 display(vid)
203 display(vid)
204
204
205 To calculate seconds from time as hours, minutes, seconds use:
205 To calculate seconds from time as hours, minutes, seconds use:
206 start=int(timedelta(hours=1, minutes=46, seconds=40).total_seconds())
206 start=int(timedelta(hours=1, minutes=46, seconds=40).total_seconds())
207
207
208 Other parameters can be provided as documented at
208 Other parameters can be provided as documented at
209 https://developers.google.com/youtube/player_parameters#parameter-subheader
209 https://developers.google.com/youtube/player_parameters#parameter-subheader
210 """
210 """
211
211
212 def __init__(self, id, width=400, height=300, **kwargs):
212 def __init__(self, id, width=400, height=300, **kwargs):
213 src = "http://www.youtube.com/embed/{0}".format(id)
213 src = "http://www.youtube.com/embed/{0}".format(id)
214 super(YouTubeVideo, self).__init__(src, width, height, **kwargs)
214 super(YouTubeVideo, self).__init__(src, width, height, **kwargs)
215
215
216 class VimeoVideo(IFrame):
216 class VimeoVideo(IFrame):
217 """
217 """
218 Class for embedding a Vimeo video in an IPython session, based on its video id.
218 Class for embedding a Vimeo video in an IPython session, based on its video id.
219 """
219 """
220
220
221 def __init__(self, id, width=400, height=300, **kwargs):
221 def __init__(self, id, width=400, height=300, **kwargs):
222 src="http://player.vimeo.com/video/{0}".format(id)
222 src="http://player.vimeo.com/video/{0}".format(id)
223 super(VimeoVideo, self).__init__(src, width, height, **kwargs)
223 super(VimeoVideo, self).__init__(src, width, height, **kwargs)
224
224
225 class ScribdDocument(IFrame):
225 class ScribdDocument(IFrame):
226 """
226 """
227 Class for embedding a Scribd document in an IPython session
227 Class for embedding a Scribd document in an IPython session
228
228
229 Use the start_page params to specify a starting point in the document
229 Use the start_page params to specify a starting point in the document
230 Use the view_mode params to specify display type one off scroll | slideshow | book
230 Use the view_mode params to specify display type one off scroll | slideshow | book
231
231
232 e.g to Display Wes' foundational paper about PANDAS in book mode from page 3
232 e.g to Display Wes' foundational paper about PANDAS in book mode from page 3
233
233
234 ScribdDocument(71048089, width=800, height=400, start_page=3, view_mode="book")
234 ScribdDocument(71048089, width=800, height=400, start_page=3, view_mode="book")
235 """
235 """
236
236
237 def __init__(self, id, width=400, height=300, **kwargs):
237 def __init__(self, id, width=400, height=300, **kwargs):
238 src="http://www.scribd.com/embeds/{0}/content".format(id)
238 src="http://www.scribd.com/embeds/{0}/content".format(id)
239 super(ScribdDocument, self).__init__(src, width, height, **kwargs)
239 super(ScribdDocument, self).__init__(src, width, height, **kwargs)
240
240
241 class FileLink(object):
241 class FileLink(object):
242 """Class for embedding a local file link in an IPython session, based on path
242 """Class for embedding a local file link in an IPython session, based on path
243
243
244 e.g. to embed a link that was generated in the IPython notebook as my/data.txt
244 e.g. to embed a link that was generated in the IPython notebook as my/data.txt
245
245
246 you would do::
246 you would do::
247
247
248 local_file = FileLink("my/data.txt")
248 local_file = FileLink("my/data.txt")
249 display(local_file)
249 display(local_file)
250
250
251 or in the HTML notebook, just::
251 or in the HTML notebook, just::
252
252
253 FileLink("my/data.txt")
253 FileLink("my/data.txt")
254 """
254 """
255
255
256 html_link_str = "<a href='%s' target='_blank'>%s</a>"
256 html_link_str = "<a href='%s' target='_blank'>%s</a>"
257
257
258 def __init__(self,
258 def __init__(self,
259 path,
259 path,
260 url_prefix='files/',
260 url_prefix='files/',
261 result_html_prefix='',
261 result_html_prefix='',
262 result_html_suffix='<br>'):
262 result_html_suffix='<br>'):
263 """
263 """
264 Parameters
264 Parameters
265 ----------
265 ----------
266 path : str
266 path : str
267 path to the file or directory that should be formatted
267 path to the file or directory that should be formatted
268 directory_prefix : str
268 directory_prefix : str
269 prefix to be prepended to all files to form a working link [default:
269 prefix to be prepended to all files to form a working link [default:
270 'files']
270 'files']
271 result_html_prefix : str
271 result_html_prefix : str
272 text to append to beginning to link [default: none]
272 text to append to beginning to link [default: none]
273 result_html_suffix : str
273 result_html_suffix : str
274 text to append at the end of link [default: '<br>']
274 text to append at the end of link [default: '<br>']
275 """
275 """
276 if isdir(path):
276 if isdir(path):
277 raise ValueError,\
277 raise ValueError,\
278 ("Cannot display a directory using FileLink. "
278 ("Cannot display a directory using FileLink. "
279 "Use FileLinks to display '%s'." % path)
279 "Use FileLinks to display '%s'." % path)
280 self.path = path
280 self.path = path
281 self.url_prefix = url_prefix
281 self.url_prefix = url_prefix
282 self.result_html_prefix = result_html_prefix
282 self.result_html_prefix = result_html_prefix
283 self.result_html_suffix = result_html_suffix
283 self.result_html_suffix = result_html_suffix
284
284
285 def _format_path(self):
285 def _format_path(self):
286 fp = ''.join([self.url_prefix,self.path])
286 fp = ''.join([self.url_prefix,self.path])
287 return ''.join([self.result_html_prefix,
287 return ''.join([self.result_html_prefix,
288 self.html_link_str % (fp, self.path),
288 self.html_link_str % (fp, self.path),
289 self.result_html_suffix])
289 self.result_html_suffix])
290
290
291 def _repr_html_(self):
291 def _repr_html_(self):
292 """return html link to file
292 """return html link to file
293 """
293 """
294 if not exists(self.path):
294 if not exists(self.path):
295 return ("Path (<tt>%s</tt>) doesn't exist. "
295 return ("Path (<tt>%s</tt>) doesn't exist. "
296 "It may still be in the process of "
296 "It may still be in the process of "
297 "being generated, or you may have the "
297 "being generated, or you may have the "
298 "incorrect path." % self.path)
298 "incorrect path." % self.path)
299
299
300 return self._format_path()
300 return self._format_path()
301
301
302 def __repr__(self):
302 def __repr__(self):
303 """return absolute path to file
303 """return absolute path to file
304 """
304 """
305 return abspath(self.path)
305 return abspath(self.path)
306
306
307 class FileLinks(FileLink):
307 class FileLinks(FileLink):
308 """Class for embedding local file links in an IPython session, based on path
308 """Class for embedding local file links in an IPython session, based on path
309
309
310 e.g. to embed links to files that were generated in the IPython notebook under my/data
310 e.g. to embed links to files that were generated in the IPython notebook under my/data
311
311
312 you would do:
312 you would do:
313
313
314 local_files = FileLinks("my/data")
314 local_files = FileLinks("my/data")
315 display(local_files)
315 display(local_files)
316
316
317 or in the HTML notebook, just
317 or in the HTML notebook, just
318
318
319 FileLinks("my/data")
319 FileLinks("my/data")
320
320
321 """
321 """
322 def __init__(self,
322 def __init__(self,
323 path,
323 path,
324 url_prefix='files/',
324 url_prefix='files/',
325 included_suffixes=None,
325 included_suffixes=None,
326 result_html_prefix='',
326 result_html_prefix='',
327 result_html_suffix='<br>',
327 result_html_suffix='<br>',
328 notebook_display_formatter=None,
328 notebook_display_formatter=None,
329 terminal_display_formatter=None):
329 terminal_display_formatter=None):
330 """
330 """
331 included_suffixes : list of filename suffixes to include when
331 included_suffixes : list of filename suffixes to include when
332 formatting output [default: include all files]
332 formatting output [default: include all files]
333
333
334 See the FileLink (baseclass of LocalDirectory) docstring for
334 See the FileLink (baseclass of LocalDirectory) docstring for
335 information on additional parameters.
335 information on additional parameters.
336
336
337 notebook_display_formatter : func used to format links for display
337 notebook_display_formatter : func used to format links for display
338 in the notebook. See discussion of formatter function below.
338 in the notebook. See discussion of formatter function below.
339
339
340 terminal_display_formatter : func used to format links for display
340 terminal_display_formatter : func used to format links for display
341 in the terminal. See discussion of formatter function below.
341 in the terminal. See discussion of formatter function below.
342
342
343
343
344 Passing custom formatter functions
344 Passing custom formatter functions
345 ----------------------------------
345 ----------------------------------
346 Formatter functions must be of the form:
346 Formatter functions must be of the form:
347 f(dirname, fnames, included_suffixes)
347 f(dirname, fnames, included_suffixes)
348 dirname : the name of a directory (a string),
348 dirname : the name of a directory (a string),
349 fnames : a list of the files in that directory
349 fnames : a list of the files in that directory
350 included_suffixes : a list of the file suffixes that should be
350 included_suffixes : a list of the file suffixes that should be
351 included in the output (passing None means
351 included in the output (passing None means
352 to include all suffixes in the output in
352 to include all suffixes in the output in
353 the built-in formatters)
353 the built-in formatters)
354
354
355 returns a list of lines that should will be print in the
355 returns a list of lines that should will be print in the
356 notebook (if passing notebook_display_formatter) or the terminal
356 notebook (if passing notebook_display_formatter) or the terminal
357 (if passing terminal_display_formatter). This function is iterated
357 (if passing terminal_display_formatter). This function is iterated
358 over for each directory in self.path. Default formatters are in
358 over for each directory in self.path. Default formatters are in
359 place, can be passed here to support alternative formatting.
359 place, can be passed here to support alternative formatting.
360
360
361 """
361 """
362 if isfile(path):
362 if isfile(path):
363 raise ValueError,\
363 raise ValueError,\
364 ("Cannot display a file using FileLinks. "
364 ("Cannot display a file using FileLinks. "
365 "Use FileLink to display '%s'." % path)
365 "Use FileLink to display '%s'." % path)
366 self.included_suffixes = included_suffixes
366 self.included_suffixes = included_suffixes
367 # remove trailing slashs for more consistent output formatting
367 # remove trailing slashs for more consistent output formatting
368 path = path.rstrip('/')
368 path = path.rstrip('/')
369
369
370 self.path = path
370 self.path = path
371 self.url_prefix = url_prefix
371 self.url_prefix = url_prefix
372 self.result_html_prefix = result_html_prefix
372 self.result_html_prefix = result_html_prefix
373 self.result_html_suffix = result_html_suffix
373 self.result_html_suffix = result_html_suffix
374
374
375 self.notebook_display_formatter = \
375 self.notebook_display_formatter = \
376 notebook_display_formatter or self._get_notebook_display_formatter()
376 notebook_display_formatter or self._get_notebook_display_formatter()
377 self.terminal_display_formatter = \
377 self.terminal_display_formatter = \
378 terminal_display_formatter or self._get_terminal_display_formatter()
378 terminal_display_formatter or self._get_terminal_display_formatter()
379
379
380 def _get_display_formatter(self,
380 def _get_display_formatter(self,
381 dirname_output_format,
381 dirname_output_format,
382 fname_output_format,
382 fname_output_format,
383 fp_format,
383 fp_format,
384 fp_cleaner=None):
384 fp_cleaner=None):
385 """ generate built-in formatter function
385 """ generate built-in formatter function
386
386
387 this is used to define both the notebook and terminal built-in
387 this is used to define both the notebook and terminal built-in
388 formatters as they only differ by some wrapper text for each entry
388 formatters as they only differ by some wrapper text for each entry
389
389
390 dirname_output_format: string to use for formatting directory
390 dirname_output_format: string to use for formatting directory
391 names, dirname will be substituted for a single "%s" which
391 names, dirname will be substituted for a single "%s" which
392 must appear in this string
392 must appear in this string
393 fname_output_format: string to use for formatting file names,
393 fname_output_format: string to use for formatting file names,
394 if a single "%s" appears in the string, fname will be substituted
394 if a single "%s" appears in the string, fname will be substituted
395 if two "%s" appear in the string, the path to fname will be
395 if two "%s" appear in the string, the path to fname will be
396 substituted for the first and fname will be substituted for the
396 substituted for the first and fname will be substituted for the
397 second
397 second
398 fp_format: string to use for formatting filepaths, must contain
398 fp_format: string to use for formatting filepaths, must contain
399 exactly two "%s" and the dirname will be subsituted for the first
399 exactly two "%s" and the dirname will be subsituted for the first
400 and fname will be substituted for the second
400 and fname will be substituted for the second
401 """
401 """
402 def f(dirname, fnames, included_suffixes=None):
402 def f(dirname, fnames, included_suffixes=None):
403 result = []
403 result = []
404 # begin by figuring out which filenames, if any,
404 # begin by figuring out which filenames, if any,
405 # are going to be displayed
405 # are going to be displayed
406 display_fnames = []
406 display_fnames = []
407 for fname in fnames:
407 for fname in fnames:
408 if (isfile(join(dirname,fname)) and
408 if (isfile(join(dirname,fname)) and
409 (included_suffixes == None or
409 (included_suffixes == None or
410 splitext(fname)[1] in included_suffixes)):
410 splitext(fname)[1] in included_suffixes)):
411 display_fnames.append(fname)
411 display_fnames.append(fname)
412
412
413 if len(display_fnames) == 0:
413 if len(display_fnames) == 0:
414 # if there are no filenames to display, don't print anything
414 # if there are no filenames to display, don't print anything
415 # (not even the directory name)
415 # (not even the directory name)
416 pass
416 pass
417 else:
417 else:
418 # otherwise print the formatted directory name followed by
418 # otherwise print the formatted directory name followed by
419 # the formatted filenames
419 # the formatted filenames
420 dirname_output_line = dirname_output_format % dirname
420 dirname_output_line = dirname_output_format % dirname
421 result.append(dirname_output_line)
421 result.append(dirname_output_line)
422 for fname in display_fnames:
422 for fname in display_fnames:
423 fp = fp_format % (dirname,fname)
423 fp = fp_format % (dirname,fname)
424 if fp_cleaner is not None:
424 if fp_cleaner is not None:
425 fp = fp_cleaner(fp)
425 fp = fp_cleaner(fp)
426 try:
426 try:
427 # output can include both a filepath and a filename...
427 # output can include both a filepath and a filename...
428 fname_output_line = fname_output_format % (fp, fname)
428 fname_output_line = fname_output_format % (fp, fname)
429 except TypeError:
429 except TypeError:
430 # ... or just a single filepath
430 # ... or just a single filepath
431 fname_output_line = fname_output_format % fname
431 fname_output_line = fname_output_format % fname
432 result.append(fname_output_line)
432 result.append(fname_output_line)
433 return result
433 return result
434 return f
434 return f
435
435
436 def _get_notebook_display_formatter(self,
436 def _get_notebook_display_formatter(self,
437 spacer="&nbsp;&nbsp;"):
437 spacer="&nbsp;&nbsp;"):
438 """ generate function to use for notebook formatting
438 """ generate function to use for notebook formatting
439 """
439 """
440 dirname_output_format = \
440 dirname_output_format = \
441 self.result_html_prefix + "%s/" + self.result_html_suffix
441 self.result_html_prefix + "%s/" + self.result_html_suffix
442 fname_output_format = \
442 fname_output_format = \
443 self.result_html_prefix + spacer + self.html_link_str + self.result_html_suffix
443 self.result_html_prefix + spacer + self.html_link_str + self.result_html_suffix
444 fp_format = self.url_prefix + '%s/%s'
444 fp_format = self.url_prefix + '%s/%s'
445 if sep == "\\":
445 if sep == "\\":
446 # Working on a platform where the path separator is "\", so
446 # Working on a platform where the path separator is "\", so
447 # must convert these to "/" for generating a URI
447 # must convert these to "/" for generating a URI
448 def fp_cleaner(fp):
448 def fp_cleaner(fp):
449 # Replace all occurences of backslash ("\") with a forward
449 # Replace all occurences of backslash ("\") with a forward
450 # slash ("/") - this is necessary on windows when a path is
450 # slash ("/") - this is necessary on windows when a path is
451 # provided as input, but we must link to a URI
451 # provided as input, but we must link to a URI
452 return fp.replace('\\','/')
452 return fp.replace('\\','/')
453 else:
453 else:
454 fp_cleaner = None
454 fp_cleaner = None
455
455
456 return self._get_display_formatter(dirname_output_format,
456 return self._get_display_formatter(dirname_output_format,
457 fname_output_format,
457 fname_output_format,
458 fp_format,
458 fp_format,
459 fp_cleaner)
459 fp_cleaner)
460
460
461 def _get_terminal_display_formatter(self,
461 def _get_terminal_display_formatter(self,
462 spacer=" "):
462 spacer=" "):
463 """ generate function to use for terminal formatting
463 """ generate function to use for terminal formatting
464 """
464 """
465 dirname_output_format = "%s/"
465 dirname_output_format = "%s/"
466 fname_output_format = spacer + "%s"
466 fname_output_format = spacer + "%s"
467 fp_format = '%s/%s'
467 fp_format = '%s/%s'
468
468
469 return self._get_display_formatter(dirname_output_format,
469 return self._get_display_formatter(dirname_output_format,
470 fname_output_format,
470 fname_output_format,
471 fp_format)
471 fp_format)
472
472
473 def _format_path(self):
473 def _format_path(self):
474 result_lines = []
474 result_lines = []
475 walked_dir = list(walk(self.path))
475 walked_dir = list(walk(self.path))
476 walked_dir.sort()
476 walked_dir.sort()
477 for dirname, subdirs, fnames in walked_dir:
477 for dirname, subdirs, fnames in walked_dir:
478 result_lines += self.notebook_display_formatter(dirname, fnames, self.included_suffixes)
478 result_lines += self.notebook_display_formatter(dirname, fnames, self.included_suffixes)
479 return '\n'.join(result_lines)
479 return '\n'.join(result_lines)
480
480
481 def __repr__(self):
481 def __repr__(self):
482 """return newline-separated absolute paths
482 """return newline-separated absolute paths
483 """
483 """
484 result_lines = []
484 result_lines = []
485 walked_dir = list(walk(self.path))
485 walked_dir = list(walk(self.path))
486 walked_dir.sort()
486 walked_dir.sort()
487 for dirname, subdirs, fnames in walked_dir:
487 for dirname, subdirs, fnames in walked_dir:
488 result_lines += self.terminal_display_formatter(dirname, fnames, self.included_suffixes)
488 result_lines += self.terminal_display_formatter(dirname, fnames, self.included_suffixes)
489 return '\n'.join(result_lines)
489 return '\n'.join(result_lines)
General Comments 0
You need to be logged in to leave comments. Login now