123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- # Copyright (c) Jupyter Development Team.
- # Distributed under the terms of the Modified BSD License.
- import sys
- import os
- from ..extensions import BaseExtensionApp, _get_config_dir, GREEN_ENABLED, RED_DISABLED
- from .._version import __version__
- from notebook.config_manager import BaseJSONConfigManager
- from jupyter_core.paths import jupyter_config_path
- from traitlets.utils.importstring import import_item
- from traitlets import Bool
- BUNDLER_SECTION = "notebook"
- BUNDLER_SUBSECTION = "bundlerextensions"
- def _get_bundler_metadata(module):
- """Gets the list of bundlers associated with a Python package.
-
- Returns a tuple of (the module, [{
- 'name': 'unique name of the bundler',
- 'label': 'file menu item label for the bundler',
- 'module_name': 'dotted package/module name containing the bundler',
- 'group': 'download or deploy parent menu item'
- }])
-
- Parameters
- ----------
- module : str
- Importable Python module exposing the
- magic-named `_jupyter_bundlerextension_paths` function
- """
- m = import_item(module)
- if not hasattr(m, '_jupyter_bundlerextension_paths'):
- raise KeyError('The Python module {} does not contain a valid bundlerextension'.format(module))
- bundlers = m._jupyter_bundlerextension_paths()
- return m, bundlers
- def _set_bundler_state(name, label, module_name, group, state,
- user=True, sys_prefix=False, logger=None):
- """Set whether a bundler is enabled or disabled.
-
- Returns True if the final state is the one requested.
-
- Parameters
- ----------
- name : string
- Unique name of the bundler
- label : string
- Human-readable label for the bundler menu item in the notebook UI
- module_name : string
- Dotted module/package name containing the bundler
- group : string
- 'download' or 'deploy' indicating the parent menu containing the label
- state : bool
- The state in which to leave the extension
- user : bool [default: True]
- Whether to update the user's .jupyter/nbconfig directory
- sys_prefix : bool [default: False]
- Whether to update the sys.prefix, i.e. environment. Will override
- `user`.
- logger : Jupyter logger [optional]
- Logger instance to use
- """
- user = False if sys_prefix else user
- config_dir = os.path.join(
- _get_config_dir(user=user, sys_prefix=sys_prefix), 'nbconfig')
- cm = BaseJSONConfigManager(config_dir=config_dir)
-
- if logger:
- logger.info("{} {} bundler {}...".format(
- "Enabling" if state else "Disabling",
- name,
- module_name
- ))
-
- if state:
- cm.update(BUNDLER_SECTION, {
- BUNDLER_SUBSECTION: {
- name: {
- "label": label,
- "module_name": module_name,
- "group" : group
- }
- }
- })
- else:
- cm.update(BUNDLER_SECTION, {
- BUNDLER_SUBSECTION: {
- name: None
- }
- })
- return (cm.get(BUNDLER_SECTION)
- .get(BUNDLER_SUBSECTION, {})
- .get(name) is not None) == state
-
- def _set_bundler_state_python(state, module, user, sys_prefix, logger=None):
- """Enables or disables bundlers defined in a Python package.
-
- Returns a list of whether the state was achieved for each bundler.
-
- Parameters
- ----------
- state : Bool
- Whether the extensions should be enabled
- module : str
- Importable Python module exposing the
- magic-named `_jupyter_bundlerextension_paths` function
- user : bool
- Whether to enable in the user's nbconfig directory.
- sys_prefix : bool
- Enable/disable in the sys.prefix, i.e. environment
- logger : Jupyter logger [optional]
- Logger instance to use
- """
- m, bundlers = _get_bundler_metadata(module)
- return [_set_bundler_state(name=bundler["name"],
- label=bundler["label"],
- module_name=bundler["module_name"],
- group=bundler["group"],
- state=state,
- user=user, sys_prefix=sys_prefix,
- logger=logger)
- for bundler in bundlers]
- def enable_bundler_python(module, user=True, sys_prefix=False, logger=None):
- """Enables bundlers defined in a Python package.
-
- Returns whether each bundle defined in the packaged was enabled or not.
-
- Parameters
- ----------
- module : str
- Importable Python module exposing the
- magic-named `_jupyter_bundlerextension_paths` function
- user : bool [default: True]
- Whether to enable in the user's nbconfig directory.
- sys_prefix : bool [default: False]
- Whether to enable in the sys.prefix, i.e. environment. Will override
- `user`
- logger : Jupyter logger [optional]
- Logger instance to use
- """
- return _set_bundler_state_python(True, module, user, sys_prefix,
- logger=logger)
-
- def disable_bundler_python(module, user=True, sys_prefix=False, logger=None):
- """Disables bundlers defined in a Python package.
-
- Returns whether each bundle defined in the packaged was enabled or not.
-
- Parameters
- ----------
- module : str
- Importable Python module exposing the
- magic-named `_jupyter_bundlerextension_paths` function
- user : bool [default: True]
- Whether to enable in the user's nbconfig directory.
- sys_prefix : bool [default: False]
- Whether to enable in the sys.prefix, i.e. environment. Will override
- `user`
- logger : Jupyter logger [optional]
- Logger instance to use
- """
- return _set_bundler_state_python(False, module, user, sys_prefix,
- logger=logger)
- class ToggleBundlerExtensionApp(BaseExtensionApp):
- """A base class for apps that enable/disable bundlerextensions"""
- name = "jupyter bundlerextension enable/disable"
- version = __version__
- description = "Enable/disable a bundlerextension in configuration."
- user = Bool(True, config=True, help="Apply the configuration only for the current user (default)")
-
- _toggle_value = None
-
- def _config_file_name_default(self):
- """The default config file name."""
- return 'jupyter_notebook_config'
-
- def toggle_bundler_python(self, module):
- """Toggle some extensions in an importable Python module.
- Returns a list of booleans indicating whether the state was changed as
- requested.
- Parameters
- ----------
- module : str
- Importable Python module exposing the
- magic-named `_jupyter_bundlerextension_paths` function
- """
- toggle = (enable_bundler_python if self._toggle_value
- else disable_bundler_python)
- return toggle(module,
- user=self.user,
- sys_prefix=self.sys_prefix,
- logger=self.log)
- def start(self):
- if not self.extra_args:
- sys.exit('Please specify an bundlerextension/package to enable or disable')
- elif len(self.extra_args) > 1:
- sys.exit('Please specify one bundlerextension/package at a time')
- if self.python:
- self.toggle_bundler_python(self.extra_args[0])
- else:
- raise NotImplementedError('Cannot install bundlers from non-Python packages')
- class EnableBundlerExtensionApp(ToggleBundlerExtensionApp):
- """An App that enables bundlerextensions"""
- name = "jupyter bundlerextension enable"
- description = """
- Enable a bundlerextension in frontend configuration.
-
- Usage
- jupyter bundlerextension enable [--system|--sys-prefix]
- """
- _toggle_value = True
-
- class DisableBundlerExtensionApp(ToggleBundlerExtensionApp):
- """An App that disables bundlerextensions"""
- name = "jupyter bundlerextension disable"
- description = """
- Disable a bundlerextension in frontend configuration.
-
- Usage
- jupyter bundlerextension disable [--system|--sys-prefix]
- """
- _toggle_value = None
- class ListBundlerExtensionApp(BaseExtensionApp):
- """An App that lists and validates nbextensions"""
- name = "jupyter nbextension list"
- version = __version__
- description = "List all nbextensions known by the configuration system"
-
- def list_nbextensions(self):
- """List all the nbextensions"""
- config_dirs = [os.path.join(p, 'nbconfig') for p in jupyter_config_path()]
-
- print("Known bundlerextensions:")
-
- for config_dir in config_dirs:
- head = u' config dir: {}'.format(config_dir)
- head_shown = False
- cm = BaseJSONConfigManager(parent=self, config_dir=config_dir)
- data = cm.get('notebook')
- if 'bundlerextensions' in data:
- if not head_shown:
- # only show heading if there is an nbextension here
- print(head)
- head_shown = True
-
- for bundler_id, info in data['bundlerextensions'].items():
- label = info.get('label')
- module = info.get('module_name')
- if label is None or module is None:
- msg = u' {} {}'.format(bundler_id, RED_DISABLED)
- else:
- msg = u' "{}" from {} {}'.format(
- label, module, GREEN_ENABLED
- )
- print(msg)
-
- def start(self):
- """Perform the App's functions as configured"""
- self.list_nbextensions()
- class BundlerExtensionApp(BaseExtensionApp):
- """Base jupyter bundlerextension command entry point"""
- name = "jupyter bundlerextension"
- version = __version__
- description = "Work with Jupyter bundler extensions"
- examples = """
- jupyter bundlerextension list # list all configured bundlers
- jupyter bundlerextension enable --py <packagename> # enable all bundlers in a Python package
- jupyter bundlerextension disable --py <packagename> # disable all bundlers in a Python package
- """
- subcommands = dict(
- enable=(EnableBundlerExtensionApp, "Enable a bundler extension"),
- disable=(DisableBundlerExtensionApp, "Disable a bundler extension"),
- list=(ListBundlerExtensionApp, "List bundler extensions")
- )
- def start(self):
- """Perform the App's functions as configured"""
- super(BundlerExtensionApp, self).start()
- # The above should have called a subcommand and raised NoStart; if we
- # get here, it didn't, so we should self.log.info a message.
- subcmds = ", ".join(sorted(self.subcommands))
- sys.exit("Please supply at least one subcommand: %s" % subcmds)
- main = BundlerExtensionApp.launch_instance
- if __name__ == '__main__':
- main()
|