From 6045d4ef0e0d38c7cb38ea9f231333d950ddae95 Mon Sep 17 00:00:00 2001 From: Peter Parente Date: Mon, 4 Jan 2016 17:11:27 -0500 Subject: [PATCH 1/8] Rename urth package to jupyter_cms * Borrow extensionapp.py from nbgrader to install / activate * Start separation of pip install from ext install (c) Copyright IBM Corp. 2016 --- MANIFEST.in | 3 +- {urth/cms => jupyter_cms}/__init__.py | 0 {urth/cms => jupyter_cms}/_version.py | 0 {urth/cms => jupyter_cms}/bundler.py | 0 jupyter_cms/extensionapp.py | 205 ++++++++++++++++++ {urth/cms => jupyter_cms}/index.py | 0 {urth/cms => jupyter_cms}/inject.py | 0 {urth/cms => jupyter_cms}/loader.py | 0 {urth/cms => jupyter_cms}/nb_bundler.py | 0 .../nbextension}/common/dnd_upload.css | 0 .../nbextension}/common/dnd_upload.js | 0 .../nbextension}/common/importer.js | 0 .../nbextension}/common/notify.css | 0 .../nbextension}/common/notify.js | 0 .../nbextension}/common/search.css | 0 .../nbextension}/common/search.js | 0 .../nbextension}/common/topics.js | 0 .../nbextension}/dashboard/main.js | 0 .../nbextension}/dashboard/search.js | 0 .../nbextension}/editor/main.js | 0 .../nbextension}/editor/search.js | 0 .../nbextension}/nls/messages.js | 0 .../nbextension}/notebook/bundle.js | 0 .../nbextension}/notebook/main.js | 0 .../nbextension}/notebook/search.js | 0 .../nbextension}/notebook/toc.css | 0 .../nbextension}/notebook/toc.js | 0 {urth/cms => jupyter_cms}/search.py | 0 {urth/cms => jupyter_cms}/uploads.py | 0 scripts/jupyter-cms | 7 + setup.py | 61 +----- test/test_bundler.py | 2 +- test/test_inject.py | 4 +- test/test_loader.py | 2 +- urth/__init__.py | 0 35 files changed, 222 insertions(+), 62 deletions(-) rename {urth/cms => jupyter_cms}/__init__.py (100%) rename {urth/cms => jupyter_cms}/_version.py (100%) rename {urth/cms => jupyter_cms}/bundler.py (100%) create mode 100644 jupyter_cms/extensionapp.py rename {urth/cms => jupyter_cms}/index.py (100%) rename {urth/cms => jupyter_cms}/inject.py (100%) rename {urth/cms => jupyter_cms}/loader.py (100%) rename {urth/cms => jupyter_cms}/nb_bundler.py (100%) rename {urth_cms_js => jupyter_cms/nbextension}/common/dnd_upload.css (100%) rename {urth_cms_js => jupyter_cms/nbextension}/common/dnd_upload.js (100%) rename {urth_cms_js => jupyter_cms/nbextension}/common/importer.js (100%) rename {urth_cms_js => jupyter_cms/nbextension}/common/notify.css (100%) rename {urth_cms_js => jupyter_cms/nbextension}/common/notify.js (100%) rename {urth_cms_js => jupyter_cms/nbextension}/common/search.css (100%) rename {urth_cms_js => jupyter_cms/nbextension}/common/search.js (100%) rename {urth_cms_js => jupyter_cms/nbextension}/common/topics.js (100%) rename {urth_cms_js => jupyter_cms/nbextension}/dashboard/main.js (100%) rename {urth_cms_js => jupyter_cms/nbextension}/dashboard/search.js (100%) rename {urth_cms_js => jupyter_cms/nbextension}/editor/main.js (100%) rename {urth_cms_js => jupyter_cms/nbextension}/editor/search.js (100%) rename {urth_cms_js => jupyter_cms/nbextension}/nls/messages.js (100%) rename {urth_cms_js => jupyter_cms/nbextension}/notebook/bundle.js (100%) rename {urth_cms_js => jupyter_cms/nbextension}/notebook/main.js (100%) rename {urth_cms_js => jupyter_cms/nbextension}/notebook/search.js (100%) rename {urth_cms_js => jupyter_cms/nbextension}/notebook/toc.css (100%) rename {urth_cms_js => jupyter_cms/nbextension}/notebook/toc.js (100%) rename {urth/cms => jupyter_cms}/search.py (100%) rename {urth/cms => jupyter_cms}/uploads.py (100%) create mode 100644 scripts/jupyter-cms delete mode 100644 urth/__init__.py diff --git a/MANIFEST.in b/MANIFEST.in index 8ef2540..7bcde35 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1 @@ -recursive-include urth_cms_js *.js *.css -include VERSION \ No newline at end of file +recursive-include jupyter_cms/nbextension *.js *.css diff --git a/urth/cms/__init__.py b/jupyter_cms/__init__.py similarity index 100% rename from urth/cms/__init__.py rename to jupyter_cms/__init__.py diff --git a/urth/cms/_version.py b/jupyter_cms/_version.py similarity index 100% rename from urth/cms/_version.py rename to jupyter_cms/_version.py diff --git a/urth/cms/bundler.py b/jupyter_cms/bundler.py similarity index 100% rename from urth/cms/bundler.py rename to jupyter_cms/bundler.py diff --git a/jupyter_cms/extensionapp.py b/jupyter_cms/extensionapp.py new file mode 100644 index 0000000..e508f0a --- /dev/null +++ b/jupyter_cms/extensionapp.py @@ -0,0 +1,205 @@ +# Copyright (c) Jupyter Development Team. +# Distributed under the terms of the Modified BSD License. +import errno +import os.path +import sys + +from jupyter_core.paths import jupyter_config_dir +from notebook.services.config import ConfigManager +from notebook.nbextensions import (InstallNBExtensionApp, EnableNBExtensionApp, + DisableNBExtensionApp, flags, aliases) +from traitlets import Unicode +from traitlets.config.application import catch_config_error +from traitlets.config.application import Application + +# Make copies to reuse flags and aliases +INSTALL_FLAGS = {} +INSTALL_FLAGS.update(flags) + +INSTALL_ALIASES = {} +INSTALL_ALIASES.update(aliases) +del INSTALL_ALIASES['destination'] + +def makedirs(path): + ''' + mkdir -p and ignore existence errors compatible with Py2/3. + ''' + try: + os.makedirs(path) + except OSError as e: + if e.errno == errno.EEXIST and os.path.isdir(path): + pass + else: + raise + +class ExtensionInstallApp(InstallNBExtensionApp): + '''Subclass that installs this particular extension.''' + name = u'jupyter-cms-extension-install' + description = u'Install the jupyter_cms extension' + + flags = INSTALL_FLAGS + aliases = INSTALL_ALIASES + + examples = """ + jupyter cms install + jupyter cms install --user + jupyter cms install --prefix=/path/to/prefix + jupyter cms install --nbextensions=/path/to/nbextensions + """ + + destination = Unicode('') + + def _classes_default(self): + return [ExtensionInstallApp, InstallNBExtensionApp] + + def start(self): + here = os.path.abspath(os.path.join(os.path.dirname(__file__))) + + self.log.info("Installing jupyter_cms JS notebook extensions") + self.extra_args = [os.path.join(here, 'nbextension')] + self.destination = 'jupyter_cms' + self.install_extensions() + + +class ExtensionActivateApp(EnableNBExtensionApp): + '''Subclass that activates this particular extension.''' + name = u'jupyter-cms-extension-activate' + description = u'Activate the jupyter_cms extension' + + flags = {} + aliases = {} + + examples = """ + jupyter cms activate + """ + + def _classes_default(self): + return [ExtensionActivateApp, EnableNBExtensionApp] + + def enable_server_extension(self, extension): + server_cm = ConfigManager(config_dir=jupyter_config_dir()) + + makedirs(server_cm.config_dir) + + cfg = server_cm.get('jupyter_notebook_config') + server_extensions = ( + cfg.setdefault('NotebookApp', {}) + .setdefault('server_extensions', []) + ) + if extension not in server_extensions: + cfg['NotebookApp']['server_extensions'] += [extension] + server_cm.update('jupyter_notebook_config', cfg) + + def start(self): + self.log.info("Activating jupyter_cms notebook server extensions") + self.enable_server_extension('jupyter_cms') + + self.log.info("Activating jupyter_cms JS notebook extensions") + self.section = "notebook" + self.enable_nbextension("jupyter_cms/notebook/main") + self.section = "tree" + self.enable_nbextension("jupyter_cms/dashboard/main") + self.section = "edit" + self.enable_nbextension("jupyter_cms/editor/main") + + self.log.info("Done. You may need to restart the Jupyter notebook server for changes to take effect.") + +class ExtensionDeactivateApp(DisableNBExtensionApp): + '''Subclass that deactivates this particular extension.''' + name = u'nbgrader-extension-deactivate' + description = u'Deactivate the nbgrader extension' + + flags = {} + aliases = {} + + examples = """ + nbgrader extension deactivate + """ + + def _classes_default(self): + return [ExtensionDeactivateApp, DisableNBExtensionApp] + + # def _recursive_get(self, obj, key_list): + # if obj is None or len(key_list) == 0: + # return obj + # return self._recursive_get(obj.get(key_list[0], None), key_list[1:]) + + def disable_server_extension(self, extension): + server_cm = ConfigManager(config_dir=jupyter_config_dir()) + + makedirs(server_cm.config_dir) + + cfg = server_cm.get('jupyter_notebook_config') + if ('NotebookApp' in cfg and + 'server_extensions' in cfg['NotebookApp'] and + extension in cfg['NotebookApp']['server_extensions']): + cfg['NotebookApp']['server_extensions'].remove(extension) + + server_cm.update('jupyter_notebook_config', cfg) + + server_extensions = ( + cfg.setdefault('NotebookApp', {}) + .setdefault('server_extensions', []) + ) + if extension in server_extensions: + cfg['NotebookApp']['server_extensions'].remove(extension) + server_cm.update('jupyter_notebook_config', cfg) + + def start(self): + self.log.info("Deactivating jupyter_cms notebook server extensions") + self.disable_server_extension('jupyter_cms') + + self.log.info("Deactivating jupyter_cms JS notebook extensions") + self.section = "notebook" + self.disable_nbextension("jupyter_cms/notebook/main") + self.section = "tree" + self.disable_nbextension("jupyter_cms/dashboard/main") + self.section = "edit" + self.disable_nbextension("jupyter_cms/editor/main") + + self.log.info("Done. You may need to restart the Jupyter notebook server for changes to take effect.") + +class ExtensionApp(Application): + + name = u'jupyter_cms extension' + description = u'Utilities for managing the jupyter_cms extension' + examples = "" + + subcommands = dict( + install=( + ExtensionInstallApp, + "Install the extension." + ), + activate=( + ExtensionActivateApp, + "Activate the extension." + ), + deactivate=( + ExtensionDeactivateApp, + "Deactivate the extension." + ) + ) + + def _classes_default(self): + classes = super(ExtensionApp, self)._classes_default() + + # include all the apps that have configurable options + for appname, (app, help) in self.subcommands.items(): + if len(app.class_traits(config=True)) > 0: + classes.append(app) + + @catch_config_error + def initialize(self, argv=None): + super(ExtensionApp, self).initialize(argv) + + def start(self): + # check: is there a subapp given? + if self.subapp is None: + self.print_help() + sys.exit(1) + + # This starts subapps + super(ExtensionApp, self).start() + +def main(): + ExtensionApp.launch_instance() diff --git a/urth/cms/index.py b/jupyter_cms/index.py similarity index 100% rename from urth/cms/index.py rename to jupyter_cms/index.py diff --git a/urth/cms/inject.py b/jupyter_cms/inject.py similarity index 100% rename from urth/cms/inject.py rename to jupyter_cms/inject.py diff --git a/urth/cms/loader.py b/jupyter_cms/loader.py similarity index 100% rename from urth/cms/loader.py rename to jupyter_cms/loader.py diff --git a/urth/cms/nb_bundler.py b/jupyter_cms/nb_bundler.py similarity index 100% rename from urth/cms/nb_bundler.py rename to jupyter_cms/nb_bundler.py diff --git a/urth_cms_js/common/dnd_upload.css b/jupyter_cms/nbextension/common/dnd_upload.css similarity index 100% rename from urth_cms_js/common/dnd_upload.css rename to jupyter_cms/nbextension/common/dnd_upload.css diff --git a/urth_cms_js/common/dnd_upload.js b/jupyter_cms/nbextension/common/dnd_upload.js similarity index 100% rename from urth_cms_js/common/dnd_upload.js rename to jupyter_cms/nbextension/common/dnd_upload.js diff --git a/urth_cms_js/common/importer.js b/jupyter_cms/nbextension/common/importer.js similarity index 100% rename from urth_cms_js/common/importer.js rename to jupyter_cms/nbextension/common/importer.js diff --git a/urth_cms_js/common/notify.css b/jupyter_cms/nbextension/common/notify.css similarity index 100% rename from urth_cms_js/common/notify.css rename to jupyter_cms/nbextension/common/notify.css diff --git a/urth_cms_js/common/notify.js b/jupyter_cms/nbextension/common/notify.js similarity index 100% rename from urth_cms_js/common/notify.js rename to jupyter_cms/nbextension/common/notify.js diff --git a/urth_cms_js/common/search.css b/jupyter_cms/nbextension/common/search.css similarity index 100% rename from urth_cms_js/common/search.css rename to jupyter_cms/nbextension/common/search.css diff --git a/urth_cms_js/common/search.js b/jupyter_cms/nbextension/common/search.js similarity index 100% rename from urth_cms_js/common/search.js rename to jupyter_cms/nbextension/common/search.js diff --git a/urth_cms_js/common/topics.js b/jupyter_cms/nbextension/common/topics.js similarity index 100% rename from urth_cms_js/common/topics.js rename to jupyter_cms/nbextension/common/topics.js diff --git a/urth_cms_js/dashboard/main.js b/jupyter_cms/nbextension/dashboard/main.js similarity index 100% rename from urth_cms_js/dashboard/main.js rename to jupyter_cms/nbextension/dashboard/main.js diff --git a/urth_cms_js/dashboard/search.js b/jupyter_cms/nbextension/dashboard/search.js similarity index 100% rename from urth_cms_js/dashboard/search.js rename to jupyter_cms/nbextension/dashboard/search.js diff --git a/urth_cms_js/editor/main.js b/jupyter_cms/nbextension/editor/main.js similarity index 100% rename from urth_cms_js/editor/main.js rename to jupyter_cms/nbextension/editor/main.js diff --git a/urth_cms_js/editor/search.js b/jupyter_cms/nbextension/editor/search.js similarity index 100% rename from urth_cms_js/editor/search.js rename to jupyter_cms/nbextension/editor/search.js diff --git a/urth_cms_js/nls/messages.js b/jupyter_cms/nbextension/nls/messages.js similarity index 100% rename from urth_cms_js/nls/messages.js rename to jupyter_cms/nbextension/nls/messages.js diff --git a/urth_cms_js/notebook/bundle.js b/jupyter_cms/nbextension/notebook/bundle.js similarity index 100% rename from urth_cms_js/notebook/bundle.js rename to jupyter_cms/nbextension/notebook/bundle.js diff --git a/urth_cms_js/notebook/main.js b/jupyter_cms/nbextension/notebook/main.js similarity index 100% rename from urth_cms_js/notebook/main.js rename to jupyter_cms/nbextension/notebook/main.js diff --git a/urth_cms_js/notebook/search.js b/jupyter_cms/nbextension/notebook/search.js similarity index 100% rename from urth_cms_js/notebook/search.js rename to jupyter_cms/nbextension/notebook/search.js diff --git a/urth_cms_js/notebook/toc.css b/jupyter_cms/nbextension/notebook/toc.css similarity index 100% rename from urth_cms_js/notebook/toc.css rename to jupyter_cms/nbextension/notebook/toc.css diff --git a/urth_cms_js/notebook/toc.js b/jupyter_cms/nbextension/notebook/toc.js similarity index 100% rename from urth_cms_js/notebook/toc.js rename to jupyter_cms/nbextension/notebook/toc.js diff --git a/urth/cms/search.py b/jupyter_cms/search.py similarity index 100% rename from urth/cms/search.py rename to jupyter_cms/search.py diff --git a/urth/cms/uploads.py b/jupyter_cms/uploads.py similarity index 100% rename from urth/cms/uploads.py rename to jupyter_cms/uploads.py diff --git a/scripts/jupyter-cms b/scripts/jupyter-cms new file mode 100644 index 0000000..ed80cd8 --- /dev/null +++ b/scripts/jupyter-cms @@ -0,0 +1,7 @@ +#!/usr/bin/env python +# Copyright (c) Jupyter Development Team. +# Distributed under the terms of the Modified BSD License. +import jupyter_cms.extensionapp + +if __name__ == '__main__': + jupyter_cms.extensionapp.main() diff --git a/setup.py b/setup.py index ca4b9c1..f35b7e7 100644 --- a/setup.py +++ b/setup.py @@ -3,64 +3,15 @@ import os from setuptools import setup -from setuptools.command.install import install -from setuptools.command.develop import develop - -from notebook.nbextensions import install_nbextension -from notebook.services.config import ConfigManager -from jupyter_core.paths import jupyter_config_dir # Get location of this file at runtime HERE = os.path.abspath(os.path.dirname(__file__)) # Eval the version tuple and string from the source VERSION_NS = {} -with open(os.path.join(HERE, 'urth/cms/_version.py')) as f: +with open(os.path.join(HERE, 'jupyter_cms', '_version.py')) as f: exec(f.read(), {}, VERSION_NS) -EXT_DIR = os.path.join(os.path.dirname(__file__), 'urth_cms_js') -SERVER_EXT_CONFIG = "c.NotebookApp.server_extensions.append('urth.cms')" - -def _install_notebook_extension(): - print('Installing notebook extension') - install_nbextension(EXT_DIR, overwrite=True, user=True) - cm = ConfigManager() - print('Enabling extension for notebook') - cm.update('notebook', {"load_extensions": {'urth_cms_js/notebook/main': True}}) - print('Enabling extension for dashboard') - cm.update('tree', {"load_extensions": {'urth_cms_js/dashboard/main': True}}) - print('Enabling extension for text editor') - cm.update('edit', {"load_extensions": {'urth_cms_js/editor/main': True}}) - print('Enabling notebook and associated files bundler') - cm.update('notebook', { - 'jupyter_cms_bundlers': { - 'notebook_associations_download': { - 'label': 'IPython Notebook bundle (.zip)', - 'module_name': 'urth.cms.nb_bundler', - 'group': 'download' - } - } - }) - - print('Installing notebook server extension') - fn = os.path.join(jupyter_config_dir(), 'jupyter_notebook_config.py') - with open(fn, 'r+') as fh: - lines = fh.read() - if SERVER_EXT_CONFIG not in lines: - fh.seek(0, 2) - fh.write('\n') - fh.write(SERVER_EXT_CONFIG) - -class InstallCommand(install): - def run(self): - install.run(self) - _install_notebook_extension() - -class DevelopCommand(develop): - def run(self): - develop.run(self) - _install_notebook_extension() - install_requires=[ 'whoosh>=2.7.0, <3.0', ] @@ -93,14 +44,12 @@ def run(self): license='BSD', platforms=['Jupyter Notebook 4.0.x'], packages=[ - 'urth', - 'urth.cms' + 'jupyter_cms' + ], + scripts=[ + 'scripts/jupyter-cms' ], install_requires=install_requires, - cmdclass={ - 'install': InstallCommand, - 'develop': DevelopCommand, - }, classifiers=[ 'Intended Audience :: Developers', 'Intended Audience :: System Administrators', diff --git a/test/test_bundler.py b/test/test_bundler.py index edb2b1d..f986b72 100644 --- a/test/test_bundler.py +++ b/test/test_bundler.py @@ -5,7 +5,7 @@ import os import shutil import tempfile -import urth.cms.bundler as bundler +import jupyter_cms.bundler as bundler HERE = os.path.abspath(os.path.dirname(__file__)) diff --git a/test/test_inject.py b/test/test_inject.py index 6614ddc..4b3dcd2 100644 --- a/test/test_inject.py +++ b/test/test_inject.py @@ -2,8 +2,8 @@ # Distributed under the terms of the Modified BSD License. import unittest -import urth.cms.loader as loader -import urth.cms.inject as inject +import jupyter_cms.loader as loader +import jupyter_cms.inject as inject from os.path import join as pjoin from os.path import abspath, dirname diff --git a/test/test_loader.py b/test/test_loader.py index d4c6bd9..6c0fe0a 100644 --- a/test/test_loader.py +++ b/test/test_loader.py @@ -3,7 +3,7 @@ import os import unittest -import urth.cms.loader as loader +import jupyter_cms.loader as loader from os.path import join as pjoin from os.path import abspath, dirname diff --git a/urth/__init__.py b/urth/__init__.py deleted file mode 100644 index e69de29..0000000 From 2be967bc1769d7f2c5f0dc90b2b1cb50342019ec Mon Sep 17 00:00:00 2001 From: Peter Parente Date: Tue, 5 Jan 2016 09:08:54 -0500 Subject: [PATCH 2/8] Update dev automation (c) Copyright IBM Corp. 2016 --- Makefile | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 3c7d9df..ab7e72a 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,18 @@ PYTHON?=python3 -REPO:=jupyter/pyspark-notebook:a388c4a66fd4 -DEV_REPO:=jupyter/pyspark-notebook-cms:a388c4a66fd4 +REPO:=jupyter/pyspark-notebook:2988869079e6 +DEV_REPO:=jupyter/pyspark-notebook-cms:2988869079e6 PYTHON2_SETUP:=source activate python2 +define EXT_DEV_SETUP + pushd /src && \ + pip install --no-deps -e . && \ + jupyter cms install --user && \ + jupyter cms activate && \ + popd +endef + help: @echo 'Host commands:' @echo ' build - build dev image' @@ -35,14 +43,13 @@ clean: dev: dev-$(PYTHON) -dev-python2: SETUP_CMD?=$(PYTHON2_SETUP); pushd /src && pip install --no-deps -e . && popd +dev-python2: LANG_SETUP_CMD?=$(PYTHON2_SETUP) && python --version dev-python2: _dev -dev-python3: SETUP_CMD?=pushd /src && pip install --no-deps -e . && popd +dev-python3: LANG_SETUP_CMD?=python --version dev-python3: _dev -_dev: NB_HOME?=/root -_dev: CMD?=sh -c "python --version; jupyter notebook --no-browser --port 8888 --ip='*'" +_dev: CMD?=start-notebook.sh _dev: AUTORELOAD?=no _dev: @docker run -it --rm \ @@ -51,7 +58,7 @@ _dev: -e AUTORELOAD=$(AUTORELOAD) \ -v `pwd`:/src \ -v `pwd`/etc/notebooks:/home/jovyan/work \ - $(DEV_REPO) bash -c '$(SETUP_CMD); $(CMD)' + $(DEV_REPO) bash -c '$(LANG_SETUP_CMD) && $(EXT_DEV_SETUP) && $(CMD)' install: CMD?=exit install: @@ -60,6 +67,8 @@ install: -v `pwd`:/src \ $(REPO) bash -c 'cd /src/dist && \ pip install --no-binary :all: $$(ls -1 *.tar.gz | tail -n 1) && \ + jupyter cms install && \ + jupyter cms activate && \ $(CMD)' sdist: REPO?=jupyter/pyspark-notebook:$(TAG) From de0a7deda08db9b833f33f8fdd3fe93756197f29 Mon Sep 17 00:00:00 2001 From: Peter Parente Date: Tue, 5 Jan 2016 09:09:28 -0500 Subject: [PATCH 3/8] Cleanup instructions and leftover code (c) Copyright IBM Corp. 2016 --- README.md | 22 ++++++++++++++++++- .../cookbooks_demo/use_cookbooks.ipynb | 6 ++--- jupyter_cms/extensionapp.py | 5 ----- setup.py | 2 ++ 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f3d6b3a..0b2ccfd 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,27 @@ Note that both of these deployments tend to lag the latest stable release. ## Install It -`pip install jupyter_cms` and then restart your Notebook server if it was running during the install. +```bash +# install the python package +pip install jupyter_cms +# install the JS extensions into ~/.local/jupyter +# see jupyter cms install --help for other options +jupyter cms install --user --symlink --overwrite +# enable the JS and server extensions in your ~/.jupyter +jupyter cms activate + +# deactivate it later with +jupyter cms deactivate +``` + +You will need to restart your notebook server if it was running during the activate step. + +## Uninstall It + +```bash +# + + ## Writing Bundlers diff --git a/etc/notebooks/cookbooks_demo/use_cookbooks.ipynb b/etc/notebooks/cookbooks_demo/use_cookbooks.ipynb index 3761af5..7b26beb 100644 --- a/etc/notebooks/cookbooks_demo/use_cookbooks.ipynb +++ b/etc/notebooks/cookbooks_demo/use_cookbooks.ipynb @@ -36,7 +36,7 @@ "source": [ "### Enable the extension\n", "\n", - "To start, we first need to load the content management extension. This magic makes it possible to import other notebooks as Python modules. (The `urth` bit comes from a historical codename for the extension and will likely change in the future.)" + "To start, we first need to load the content management extension. This magic makes it possible to import other notebooks as Python modules." ] }, { @@ -47,7 +47,7 @@ }, "outputs": [], "source": [ - "%load_ext urth.cms" + "%load_ext jupyter_cms" ] }, { @@ -101,7 +101,7 @@ }, "outputs": [], "source": [ - "from urth.cms.loader import load_notebook" + "from jupyter_cms.loader import load_notebook" ] }, { diff --git a/jupyter_cms/extensionapp.py b/jupyter_cms/extensionapp.py index e508f0a..7ff4007 100644 --- a/jupyter_cms/extensionapp.py +++ b/jupyter_cms/extensionapp.py @@ -119,11 +119,6 @@ class ExtensionDeactivateApp(DisableNBExtensionApp): def _classes_default(self): return [ExtensionDeactivateApp, DisableNBExtensionApp] - # def _recursive_get(self, obj, key_list): - # if obj is None or len(key_list) == 0: - # return obj - # return self._recursive_get(obj.get(key_list[0], None), key_list[1:]) - def disable_server_extension(self, extension): server_cm = ConfigManager(config_dir=jupyter_config_dir()) diff --git a/setup.py b/setup.py index f35b7e7..93d830a 100644 --- a/setup.py +++ b/setup.py @@ -35,6 +35,8 @@ * IPython kernel extension to make notebooks importable, and notebook cells injectable via # and # annotations * Full-page drag-and-drop upload target * Pop-over table of contents navigation for notebooks +* Plugin system for deploying and downloading notebook bundles +* Example *IPython Notebook bundle (.zip)* download bundler See `the project README `_ for more information. From 40062afa424dbb4d0d57d8be987b7367e521ea64 Mon Sep 17 00:00:00 2001 From: Peter Parente Date: Tue, 5 Jan 2016 14:12:10 -0500 Subject: [PATCH 4/8] Fix install options in makefile (c) Copyright IBM Corp. 2016 --- Makefile | 3 +-- setup.py | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index ab7e72a..b9f3af9 100644 --- a/Makefile +++ b/Makefile @@ -63,11 +63,10 @@ _dev: install: CMD?=exit install: @docker run -it --rm \ - --user jovyan \ -v `pwd`:/src \ $(REPO) bash -c 'cd /src/dist && \ pip install --no-binary :all: $$(ls -1 *.tar.gz | tail -n 1) && \ - jupyter cms install && \ + jupyter cms install --user && \ jupyter cms activate && \ $(CMD)' diff --git a/setup.py b/setup.py index 93d830a..6aa5964 100644 --- a/setup.py +++ b/setup.py @@ -48,6 +48,7 @@ packages=[ 'jupyter_cms' ], + include_package_data=True, scripts=[ 'scripts/jupyter-cms' ], From 4e3e65fb633f859a1b52bbf8bd601ada0d926f65 Mon Sep 17 00:00:00 2001 From: Peter Parente Date: Tue, 5 Jan 2016 14:12:50 -0500 Subject: [PATCH 5/8] Complete the uninstall note (c) Copyright IBM Corp. 2016 --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0b2ccfd..c96a4bb 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Note that both of these deployments tend to lag the latest stable release. ```bash # install the python package pip install jupyter_cms -# install the JS extensions into ~/.local/jupyter +# register the notebook frontend extensions into ~/.local/jupyter # see jupyter cms install --help for other options jupyter cms install --user --symlink --overwrite # enable the JS and server extensions in your ~/.jupyter @@ -50,9 +50,11 @@ You will need to restart your notebook server if it was running during the activ ## Uninstall It ```bash -# - +jupyter cms deactivate +pip uninstall jupyter_cms +``` +Note that there is no Jupyter method for removing the installed JavaScript extension assets. You will need to clean them up manually from your chosen install location. ## Writing Bundlers From 04b629fe55c3e5cf0745cbb1d2ccada7285d7d30 Mon Sep 17 00:00:00 2001 From: Peter Parente Date: Thu, 7 Jan 2016 14:38:34 -0500 Subject: [PATCH 6/8] Fix forgotten assoc bundler, nbgrader comment (c) Copyright IBM Corp. 2016 --- jupyter_cms/extensionapp.py | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/jupyter_cms/extensionapp.py b/jupyter_cms/extensionapp.py index 7ff4007..dee9a57 100644 --- a/jupyter_cms/extensionapp.py +++ b/jupyter_cms/extensionapp.py @@ -77,6 +77,7 @@ def _classes_default(self): return [ExtensionActivateApp, EnableNBExtensionApp] def enable_server_extension(self, extension): + '''Enables the server side extension in the user config.''' server_cm = ConfigManager(config_dir=jupyter_config_dir()) makedirs(server_cm.config_dir) @@ -90,6 +91,19 @@ def enable_server_extension(self, extension): cfg['NotebookApp']['server_extensions'] += [extension] server_cm.update('jupyter_notebook_config', cfg) + def enable_bundler(self): + '''Enables the notebook bundler extension.''' + cm = ConfigManager(parent=self, config=self.config) + cm.update('notebook', { + 'jupyter_cms_bundlers': { + 'notebook_associations_download': { + 'label': 'IPython Notebook bundle (.zip)', + 'module_name': 'jupyter_cms.nb_bundler', + 'group': 'download' + } + } + }) + def start(self): self.log.info("Activating jupyter_cms notebook server extensions") self.enable_server_extension('jupyter_cms') @@ -101,25 +115,27 @@ def start(self): self.enable_nbextension("jupyter_cms/dashboard/main") self.section = "edit" self.enable_nbextension("jupyter_cms/editor/main") + self.enable_bundler() self.log.info("Done. You may need to restart the Jupyter notebook server for changes to take effect.") class ExtensionDeactivateApp(DisableNBExtensionApp): '''Subclass that deactivates this particular extension.''' - name = u'nbgrader-extension-deactivate' - description = u'Deactivate the nbgrader extension' + name = u'jupyter-cms-extension-deactivate' + description = u'Deactivate the jupyter_cms extension' flags = {} aliases = {} examples = """ - nbgrader extension deactivate + jupyter cms deactivate """ def _classes_default(self): return [ExtensionDeactivateApp, DisableNBExtensionApp] def disable_server_extension(self, extension): + '''Disables the server side extension in the user config.''' server_cm = ConfigManager(config_dir=jupyter_config_dir()) makedirs(server_cm.config_dir) @@ -140,6 +156,15 @@ def disable_server_extension(self, extension): cfg['NotebookApp']['server_extensions'].remove(extension) server_cm.update('jupyter_notebook_config', cfg) + def disable_bundler(self): + '''Disables the notebook bundler extension.''' + cm = ConfigManager(parent=self, config=self.config) + cm.update('notebook', { + 'jupyter_cms_bundlers': { + 'notebook_associations_download': None + } + }) + def start(self): self.log.info("Deactivating jupyter_cms notebook server extensions") self.disable_server_extension('jupyter_cms') @@ -151,11 +176,12 @@ def start(self): self.disable_nbextension("jupyter_cms/dashboard/main") self.section = "edit" self.disable_nbextension("jupyter_cms/editor/main") + self.disable_bundler() self.log.info("Done. You may need to restart the Jupyter notebook server for changes to take effect.") class ExtensionApp(Application): - + '''CLI for extension management.''' name = u'jupyter_cms extension' description = u'Utilities for managing the jupyter_cms extension' examples = "" From 309c61a2eae80b860e52760b634e34035d817ae3 Mon Sep 17 00:00:00 2001 From: Peter Parente Date: Mon, 11 Jan 2016 12:45:42 -0500 Subject: [PATCH 7/8] Remove leftover REPO variable on sdist target (c) Copyright IBM Corp. 2016 --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index b9f3af9..fc5f45b 100644 --- a/Makefile +++ b/Makefile @@ -70,7 +70,6 @@ install: jupyter cms activate && \ $(CMD)' -sdist: REPO?=jupyter/pyspark-notebook:$(TAG) sdist: @docker run -it --rm \ -v `pwd`:/src \ From 88d7e13c90018d330e01a0ac28525b915dbfd0c7 Mon Sep 17 00:00:00 2001 From: Peter Parente Date: Wed, 20 Jan 2016 09:29:00 -0500 Subject: [PATCH 8/8] Use setuptools entry_points when available Properly installs top-level scripts as exes on Windows (c) Copyright IBM Corp. 2016 --- setup.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 6aa5964..d65afc5 100644 --- a/setup.py +++ b/setup.py @@ -2,6 +2,7 @@ # Distributed under the terms of the Modified BSD License. import os +import sys from setuptools import setup # Get location of this file at runtime @@ -16,14 +17,14 @@ 'whoosh>=2.7.0, <3.0', ] -# Use the built-in version of scandir if possible, +# Use the built-in version of scandir if possible, # otherwise require the scandir module try: from os import scandir except ImportError: install_requires.append('scandir>=1.1, <2.0') -setup( +setup_args = dict( name='jupyter_cms', author='Jupyter Development Team', author_email='jupyter@googlegroups.com', @@ -39,8 +40,8 @@ * Example *IPython Notebook bundle (.zip)* download bundler See `the project README `_ -for more information. -''', +for more information. +''', url='https://github.com/jupyter-incubator/contentmanagement', version=VERSION_NS['__version__'], license='BSD', @@ -64,4 +65,17 @@ 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5' ] -) \ No newline at end of file +) + +if 'setuptools' in sys.modules: + # setupstools turns entrypoint scripts into executables on windows + setup_args['entry_points'] = { + 'console_scripts': [ + 'jupyter-cms = jupyter_cms.extensionapp:main' + ] + } + # Don't bother installing the .py scripts if if we're using entrypoints + setup_args.pop('scripts', None) + +if __name__ == '__main__': + setup(**setup_args)