##// END OF EJS Templates
pin requests to 2.4.1 on travis...
pin requests to 2.4.1 on travis bug in requests 2.4.2 doesn't allow unicode URLs on Python 2

File last commit:

r16486:19651d21
r18154:7bf59442
Show More
nbextensions.py
262 lines | 8.6 KiB | text/x-python | PythonLexer
MinRK
add IPython.html.nbextensions.install_nbextension...
r15220 # coding: utf-8
"""Utilities for installing Javascript extensions for the notebook"""
MinRK
add utils.path.ensure_dir_exists...
r16486 # Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
MinRK
add IPython.html.nbextensions.install_nbextension...
r15220
from __future__ import print_function
import os
import shutil
MinRK
support URLs and zip/tarballs in install_extension
r15223 import tarfile
import zipfile
MinRK
add IPython.html.nbextensions.install_nbextension...
r15220 from os.path import basename, join as pjoin
MinRK
support URLs and zip/tarballs in install_extension
r15223 # Deferred imports
try:
from urllib.parse import urlparse # Py3
from urllib.request import urlretrieve
except ImportError:
from urlparse import urlparse
from urllib import urlretrieve
MinRK
add utils.path.ensure_dir_exists...
r16486 from IPython.utils.path import get_ipython_dir, ensure_dir_exists
MinRK
add IPython.html.nbextensions.install_nbextension...
r15220 from IPython.utils.py3compat import string_types, cast_unicode_py2
MinRK
support URLs and zip/tarballs in install_extension
r15223 from IPython.utils.tempdir import TemporaryDirectory
MinRK
add IPython.html.nbextensions.install_nbextension...
r15220
def _should_copy(src, dest, verbose=1):
"""should a file be copied?"""
if not os.path.exists(dest):
return True
if os.stat(dest).st_mtime < os.stat(src).st_mtime:
if verbose >= 2:
print("%s is out of date" % dest)
return True
if verbose >= 2:
print("%s is up to date" % dest)
return False
def _maybe_copy(src, dest, verbose=1):
"""copy a file if it needs updating"""
if _should_copy(src, dest, verbose):
if verbose >= 1:
print("copying %s -> %s" % (src, dest))
shutil.copy2(src, dest)
MinRK
support URLs and zip/tarballs in install_extension
r15223 def _safe_is_tarfile(path):
"""safe version of is_tarfile, return False on IOError"""
try:
return tarfile.is_tarfile(path)
except IOError:
return False
MinRK
add check_nbextension
r15227 def check_nbextension(files, ipython_dir=None):
"""Check whether nbextension files have been installed
files should be a list of relative paths within nbextensions.
Returns True if all files are found, False if any are missing.
"""
ipython_dir = ipython_dir or get_ipython_dir()
nbext = pjoin(ipython_dir, u'nbextensions')
# make sure nbextensions dir exists
if not os.path.exists(nbext):
return False
if isinstance(files, string_types):
# one file given, turn it into a list
files = [files]
MinRK
clarify with all in check_nbextension
r15340 return all(os.path.exists(pjoin(nbext, f)) for f in files)
MinRK
add check_nbextension
r15227
MinRK
allow installing nbextensions with symlinks
r15226 def install_nbextension(files, overwrite=False, symlink=False, ipython_dir=None, verbose=1):
MinRK
add IPython.html.nbextensions.install_nbextension...
r15220 """Install a Javascript extension for the notebook
Stages files and/or directories into IPYTHONDIR/nbextensions.
MinRK
support URLs and zip/tarballs in install_extension
r15223 By default, this compares modification time, and only stages files that need updating.
MinRK
add IPython.html.nbextensions.install_nbextension...
r15220 If `overwrite` is specified, matching files are purged before proceeding.
Parameters
----------
MinRK
support URLs and zip/tarballs in install_extension
r15223 files : list(paths or URLs)
One or more paths or URLs to existing files directories to install.
MinRK
add IPython.html.nbextensions.install_nbextension...
r15220 These will be installed with their base name, so '/path/to/foo'
will install to 'nbextensions/foo'.
MinRK
support URLs and zip/tarballs in install_extension
r15223 Archives (zip or tarballs) will be extracted into the nbextensions directory.
MinRK
add IPython.html.nbextensions.install_nbextension...
r15220 overwrite : bool [default: False]
If True, always install the files, regardless of what may already be installed.
MinRK
allow installing nbextensions with symlinks
r15226 symlink : bool [default: False]
If True, create a symlink in nbextensions, rather than copying files.
Not allowed with URLs or archives.
MinRK
add IPython.html.nbextensions.install_nbextension...
r15220 ipython_dir : str [optional]
The path to an IPython directory, if the default value is not desired.
get_ipython_dir() is used by default.
verbose : int [default: 1]
Set verbosity level. The default is 1, where file actions are printed.
set verbose=2 for more output, or verbose=0 for silence.
"""
ipython_dir = ipython_dir or get_ipython_dir()
nbext = pjoin(ipython_dir, u'nbextensions')
# make sure nbextensions dir exists
MinRK
add utils.path.ensure_dir_exists...
r16486 ensure_dir_exists(nbext)
MinRK
add IPython.html.nbextensions.install_nbextension...
r15220
if isinstance(files, string_types):
# one file given, turn it into a list
files = [files]
for path in map(cast_unicode_py2, files):
MinRK
support URLs and zip/tarballs in install_extension
r15223
if path.startswith(('https://', 'http://')):
MinRK
allow installing nbextensions with symlinks
r15226 if symlink:
raise ValueError("Cannot symlink from URLs")
MinRK
support URLs and zip/tarballs in install_extension
r15223 # Given a URL, download it
with TemporaryDirectory() as td:
filename = urlparse(path).path.split('/')[-1]
local_path = os.path.join(td, filename)
if verbose >= 1:
print("downloading %s to %s" % (path, local_path))
urlretrieve(path, local_path)
# now install from the local copy
MinRK
allow installing nbextensions with symlinks
r15226 install_nbextension(local_path, overwrite, symlink, ipython_dir, verbose)
MinRK
support URLs and zip/tarballs in install_extension
r15223 continue
# handle archives
archive = None
if path.endswith('.zip'):
archive = zipfile.ZipFile(path)
elif _safe_is_tarfile(path):
archive = tarfile.open(path)
if archive:
MinRK
allow installing nbextensions with symlinks
r15226 if symlink:
MinRK
typo
r15339 raise ValueError("Cannot symlink from archives")
MinRK
support URLs and zip/tarballs in install_extension
r15223 if verbose >= 1:
print("extracting %s to %s" % (path, nbext))
archive.extractall(nbext)
archive.close()
continue
MinRK
add IPython.html.nbextensions.install_nbextension...
r15220 dest = pjoin(nbext, basename(path))
if overwrite and os.path.exists(dest):
if verbose >= 1:
print("removing %s" % dest)
if os.path.isdir(dest):
shutil.rmtree(dest)
else:
os.remove(dest)
MinRK
allow installing nbextensions with symlinks
r15226
if symlink:
path = os.path.abspath(path)
if not os.path.exists(dest):
if verbose >= 1:
print("symlink %s -> %s" % (dest, path))
os.symlink(path, dest)
continue
MinRK
add IPython.html.nbextensions.install_nbextension...
r15220
if os.path.isdir(path):
strip_prefix_len = len(path) - len(basename(path))
for parent, dirs, files in os.walk(path):
dest_dir = pjoin(nbext, parent[strip_prefix_len:])
if not os.path.exists(dest_dir):
if verbose >= 2:
print("making directory %s" % dest_dir)
os.makedirs(dest_dir)
for file in files:
src = pjoin(parent, file)
# print("%r, %r" % (dest_dir, file))
dest = pjoin(dest_dir, file)
_maybe_copy(src, dest, verbose)
else:
src = path
_maybe_copy(src, dest, verbose)
MinRK
add `ipython install-nbextension` entrypoint
r15221
#----------------------------------------------------------------------
# install nbextension app
#----------------------------------------------------------------------
from IPython.utils.traitlets import Bool, Enum
from IPython.core.application import BaseIPythonApplication
flags = {
"overwrite" : ({
"NBExtensionApp" : {
"overwrite" : True,
}}, "Force overwrite of existing files"
),
"debug" : ({
"NBExtensionApp" : {
"verbose" : 2,
}}, "Extra output"
),
"quiet" : ({
"NBExtensionApp" : {
"verbose" : 0,
}}, "Minimal output"
),
MinRK
allow installing nbextensions with symlinks
r15226 "symlink" : ({
"NBExtensionApp" : {
"symlink" : True,
}}, "Create symlinks instead of copying files"
),
MinRK
add `ipython install-nbextension` entrypoint
r15221 }
MinRK
allow installing nbextensions with symlinks
r15226 flags['s'] = flags['symlink']
MinRK
add `ipython install-nbextension` entrypoint
r15221 aliases = {
"ipython-dir" : "NBExtensionApp.ipython_dir"
}
class NBExtensionApp(BaseIPythonApplication):
"""Entry point for installing notebook extensions"""
description = """Install IPython notebook extensions
Usage
MinRK
support URLs and zip/tarballs in install_extension
r15223 ipython install-nbextension file [more files, folders, archives or urls]
MinRK
add `ipython install-nbextension` entrypoint
r15221
This copies files and/or folders into the IPython nbextensions directory.
MinRK
support URLs and zip/tarballs in install_extension
r15223 If a URL is given, it will be downloaded.
If an archive is given, it will be extracted into nbextensions.
MinRK
add `ipython install-nbextension` entrypoint
r15221 If the requested files are already up to date, no action is taken
unless --overwrite is specified.
"""
examples = """
ipython install-nbextension /path/to/d3.js /path/to/myextension
"""
aliases = aliases
flags = flags
overwrite = Bool(False, config=True, help="Force overwrite of existing files")
MinRK
allow installing nbextensions with symlinks
r15226 symlink = Bool(False, config=True, help="Create symlinks instead of copying files")
MinRK
add `ipython install-nbextension` entrypoint
r15221 verbose = Enum((0,1,2), default_value=1, config=True,
help="Verbosity level"
)
def install_extensions(self):
install_nbextension(self.extra_args,
overwrite=self.overwrite,
MinRK
allow installing nbextensions with symlinks
r15226 symlink=self.symlink,
MinRK
add `ipython install-nbextension` entrypoint
r15221 verbose=self.verbose,
ipython_dir=self.ipython_dir,
)
def start(self):
if not self.extra_args:
nbext = pjoin(self.ipython_dir, u'nbextensions')
print("Notebook extensions in %s:" % nbext)
for ext in os.listdir(nbext):
print(u" %s" % ext)
else:
self.install_extensions()
if __name__ == '__main__':
NBExtensionApp.launch_instance()