display.py
557 lines
| 20.1 KiB
| text/x-python
|
PythonLexer
Brian E. Granger
|
r4408 | """Various display related classes. | ||
Greg Caporaso
|
r8798 | Authors : MinRK, gregcaporaso, dannystaple | ||
Brian E. Granger
|
r4408 | """ | ||
Greg Caporaso
|
r8800 | from os.path import exists, isfile, splitext, abspath, join, isdir | ||
Doug Blank
|
r19167 | from os import walk, sep | ||
Greg Caporaso
|
r8272 | |||
David Österberg
|
r12829 | from IPython.core.display import DisplayObject | ||
Thomas Kluyver
|
r17121 | __all__ = ['Audio', 'IFrame', 'YouTubeVideo', 'VimeoVideo', 'ScribdDocument', | ||
'FileLink', 'FileLinks'] | ||||
David Österberg
|
r12829 | |||
class Audio(DisplayObject): | ||||
"""Create an audio object. | ||||
When this object is returned by an input cell or passed to the | ||||
display function, it will result in Audio controls being displayed | ||||
in the frontend (only works in the notebook). | ||||
Erik Tollerud
|
r16550 | |||
David Österberg
|
r12829 | Parameters | ||
---------- | ||||
David Österberg
|
r12968 | data : numpy array, list, unicode, str or bytes | ||
Erik Tollerud
|
r16551 | Can be one of | ||
* Numpy 1d array containing the desired waveform (mono) | ||||
* Numpy 2d array containing waveforms for each channel. | ||||
Shape=(NCHAN, NSAMPLES). For the standard channel order, see | ||||
http://msdn.microsoft.com/en-us/library/windows/hardware/dn653308(v=vs.85).aspx | ||||
* List of float or integer representing the waveform (mono) | ||||
* String containing the filename | ||||
* Bytestring containing raw PCM data or | ||||
* URL pointing to a file on the web. | ||||
Erik Tollerud
|
r16550 | |||
David Österberg
|
r12829 | If the array option is used the waveform will be normalized. | ||
Erik Tollerud
|
r16550 | |||
If a filename or url is used the format support will be browser | ||||
dependent. | ||||
David Österberg
|
r12829 | url : unicode | ||
A URL to download the data from. | ||||
filename : unicode | ||||
Path to a local file to load the data from. | ||||
embed : boolean | ||||
Jonas Rauber
|
r22201 | Should the audio data be embedded using a data URI (True) or should | ||
Erik Tollerud
|
r16550 | the original source be referenced. Set this to True if you want the | ||
David Österberg
|
r12834 | audio to playable later with no internet connection in the notebook. | ||
David Österberg
|
r12829 | |||
Default is `True`, unless the keyword argument `url` is set, then | ||||
default value is `False`. | ||||
rate : integer | ||||
The sampling rate of the raw data. | ||||
Only required when data parameter is being used as an array | ||||
autoplay : bool | ||||
Set to True if the audio should immediately start playing. | ||||
Default is `False`. | ||||
Examples | ||||
-------- | ||||
Thomas Kluyver
|
r13587 | :: | ||
# Generate a sound | ||||
import numpy as np | ||||
framerate = 44100 | ||||
t = np.linspace(0,5,framerate*5) | ||||
data = np.sin(2*np.pi*220*t) + np.sin(2*np.pi*224*t)) | ||||
Audio(data,rate=framerate) | ||||
Erik Tollerud
|
r16551 | # Can also do stereo or more channels | ||
dataleft = np.sin(2*np.pi*220*t) | ||||
dataright = np.sin(2*np.pi*224*t) | ||||
Audio([dataleft, dataright],rate=framerate) | ||||
Thomas Kluyver
|
r13587 | Audio("http://www.nch.com.au/acm/8k16bitpcm.wav") # From URL | ||
Audio(url="http://www.w3schools.com/html/horse.ogg") | ||||
Audio('/path/to/sound.wav') # From file | ||||
Audio(filename='/path/to/sound.ogg') | ||||
Audio(b'RAW_WAV_DATA..) # From bytes | ||||
Audio(data=b'RAW_WAV_DATA..) | ||||
David Österberg
|
r12829 | |||
""" | ||||
Thomas Kluyver
|
r13549 | _read_flags = 'rb' | ||
David Österberg
|
r12829 | def __init__(self, data=None, filename=None, url=None, embed=None, rate=None, autoplay=False): | ||
if filename is None and url is None and data is None: | ||||
raise ValueError("No image data found. Expecting filename, url, or data.") | ||||
if embed is False and url is None: | ||||
raise ValueError("No url found. Expecting url when embed=False") | ||||
Erik Tollerud
|
r16550 | |||
David Österberg
|
r12829 | if url is not None and embed is not True: | ||
self.embed = False | ||||
else: | ||||
self.embed = True | ||||
self.autoplay = autoplay | ||||
super(Audio, self).__init__(data=data, url=url, filename=filename) | ||||
Erik Tollerud
|
r16550 | |||
David Österberg
|
r12829 | if self.data is not None and not isinstance(self.data, bytes): | ||
self.data = self._make_wav(data,rate) | ||||
Erik Tollerud
|
r16550 | |||
David Österberg
|
r12829 | def reload(self): | ||
"""Reload the raw data from file or URL.""" | ||||
David Österberg
|
r12833 | import mimetypes | ||
David Österberg
|
r12829 | if self.embed: | ||
super(Audio, self).reload() | ||||
if self.filename is not None: | ||||
self.mimetype = mimetypes.guess_type(self.filename)[0] | ||||
elif self.url is not None: | ||||
self.mimetype = mimetypes.guess_type(self.url)[0] | ||||
else: | ||||
self.mimetype = "audio/wav" | ||||
Erik Tollerud
|
r16550 | |||
David Österberg
|
r12871 | def _make_wav(self, data, rate): | ||
David Österberg
|
r12829 | """ Transform a numpy array to a PCM bytestring """ | ||
David Österberg
|
r12833 | import struct | ||
from io import BytesIO | ||||
import wave | ||||
Erik Tollerud
|
r16550 | |||
David Österberg
|
r12869 | try: | ||
import numpy as np | ||||
Erik Tollerud
|
r16550 | |||
data = np.array(data, dtype=float) | ||||
if len(data.shape) == 1: | ||||
nchan = 1 | ||||
elif len(data.shape) == 2: | ||||
# In wave files,channels are interleaved. E.g., | ||||
# "L1R1L2R2..." for stereo. See | ||||
# http://msdn.microsoft.com/en-us/library/windows/hardware/dn653308(v=vs.85).aspx | ||||
# for channel ordering | ||||
nchan = data.shape[0] | ||||
data = data.T.ravel() | ||||
else: | ||||
raise ValueError('Array audio input must be a 1D or 2D array') | ||||
David Österberg
|
r12871 | scaled = np.int16(data/np.max(np.abs(data))*32767).tolist() | ||
David Österberg
|
r12869 | except ImportError: | ||
Erik Tollerud
|
r16550 | # check that it is a "1D" list | ||
idata = iter(data) # fails if not an iterable | ||||
try: | ||||
iter(idata.next()) | ||||
raise TypeError('Only lists of mono audio are ' | ||||
'supported if numpy is not installed') | ||||
except TypeError: | ||||
# this means it's not a nested list, which is what we want | ||||
pass | ||||
David Österberg
|
r12968 | maxabsvalue = float(max([abs(x) for x in data])) | ||
Erik Tollerud
|
r16550 | scaled = [int(x/maxabsvalue*32767) for x in data] | ||
nchan = 1 | ||||
David Österberg
|
r12829 | fp = BytesIO() | ||
waveobj = wave.open(fp,mode='wb') | ||||
Erik Tollerud
|
r16550 | waveobj.setnchannels(nchan) | ||
David Österberg
|
r12829 | waveobj.setframerate(rate) | ||
waveobj.setsampwidth(2) | ||||
waveobj.setcomptype('NONE','NONE') | ||||
waveobj.writeframes(b''.join([struct.pack('<h',x) for x in scaled])) | ||||
val = fp.getvalue() | ||||
waveobj.close() | ||||
Erik Tollerud
|
r16550 | |||
return val | ||||
David Österberg
|
r12829 | def _data_and_metadata(self): | ||
"""shortcut for returning metadata with url information, if defined""" | ||||
md = {} | ||||
if self.url: | ||||
md['url'] = self.url | ||||
if md: | ||||
return self.data, md | ||||
else: | ||||
return self.data | ||||
Erik Tollerud
|
r16550 | |||
David Österberg
|
r12829 | def _repr_html_(self): | ||
src = """ | ||||
<audio controls="controls" {autoplay}> | ||||
<source src="{src}" type="{type}" /> | ||||
Your browser does not support the audio element. | ||||
</audio> | ||||
""" | ||||
return src.format(src=self.src_attr(),type=self.mimetype, autoplay=self.autoplay_attr()) | ||||
def src_attr(self): | ||||
David Österberg
|
r12833 | import base64 | ||
David Österberg
|
r12829 | if self.embed and (self.data is not None): | ||
David Österberg
|
r12840 | data = base64=base64.b64encode(self.data).decode('ascii') | ||
David Österberg
|
r12839 | return """data:{type};base64,{base64}""".format(type=self.mimetype, | ||
base64=data) | ||||
David Österberg
|
r12829 | elif self.url is not None: | ||
return self.url | ||||
else: | ||||
return "" | ||||
def autoplay_attr(self): | ||||
if(self.autoplay): | ||||
return 'autoplay="autoplay"' | ||||
else: | ||||
return '' | ||||
Greg Caporaso
|
r8272 | |||
Eugene Van den Bulke
|
r10260 | class IFrame(object): | ||
Eugene Van den Bulke
|
r10249 | """ | ||
Eugene Van den Bulke
|
r10260 | Generic class to embed an iframe in an IPython notebook | ||
Eugene Van den Bulke
|
r10249 | """ | ||
Eugene Van den Bulke
|
r10262 | iframe = """ | ||
<iframe | ||||
width="{width}" | ||||
Cyrille Rossant
|
r18018 | height="{height}" | ||
Eugene Van den Bulke
|
r10262 | src="{src}{params}" | ||
frameborder="0" | ||||
allowfullscreen | ||||
></iframe> | ||||
""" | ||||
def __init__(self, src, width, height, **kwargs): | ||||
self.src = src | ||||
Eugene Van den Bulke
|
r10249 | self.width = width | ||
self.height = height | ||||
self.params = kwargs | ||||
def _repr_html_(self): | ||||
Eugene Van den Bulke
|
r10262 | """return the embed iframe""" | ||
Eugene Van den Bulke
|
r10249 | if self.params: | ||
Sean Vig
|
r13640 | try: | ||
from urllib.parse import urlencode # Py 3 | ||||
except ImportError: | ||||
from urllib import urlencode | ||||
Eugene Van den Bulke
|
r10249 | params = "?" + urlencode(self.params) | ||
else: | ||||
params = "" | ||||
Eugene Van den Bulke
|
r10262 | return self.iframe.format(src=self.src, | ||
width=self.width, | ||||
Eugene Van den Bulke
|
r10253 | height=self.height, | ||
params=params) | ||||
Eugene Van den Bulke
|
r10249 | |||
Eugene Van den Bulke
|
r10260 | class YouTubeVideo(IFrame): | ||
Brian E. Granger
|
r4408 | """Class for embedding a YouTube Video in an IPython session, based on its video id. | ||
Bernardo B. Marques
|
r4872 | |||
MinRK
|
r14829 | e.g. to embed the video from https://www.youtube.com/watch?v=foo , you would | ||
Thomas Kluyver
|
r13587 | do:: | ||
Bernardo B. Marques
|
r4872 | |||
Thomas Kluyver
|
r13587 | vid = YouTubeVideo("foo") | ||
display(vid) | ||||
Bernardo B. Marques
|
r4872 | |||
Thomas Kluyver
|
r13587 | To start from 30 seconds:: | ||
Eugene Van den Bulke
|
r10249 | |||
Thomas Kluyver
|
r13587 | vid = YouTubeVideo("abc", start=30) | ||
display(vid) | ||||
Eugene Van den Bulke
|
r10249 | |||
Thomas Kluyver
|
r13587 | To calculate seconds from time as hours, minutes, seconds use | ||
:class:`datetime.timedelta`:: | ||||
Eugene Van den Bulke
|
r10249 | |||
Thomas Kluyver
|
r13587 | start=int(timedelta(hours=1, minutes=46, seconds=40).total_seconds()) | ||
Danny Staple
|
r8651 | |||
Eugene Van den Bulke
|
r10249 | Other parameters can be provided as documented at | ||
Danny Staple
|
r8645 | https://developers.google.com/youtube/player_parameters#parameter-subheader | ||
Ben Kasel
|
r21862 | |||
When converting the notebook using nbconvert, a jpeg representation of the video | ||||
will be inserted in the document. | ||||
Brian E. Granger
|
r4408 | """ | ||
Bernardo B. Marques
|
r4872 | |||
Eugene Van den Bulke
|
r10262 | def __init__(self, id, width=400, height=300, **kwargs): | ||
Ben Kasel
|
r21861 | self.id=id | ||
MinRK
|
r14829 | src = "https://www.youtube.com/embed/{0}".format(id) | ||
Eugene Van den Bulke
|
r10262 | super(YouTubeVideo, self).__init__(src, width, height, **kwargs) | ||
Ben Kasel
|
r21862 | |||
Ben Kasel
|
r21861 | def _repr_jpeg_(self): | ||
Srinivas Reddy Thatiparthy
|
r23075 | # Deferred import | ||
from urllib.request import urlopen | ||||
Ben Kasel
|
r21865 | try: | ||
return urlopen("https://img.youtube.com/vi/{id}/hqdefault.jpg".format(id=self.id)).read() | ||||
except IOError: | ||||
return None | ||||
Eugene Van den Bulke
|
r10249 | |||
Eugene Van den Bulke
|
r10261 | class VimeoVideo(IFrame): | ||
Eugene Van den Bulke
|
r10249 | """ | ||
Class for embedding a Vimeo video in an IPython session, based on its video id. | ||||
""" | ||||
Eugene Van den Bulke
|
r10262 | def __init__(self, id, width=400, height=300, **kwargs): | ||
MinRK
|
r14829 | src="https://player.vimeo.com/video/{0}".format(id) | ||
Eugene Van den Bulke
|
r10262 | super(VimeoVideo, self).__init__(src, width, height, **kwargs) | ||
Eugene Van den Bulke
|
r10249 | |||
Eugene Van den Bulke
|
r10260 | class ScribdDocument(IFrame): | ||
""" | ||||
Class for embedding a Scribd document in an IPython session | ||||
Use the start_page params to specify a starting point in the document | ||||
Use the view_mode params to specify display type one off scroll | slideshow | book | ||||
e.g to Display Wes' foundational paper about PANDAS in book mode from page 3 | ||||
ScribdDocument(71048089, width=800, height=400, start_page=3, view_mode="book") | ||||
""" | ||||
Eugene Van den Bulke
|
r10262 | def __init__(self, id, width=400, height=300, **kwargs): | ||
MinRK
|
r14829 | src="https://www.scribd.com/embeds/{0}/content".format(id) | ||
Eugene Van den Bulke
|
r10262 | super(ScribdDocument, self).__init__(src, width, height, **kwargs) | ||
Brian E. Granger
|
r4408 | |||
Greg Caporaso
|
r8365 | class FileLink(object): | ||
Greg Caporaso
|
r8272 | """Class for embedding a local file link in an IPython session, based on path | ||
e.g. to embed a link that was generated in the IPython notebook as my/data.txt | ||||
Thomas Kluyver
|
r9244 | you would do:: | ||
Greg Caporaso
|
r8272 | |||
Thomas Kluyver
|
r9244 | local_file = FileLink("my/data.txt") | ||
display(local_file) | ||||
Eugene Van den Bulke
|
r10249 | |||
Thomas Kluyver
|
r9244 | or in the HTML notebook, just:: | ||
Eugene Van den Bulke
|
r10249 | |||
Thomas Kluyver
|
r9244 | FileLink("my/data.txt") | ||
Greg Caporaso
|
r8272 | """ | ||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8442 | html_link_str = "<a href='%s' target='_blank'>%s</a>" | ||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8272 | def __init__(self, | ||
path, | ||||
MinRK
|
r14894 | url_prefix='', | ||
Greg Caporaso
|
r8439 | result_html_prefix='', | ||
result_html_suffix='<br>'): | ||||
Greg Caporaso
|
r8272 | """ | ||
Thomas Kluyver
|
r9244 | Parameters | ||
---------- | ||||
path : str | ||||
path to the file or directory that should be formatted | ||||
directory_prefix : str | ||||
prefix to be prepended to all files to form a working link [default: | ||||
'files'] | ||||
result_html_prefix : str | ||||
text to append to beginning to link [default: none] | ||||
Eugene Van den Bulke
|
r10249 | result_html_suffix : str | ||
Thomas Kluyver
|
r9244 | text to append at the end of link [default: '<br>'] | ||
Greg Caporaso
|
r8272 | """ | ||
Greg Caporaso
|
r8835 | if isdir(path): | ||
Thomas Kluyver
|
r13349 | raise ValueError("Cannot display a directory using FileLink. " | ||
Greg Caporaso
|
r8835 | "Use FileLinks to display '%s'." % path) | ||
Greg Caporaso
|
r8272 | self.path = path | ||
Greg Caporaso
|
r8437 | self.url_prefix = url_prefix | ||
Greg Caporaso
|
r8439 | self.result_html_prefix = result_html_prefix | ||
self.result_html_suffix = result_html_suffix | ||||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8272 | def _format_path(self): | ||
Greg Caporaso
|
r8446 | fp = ''.join([self.url_prefix,self.path]) | ||
Greg Caporaso
|
r8439 | return ''.join([self.result_html_prefix, | ||
Greg Caporaso
|
r8442 | self.html_link_str % (fp, self.path), | ||
Greg Caporaso
|
r8439 | self.result_html_suffix]) | ||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8272 | def _repr_html_(self): | ||
Greg Caporaso
|
r8442 | """return html link to file | ||
Greg Caporaso
|
r8272 | """ | ||
if not exists(self.path): | ||||
Eugene Van den Bulke
|
r10249 | return ("Path (<tt>%s</tt>) doesn't exist. " | ||
Greg Caporaso
|
r8272 | "It may still be in the process of " | ||
"being generated, or you may have the " | ||||
"incorrect path." % self.path) | ||||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8272 | return self._format_path() | ||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8442 | def __repr__(self): | ||
Greg Caporaso
|
r8443 | """return absolute path to file | ||
Greg Caporaso
|
r8442 | """ | ||
return abspath(self.path) | ||||
Greg Caporaso
|
r8272 | |||
Greg Caporaso
|
r8365 | class FileLinks(FileLink): | ||
Greg Caporaso
|
r8272 | """Class for embedding local file links in an IPython session, based on path | ||
Thomas Kluyver
|
r13587 | e.g. to embed links to files that were generated in the IPython notebook | ||
under ``my/data``, you would do:: | ||||
Greg Caporaso
|
r8272 | |||
Thomas Kluyver
|
r13587 | local_files = FileLinks("my/data") | ||
display(local_files) | ||||
Eugene Van den Bulke
|
r10249 | |||
Thomas Kluyver
|
r13587 | or in the HTML notebook, just:: | ||
Eugene Van den Bulke
|
r10249 | |||
Thomas Kluyver
|
r13587 | FileLinks("my/data") | ||
Greg Caporaso
|
r8272 | """ | ||
def __init__(self, | ||||
path, | ||||
MinRK
|
r14894 | url_prefix='', | ||
Greg Caporaso
|
r8439 | included_suffixes=None, | ||
result_html_prefix='', | ||||
Greg Caporaso
|
r8619 | result_html_suffix='<br>', | ||
notebook_display_formatter=None, | ||||
Doug Blank
|
r19166 | terminal_display_formatter=None, | ||
recursive=True): | ||||
Greg Caporaso
|
r8272 | """ | ||
Thomas Kluyver
|
r13587 | See :class:`FileLink` for the ``path``, ``url_prefix``, | ||
``result_html_prefix`` and ``result_html_suffix`` parameters. | ||||
included_suffixes : list | ||||
Filename suffixes to include when formatting output [default: include | ||||
all files] | ||||
notebook_display_formatter : function | ||||
Used to format links for display in the notebook. See discussion of | ||||
formatter functions below. | ||||
terminal_display_formatter : function | ||||
Used to format links for display in the terminal. See discussion of | ||||
formatter functions below. | ||||
Formatter functions must be of the form:: | ||||
f(dirname, fnames, included_suffixes) | ||||
dirname : str | ||||
The name of a directory | ||||
fnames : list | ||||
The files in that directory | ||||
included_suffixes : list | ||||
The file suffixes that should be included in the output (passing None | ||||
meansto include all suffixes in the output in the built-in formatters) | ||||
Doug Blank
|
r19167 | recursive : boolean | ||
Whether to recurse into subdirectories. Default is True. | ||||
Thomas Kluyver
|
r13587 | |||
The function should return a list of lines that will be printed in the | ||||
notebook (if passing notebook_display_formatter) or the terminal (if | ||||
passing terminal_display_formatter). This function is iterated over for | ||||
each directory in self.path. Default formatters are in place, can be | ||||
passed here to support alternative formatting. | ||||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8272 | """ | ||
Greg Caporaso
|
r8836 | if isfile(path): | ||
Thomas Kluyver
|
r13349 | raise ValueError("Cannot display a file using FileLinks. " | ||
Greg Caporaso
|
r8836 | "Use FileLink to display '%s'." % path) | ||
Greg Caporaso
|
r8439 | self.included_suffixes = included_suffixes | ||
Greg Caporaso
|
r8631 | # remove trailing slashs for more consistent output formatting | ||
path = path.rstrip('/') | ||||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8835 | self.path = path | ||
self.url_prefix = url_prefix | ||||
self.result_html_prefix = result_html_prefix | ||||
self.result_html_suffix = result_html_suffix | ||||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8624 | self.notebook_display_formatter = \ | ||
Greg Caporaso
|
r8626 | notebook_display_formatter or self._get_notebook_display_formatter() | ||
Greg Caporaso
|
r8624 | self.terminal_display_formatter = \ | ||
Greg Caporaso
|
r8626 | terminal_display_formatter or self._get_terminal_display_formatter() | ||
Eugene Van den Bulke
|
r10249 | |||
Doug Blank
|
r19166 | self.recursive = recursive | ||
Greg Caporaso
|
r8624 | def _get_display_formatter(self, | ||
dirname_output_format, | ||||
fname_output_format, | ||||
Greg Caporaso
|
r9093 | fp_format, | ||
fp_cleaner=None): | ||||
Greg Caporaso
|
r8803 | """ generate built-in formatter function | ||
Eugene Van den Bulke
|
r10249 | |||
this is used to define both the notebook and terminal built-in | ||||
Greg Caporaso
|
r8803 | formatters as they only differ by some wrapper text for each entry | ||
Eugene Van den Bulke
|
r10249 | |||
dirname_output_format: string to use for formatting directory | ||||
Greg Caporaso
|
r8631 | names, dirname will be substituted for a single "%s" which | ||
must appear in this string | ||||
fname_output_format: string to use for formatting file names, | ||||
if a single "%s" appears in the string, fname will be substituted | ||||
Eugene Van den Bulke
|
r10249 | if two "%s" appear in the string, the path to fname will be | ||
Greg Caporaso
|
r8631 | substituted for the first and fname will be substituted for the | ||
second | ||||
fp_format: string to use for formatting filepaths, must contain | ||||
exactly two "%s" and the dirname will be subsituted for the first | ||||
and fname will be substituted for the second | ||||
""" | ||||
Greg Caporaso
|
r8802 | def f(dirname, fnames, included_suffixes=None): | ||
Greg Caporaso
|
r8801 | result = [] | ||
Eugene Van den Bulke
|
r10249 | # begin by figuring out which filenames, if any, | ||
Greg Caporaso
|
r8619 | # are going to be displayed | ||
display_fnames = [] | ||||
for fname in fnames: | ||||
if (isfile(join(dirname,fname)) and | ||||
Boris Egorov
|
r18172 | (included_suffixes is None or | ||
Greg Caporaso
|
r8619 | splitext(fname)[1] in included_suffixes)): | ||
display_fnames.append(fname) | ||||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8619 | if len(display_fnames) == 0: | ||
Greg Caporaso
|
r8631 | # if there are no filenames to display, don't print anything | ||
# (not even the directory name) | ||||
Greg Caporaso
|
r8619 | pass | ||
else: | ||||
Eugene Van den Bulke
|
r10249 | # otherwise print the formatted directory name followed by | ||
Greg Caporaso
|
r8631 | # the formatted filenames | ||
Greg Caporaso
|
r8624 | dirname_output_line = dirname_output_format % dirname | ||
Greg Caporaso
|
r8801 | result.append(dirname_output_line) | ||
Greg Caporaso
|
r8619 | for fname in display_fnames: | ||
Greg Caporaso
|
r8624 | fp = fp_format % (dirname,fname) | ||
Greg Caporaso
|
r9305 | if fp_cleaner is not None: | ||
Greg Caporaso
|
r9093 | fp = fp_cleaner(fp) | ||
Greg Caporaso
|
r8624 | try: | ||
# output can include both a filepath and a filename... | ||||
fname_output_line = fname_output_format % (fp, fname) | ||||
except TypeError: | ||||
# ... or just a single filepath | ||||
fname_output_line = fname_output_format % fname | ||||
Greg Caporaso
|
r8801 | result.append(fname_output_line) | ||
return result | ||||
Greg Caporaso
|
r8619 | return f | ||
Greg Caporaso
|
r8624 | def _get_notebook_display_formatter(self, | ||
spacer=" "): | ||||
Greg Caporaso
|
r8802 | """ generate function to use for notebook formatting | ||
Greg Caporaso
|
r8631 | """ | ||
Greg Caporaso
|
r8624 | dirname_output_format = \ | ||
Greg Caporaso
|
r8631 | self.result_html_prefix + "%s/" + self.result_html_suffix | ||
Greg Caporaso
|
r8624 | fname_output_format = \ | ||
self.result_html_prefix + spacer + self.html_link_str + self.result_html_suffix | ||||
fp_format = self.url_prefix + '%s/%s' | ||||
Greg Caporaso
|
r9093 | if sep == "\\": | ||
Eugene Van den Bulke
|
r10249 | # Working on a platform where the path separator is "\", so | ||
Greg Caporaso
|
r9093 | # must convert these to "/" for generating a URI | ||
def fp_cleaner(fp): | ||||
# Replace all occurences of backslash ("\") with a forward | ||||
# slash ("/") - this is necessary on windows when a path is | ||||
# provided as input, but we must link to a URI | ||||
return fp.replace('\\','/') | ||||
else: | ||||
fp_cleaner = None | ||||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8624 | return self._get_display_formatter(dirname_output_format, | ||
fname_output_format, | ||||
Greg Caporaso
|
r9093 | fp_format, | ||
fp_cleaner) | ||||
Greg Caporaso
|
r8619 | |||
Greg Caporaso
|
r8624 | def _get_terminal_display_formatter(self, | ||
spacer=" "): | ||||
Greg Caporaso
|
r8802 | """ generate function to use for terminal formatting | ||
Greg Caporaso
|
r8631 | """ | ||
dirname_output_format = "%s/" | ||||
Greg Caporaso
|
r8624 | fname_output_format = spacer + "%s" | ||
fp_format = '%s/%s' | ||||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8624 | return self._get_display_formatter(dirname_output_format, | ||
fname_output_format, | ||||
fp_format) | ||||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8619 | def _format_path(self): | ||
result_lines = [] | ||||
Doug Blank
|
r19166 | if self.recursive: | ||
walked_dir = list(walk(self.path)) | ||||
else: | ||||
Doug Blank
|
r19367 | walked_dir = [next(walk(self.path))] | ||
Greg Caporaso
|
r8800 | walked_dir.sort() | ||
for dirname, subdirs, fnames in walked_dir: | ||||
Greg Caporaso
|
r8802 | result_lines += self.notebook_display_formatter(dirname, fnames, self.included_suffixes) | ||
Greg Caporaso
|
r8619 | return '\n'.join(result_lines) | ||
Eugene Van den Bulke
|
r10249 | |||
Greg Caporaso
|
r8443 | def __repr__(self): | ||
"""return newline-separated absolute paths | ||||
""" | ||||
Greg Caporaso
|
r8619 | result_lines = [] | ||
Doug Blank
|
r19166 | if self.recursive: | ||
walked_dir = list(walk(self.path)) | ||||
else: | ||||
Doug Blank
|
r19367 | walked_dir = [next(walk(self.path))] | ||
Greg Caporaso
|
r8800 | walked_dir.sort() | ||
for dirname, subdirs, fnames in walked_dir: | ||||
Greg Caporaso
|
r8802 | result_lines += self.terminal_display_formatter(dirname, fnames, self.included_suffixes) | ||
Greg Caporaso
|
r8798 | return '\n'.join(result_lines) | ||