Hello community,
here is the log from the commit of package jupyter-jupyterlab-server for
openSUSE:Factory checked in at 2019-08-22 10:52:54
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/jupyter-jupyterlab-server (Old)
and /work/SRC/openSUSE:Factory/.jupyter-jupyterlab-server.new.22127 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "jupyter-jupyterlab-server"
Thu Aug 22 10:52:54 2019 rev:2 rq:724865 version:1.0.6
Changes:
--------
---
/work/SRC/openSUSE:Factory/jupyter-jupyterlab-server/jupyter-jupyterlab-server.changes
2019-05-22 11:13:17.810566038 +0200
+++
/work/SRC/openSUSE:Factory/.jupyter-jupyterlab-server.new.22127/jupyter-jupyterlab-server.changes
2019-08-22 10:52:57.425695178 +0200
@@ -1,0 +2,31 @@
+Tue Aug 20 15:56:39 UTC 2019 - Todd R <[email protected]>
+
+- Update to 1.0.6
+ * Add .json.orig files to sdists
+- Disable spurious rpmlint checks.
+ They are incorrectly flagging valid test files.
+ These tests are used by other packages besides this one,
+ so they need to stay in.
+
+-------------------------------------------------------------------
+Tue Aug 20 15:23:40 UTC 2019 - Todd R <[email protected]>
+
+- This replaces jupyterlab-launcher
+
+-------------------------------------------------------------------
+Sat Jul 27 23:41:02 UTC 2019 - Todd R <[email protected]>
+
+- Update to 1.0.5
+ * require jinja2 to make tojson always safe
+- Update to 1.0.4
+ * use escape instead of urlencode for urls
+- Update to 1.0.3
+ * Escape template values in Jinja
+- Update to 1.0.2
+ * Add store ID to page config
+- Update to 1.0.1
+ * fix page config escaping
+- Update to 1.0.0
+ * jupyterlab 1.0.0 support
+
+-------------------------------------------------------------------
Old:
----
jupyterlab_server-0.2.0.tar.gz
New:
----
jupyter-jupyterlab-server-rpmlintrc
jupyterlab_server-1.0.6.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ jupyter-jupyterlab-server.spec ++++++
--- /var/tmp/diff_new_pack.1GdcFk/_old 2019-08-22 10:52:57.933695110 +0200
+++ /var/tmp/diff_new_pack.1GdcFk/_new 2019-08-22 10:52:57.937695109 +0200
@@ -17,33 +17,38 @@
Name: jupyter-jupyterlab-server
-# Do not update to 0.3.0 until jupyter-jupyterlab supports it (probably
version 1.0)
-Version: 0.2.0
+Version: 1.0.6
Release: 0
Summary: Server components for JupyterLab and JupyterLab-like
applications
License: BSD-3-Clause
Group: Development/Languages/Python
-URL: http://jupyter.org
-Source:
https://files.pythonhosted.org/packages/source/j/jupyterlab_server/jupyterlab_server-%{version}.tar.gz
+URL: https://github.com/jupyterlab/jupyterlab_server
+Source:
https://files.pythonhosted.org/packages/source/j/jupyterlab-server/jupyterlab_server-%{version}.tar.gz
+Source100: jupyter-jupyterlab-server-rpmlintrc
BuildRequires: fdupes
BuildRequires: python-rpm-macros
BuildRequires: python3-setuptools
Requires: jupyter-notebook >= 4.2.0
-Requires: python3-jsonschema >= 2.6.0
-Requires: python3-tornado
-Requires: python3-traitlets
+Requires: python3-Jinja2 >= 2.10
+Requires: python3-base >= 3.5
+Requires: python3-json5
+Requires: python3-jsonschema >= 2.6
Provides: python3-jupyter_jupyterlab_server = %{version}
-Obsoletes: python3-jupyter_jupyterlab_server <= %{version}
-# Factory has a newer, unsupported version due to a packaging mistake
-Obsoletes: python3-jupyter_jupyterlab_server <= 0.3.0
+Obsoletes: python3-jupyter_jupyterlab_server < %{version}
Provides: python3-jupyterlab-server = %{version}
+Provides: jupyter-jupyterlab-launcher = %{version}
+Obsoletes: jupyter-jupyterlab-launcher < %{version}
+Provides: python3-jupyter_jupyterlab_launcher = %{version}
+Obsoletes: python3-jupyter_jupyterlab_launcher < %{version}
BuildArch: noarch
# SECTION test requirements
BuildRequires: jupyter-notebook >= 4.2.0
-BuildRequires: python3-jsonschema >= 2.6.0
+BuildRequires: python3-Jinja2 >= 2.10
+BuildRequires: python3-base >= 3.5
+BuildRequires: python3-json5
+BuildRequires: python3-jsonschema >= 2.6
BuildRequires: python3-pytest
BuildRequires: python3-requests
-BuildRequires: python3-traitlets
# /SECTION
%description
@@ -59,6 +64,9 @@
%python3_install
%fdupes %{buildroot}%{python3_sitelib}
+%check
+pytest-%{python3_bin_suffix} -v .
+
%files
%license LICENSE
%doc README.md
++++++ jupyter-jupyterlab-server-rpmlintrc ++++++
# This is an importan test file.
# The tests don't work without it, and other packages' tests depend on these
tests being available
addFilter("backup-file-in-package
.*/jupyterlab_server/tests/schemas/@jupyterlab/shortcuts-extension/package.json.orig")
addFilter("suse-filelist-forbidden
.*/jupyterlab_server/tests/schemas/@jupyterlab/shortcuts-extension/package.json.orig")
++++++ jupyterlab_server-0.2.0.tar.gz -> jupyterlab_server-1.0.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyterlab_server-0.2.0/MANIFEST.in
new/jupyterlab_server-1.0.6/MANIFEST.in
--- old/jupyterlab_server-0.2.0/MANIFEST.in 2018-09-13 13:15:04.000000000
+0200
+++ new/jupyterlab_server-1.0.6/MANIFEST.in 2019-08-20 17:52:17.000000000
+0200
@@ -1,8 +1,8 @@
include README.md
include LICENSE
include setupbase.py
-include jupyterlab_server/*.html
-recursive-include jupyterlab_server/tests *.json *.jupyterlab-workspace
+include jupyterlab_server/templates/*.html
+recursive-include jupyterlab_server/tests *.json *.json.orig
*.jupyterlab-workspace
# Patterns to exclude from any directory
global-exclude *~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyterlab_server-0.2.0/PKG-INFO
new/jupyterlab_server-1.0.6/PKG-INFO
--- old/jupyterlab_server-0.2.0/PKG-INFO 2018-09-15 09:15:02.000000000
+0200
+++ new/jupyterlab_server-1.0.6/PKG-INFO 2019-08-20 17:52:31.000000000
+0200
@@ -1,15 +1,34 @@
-Metadata-Version: 1.2
+Metadata-Version: 2.1
Name: jupyterlab_server
-Version: 0.2.0
+Version: 1.0.6
Summary: JupyterLab Server
-Home-page: http://jupyter.org
+Home-page: https://jupyter.org
Author: Jupyter Development Team
Author-email: [email protected]
License: BSD
-Description-Content-Type: UNKNOWN
-Description:
- This package is used to launch an application built using
JupyterLab
-
+Description: # jupyterlab server
+
+ https://github.com/jupyterlab/jupyterlab_server
+
+ ## Install
+
+ `pip install jupyterlab_server`
+
+ ## Usage
+ The application author creates a JupyterLab build on their machine
+ using the core JupyterLab application. They can then serve their
+ files by subclassing the `LabServerApp` with the appropriate
+ configuration and creating a Python entry point that launches the app.
+
+
+ ## Development Install
+
+ ```
+ git clone https://github.com/jupyterlab/jupyterlab_server.git
+ cd jupyterlab_server
+ pip install -e .
+ ```
+
Keywords: Jupyter,JupyterLab
Platform: Linux
Platform: Mac OS X
@@ -23,3 +42,5 @@
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Requires-Python: >=3.5
+Description-Content-Type: text/markdown
+Provides-Extra: test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/_version.py
new/jupyterlab_server-1.0.6/jupyterlab_server/_version.py
--- old/jupyterlab_server-0.2.0/jupyterlab_server/_version.py 2018-09-15
09:14:58.000000000 +0200
+++ new/jupyterlab_server-1.0.6/jupyterlab_server/_version.py 2019-08-20
17:52:28.000000000 +0200
@@ -1,2 +1,2 @@
-version_info = (0, 2, 0)
-__version__ = '.'.join(map(str, version_info))
+version_info = (1, 0, 6)
+__version__ = '.'.join(map(str, version_info[:3])) + ''.join(map(str,
version_info[3:]))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyterlab_server-0.2.0/jupyterlab_server/error.html
new/jupyterlab_server-1.0.6/jupyterlab_server/error.html
--- old/jupyterlab_server-0.2.0/jupyterlab_server/error.html 2018-09-13
13:15:04.000000000 +0200
+++ new/jupyterlab_server-1.0.6/jupyterlab_server/error.html 1970-01-01
01:00:00.000000000 +0100
@@ -1,59 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright (c) Jupyter Development Team.
-Distributed under the terms of the Modified BSD License.
--->
-<html>
-
-<head>
- <meta charset="utf-8">
-
- <title>{% block title %}{{page_title}}{% endblock %}</title>
-
- {% block favicon %}<link rel="shortcut icon" type="image/x-icon"
href="/static/base/images/favicon.ico">{% endblock %}
-
-</head>
-
-<body>
-
-{% block stylesheet %}
-<style type="text/css">
-/* disable initial hide */
-div#header, div#site {
- display: block;
-}
-</style>
-{% endblock %}
-{% block site %}
-
-<div class="error">
- {% block h1_error %}
- <h1>{{status_code}} : {{status_message}}</h1>
- {% endblock h1_error %}
- {% block error_detail %}
- {% if message %}
- <p>The error was:</p>
- <div class="traceback-wrapper">
- <pre class="traceback">{{message}}</pre>
- </div>
- {% endif %}
- {% endblock %}
-</header>
-
-{% endblock %}
-
-{% block script %}
-<script type='text/javascript'>
-window.onload = function () {
- var tb = document.getElementsByClassName('traceback')[0];
- tb.scrollTop = tb.scrollHeight;
- {% if message %}
- console.error("{{message}}")
- {% endif %}
-};
-</script>
-{% endblock script %}
-
-</body>
-
-</html>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/handlers.py
new/jupyterlab_server-1.0.6/jupyterlab_server/handlers.py
--- old/jupyterlab_server-0.2.0/jupyterlab_server/handlers.py 2018-09-15
09:14:48.000000000 +0200
+++ new/jupyterlab_server-1.0.6/jupyterlab_server/handlers.py 2019-08-17
12:37:31.000000000 +0200
@@ -5,6 +5,7 @@
# Distributed under the terms of the Modified BSD License.
import json
import os
+from urllib.parse import urlparse
from tornado import web, template
from jinja2 import FileSystemLoader, TemplateError
@@ -36,6 +37,18 @@
""")
+def is_url(url):
+ """Test whether a string is a full url (e.g. https://nasa.gov)
+
+ https://stackoverflow.com/a/52455972
+ """
+ try:
+ result = urlparse(url)
+ return all([result.scheme, result.netloc])
+ except ValueError:
+ return False
+
+
class LabHandler(JupyterHandler):
"""Render the JupyterLab View."""
@@ -46,6 +59,7 @@
@web.authenticated
@web.removeslash
def get(self):
+ self.application.store_id = getattr(self.application, 'store_id', 0)
config = self.lab_config
settings_dir = config.app_settings_dir
@@ -54,18 +68,31 @@
terminals = self.settings.get('terminals_available', False)
server_root = self.settings.get('server_root_dir', '')
server_root = server_root.replace(os.sep, '/')
+ base_url = self.settings.get('base_url')
+
page_config.setdefault('terminalsAvailable', terminals)
page_config.setdefault('ignorePlugins', [])
page_config.setdefault('serverRoot', server_root)
+ page_config['store_id'] = self.application.store_id
+ self.application.store_id += 1
mathjax_config = self.settings.get('mathjax_config',
'TeX-AMS_HTML-full,Safe')
page_config.setdefault('mathjaxConfig', mathjax_config)
- page_config.setdefault('mathjaxUrl', self.mathjax_url)
+ page_config.setdefault('fullMathjaxUrl', self.mathjax_url)
+ # Put all our config in page_config
for name in config.trait_names():
page_config[_camelCase(name)] = getattr(config, name)
+ # Add full versions of all the urls
+ for name in config.trait_names():
+ if not name.endswith('_url'):
+ continue
+ full_name = _camelCase('full_' + name)
+ full_url = ujoin(base_url, getattr(config, name))
+ page_config[full_name] = full_url
+
# Load the current page config file if available.
page_config_file = os.path.join(settings_dir, 'page_config.json')
if os.path.exists(page_config_file):
@@ -99,7 +126,7 @@
app_namespace = Unicode('', help='The namespace of the application.')
- page_url = Unicode('/lab', help='The url path for the application.')
+ app_url = Unicode('/lab', help='The url path for the application.')
app_settings_dir = Unicode('', help='The application settings directory.')
@@ -110,8 +137,8 @@
'If given, a static file handler will be '
'added.'))
- public_url = Unicode(help=('The url public path for static application '
- 'files. This can be a CDN if desired.'))
+ static_url = Unicode(help=('The url path for static application '
+ 'assets. This can be a CDN if desired.'))
settings_url = Unicode(help='The url path of the settings handler.')
@@ -146,29 +173,29 @@
help=('Whether to cache files on the server. '
'This should be `True` except in dev mode.'))
- @default('public_url')
- def _default_public_url(self):
- return ujoin(self.page_url, 'static/')
+ @default('static_url')
+ def _default_static_url(self):
+ return ujoin('static/', self.app_url)
@default('workspaces_url')
def _default_workspaces_url(self):
- return ujoin(self.page_url, 'workspaces/')
+ return ujoin(self.app_url, 'workspaces/')
@default('workspaces_api_url')
def _default_workspaces_api_url(self):
- return ujoin(self.page_url, 'api', 'workspaces/')
+ return ujoin(self.app_url, 'api', 'workspaces/')
@default('settings_url')
def _default_settings_url(self):
- return ujoin(self.page_url, 'api', 'settings/')
+ return ujoin(self.app_url, 'api', 'settings/')
@default('themes_url')
def _default_themes_url(self):
- return ujoin(self.page_url, 'api', 'themes/')
+ return ujoin(self.app_url, 'api', 'themes/')
@default('tree_url')
def _default_tree_url(self):
- return ujoin(self.page_url, 'tree/')
+ return ujoin(self.app_url, 'tree/')
class NotFoundHandler(LabHandler):
@@ -189,9 +216,23 @@
value = getattr(config, name)
setattr(config, name, value.replace(os.sep, '/'))
+ # Normalize urls
+ # Local urls should have a leading slash but no trailing slash
+ for name in config.trait_names():
+ if not name.endswith('_url'):
+ continue
+ value = getattr(config, name)
+ if is_url(value):
+ continue
+ if not value.startswith('/'):
+ value = '/' + value
+ if value.endswith('/'):
+ value = value[:-1]
+ setattr(config, name, value)
+
# Set up the main page handler and tree handler.
base_url = web_app.settings['base_url']
- lab_path = ujoin(base_url, config.page_url)
+ lab_path = ujoin(base_url, config.app_url)
tree_path = ujoin(base_url, config.tree_url, r'.+')
handlers = [
(lab_path, LabHandler, {'lab_config': config}),
@@ -203,8 +244,8 @@
# Handle local static assets.
if config.static_dir:
- public_path = ujoin(base_url, config.public_url + '(.*)')
- handlers.append((public_path, FileFindHandler, {
+ static_path = ujoin(base_url, config.static_url, '(.*)')
+ handlers.append((static_path, FileFindHandler, {
'path': config.static_dir,
'no_cache_paths': no_cache_paths
}))
@@ -218,18 +259,18 @@
}
# Handle requests for the list of settings. Make slash optional.
- settings_path = ujoin(base_url, config.settings_url + '?')
+ settings_path = ujoin(base_url, config.settings_url, '?')
handlers.append((settings_path, SettingsHandler, settings_config))
# Handle requests for an individual set of settings.
setting_path = ujoin(
- base_url, config.settings_url + '(?P<schema_name>.+)')
+ base_url, config.settings_url, '(?P<schema_name>.+)')
handlers.append((setting_path, SettingsHandler, settings_config))
# Handle saved workspaces.
if config.workspaces_dir:
# Handle JupyterLab client URLs that include workspaces.
- workspaces_path = ujoin(base_url, config.workspaces_url, r'/.+')
+ workspaces_path = ujoin(base_url, config.workspaces_url, r'.+')
handlers.append((workspaces_path, LabHandler, {'lab_config': config}))
workspaces_config = {
@@ -238,31 +279,32 @@
}
# Handle requests for the list of workspaces. Make slash optional.
- workspaces_api_path = ujoin(base_url, config.workspaces_api_url + '?')
+ workspaces_api_path = ujoin(base_url, config.workspaces_api_url, '?')
handlers.append((
workspaces_api_path, WorkspacesHandler, workspaces_config))
# Handle requests for an individually named workspace.
workspace_api_path = ujoin(
- base_url, config.workspaces_api_url + '(?P<space_name>.+)')
+ base_url, config.workspaces_api_url, '(?P<space_name>.+)')
handlers.append((
workspace_api_path, WorkspacesHandler, workspaces_config))
# Handle local themes.
if config.themes_dir:
- themes_path = ujoin(base_url, config.themes_url, '(.*)')
+ themes_url = ujoin(base_url, config.themes_url)
+ themes_path = ujoin(themes_url, '(.*)')
handlers.append((
themes_path,
ThemesHandler,
{
- 'themes_url': config.themes_url,
+ 'themes_url': themes_url,
'path': config.themes_dir,
'no_cache_paths': no_cache_paths
}
))
# Let the lab handler act as the fallthrough option instead of a 404.
- fallthrough_url = ujoin(base_url, config.page_url, r'.*')
+ fallthrough_url = ujoin(base_url, config.app_url, r'.*')
handlers.append((fallthrough_url, NotFoundHandler, {'lab_config': config}))
web_app.add_handlers('.*$', handlers)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyterlab_server-0.2.0/jupyterlab_server/index.html
new/jupyterlab_server-1.0.6/jupyterlab_server/index.html
--- old/jupyterlab_server-0.2.0/jupyterlab_server/index.html 2018-09-14
09:52:43.000000000 +0200
+++ new/jupyterlab_server-1.0.6/jupyterlab_server/index.html 1970-01-01
01:00:00.000000000 +0100
@@ -1,49 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>{% block title %}{{page_title}}{% endblock %}</title>
-
- {% block stylesheet %}
- {% for css_file in css_files %}
- <link href="{{ css_file }}" rel="stylesheet">
- {% endfor %}
- {% endblock %}
-
- <script id="jupyter-config-data" type="application/json">{
- {% for key, value in page_config.items() -%}
- "{{ key }}": "{{ value }}",
- {% endfor -%}
- "baseUrl": "{{ base_url }}",
- "wsUrl": "{{ ws_url }}",
- "publicUrl": "{{ public_url }}"
- }</script>
-
- {% block favicon %}
- {% endblock %}
-
- {% for js_file in js_files %}
- <script src="{{ js_file }}" type="text/javascript" charset="utf-8"></script>
- {% endfor %}
-
- {% block meta %}
- {% endblock %}
-
-</head>
-
-<body>
-
- <script type="text/javascript">
- // Remove token from URL.
- (function () {
- var parsedUrl = new URL(window.location.href);
- if (parsedUrl.searchParams.get('token')) {
- parsedUrl.searchParams.delete('token');
- window.history.replaceState({ }, '', parsedUrl.href);
- }
- })();
- </script>
-
-</body>
-
-</html>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/json_minify.py
new/jupyterlab_server-1.0.6/jupyterlab_server/json_minify.py
--- old/jupyterlab_server-0.2.0/jupyterlab_server/json_minify.py
2018-09-13 13:15:04.000000000 +0200
+++ new/jupyterlab_server-1.0.6/jupyterlab_server/json_minify.py
1970-01-01 01:00:00.000000000 +0100
@@ -1,99 +0,0 @@
-# This file comes from
-#
https://raw.githubusercontent.com/getify/JSON.minify/1e3590ddb043b62c851506d9ae8425336335d879/json_minify/__init__.py
-#
-# It is licensed under the following license:
-
-# Copyright (c) 2017 Kyle Simpson <[email protected]>
-
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-"""A port of the `JSON-minify` utility to the Python language.
-
-Based on JSON.minify.js: https://github.com/getify/JSON.minify
-
-Contributers:
- - Gerald Storer
- - Contributed original version
- - Felipe Machado
- - Performance optimization
- - Pradyun S. Gedam
- - Conditions and variable names changed
- - Reformatted tests and moved to separate file
- - Made into a PyPI Package
-"""
-
-import re
-
-
-def json_minify(string, strip_space=True):
- tokenizer = re.compile('"|(/\*)|(\*/)|(//)|\n|\r')
- end_slashes_re = re.compile(r'(\\)*$')
-
- in_string = False
- in_multi = False
- in_single = False
-
- new_str = []
- index = 0
-
- for match in re.finditer(tokenizer, string):
-
- if not (in_multi or in_single):
- tmp = string[index:match.start()]
- if not in_string and strip_space:
- # replace white space as defined in standard
- tmp = re.sub('[ \t\n\r]+', '', tmp)
- new_str.append(tmp)
- elif not strip_space:
- # Replace comments with white space so that the JSON parser reports
- # the correct column numbers on parsing errors.
- new_str.append(' ' * (match.start() - index))
-
- index = match.end()
- val = match.group()
-
- if val == '"' and not (in_multi or in_single):
- escaped = end_slashes_re.search(string, 0, match.start())
-
- # start of string or unescaped quote character to end string
- if not in_string or (escaped is None or len(escaped.group()) % 2
== 0): # noqa
- in_string = not in_string
- index -= 1 # include " character in next catch
- elif not (in_string or in_multi or in_single):
- if val == '/*':
- in_multi = True
- elif val == '//':
- in_single = True
- elif val == '*/' and in_multi and not (in_string or in_single):
- in_multi = False
- if not strip_space:
- new_str.append(' ' * len(val))
- elif val in '\r\n' and not (in_multi or in_string) and in_single:
- in_single = False
- elif not ((in_multi or in_single) or (val in ' \r\n\t' and
strip_space)): # noqa
- new_str.append(val)
-
- if not strip_space:
- if val in '\r\n':
- new_str.append(val)
- elif in_multi or in_single:
- new_str.append(' ' * len(val))
-
- new_str.append(string[index:])
- return ''.join(new_str)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/settings_handler.py
new/jupyterlab_server-1.0.6/jupyterlab_server/settings_handler.py
--- old/jupyterlab_server-0.2.0/jupyterlab_server/settings_handler.py
2018-09-13 13:15:04.000000000 +0200
+++ new/jupyterlab_server-1.0.6/jupyterlab_server/settings_handler.py
2019-08-17 12:37:31.000000000 +0200
@@ -6,11 +6,11 @@
import os
from glob import glob
+import json5
from jsonschema import ValidationError
from jsonschema import Draft4Validator as Validator
from tornado import web
-from .json_minify import json_minify
from .server import APIHandler, json_errors
@@ -66,7 +66,7 @@
with open(path) as fid:
try: # to load and parse the settings file.
raw = fid.read() or raw
- settings = json.loads(json_minify(raw))
+ settings = json5.loads(raw)
except Exception as e:
raise web.HTTPError(500, parse_error % (schema_name, str(e)))
@@ -202,7 +202,6 @@
except Exception as e:
self.log.warn(overrides_warning % str(e))
- @json_errors
@web.authenticated
def get(self, schema_name=''):
overrides = self.overrides
@@ -232,7 +231,6 @@
version=version
)))
- @json_errors
@web.authenticated
def put(self, schema_name):
overrides = self.overrides
@@ -250,7 +248,7 @@
schema = _get_schema(schemas_dir, schema_name, overrides)
validator = Validator(schema)
try:
- validator.validate(json.loads(json_minify(raw)))
+ validator.validate(json5.loads(raw))
except ValidationError as e:
raise web.HTTPError(400, validation_error % str(e))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/templates/403.html
new/jupyterlab_server-1.0.6/jupyterlab_server/templates/403.html
--- old/jupyterlab_server-0.2.0/jupyterlab_server/templates/403.html
1970-01-01 01:00:00.000000000 +0100
+++ new/jupyterlab_server-1.0.6/jupyterlab_server/templates/403.html
2019-08-17 12:37:31.000000000 +0200
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>403 Forbidden</title>
+</head>
+<body>
+<h2>Sorry ..</h2>
+<p>.. you are not allowed to see this content!</p>
+</body>
+</html>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/templates/error.html
new/jupyterlab_server-1.0.6/jupyterlab_server/templates/error.html
--- old/jupyterlab_server-0.2.0/jupyterlab_server/templates/error.html
1970-01-01 01:00:00.000000000 +0100
+++ new/jupyterlab_server-1.0.6/jupyterlab_server/templates/error.html
2019-08-17 12:37:31.000000000 +0200
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) Jupyter Development Team.
+Distributed under the terms of the Modified BSD License.
+-->
+<html>
+
+<head>
+ <meta charset="utf-8">
+
+ <title>{% block title %}{{page_title | escape}{% endblock %}</title>
+
+ {% block favicon %}<link rel="shortcut icon" type="image/x-icon"
href="/static/base/images/favicon.ico">{% endblock %}
+
+</head>
+
+<body>
+
+{% block stylesheet %}
+<style type="text/css">
+/* disable initial hide */
+div#header, div#site {
+ display: block;
+}
+</style>
+{% endblock %}
+{% block site %}
+
+<div class="error">
+ {% block h1_error %}
+ <h1>{{status_code | escape }} : {{status_message | escape }}</h1>
+ {% endblock h1_error %}
+ {% block error_detail %}
+ {% if message %}
+ <p>The error was:</p>
+ <div class="traceback-wrapper">
+ <pre class="traceback">{{message | escape }}</pre>
+ </div>
+ {% endif %}
+ {% endblock %}
+</header>
+
+{% endblock %}
+
+{% block script %}
+<script type='text/javascript'>
+window.onload = function () {
+ var tb = document.getElementsByClassName('traceback')[0];
+ tb.scrollTop = tb.scrollHeight;
+ {% if message %}
+ console.error("{{message | escape}}")
+ {% endif %}
+};
+</script>
+{% endblock script %}
+
+</body>
+
+</html>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/templates/index.html
new/jupyterlab_server-1.0.6/jupyterlab_server/templates/index.html
--- old/jupyterlab_server-0.2.0/jupyterlab_server/templates/index.html
1970-01-01 01:00:00.000000000 +0100
+++ new/jupyterlab_server-1.0.6/jupyterlab_server/templates/index.html
2019-08-17 12:37:31.000000000 +0200
@@ -0,0 +1,50 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>{% block title %}{{page_title | escape }}{% endblock %}</title>
+
+ {% block stylesheet %}
+ {% for css_file in css_files %}
+ <link href="{{ css_file | escape }}" rel="stylesheet">
+ {% endfor %}
+ {% endblock %}
+
+{# Copy so we do not modify the page_config with updates. #}
+{% set page_config_full = page_config.copy() %}
+
+{# Set a dummy variable - we just want the side effect of the update. #}
+{% set _ = page_config_full.update(baseUrl=base_url, wsUrl=ws_url,
staticUrl=static_url) %}
+
+ <script id="jupyter-config-data" type="application/json">
+ {{ page_config_full | tojson }}
+ </script>
+
+ {% block favicon %}
+ {% endblock %}
+
+ {% for js_file in js_files %}
+ <script src="{{ js_file | escape }}" type="text/javascript"
charset="utf-8"></script>
+ {% endfor %}
+
+ {% block meta %}
+ {% endblock %}
+
+</head>
+
+<body>
+
+ <script type="text/javascript">
+ // Remove token from URL.
+ (function () {
+ var parsedUrl = new URL(window.location.href);
+ if (parsedUrl.searchParams.get('token')) {
+ parsedUrl.searchParams.delete('token');
+ window.history.replaceState({ }, '', parsedUrl.href);
+ }
+ })();
+ </script>
+
+</body>
+
+</html>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/tests/schemas/@jupyterlab/shortcuts-extension/package.json.orig
new/jupyterlab_server-1.0.6/jupyterlab_server/tests/schemas/@jupyterlab/shortcuts-extension/package.json.orig
---
old/jupyterlab_server-0.2.0/jupyterlab_server/tests/schemas/@jupyterlab/shortcuts-extension/package.json.orig
1970-01-01 01:00:00.000000000 +0100
+++
new/jupyterlab_server-1.0.6/jupyterlab_server/tests/schemas/@jupyterlab/shortcuts-extension/package.json.orig
2019-08-17 12:37:31.000000000 +0200
@@ -0,0 +1,4 @@
+{
+ "name": "@jupyterlab/shortcuts-extension",
+ "version": "test-version"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/tests/test_workspaces_api.py
new/jupyterlab_server-1.0.6/jupyterlab_server/tests/test_workspaces_api.py
--- old/jupyterlab_server-0.2.0/jupyterlab_server/tests/test_workspaces_api.py
2018-09-13 13:15:04.000000000 +0200
+++ new/jupyterlab_server-1.0.6/jupyterlab_server/tests/test_workspaces_api.py
2019-08-17 12:37:31.000000000 +0200
@@ -47,25 +47,28 @@
def test_get(self):
id = 'foo'
-
assert self.workspaces_api.get(id).json()['metadata']['id'] == id
def test_listing(self):
# ID fields are from workspaces/*.jupyterlab-workspace
listing = set(['foo', 'f/o/o/'])
-
- assert set(self.workspaces_api.get().json()['workspaces']) == listing
+ output = set(self.workspaces_api.get().json()['workspaces']['ids'])
+ assert output == listing
def test_put(self):
id = 'foo'
data = self.workspaces_api.get(id).json()
-
assert self.workspaces_api.put(id, data).status_code == 204
def test_bad_put(self):
orig = 'foo'
copy = 'bar'
data = self.workspaces_api.get(orig).json()
-
with assert_http_error(400):
self.workspaces_api.put(copy, data)
+
+ def test_blank_put(self):
+ orig = 'foo'
+ data = self.workspaces_api.get(orig).json()
+ with assert_http_error(400):
+ self.workspaces_api.put('', data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/tests/workspaces/abfoo-19e2.jupyterlab-workspace
new/jupyterlab_server-1.0.6/jupyterlab_server/tests/workspaces/abfoo-19e2.jupyterlab-workspace
---
old/jupyterlab_server-0.2.0/jupyterlab_server/tests/workspaces/abfoo-19e2.jupyterlab-workspace
2018-09-13 13:15:04.000000000 +0200
+++
new/jupyterlab_server-1.0.6/jupyterlab_server/tests/workspaces/abfoo-19e2.jupyterlab-workspace
1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-{"data": {}, "metadata": {"id": "f/o/o/"}}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/tests/workspaces/abfoo-2c26.jupyterlab-workspace
new/jupyterlab_server-1.0.6/jupyterlab_server/tests/workspaces/abfoo-2c26.jupyterlab-workspace
---
old/jupyterlab_server-0.2.0/jupyterlab_server/tests/workspaces/abfoo-2c26.jupyterlab-workspace
2018-09-13 13:15:04.000000000 +0200
+++
new/jupyterlab_server-1.0.6/jupyterlab_server/tests/workspaces/abfoo-2c26.jupyterlab-workspace
1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-{"data": {}, "metadata": {"id": "foo"}}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/tests/workspaces/foo-2c26.jupyterlab-workspace
new/jupyterlab_server-1.0.6/jupyterlab_server/tests/workspaces/foo-2c26.jupyterlab-workspace
---
old/jupyterlab_server-0.2.0/jupyterlab_server/tests/workspaces/foo-2c26.jupyterlab-workspace
1970-01-01 01:00:00.000000000 +0100
+++
new/jupyterlab_server-1.0.6/jupyterlab_server/tests/workspaces/foo-2c26.jupyterlab-workspace
2019-08-17 12:37:31.000000000 +0200
@@ -0,0 +1 @@
+{"data": {}, "metadata": {"id": "foo"}}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/tests/workspaces/foo-92dd.jupyterlab-workspace
new/jupyterlab_server-1.0.6/jupyterlab_server/tests/workspaces/foo-92dd.jupyterlab-workspace
---
old/jupyterlab_server-0.2.0/jupyterlab_server/tests/workspaces/foo-92dd.jupyterlab-workspace
1970-01-01 01:00:00.000000000 +0100
+++
new/jupyterlab_server-1.0.6/jupyterlab_server/tests/workspaces/foo-92dd.jupyterlab-workspace
2019-08-17 12:37:31.000000000 +0200
@@ -0,0 +1 @@
+{"data": {}, "metadata": {"id": "f/o/o/"}}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server/workspaces_handler.py
new/jupyterlab_server-1.0.6/jupyterlab_server/workspaces_handler.py
--- old/jupyterlab_server-0.2.0/jupyterlab_server/workspaces_handler.py
2018-09-13 13:15:04.000000000 +0200
+++ new/jupyterlab_server-1.0.6/jupyterlab_server/workspaces_handler.py
2019-08-17 12:37:31.000000000 +0200
@@ -15,16 +15,12 @@
# The JupyterLab workspace file extension.
WORKSPACE_EXTENSION = '.jupyterlab-workspace'
-# A cache of workspace names and their slug file name counterparts.
-_cache = dict()
-
-
def _list_workspaces(directory, prefix):
"""
Return the list of workspaces in a given directory beginning with the
given prefix.
"""
- workspaces = []
+ workspaces = { 'ids': [], 'values': [] }
if not os.path.exists(directory):
return workspaces
@@ -35,24 +31,22 @@
items.sort()
for slug in items:
- if slug in _cache:
- workspaces.append(_cache[slug])
- continue
workspace_path = os.path.join(directory, slug)
if os.path.exists(workspace_path):
with open(workspace_path) as fid:
try: # to load and parse the workspace file.
- _cache[slug] = json.load(fid)['metadata']['id']
- workspaces.append(_cache[slug])
+ workspace = json.load(fid)
+ workspaces.get('ids').append(workspace['metadata']['id'])
+ workspaces.get('values').append(workspace)
except Exception as e:
raise web.HTTPError(500, str(e))
return workspaces
-def slugify(raw, base, sign=True, max_length=128 - len(WORKSPACE_EXTENSION)):
+def slugify(raw, base='', sign=True, max_length=128 -
len(WORKSPACE_EXTENSION)):
"""
Use the common superset of raw and base values to build a slug shorter
- than max_length.
+ than max_length. By default, base value is an empty string.
Convert spaces to hyphens. Remove characters that aren't alphanumerics
underscores, or hyphens. Convert to lowercase. Strip leading and trailing
whitespace.
@@ -94,16 +88,14 @@
return self.workspaces_dir
- @json_errors
@web.authenticated
def delete(self, space_name):
- base_url = self.base_url
directory = self.ensure_directory()
if not space_name:
raise web.HTTPError(400, 'Workspace name is required for DELETE')
- slug = slugify(space_name, base_url)
+ slug = slugify(space_name)
workspace_path = os.path.join(directory, slug + WORKSPACE_EXTENSION)
if not os.path.exists(workspace_path):
@@ -116,18 +108,16 @@
except Exception as e:
raise web.HTTPError(500, str(e))
- @json_errors
@web.authenticated
def get(self, space_name=''):
- base_url = self.base_url
directory = self.ensure_directory()
if not space_name:
- prefix = slugify('', base_url, sign=False)
+ prefix = slugify('', sign=False)
workspaces = _list_workspaces(directory, prefix)
return self.finish(json.dumps(dict(workspaces=workspaces)))
- slug = slugify(space_name, base_url)
+ slug = slugify(space_name)
workspace_path = os.path.join(directory, slug + WORKSPACE_EXTENSION)
if os.path.exists(workspace_path):
@@ -137,13 +127,16 @@
except Exception as e:
raise web.HTTPError(500, str(e))
else:
- raise web.HTTPError(404, 'Workspace %r (%r) not found' %
- (space_name, slug))
+ id = (space_name if space_name.startswith('/')
+ else '/' + space_name)
+ workspace = dict(data=dict(), metadata=dict(id=id))
+ return self.finish(json.dumps(workspace))
- @json_errors
@web.authenticated
- def put(self, space_name):
- base_url = self.base_url
+ def put(self, space_name=''):
+ if not space_name:
+ raise web.HTTPError(400, 'Workspace name is required for PUT.')
+
directory = self.ensure_directory()
if not os.path.exists(directory):
@@ -167,12 +160,13 @@
metadata_id = workspace['metadata']['id']
metadata_id = (metadata_id if metadata_id.startswith('/')
else '/' + metadata_id)
+ metadata_id = urllib.parse.unquote(metadata_id)
if metadata_id != '/' + space_name:
message = ('Workspace metadata ID mismatch: expected %r got %r'
% (space_name, metadata_id))
raise web.HTTPError(400, message)
- slug = slugify(space_name, base_url)
+ slug = slugify(space_name)
workspace_path = os.path.join(directory, slug + WORKSPACE_EXTENSION)
# Write the workspace data to a file.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server.egg-info/PKG-INFO
new/jupyterlab_server-1.0.6/jupyterlab_server.egg-info/PKG-INFO
--- old/jupyterlab_server-0.2.0/jupyterlab_server.egg-info/PKG-INFO
2018-09-15 09:15:02.000000000 +0200
+++ new/jupyterlab_server-1.0.6/jupyterlab_server.egg-info/PKG-INFO
2019-08-20 17:52:30.000000000 +0200
@@ -1,15 +1,34 @@
-Metadata-Version: 1.2
+Metadata-Version: 2.1
Name: jupyterlab-server
-Version: 0.2.0
+Version: 1.0.6
Summary: JupyterLab Server
-Home-page: http://jupyter.org
+Home-page: https://jupyter.org
Author: Jupyter Development Team
Author-email: [email protected]
License: BSD
-Description-Content-Type: UNKNOWN
-Description:
- This package is used to launch an application built using
JupyterLab
-
+Description: # jupyterlab server
+
+ https://github.com/jupyterlab/jupyterlab_server
+
+ ## Install
+
+ `pip install jupyterlab_server`
+
+ ## Usage
+ The application author creates a JupyterLab build on their machine
+ using the core JupyterLab application. They can then serve their
+ files by subclassing the `LabServerApp` with the appropriate
+ configuration and creating a Python entry point that launches the app.
+
+
+ ## Development Install
+
+ ```
+ git clone https://github.com/jupyterlab/jupyterlab_server.git
+ cd jupyterlab_server
+ pip install -e .
+ ```
+
Keywords: Jupyter,JupyterLab
Platform: Linux
Platform: Mac OS X
@@ -23,3 +42,5 @@
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Requires-Python: >=3.5
+Description-Content-Type: text/markdown
+Provides-Extra: test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server.egg-info/SOURCES.txt
new/jupyterlab_server-1.0.6/jupyterlab_server.egg-info/SOURCES.txt
--- old/jupyterlab_server-0.2.0/jupyterlab_server.egg-info/SOURCES.txt
2018-09-15 09:15:02.000000000 +0200
+++ new/jupyterlab_server-1.0.6/jupyterlab_server.egg-info/SOURCES.txt
2019-08-20 17:52:30.000000000 +0200
@@ -7,10 +7,7 @@
jupyterlab_server/__init__.py
jupyterlab_server/_version.py
jupyterlab_server/app.py
-jupyterlab_server/error.html
jupyterlab_server/handlers.py
-jupyterlab_server/index.html
-jupyterlab_server/json_minify.py
jupyterlab_server/process.py
jupyterlab_server/process_app.py
jupyterlab_server/server.py
@@ -23,6 +20,9 @@
jupyterlab_server.egg-info/dependency_links.txt
jupyterlab_server.egg-info/requires.txt
jupyterlab_server.egg-info/top_level.txt
+jupyterlab_server/templates/403.html
+jupyterlab_server/templates/error.html
+jupyterlab_server/templates/index.html
jupyterlab_server/tests/__init__.py
jupyterlab_server/tests/test_settings_api.py
jupyterlab_server/tests/test_workspaces_api.py
@@ -30,6 +30,7 @@
jupyterlab_server/tests/app-settings/overrides.json
jupyterlab_server/tests/schemas/@jupyterlab/apputils-extension/themes.json
jupyterlab_server/tests/schemas/@jupyterlab/codemirror-extension/commands.json
+jupyterlab_server/tests/schemas/@jupyterlab/shortcuts-extension/package.json.orig
jupyterlab_server/tests/schemas/@jupyterlab/shortcuts-extension/plugin.json
-jupyterlab_server/tests/workspaces/abfoo-19e2.jupyterlab-workspace
-jupyterlab_server/tests/workspaces/abfoo-2c26.jupyterlab-workspace
\ No newline at end of file
+jupyterlab_server/tests/workspaces/foo-2c26.jupyterlab-workspace
+jupyterlab_server/tests/workspaces/foo-92dd.jupyterlab-workspace
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyterlab_server-0.2.0/jupyterlab_server.egg-info/requires.txt
new/jupyterlab_server-1.0.6/jupyterlab_server.egg-info/requires.txt
--- old/jupyterlab_server-0.2.0/jupyterlab_server.egg-info/requires.txt
2018-09-15 09:15:02.000000000 +0200
+++ new/jupyterlab_server-1.0.6/jupyterlab_server.egg-info/requires.txt
2019-08-20 17:52:30.000000000 +0200
@@ -1,5 +1,7 @@
-jsonschema>=2.6.0
+json5
+jsonschema>=3.0.1
notebook>=4.2.0
+jinja2>=2.10
[test]
pytest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyterlab_server-0.2.0/setup.py
new/jupyterlab_server-1.0.6/setup.py
--- old/jupyterlab_server-0.2.0/setup.py 2018-09-13 13:15:04.000000000
+0200
+++ new/jupyterlab_server-1.0.6/setup.py 2019-08-20 13:14:51.000000000
+0200
@@ -8,17 +8,17 @@
from setuptools import find_packages, setup
import sys
+
setup_args = dict(
name='jupyterlab_server',
version=__version__,
packages=find_packages('.'),
description='JupyterLab Server',
- long_description="""
- This package is used to launch an application built using JupyterLab
- """,
+ long_description=open('./README.md').read(),
+ long_description_content_type='text/markdown',
author='Jupyter Development Team',
author_email='[email protected]',
- url='http://jupyter.org',
+ url='https://jupyter.org',
license='BSD',
platforms='Linux, Mac OS X, Windows',
keywords=['Jupyter', 'JupyterLab'],
@@ -39,7 +39,12 @@
if 'setuptools' in sys.modules:
setup_args['python_requires'] = '>=3.5'
setup_args['extras_require'] = {'test': ['pytest', 'requests']}
- setup_args['install_requires'] = ['jsonschema>=2.6.0', 'notebook>=4.2.0']
+ setup_args['install_requires'] = [
+ 'json5',
+ 'jsonschema>=3.0.1',
+ 'notebook>=4.2.0',
+ 'jinja2>=2.10'
+ ]
if __name__ == '__main__':
setup(**setup_args)