Hello community, here is the log from the commit of package python-jupyter-server for openSUSE:Factory checked in at 2019-06-13 23:05:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-jupyter-server (Old) and /work/SRC/openSUSE:Factory/.python-jupyter-server.new.4811 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-jupyter-server" Thu Jun 13 23:05:43 2019 rev:3 rq:709567 version:0.0.5 Changes: -------- --- /work/SRC/openSUSE:Factory/python-jupyter-server/python-jupyter-server.changes 2019-05-27 08:38:15.527073936 +0200 +++ /work/SRC/openSUSE:Factory/.python-jupyter-server.new.4811/python-jupyter-server.changes 2019-06-13 23:05:47.115227195 +0200 @@ -1,0 +2,6 @@ +Wed Jun 12 20:07:20 UTC 2019 - Todd R <toddrme2...@gmail.com> + +- Update to 0.0.5 + * Remove bundler endpoints + +------------------------------------------------------------------- Old: ---- jupyter_server-0.0.4.tar.gz New: ---- jupyter_server-0.0.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-jupyter-server.spec ++++++ --- /var/tmp/diff_new_pack.6fQ1xl/_old 2019-06-13 23:05:47.759226354 +0200 +++ /var/tmp/diff_new_pack.6fQ1xl/_new 2019-06-13 23:05:47.763226348 +0200 @@ -17,7 +17,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-jupyter-server -Version: 0.0.4 +Version: 0.0.5 Release: 0 License: BSD-3-Clause Summary: The Jupyter Server @@ -99,7 +99,6 @@ %prep %setup -q -n jupyter_server-%{version} -rm jupyter_server/bundler/tests/resources/subdir/subsubdir/.gitkeep %build %python_build ++++++ jupyter_server-0.0.4.tar.gz -> jupyter_server-0.0.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/PKG-INFO new/jupyter_server-0.0.5/PKG-INFO --- old/jupyter_server-0.0.4/PKG-INFO 2019-03-22 16:32:42.000000000 +0100 +++ new/jupyter_server-0.0.5/PKG-INFO 2019-05-16 12:42:50.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: jupyter_server -Version: 0.0.4 +Version: 0.0.5 Summary: The Jupyter Server Home-page: http://jupyter.org Author: Jupyter Development Team diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/docs/doc-requirements.txt new/jupyter_server-0.0.5/docs/doc-requirements.txt --- old/jupyter_server-0.0.4/docs/doc-requirements.txt 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/docs/doc-requirements.txt 2019-05-16 12:38:16.000000000 +0200 @@ -1,3 +1,4 @@ sphinx>=1.3.6 sphinx-rtd-theme nbsphinx +sphinxcontrib_github_alt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/docs/environment.yml new/jupyter_server-0.0.5/docs/environment.yml --- old/jupyter_server-0.0.4/docs/environment.yml 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/docs/environment.yml 2019-05-16 12:38:16.000000000 +0200 @@ -12,3 +12,4 @@ - nbsphinx - Send2Trash - prometheus_client + - sphinxcontrib_github_alt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/docs/source/conf.py new/jupyter_server-0.0.5/docs/source/conf.py --- old/jupyter_server-0.0.4/docs/source/conf.py 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/docs/source/conf.py 2019-05-16 12:38:16.000000000 +0200 @@ -30,8 +30,6 @@ # add repo root to sys.path # here = root/docs/source here = os.path.abspath(os.path.dirname(__file__)) -sphinxext = os.path.join(os.path.dirname(here), 'sphinxext') -sys.path.insert(0, sphinxext) repo_root = os.path.dirname(os.path.dirname(here)) sys.path.insert(0, repo_root) @@ -72,7 +70,7 @@ 'sphinx.ext.mathjax', 'IPython.sphinxext.ipython_console_highlighting', 'nbsphinx', - 'github', + 'sphinxcontrib_github_alt', ] # Add any paths that contain templates here, relative to this directory. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/docs/sphinxext/github.py new/jupyter_server-0.0.5/docs/sphinxext/github.py --- old/jupyter_server-0.0.4/docs/sphinxext/github.py 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/docs/sphinxext/github.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,157 +0,0 @@ -"""Define text roles for GitHub - -* ghissue - Issue -* ghpull - Pull Request -* ghuser - User - -Adapted from bitbucket example here: -https://bitbucket.org/birkenfeld/sphinx-contrib/src/tip/bitbucket/sphinxcontrib/bitbucket.py - -Authors -------- - -* Doug Hellmann -* Min RK -""" -# -# Original Copyright (c) 2010 Doug Hellmann. All rights reserved. -# - -from docutils import nodes, utils -from docutils.parsers.rst.roles import set_classes - -def make_link_node(rawtext, app, type, slug, options): - """Create a link to a github resource. - - :param rawtext: Text being replaced with link node. - :param app: Sphinx application context - :param type: Link type (issues, changeset, etc.) - :param slug: ID of the thing to link to - :param options: Options dictionary passed to role func. - """ - - try: - base = app.config.github_project_url - if not base: - raise AttributeError - if not base.endswith('/'): - base += '/' - except AttributeError as err: - raise ValueError('github_project_url configuration value is not set (%s)' % str(err)) - - ref = base + type + '/' + slug + '/' - set_classes(options) - prefix = "#" - if type == 'pull': - prefix = "PR " + prefix - node = nodes.reference(rawtext, prefix + utils.unescape(slug), refuri=ref, - **options) - return node - -def ghissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): - """Link to a GitHub issue. - - Returns 2 part tuple containing list of nodes to insert into the - document and a list of system messages. Both are allowed to be - empty. - - :param name: The role name used in the document. - :param rawtext: The entire markup snippet, with role. - :param text: The text marked with the role. - :param lineno: The line number where rawtext appears in the input. - :param inliner: The inliner instance that called us. - :param options: Directive options for customization. - :param content: The directive content for customization. - """ - - try: - issue_num = int(text) - if issue_num <= 0: - raise ValueError - except ValueError: - msg = inliner.reporter.error( - 'GitHub issue number must be a number greater than or equal to 1; ' - '"%s" is invalid.' % text, line=lineno) - prb = inliner.problematic(rawtext, rawtext, msg) - return [prb], [msg] - app = inliner.document.settings.env.app - #app.info('issue %r' % text) - if 'pull' in name.lower(): - category = 'pull' - elif 'issue' in name.lower(): - category = 'issues' - else: - msg = inliner.reporter.error( - 'GitHub roles include "ghpull" and "ghissue", ' - '"%s" is invalid.' % name, line=lineno) - prb = inliner.problematic(rawtext, rawtext, msg) - return [prb], [msg] - node = make_link_node(rawtext, app, category, str(issue_num), options) - return [node], [] - -def ghuser_role(name, rawtext, text, lineno, inliner, options={}, content=[]): - """Link to a GitHub user. - - Returns 2 part tuple containing list of nodes to insert into the - document and a list of system messages. Both are allowed to be - empty. - - :param name: The role name used in the document. - :param rawtext: The entire markup snippet, with role. - :param text: The text marked with the role. - :param lineno: The line number where rawtext appears in the input. - :param inliner: The inliner instance that called us. - :param options: Directive options for customization. - :param content: The directive content for customization. - """ - app = inliner.document.settings.env.app - #app.info('user link %r' % text) - ref = 'https://www.github.com/' + text - node = nodes.reference(rawtext, text, refuri=ref, **options) - return [node], [] - -def ghcommit_role(name, rawtext, text, lineno, inliner, options={}, content=[]): - """Link to a GitHub commit. - - Returns 2 part tuple containing list of nodes to insert into the - document and a list of system messages. Both are allowed to be - empty. - - :param name: The role name used in the document. - :param rawtext: The entire markup snippet, with role. - :param text: The text marked with the role. - :param lineno: The line number where rawtext appears in the input. - :param inliner: The inliner instance that called us. - :param options: Directive options for customization. - :param content: The directive content for customization. - """ - app = inliner.document.settings.env.app - #app.info('user link %r' % text) - try: - base = app.config.github_project_url - if not base: - raise AttributeError - if not base.endswith('/'): - base += '/' - except AttributeError as err: - raise ValueError('github_project_url configuration value is not set (%s)' % str(err)) - - ref = base + text - node = nodes.reference(rawtext, text[:6], refuri=ref, **options) - return [node], [] - - -def setup(app): - """Install the plugin. - - :param app: Sphinx application context. - """ - app.info('Initializing GitHub plugin') - app.add_role('ghissue', ghissue_role) - app.add_role('ghpull', ghissue_role) - app.add_role('ghuser', ghuser_role) - app.add_role('ghcommit', ghcommit_role) - app.add_config_value('github_project_url', None, 'env') - - metadata = {'parallel_read_safe': True, 'parallel_write_safe': True} - return metadata diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/_version.py new/jupyter_server-0.0.5/jupyter_server/_version.py --- old/jupyter_server-0.0.4/jupyter_server/_version.py 2019-03-22 14:18:55.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/_version.py 2019-05-16 12:39:58.000000000 +0200 @@ -9,5 +9,5 @@ # Next beta/alpha/rc release: The version number for beta is X.Y.ZbN **without dots**. -version_info = (0, 0, 4, '') +version_info = (0, 0, 5, '') __version__ = '.'.join(map(str, version_info[:3])) + ''.join(version_info[3:]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/bundler/__main__.py new/jupyter_server-0.0.5/jupyter_server/bundler/__main__.py --- old/jupyter_server-0.0.4/jupyter_server/bundler/__main__.py 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/bundler/__main__.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,7 +0,0 @@ -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -from .bundlerextensions import main - -if __name__ == '__main__': - main() \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/bundler/bundlerextensions.py new/jupyter_server-0.0.5/jupyter_server/bundler/bundlerextensions.py --- old/jupyter_server-0.0.4/jupyter_server/bundler/bundlerextensions.py 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/bundler/bundlerextensions.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,306 +0,0 @@ -# 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 jupyter_server.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 = "jupyter_server" -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 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/serverconfig 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), 'serverconfig') - 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 serverconfig 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 serverconfig 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 serverconfig 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_server_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 extensions""" - name = "jupyter extension list" - version = __version__ - description = "List all extensions known by the configuration system" - - def list_extensions(self): - """List all the extensions""" - config_dirs = [os.path.join(p, 'serverconfig') 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('jupyter_server') - if 'bundlerextensions' in data: - if not head_shown: - # only show heading if there is an extension 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_extensions() - - -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() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/bundler/handlers.py new/jupyter_server-0.0.5/jupyter_server/bundler/handlers.py --- old/jupyter_server-0.0.4/jupyter_server/bundler/handlers.py 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/bundler/handlers.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,83 +0,0 @@ -"""Tornado handler for bundling content.""" - -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. -from . import tools -from jupyter_server.utils import url2path -from jupyter_server.base.handlers import JupyterHandler -from jupyter_server.services.config import ConfigManager -from ipython_genutils.importstring import import_item -from tornado import web, gen - - -class BundlerHandler(JupyterHandler): - - def initialize(self): - """Make tools module available on the handler instance for compatibility - with existing bundler API and ease of reference.""" - self.tools = tools - - def get_bundler(self, bundler_id): - """ - Get bundler metadata from config given a bundler ID. - - Parameters - ---------- - bundler_id: str - Unique bundler ID within the jupyter_server/bundlerextensions config section - - Returns - ------- - dict - Bundler metadata with label, group, and module_name attributes - - Raises - ------ - KeyError - If the bundler ID is unknown - """ - cm = ConfigManager() - return cm.get('jupyter_server').get('bundlerextensions', {})[bundler_id] - - @web.authenticated - @gen.coroutine - def get(self, path): - """Bundle the given notebook. - - Parameters - ---------- - path: str - Path to the notebook (path parameter) - bundler: str - Bundler ID to use (query parameter) - """ - bundler_id = self.get_query_argument('bundler') - model = self.contents_manager.get(path=url2path(path)) - - try: - bundler = self.get_bundler(bundler_id) - except KeyError: - raise web.HTTPError(400, 'Bundler %s not enabled' % bundler_id) - - module_name = bundler['module_name'] - try: - # no-op in python3, decode error in python2 - module_name = str(module_name) - except UnicodeEncodeError: - # Encode unicode as utf-8 in python2 else import_item fails - module_name = module_name.encode('utf-8') - - try: - bundler_mod = import_item(module_name) - except ImportError: - raise web.HTTPError(500, 'Could not import bundler %s ' % bundler_id) - - # Let the bundler respond in any way it sees fit and assume it will - # finish the request - yield gen.maybe_future(bundler_mod.bundle(self, model)) - -_bundler_id_regex = r'(?P<bundler_id>[A-Za-z0-9_]+)' - -default_handlers = [ - (r"/bundle/(.*)", BundlerHandler) -] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/bundler/tarball_bundler.py new/jupyter_server-0.0.5/jupyter_server/bundler/tarball_bundler.py --- old/jupyter_server-0.0.4/jupyter_server/bundler/tarball_bundler.py 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/bundler/tarball_bundler.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,47 +0,0 @@ -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. -import os -import io -import tarfile -import nbformat - -def _jupyter_bundlerextension_paths(): - """Metadata for server bundlerextension""" - return [{ - # unique bundler name - "name": "tarball_bundler", - # module containing bundle function - "module_name": "jupyter_server.bundler.tarball_bundler", - # human-redable menu item label - "label" : "Tarball (tar.gz)", - # group under 'deploy' or 'download' menu - "group" : "download", - }] - -def bundle(handler, model): - """Create a compressed tarball containing the notebook document. - - Parameters - ---------- - handler : tornado.web.RequestHandler - Handler that serviced the bundle request - model : dict - Notebook model from the configured ContentManager - """ - notebook_filename = model['name'] - notebook_content = nbformat.writes(model['content']).encode('utf-8') - notebook_name = os.path.splitext(notebook_filename)[0] - tar_filename = '{}.tar.gz'.format(notebook_name) - - info = tarfile.TarInfo(notebook_filename) - info.size = len(notebook_content) - - with io.BytesIO() as tar_buffer: - with tarfile.open(tar_filename, "w:gz", fileobj=tar_buffer) as tar: - tar.addfile(info, io.BytesIO(notebook_content)) - - handler.set_attachment_header(tar_filename) - handler.set_header('Content-Type', 'application/gzip') - - # Return the buffer value as the response - handler.finish(tar_buffer.getvalue()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/bundler/tests/resources/another_subdir/test_file.txt new/jupyter_server-0.0.5/jupyter_server/bundler/tests/resources/another_subdir/test_file.txt --- old/jupyter_server-0.0.4/jupyter_server/bundler/tests/resources/another_subdir/test_file.txt 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/bundler/tests/resources/another_subdir/test_file.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -Used to test globbing. \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/bundler/tests/resources/empty.ipynb new/jupyter_server-0.0.5/jupyter_server/bundler/tests/resources/empty.ipynb --- old/jupyter_server-0.0.4/jupyter_server/bundler/tests/resources/empty.ipynb 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/bundler/tests/resources/empty.ipynb 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +0,0 @@ -{ - "nbformat_minor": 0, - "cells": [], - "nbformat": 4, - "metadata": {} -} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/bundler/tests/resources/subdir/test_file.txt new/jupyter_server-0.0.5/jupyter_server/bundler/tests/resources/subdir/test_file.txt --- old/jupyter_server-0.0.4/jupyter_server/bundler/tests/resources/subdir/test_file.txt 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/bundler/tests/resources/subdir/test_file.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -Used to test globbing. \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/bundler/tests/test_bundler_api.py new/jupyter_server-0.0.5/jupyter_server/bundler/tests/test_bundler_api.py --- old/jupyter_server-0.0.4/jupyter_server/bundler/tests/test_bundler_api.py 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/bundler/tests/test_bundler_api.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,85 +0,0 @@ -"""Test the bundlers API.""" - -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -import io -from os.path import join as pjoin - -from jupyter_server.tests.launchserver import ServerTestBase -from nbformat import write -from nbformat.v4 import ( - new_notebook, new_markdown_cell, new_code_cell, new_output, -) - -try: - from unittest.mock import patch -except ImportError: - from mock import patch # py3 - -def bundle(handler, model): - """Bundler test stub. Echo the notebook path.""" - handler.finish(model['path']) - - -class BundleAPITest(ServerTestBase): - """Test the bundlers web service API""" - - @classmethod - def setup_class(cls): - """Make a test notebook. Borrowed from nbconvert test. Assumes the class - teardown will clean it up in the end.""" - super(BundleAPITest, cls).setup_class() - rootdir = cls.root_dir - - nb = new_notebook() - - nb.cells.append(new_markdown_cell(u'Created by test')) - cc1 = new_code_cell(source=u'print(2*6)') - cc1.outputs.append(new_output(output_type="stream", text=u'12')) - nb.cells.append(cc1) - - with io.open(pjoin(rootdir, 'testnb.ipynb'), 'w', - encoding='utf-8') as f: - write(nb, f, version=4) - - def test_missing_bundler_arg(self): - """Should respond with 400 error about missing bundler arg""" - resp = self.request('GET', 'bundle/fake.ipynb') - self.assertEqual(resp.status_code, 400) - self.assertIn('Missing argument bundler', resp.text) - - def test_notebook_not_found(self): - """Shoudl respond with 404 error about missing notebook""" - resp = self.request('GET', 'bundle/fake.ipynb', - params={'bundler': 'fake_bundler'}) - self.assertEqual(resp.status_code, 404) - self.assertIn('Not Found', resp.text) - - def test_bundler_not_enabled(self): - """Should respond with 400 error about disabled bundler""" - resp = self.request('GET', 'bundle/testnb.ipynb', - params={'bundler': 'fake_bundler'}) - self.assertEqual(resp.status_code, 400) - self.assertIn('Bundler fake_bundler not enabled', resp.text) - - def test_bundler_import_error(self): - """Should respond with 500 error about failure to load bundler module""" - with patch('jupyter_server.bundler.handlers.BundlerHandler.get_bundler') as mock: - mock.return_value = {'module_name': 'fake_module'} - resp = self.request('GET', 'bundle/testnb.ipynb', - params={'bundler': 'fake_bundler'}) - mock.assert_called_with('fake_bundler') - self.assertEqual(resp.status_code, 500) - self.assertIn('Could not import bundler fake_bundler', resp.text) - - def test_bundler_invoke(self): - """Should respond with 200 and output from test bundler stub""" - with patch('jupyter_server.bundler.handlers.BundlerHandler.get_bundler') as mock: - mock.return_value = {'module_name': 'jupyter_server.bundler.tests.test_bundler_api'} - resp = self.request('GET', 'bundle/testnb.ipynb', - params={'bundler': 'stub_bundler'}) - mock.assert_called_with('stub_bundler') - self.assertEqual(resp.status_code, 200) - self.assertIn('testnb.ipynb', resp.text) - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/bundler/tests/test_bundler_tools.py new/jupyter_server-0.0.5/jupyter_server/bundler/tests/test_bundler_tools.py --- old/jupyter_server-0.0.4/jupyter_server/bundler/tests/test_bundler_tools.py 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/bundler/tests/test_bundler_tools.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,124 +0,0 @@ -"""Test the bundler tools.""" - -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -import unittest -import os -import shutil -import tempfile -import jupyter_server.bundler.tools as tools - -HERE = os.path.abspath(os.path.dirname(__file__)) - -class TestBundlerTools(unittest.TestCase): - def setUp(self): - self.tmp = tempfile.mkdtemp() - - def tearDown(self): - shutil.rmtree(self.tmp, ignore_errors=True) - - def test_get_no_cell_references(self): - '''Should find no references in a regular HTML comment.''' - no_references = tools.get_cell_reference_patterns({'source':'''!<-- -a -b -c --->''', 'cell_type':'markdown'}) - self.assertEqual(len(no_references), 0) - - def test_get_cell_reference_patterns_comment_multiline(self): - '''Should find two references and ignore a comment within an HTML comment.''' - cell = {'cell_type':'markdown', 'source':'''<!--associate: -a -b/ -#comment --->'''} - references = tools.get_cell_reference_patterns(cell) - self.assertTrue('a' in references and 'b/' in references, str(references)) - self.assertEqual(len(references), 2, str(references)) - - def test_get_cell_reference_patterns_comment_trailing_filename(self): - '''Should find three references within an HTML comment.''' - cell = {'cell_type':'markdown', 'source':'''<!--associate:c -a -b/ -#comment --->'''} - references = tools.get_cell_reference_patterns(cell) - self.assertTrue('a' in references and 'b/' in references and 'c' in references, str(references)) - self.assertEqual(len(references), 3, str(references)) - - def test_get_cell_reference_patterns_precode(self): - '''Should find no references in a fenced code block in a *code* cell.''' - self.assertTrue(tools.get_cell_reference_patterns) - no_references = tools.get_cell_reference_patterns({'source':'''``` -foo -bar -baz -``` -''', 'cell_type':'code'}) - self.assertEqual(len(no_references), 0) - - def test_get_cell_reference_patterns_precode_mdcomment(self): - '''Should find two references and ignore a comment in a fenced code block.''' - cell = {'cell_type':'markdown', 'source':'''``` -a -b/ -#comment -```'''} - references = tools.get_cell_reference_patterns(cell) - self.assertTrue('a' in references and 'b/' in references, str(references)) - self.assertEqual(len(references), 2, str(references)) - - def test_get_cell_reference_patterns_precode_backticks(self): - '''Should find three references in a fenced code block.''' - cell = {'cell_type':'markdown', 'source':'''```c -a -b/ -#comment -```'''} - references = tools.get_cell_reference_patterns(cell) - self.assertTrue('a' in references and 'b/' in references and 'c' in references, str(references)) - self.assertEqual(len(references), 3, str(references)) - - def test_glob_dir(self): - '''Should expand to single file in the resources/ subfolder.''' - self.assertIn(os.path.join('resources', 'empty.ipynb'), - tools.expand_references(HERE, ['resources/empty.ipynb'])) - - def test_glob_subdir(self): - '''Should expand to all files in the resources/ subfolder.''' - self.assertIn(os.path.join('resources', 'empty.ipynb'), - tools.expand_references(HERE, ['resources/'])) - - def test_glob_splat(self): - '''Should expand to all contents under this test/ directory.''' - globs = tools.expand_references(HERE, ['*']) - self.assertIn('test_bundler_tools.py', globs, globs) - self.assertIn('resources', globs, globs) - - def test_glob_splatsplat_in_middle(self): - '''Should expand to test_file.txt deep under this test/ directory.''' - globs = tools.expand_references(HERE, ['resources/**/test_file.txt']) - self.assertIn(os.path.join('resources', 'subdir', 'test_file.txt'), globs, globs) - - def test_glob_splatsplat_trailing(self): - '''Should expand to all descendants of this test/ directory.''' - globs = tools.expand_references(HERE, ['resources/**']) - self.assertIn(os.path.join('resources', 'empty.ipynb'), globs, globs) - self.assertIn(os.path.join('resources', 'subdir', 'test_file.txt'), globs, globs) - - def test_glob_splatsplat_leading(self): - '''Should expand to test_file.txt under any path.''' - globs = tools.expand_references(HERE, ['**/test_file.txt']) - self.assertIn(os.path.join('resources', 'subdir', 'test_file.txt'), globs, globs) - self.assertIn(os.path.join('resources', 'another_subdir', 'test_file.txt'), globs, globs) - - def test_copy_filelist(self): - '''Should copy select files from source to destination''' - globs = tools.expand_references(HERE, ['**/test_file.txt']) - tools.copy_filelist(HERE, self.tmp, globs) - self.assertTrue(os.path.isfile(os.path.join(self.tmp, 'resources', 'subdir', 'test_file.txt'))) - self.assertTrue(os.path.isfile(os.path.join(self.tmp, 'resources', 'another_subdir', 'test_file.txt'))) - self.assertFalse(os.path.isfile(os.path.join(self.tmp, 'resources', 'empty.ipynb'))) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/bundler/tests/test_bundlerextension.py new/jupyter_server-0.0.5/jupyter_server/bundler/tests/test_bundlerextension.py --- old/jupyter_server-0.0.4/jupyter_server/bundler/tests/test_bundlerextension.py 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/bundler/tests/test_bundlerextension.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,73 +0,0 @@ -"""Test the bundlerextension CLI.""" - -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -import os -import shutil -import unittest - -try: - from unittest.mock import patch -except ImportError: - from mock import patch # py2 - -from ipython_genutils.tempdir import TemporaryDirectory -from ipython_genutils import py3compat - -from traitlets.tests.utils import check_help_all_output - -from jupyter_server.config_manager import BaseJSONConfigManager -from ..bundlerextensions import ( - _get_config_dir, enable_bundler_python, disable_bundler_python -) - -def test_help_output(): - check_help_all_output('jupyter_server.bundler.bundlerextensions') - check_help_all_output('jupyter_server.bundler.bundlerextensions', ['enable']) - check_help_all_output('jupyter_server.bundler.bundlerextensions', ['disable']) - - -class TestBundlerExtensionCLI(unittest.TestCase): - """Tests the bundlerextension CLI against the example zip_bundler.""" - def setUp(self): - """Build an isolated config environment.""" - td = TemporaryDirectory() - - self.test_dir = py3compat.cast_unicode(td.name) - self.data_dir = os.path.join(self.test_dir, 'data') - self.config_dir = os.path.join(self.test_dir, 'config') - self.system_data_dir = os.path.join(self.test_dir, 'system_data') - self.system_path = [self.system_data_dir] - - # Use temp directory, not real user or system config paths - self.patch_env = patch.dict('os.environ', { - 'JUPYTER_CONFIG_DIR': self.config_dir, - 'JUPYTER_DATA_DIR': self.data_dir, - }) - self.patch_env.start() - - def tearDown(self): - """Remove the test config environment.""" - shutil.rmtree(self.test_dir, ignore_errors=True) - self.patch_env.stop() - - def test_enable(self): - """Should add the bundler to the notebook configuration.""" - enable_bundler_python('jupyter_server.bundler.zip_bundler') - - config_dir = os.path.join(_get_config_dir(user=True), 'serverconfig') - cm = BaseJSONConfigManager(config_dir=config_dir) - bundlers = cm.get('jupyter_server').get('bundlerextensions', {}) - self.assertEqual(len(bundlers), 1) - self.assertIn('notebook_zip_download', bundlers) - - def test_disable(self): - """Should remove the bundler from the notebook configuration.""" - self.test_enable() - disable_bundler_python('jupyter_server.bundler.zip_bundler') - - config_dir = os.path.join(_get_config_dir(user=True), 'serverconfig') - cm = BaseJSONConfigManager(config_dir=config_dir) - bundlers = cm.get('jupyter_server').get('bundlerextensions', {}) - self.assertEqual(len(bundlers), 0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/bundler/tools.py new/jupyter_server-0.0.5/jupyter_server/bundler/tools.py --- old/jupyter_server-0.0.4/jupyter_server/bundler/tools.py 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/bundler/tools.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,230 +0,0 @@ -"""Set of common tools to aid bundler implementations.""" - -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. -import os -import shutil -import errno -import nbformat -import fnmatch -import glob - -def get_file_references(abs_nb_path, version): - """Gets a list of files referenced either in Markdown fenced code blocks - or in HTML comments from the notebook. Expands patterns expressed in - gitignore syntax (https://git-scm.com/docs/gitignore). Returns the - fully expanded list of filenames relative to the notebook dirname. - - Parameters - ---------- - abs_nb_path: str - Absolute path of the notebook on disk - version: int - Version of the notebook document format to use - - Returns - ------- - list - Filename strings relative to the notebook path - """ - ref_patterns = get_reference_patterns(abs_nb_path, version) - expanded = expand_references(os.path.dirname(abs_nb_path), ref_patterns) - return expanded - -def get_reference_patterns(abs_nb_path, version): - """Gets a list of reference patterns either in Markdown fenced code blocks - or in HTML comments from the notebook. - - Parameters - ---------- - abs_nb_path: str - Absolute path of the notebook on disk - version: int - Version of the notebook document format to use - - Returns - ------- - list - Pattern strings from the notebook - """ - notebook = nbformat.read(abs_nb_path, version) - referenced_list = [] - for cell in notebook.cells: - references = get_cell_reference_patterns(cell) - if references: - referenced_list = referenced_list + references - return referenced_list - -def get_cell_reference_patterns(cell): - ''' - Retrieves the list of references from a single notebook cell. Looks for - fenced code blocks or HTML comments in Markdown cells, e.g., - - ``` - some.csv - foo/ - !foo/bar - ``` - - or - - <!--associate: - some.csv - foo/ - !foo/bar - --> - - Parameters - ---------- - cell: dict - Notebook cell object - - Returns - ------- - list - Reference patterns found in the cell - ''' - referenced = [] - # invisible after execution: unrendered HTML comment - if cell.get('cell_type').startswith('markdown') and cell.get('source').startswith('<!--associate:'): - lines = cell.get('source')[len('<!--associate:'):].splitlines() - for line in lines: - if line.startswith('-->'): - break - # Trying to go out of the current directory leads to - # trouble when deploying - if line.find('../') < 0 and not line.startswith('#'): - referenced.append(line) - # visible after execution: rendered as a code element within a pre element - elif cell.get('cell_type').startswith('markdown') and cell.get('source').find('```') >= 0: - source = cell.get('source') - offset = source.find('```') - lines = source[offset + len('```'):].splitlines() - for line in lines: - if line.startswith('```'): - break - # Trying to go out of the current directory leads to - # trouble when deploying - if line.find('../') < 0 and not line.startswith('#'): - referenced.append(line) - - # Clean out blank references - return [ref for ref in referenced if ref.strip()] - -def expand_references(root_path, references): - """Expands a set of reference patterns by evaluating them against the - given root directory. Expansions are performed against patterns - expressed in the same manner as in gitignore - (https://git-scm.com/docs/gitignore). - - NOTE: Temporarily changes the current working directory when called. - - Parameters - ---------- - root_path: str - Assumed root directory for the patterns - references: list - Reference patterns from get_reference_patterns expressed with - forward-slash directory separators - - Returns - ------- - list - Filename strings relative to the root path - """ - # Use normpath to convert to platform specific slashes, but be sure - # to retain a trailing slash which normpath pulls off - normalized_references = [] - for ref in references: - normalized_ref = os.path.normpath(ref) - # un-normalized separator - if ref.endswith('/'): - normalized_ref += os.sep - normalized_references.append(normalized_ref) - references = normalized_references - - globbed = [] - negations = [] - must_walk = [] - for pattern in references: - if pattern and pattern.find(os.sep) < 0: - # simple shell glob - cwd = os.getcwd() - os.chdir(root_path) - if pattern.startswith('!'): - negations = negations + glob.glob(pattern[1:]) - else: - globbed = globbed + glob.glob(pattern) - os.chdir(cwd) - elif pattern: - must_walk.append(pattern) - - for pattern in must_walk: - pattern_is_negation = pattern.startswith('!') - if pattern_is_negation: - testpattern = pattern[1:] - else: - testpattern = pattern - for root, _, filenames in os.walk(root_path): - for filename in filenames: - joined = os.path.join(root[len(root_path) + 1:], filename) - if testpattern.endswith(os.sep): - if joined.startswith(testpattern): - if pattern_is_negation: - negations.append(joined) - else: - globbed.append(joined) - elif testpattern.find('**') >= 0: - # path wildcard - ends = testpattern.split('**') - if len(ends) == 2: - if joined.startswith(ends[0]) and joined.endswith(ends[1]): - if pattern_is_negation: - negations.append(joined) - else: - globbed.append(joined) - else: - # segments should be respected - if fnmatch.fnmatch(joined, testpattern): - if pattern_is_negation: - negations.append(joined) - else: - globbed.append(joined) - - for negated in negations: - try: - globbed.remove(negated) - except ValueError as err: - pass - return set(globbed) - -def copy_filelist(src, dst, src_relative_filenames): - """Copies the given list of files, relative to src, into dst, creating - directories along the way as needed and ignore existence errors. - Skips any files that do not exist. Does not create empty directories - from src in dst. - - Parameters - ---------- - src: str - Root of the source directory - dst: str - Root of the destination directory - src_relative_filenames: list - Filenames relative to src - """ - for filename in src_relative_filenames: - # Only consider the file if it exists in src - if os.path.isfile(os.path.join(src, filename)): - parent_relative = os.path.dirname(filename) - if parent_relative: - # Make sure the parent directory exists - parent_dst = os.path.join(dst, parent_relative) - try: - os.makedirs(parent_dst) - except OSError as exc: - if exc.errno == errno.EEXIST: - pass - else: - raise exc - shutil.copy2(os.path.join(src, filename), os.path.join(dst, filename)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/bundler/zip_bundler.py new/jupyter_server-0.0.5/jupyter_server/bundler/zip_bundler.py --- old/jupyter_server-0.0.4/jupyter_server/bundler/zip_bundler.py 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/bundler/zip_bundler.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,59 +0,0 @@ -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. -import os -import io -import zipfile -import jupyter_server.bundler.tools as tools - -def _jupyter_bundlerextension_paths(): - """Metadata for notebook bundlerextension""" - return [{ - 'name': 'notebook_zip_download', - 'label': 'Jupyter Notebook bundle (.zip)', - 'module_name': 'jupyter_server.bundler.zip_bundler', - 'group': 'download' - }] - -def bundle(handler, model): - """Create a zip file containing the original notebook and files referenced - from it. Retain the referenced files in paths relative to the notebook. - Return the zip as a file download. - - Assumes the notebook and other files are all on local disk. - - Parameters - ---------- - handler : tornado.web.RequestHandler - Handler that serviced the bundle request - model : dict - Notebook model from the configured ContentManager - """ - abs_nb_path = os.path.join(handler.settings['contents_manager'].root_dir, - model['path']) - notebook_filename = model['name'] - notebook_name = os.path.splitext(notebook_filename)[0] - - # Headers - zip_filename = os.path.splitext(notebook_name)[0] + '.zip' - handler.set_attachment_header(zip_filename) - handler.set_header('Content-Type', 'application/zip') - - # Get associated files - ref_filenames = tools.get_file_references(abs_nb_path, 4) - - # Prepare the zip file - zip_buffer = io.BytesIO() - zipf = zipfile.ZipFile(zip_buffer, mode='w', compression=zipfile.ZIP_DEFLATED) - zipf.write(abs_nb_path, notebook_filename) - - root_dir = os.path.dirname(abs_nb_path) - for nb_relative_filename in ref_filenames: - # Build absolute path to file on disk - abs_fn = os.path.join(root_dir, nb_relative_filename) - # Store file under path relative to notebook - zipf.write(abs_fn, nb_relative_filename) - - zipf.close() - - # Return the buffer value as the response - handler.finish(zip_buffer.getvalue()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server/serverapp.py new/jupyter_server-0.0.5/jupyter_server/serverapp.py --- old/jupyter_server-0.0.4/jupyter_server/serverapp.py 2019-01-23 16:39:41.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server/serverapp.py 2019-05-16 12:38:16.000000000 +0200 @@ -283,7 +283,6 @@ handlers.extend(load_handlers('jupyter_server.files.handlers')) handlers.extend(load_handlers('jupyter_server.view.handlers')) handlers.extend(load_handlers('jupyter_server.nbconvert.handlers')) - handlers.extend(load_handlers('jupyter_server.bundler.handlers')) handlers.extend(load_handlers('jupyter_server.kernelspecs.handlers')) handlers.extend(load_handlers('jupyter_server.edit.handlers')) handlers.extend(load_handlers('jupyter_server.services.api.handlers')) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server.egg-info/PKG-INFO new/jupyter_server-0.0.5/jupyter_server.egg-info/PKG-INFO --- old/jupyter_server-0.0.4/jupyter_server.egg-info/PKG-INFO 2019-03-22 16:32:42.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server.egg-info/PKG-INFO 2019-05-16 12:42:50.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: jupyter-server -Version: 0.0.4 +Version: 0.0.5 Summary: The Jupyter Server Home-page: http://jupyter.org Author: Jupyter Development Team diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-0.0.4/jupyter_server.egg-info/SOURCES.txt new/jupyter_server-0.0.5/jupyter_server.egg-info/SOURCES.txt --- old/jupyter_server-0.0.4/jupyter_server.egg-info/SOURCES.txt 2019-03-22 16:32:42.000000000 +0100 +++ new/jupyter_server-0.0.5/jupyter_server.egg-info/SOURCES.txt 2019-05-16 12:42:50.000000000 +0200 @@ -114,7 +114,6 @@ docs/source/extending/index.rst docs/source/extending/keymaps.rst docs/source/extending/savehooks.rst -docs/sphinxext/github.py jupyter_server/__init__.py jupyter_server/__main__.py jupyter_server/_sysinfo.py @@ -145,21 +144,6 @@ jupyter_server/base/__init__.py jupyter_server/base/handlers.py jupyter_server/base/zmqhandlers.py -jupyter_server/bundler/__init__.py -jupyter_server/bundler/__main__.py -jupyter_server/bundler/bundlerextensions.py -jupyter_server/bundler/handlers.py -jupyter_server/bundler/tarball_bundler.py -jupyter_server/bundler/tools.py -jupyter_server/bundler/zip_bundler.py -jupyter_server/bundler/tests/__init__.py -jupyter_server/bundler/tests/test_bundler_api.py -jupyter_server/bundler/tests/test_bundler_tools.py -jupyter_server/bundler/tests/test_bundlerextension.py -jupyter_server/bundler/tests/resources/empty.ipynb -jupyter_server/bundler/tests/resources/another_subdir/test_file.txt -jupyter_server/bundler/tests/resources/subdir/test_file.txt -jupyter_server/bundler/tests/resources/subdir/subsubdir/.gitkeep jupyter_server/edit/__init__.py jupyter_server/edit/handlers.py jupyter_server/files/__init__.py