소스 검색

Merge pull request #6509 from blink1073/url-cleanup

Update for changes to server
Steven Silvester 5 년 전
부모
커밋
6b2e2935d5

+ 1 - 1
dev_mode/index.js

@@ -9,7 +9,7 @@ import {
   PageConfig, URLExt
 } from '@jupyterlab/coreutils';
 
-__webpack_public_path__ = PageConfig.getOption('frontendUrl');
+__webpack_public_path__ = PageConfig.getOption('fullStaticUrl') + '/';
 
 // This needs to come after __webpack_public_path__ is set.
 require('font-awesome/css/font-awesome.min.css');

+ 11 - 0
dev_mode/templates/403.html

@@ -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>

+ 1 - 9
dev_mode/webpack.config.js

@@ -86,14 +86,6 @@ JupyterFrontEndPlugin.prototype.apply = function(compiler) {
   compiler.hooks.afterEmit.tap(
     'JupyterFrontEndPlugin',
     function() {
-      // Fix the template output.
-      var indexPath = path.join(buildDir, 'index.html');
-      var indexData = fs.readFileSync(indexPath, 'utf8');
-      indexData = indexData
-        .split('{{page_config.frontendUrl}}/')
-        .join('{{page_config.frontendUrl}}');
-      fs.writeFileSync(indexPath, indexData, 'utf8');
-
       // Copy the static assets.
       var staticDir = jlab.staticDir;
       if (!staticDir) {
@@ -142,7 +134,7 @@ module.exports = [
     },
     output: {
       path: path.resolve(buildDir),
-      publicPath: '{{page_config.frontendUrl}}',
+      publicPath: '{{page_config.fullStaticUrl}}/',
       filename: '[name].[chunkhash].js'
     },
     optimization: {

+ 2 - 5
examples/app/index.js

@@ -1,12 +1,9 @@
 // Copyright (c) Jupyter Development Team.
 // Distributed under the terms of the Modified BSD License.
 
-import { PageConfig, URLExt } from '@jupyterlab/coreutils';
+import { PageConfig } from '@jupyterlab/coreutils';
 // eslint-disable-next-line
-__webpack_public_path__ = URLExt.join(
-  PageConfig.getBaseUrl(),
-  'example/static/'
-);
+__webpack_public_path__ = PageConfig.getOption('fullStaticUrl') + '/';
 
 window.addEventListener('load', async function() {
   var JupyterLab = require('@jupyterlab/application').JupyterLab;

+ 2 - 2
examples/app/main.py

@@ -17,7 +17,7 @@ with open(os.path.join(HERE, 'package.json')) as fid:
     version = json.load(fid)['version']
 
 class ExampleApp(LabServerApp):
-    base_url = '/foo/'
+    base_url = '/foo'
     default_url = Unicode('/example',
                           help='The default URL to redirect to from `/`')
 
@@ -25,7 +25,7 @@ class ExampleApp(LabServerApp):
         app_name = 'JupyterLab Example App',
         app_settings_dir = os.path.join(HERE, 'build', 'application_settings'),
         app_version = version,
-        page_url = '/example',
+        app_url = '/example',
         schemas_dir = os.path.join(HERE, 'build', 'schemas'),
         static_dir = os.path.join(HERE, 'build'),
         templates_dir = os.path.join(HERE, 'templates'),

+ 1 - 1
examples/app/templates/index.html

@@ -11,7 +11,7 @@
   "baseUrl": "{{base_url}}",
   "wsUrl": "{{ws_url}}"
  }</script>
-  <script src="{{page_config['frontendUrl']}}bundle.js" main="index"></script>
+  <script src="{{page_config['fullStaticUrl']}}/bundle.js" main="index"></script>
 
   <script type="text/javascript">
     /* Remove token from URL. */

+ 8 - 8
jupyterlab/commands.py

@@ -297,7 +297,7 @@ def clean(app_dir=None, logger=None):
     logger.info('Success!')
 
 
-def build(app_dir=None, name=None, version=None, public_url=None,
+def build(app_dir=None, name=None, version=None, static_url=None,
           logger=None, command='build:prod', kill_event=None,
           clean_staging=False):
     """Build the JupyterLab application.
@@ -305,7 +305,7 @@ def build(app_dir=None, name=None, version=None, public_url=None,
     logger = _ensure_logger(logger)
     _node_check(logger)
     handler = _AppHandler(app_dir, logger, kill_event=kill_event)
-    return handler.build(name=name, version=version, public_url=public_url,
+    return handler.build(name=name, version=version, static_url=static_url,
                          command=command, clean_staging=clean_staging)
 
 
@@ -469,7 +469,7 @@ class _AppHandler(object):
 
         return True
 
-    def build(self, name=None, version=None, public_url=None,
+    def build(self, name=None, version=None, static_url=None,
               command='build:prod', clean_staging=False):
         """Build the application.
         """
@@ -477,7 +477,7 @@ class _AppHandler(object):
         app_dir = self.app_dir
 
         self._populate_staging(
-            name=name, version=version, public_url=public_url,
+            name=name, version=version, static_url=static_url,
             clean=clean_staging
         )
 
@@ -882,7 +882,7 @@ class _AppHandler(object):
         info['static_data'] = _get_static_data(self.app_dir)
         app_data = info['static_data'] or core_data
         info['version'] = app_data['jupyterlab']['version']
-        info['publicUrl'] = app_data['jupyterlab'].get('publicUrl', '')
+        info['staticUrl'] = app_data['jupyterlab'].get('staticUrl', '')
 
         info['sys_dir'] = self.sys_dir
         info['app_dir'] = self.app_dir
@@ -897,7 +897,7 @@ class _AppHandler(object):
         info['disabled_core'] = disabled_core
         return info
 
-    def _populate_staging(self, name=None, version=None, public_url=None,
+    def _populate_staging(self, name=None, version=None, static_url=None,
                           clean=False):
         """Set up the assets in the staging directory.
         """
@@ -986,8 +986,8 @@ class _AppHandler(object):
         if name:
             data['jupyterlab']['name'] = name
 
-        if public_url:
-            data['jupyterlab']['publicUrl'] = public_url
+        if static_url:
+            data['jupyterlab']['staticUrl'] = static_url
 
         pkg_path = pjoin(staging, 'package.json')
         with open(pkg_path, 'w') as fid:

+ 17 - 5
jupyterlab/extension.py

@@ -39,7 +39,7 @@ def load_config(nbapp):
 
     app_dir = getattr(nbapp, 'app_dir', get_app_dir())
     info = get_app_info(app_dir)
-    public_url = info['publicUrl']
+    static_url = info['staticUrl']
     user_settings_dir = getattr(
         nbapp, 'user_settings_dir', get_user_settings_dir()
     )
@@ -59,13 +59,18 @@ def load_config(nbapp):
     config.workspaces_dir = workspaces_dir
 
     if getattr(nbapp, 'override_static_url', ''):
-        public_url = nbapp.override_static_url
+        static_url = nbapp.override_static_url
     if getattr(nbapp, 'override_theme_url', ''):
         config.themes_url = nbapp.override_theme_url
         config.themes_dir = ''
 
-    if public_url:
-        config.public_url = public_url
+    # shim for jupyterlab_server 0.3
+    # XXX remove after next JLab release (current is 1.0.0a6)
+    if static_url:
+        if hasattr(config, 'static_url'):
+            config.static_url = static_url
+        else:
+            config.public_url = static_url
     else:
         config.static_dir = pjoin(app_dir, 'static')
 
@@ -119,7 +124,14 @@ def load_jupyter_server_extension(nbapp):
     config = load_config(nbapp)
     config.app_name = 'JupyterLab'
     config.app_namespace = 'jupyterlab'
-    config.page_url = '/lab'
+
+    # shim for jupyterlab_server 0.3
+    # XXX remove after next JLab release (current is 1.0.0a6)
+    if hasattr(config, 'app_url'):
+        config.app_url = '/lab'
+    else:
+        config.page_url = '/lab'
+
     config.cache_files = True
 
     # Check for watch.

+ 2 - 2
jupyterlab/tests/test_jupyterlab.py

@@ -364,7 +364,7 @@ class TestExtension(TestCase):
 
     def test_build_custom(self):
         assert install_extension(self.mock_extension) is True
-        build(name='foo', version='1.0', public_url='bar')
+        build(name='foo', version='1.0', static_url='bar')
 
         # check static directory.
         entry = pjoin(self.app_dir, 'static', 'index.out.js')
@@ -377,7 +377,7 @@ class TestExtension(TestCase):
             data = json.load(fid)
         assert data['jupyterlab']['name'] == 'foo'
         assert data['jupyterlab']['version'] == '1.0'
-        assert data['jupyterlab']['publicUrl'] == 'bar'
+        assert data['jupyterlab']['staticUrl'] == 'bar'
 
     def test_load_extension(self):
         app = NotebookApp()

+ 1 - 1
package.json

@@ -41,7 +41,7 @@
     "clean:src": "jlpm run clean",
     "clean:test": "lerna run clean --scope \"@jupyterlab/test-*\"",
     "clean:utils": "cd buildutils && jlpm run clean",
-    "coverage": "lerna run coverage --scope \"@jupyterlab/test-*\" --stream --concurrency 1 --no-bail",
+    "coverage": "lerna run coverage --scope \"@jupyterlab/test-*\" --stream --concurrency 1",
     "create:package": "node buildutils/lib/create-package.js",
     "create:test": "node buildutils/lib/create-test-package.js",
     "create:theme": "node buildutils/lib/create-theme.js",

+ 1 - 1
packages/application-extension/src/index.tsx

@@ -268,7 +268,7 @@ const tree: JupyterFrontEndPlugin<void> = {
         const url =
           (workspaceMatch
             ? URLExt.join(paths.urls.workspaces, workspace)
-            : paths.urls.page) +
+            : paths.urls.app) +
           args.search +
           args.hash;
         const immediate = true;

+ 2 - 2
packages/application/src/frontend.ts

@@ -266,8 +266,8 @@ export namespace JupyterFrontEnd {
     readonly urls: {
       readonly base: string;
       readonly notFound?: string;
-      readonly page: string;
-      readonly public: string;
+      readonly app: string;
+      readonly static: string;
       readonly settings: string;
       readonly themes: string;
       readonly tree: string;

+ 2 - 2
packages/application/src/lab.ts

@@ -239,8 +239,8 @@ export namespace JupyterLab {
     urls: {
       base: PageConfig.getOption('baseUrl'),
       notFound: PageConfig.getOption('notFoundUrl'),
-      page: PageConfig.getOption('pageUrl'),
-      public: PageConfig.getOption('publicUrl'),
+      app: PageConfig.getOption('appUrl'),
+      static: PageConfig.getOption('staticUrl'),
       settings: PageConfig.getOption('settingsUrl'),
       themes: PageConfig.getOption('themesUrl'),
       tree: PageConfig.getOption('treeUrl'),

+ 6 - 6
packages/apputils-extension/src/index.ts

@@ -241,13 +241,13 @@ const resolver: JupyterFrontEndPlugin<IWindowResolver> = {
     const { hash, path, search } = router.current;
     const query = URLExt.queryStringToObject(search || '');
     const solver = new WindowResolver();
-    const match = path.match(new RegExp(`^${paths.urls.workspaces}([^?\/]+)`));
+    const { urls } = paths;
+    const match = path.match(new RegExp(`^${urls.workspaces}\/([^?\/]+)`));
     const workspace = (match && decodeURIComponent(match[1])) || '';
     const candidate = Private.candidate(paths, workspace);
     const rest = workspace
-      ? path.replace(new RegExp(`^${paths.urls.workspaces}${workspace}`), '')
-      : path.replace(new RegExp(`^${paths.urls.page}`), '');
-
+      ? path.replace(new RegExp(`^${urls.workspaces}\/${workspace}`), '')
+      : path.replace(new RegExp(`^${urls.app}\/?`), '');
     try {
       await solver.resolve(candidate);
       return solver;
@@ -449,7 +449,7 @@ const state: JupyterFrontEndPlugin<IStateDB> = {
         const clone =
           typeof query['clone'] === 'string'
             ? query['clone'] === ''
-              ? URLExt.join(urls.base, urls.page)
+              ? URLExt.join(urls.base, urls.app)
               : URLExt.join(urls.base, urls.workspaces, query['clone'])
             : null;
         const source = clone || workspace || null;
@@ -608,6 +608,6 @@ namespace Private {
   ): string {
     return workspace
       ? URLExt.join(urls.workspaces, workspace)
-      : URLExt.join(urls.page);
+      : URLExt.join(urls.app);
   }
 }

+ 2 - 2
packages/console-extension/src/index.ts

@@ -20,7 +20,7 @@ import { IEditorServices } from '@jupyterlab/codeeditor';
 
 import { ConsolePanel, IConsoleTracker } from '@jupyterlab/console';
 
-import { ISettingRegistry, PageConfig } from '@jupyterlab/coreutils';
+import { ISettingRegistry, PageConfig, URLExt } from '@jupyterlab/coreutils';
 
 import { IFileBrowserFactory } from '@jupyterlab/filebrowser';
 
@@ -181,7 +181,7 @@ async function activateConsole(
           let kernelIconUrl = specs.kernelspecs[name].resources['logo-64x64'];
           if (kernelIconUrl) {
             let index = kernelIconUrl.indexOf('kernelspecs');
-            kernelIconUrl = baseUrl + kernelIconUrl.slice(index);
+            kernelIconUrl = URLExt.join(baseUrl, kernelIconUrl.slice(index));
           }
           disposables.add(
             launcher.add({

+ 1 - 1
packages/mathjax2-extension/src/index.ts

@@ -19,7 +19,7 @@ const plugin: JupyterFrontEndPlugin<ILatexTypesetter> = {
   autoStart: true,
   provides: ILatexTypesetter,
   activate: () => {
-    const url = PageConfig.getOption('mathjaxUrl');
+    const url = PageConfig.getOption('fullMathjaxUrl');
     const config = PageConfig.getOption('mathjaxConfig');
 
     if (!url) {

+ 3 - 2
packages/notebook-extension/src/index.ts

@@ -24,7 +24,8 @@ import {
   ISettingRegistry,
   IStateDB,
   nbformat,
-  PageConfig
+  PageConfig,
+  URLExt
 } from '@jupyterlab/coreutils';
 
 import { IDocumentManager } from '@jupyterlab/docmanager';
@@ -707,7 +708,7 @@ function activateNotebookHandler(
           let kernelIconUrl = specs.kernelspecs[name].resources['logo-64x64'];
           if (kernelIconUrl) {
             let index = kernelIconUrl.indexOf('kernelspecs');
-            kernelIconUrl = baseUrl + kernelIconUrl.slice(index);
+            kernelIconUrl = URLExt.join(baseUrl, kernelIconUrl.slice(index));
           }
           disposables.add(
             launcher.add({

+ 11 - 13
packages/services/src/builder/index.ts

@@ -8,7 +8,7 @@ import { ServerConnection } from '../serverconnection';
 /**
  * The url for the lab build service.
  */
-const BUILD_SETTINGS_URL = 'lab/api/build';
+const BUILD_SETTINGS_URL = 'api/build';
 
 /**
  * The build API service manager.
@@ -20,6 +20,8 @@ export class BuildManager {
   constructor(options: BuildManager.IOptions = {}) {
     this.serverSettings =
       options.serverSettings || ServerConnection.makeSettings();
+    const { baseUrl, appUrl } = this.serverSettings;
+    this._url = URLExt.join(baseUrl, appUrl, BUILD_SETTINGS_URL);
   }
 
   /**
@@ -45,10 +47,8 @@ export class BuildManager {
    * Get whether the application should be built.
    */
   getStatus(): Promise<BuildManager.IStatus> {
-    const base = this.serverSettings.baseUrl;
-    const url = URLExt.join(base, BUILD_SETTINGS_URL);
-    const { serverSettings } = this;
-    const promise = ServerConnection.makeRequest(url, {}, serverSettings);
+    const { _url, serverSettings } = this;
+    const promise = ServerConnection.makeRequest(_url, {}, serverSettings);
 
     return promise
       .then(response => {
@@ -73,11 +73,9 @@ export class BuildManager {
    * Build the application.
    */
   build(): Promise<void> {
-    const base = this.serverSettings.baseUrl;
-    const url = URLExt.join(base, BUILD_SETTINGS_URL);
-    const { serverSettings } = this;
+    const { _url, serverSettings } = this;
     const init = { method: 'POST' };
-    const promise = ServerConnection.makeRequest(url, init, serverSettings);
+    const promise = ServerConnection.makeRequest(_url, init, serverSettings);
 
     return promise.then(response => {
       if (response.status === 400) {
@@ -96,11 +94,9 @@ export class BuildManager {
    * Cancel an active build.
    */
   cancel(): Promise<void> {
-    const base = this.serverSettings.baseUrl;
-    const url = URLExt.join(base, BUILD_SETTINGS_URL);
-    const { serverSettings } = this;
+    const { _url, serverSettings } = this;
     const init = { method: 'DELETE' };
-    const promise = ServerConnection.makeRequest(url, init, serverSettings);
+    const promise = ServerConnection.makeRequest(_url, init, serverSettings);
 
     return promise.then(response => {
       if (response.status !== 204) {
@@ -108,6 +104,8 @@ export class BuildManager {
       }
     });
   }
+
+  private _url = '';
 }
 
 /**

+ 3 - 3
packages/services/src/serverconnection.ts

@@ -57,9 +57,9 @@ export namespace ServerConnection {
     readonly baseUrl: string;
 
     /**
-     * The page url of the JupyterLab application.
+     * The app url of the JupyterLab application.
      */
-    readonly pageUrl: string;
+    readonly appUrl: string;
 
     /**
      * The base ws url of the server.
@@ -178,7 +178,7 @@ export namespace ServerConnection {
    */
   export const defaultSettings: ServerConnection.ISettings = {
     baseUrl: PageConfig.getBaseUrl(),
-    pageUrl: PageConfig.getOption('pageUrl'),
+    appUrl: PageConfig.getOption('appUrl'),
     wsUrl: PageConfig.getWsUrl(),
     token: PageConfig.getToken(),
     init: { cache: 'no-store', credentials: 'same-origin' },

+ 6 - 6
packages/services/src/setting/index.ts

@@ -40,9 +40,9 @@ export class SettingManager extends DataConnector<
    */
   async fetch(id: string): Promise<ISettingRegistry.IPlugin> {
     const { serverSettings } = this;
-    const { baseUrl, pageUrl } = serverSettings;
+    const { baseUrl, appUrl } = serverSettings;
     const { makeRequest, ResponseError } = ServerConnection;
-    const base = baseUrl + pageUrl;
+    const base = baseUrl + appUrl;
     const url = Private.url(base, id);
     const response = await makeRequest(url, {}, serverSettings);
 
@@ -65,9 +65,9 @@ export class SettingManager extends DataConnector<
    */
   async list(): Promise<{ ids: string[]; values: ISettingRegistry.IPlugin[] }> {
     const { serverSettings } = this;
-    const { baseUrl, pageUrl } = serverSettings;
+    const { baseUrl, appUrl } = serverSettings;
     const { makeRequest, ResponseError } = ServerConnection;
-    const base = baseUrl + pageUrl;
+    const base = baseUrl + appUrl;
     const url = Private.url(base, '');
     const response = await makeRequest(url, {}, serverSettings);
 
@@ -98,9 +98,9 @@ export class SettingManager extends DataConnector<
    */
   async save(id: string, raw: string): Promise<void> {
     const { serverSettings } = this;
-    const { baseUrl, pageUrl } = serverSettings;
+    const { baseUrl, appUrl } = serverSettings;
     const { makeRequest, ResponseError } = ServerConnection;
-    const base = baseUrl + pageUrl;
+    const base = baseUrl + appUrl;
     const url = Private.url(base, id);
     const init = { body: raw, method: 'PUT' };
     const response = await makeRequest(url, init, serverSettings);

+ 8 - 8
packages/services/src/workspace/index.ts

@@ -39,9 +39,9 @@ export class WorkspaceManager extends DataConnector<Workspace.IWorkspace> {
    */
   async fetch(id: string): Promise<Workspace.IWorkspace> {
     const { serverSettings } = this;
-    const { baseUrl, pageUrl } = serverSettings;
+    const { baseUrl, appUrl } = serverSettings;
     const { makeRequest, ResponseError } = ServerConnection;
-    const base = baseUrl + pageUrl;
+    const base = baseUrl + appUrl;
     const url = Private.url(base, id);
     const response = await makeRequest(url, {}, serverSettings);
 
@@ -59,9 +59,9 @@ export class WorkspaceManager extends DataConnector<Workspace.IWorkspace> {
    */
   async list(): Promise<{ ids: string[]; values: Workspace.IWorkspace[] }> {
     const { serverSettings } = this;
-    const { baseUrl, pageUrl } = serverSettings;
+    const { baseUrl, appUrl } = serverSettings;
     const { makeRequest, ResponseError } = ServerConnection;
-    const base = baseUrl + pageUrl;
+    const base = baseUrl + appUrl;
     const url = Private.url(base, '');
     const response = await makeRequest(url, {}, serverSettings);
 
@@ -83,9 +83,9 @@ export class WorkspaceManager extends DataConnector<Workspace.IWorkspace> {
    */
   async remove(id: string): Promise<void> {
     const { serverSettings } = this;
-    const { baseUrl, pageUrl } = serverSettings;
+    const { baseUrl, appUrl } = serverSettings;
     const { makeRequest, ResponseError } = ServerConnection;
-    const base = baseUrl + pageUrl;
+    const base = baseUrl + appUrl;
     const url = Private.url(base, id);
     const init = { method: 'DELETE' };
     const response = await makeRequest(url, init, serverSettings);
@@ -106,9 +106,9 @@ export class WorkspaceManager extends DataConnector<Workspace.IWorkspace> {
    */
   async save(id: string, workspace: Workspace.IWorkspace): Promise<void> {
     const { serverSettings } = this;
-    const { baseUrl, pageUrl } = serverSettings;
+    const { baseUrl, appUrl } = serverSettings;
     const { makeRequest, ResponseError } = ServerConnection;
-    const base = baseUrl + pageUrl;
+    const base = baseUrl + appUrl;
     const url = Private.url(base, id);
     const init = { body: JSON.stringify(workspace), method: 'PUT' };
     const response = await makeRequest(url, init, serverSettings);

+ 1 - 0
scripts/travis_install.sh

@@ -17,6 +17,7 @@ mkdir ~/.jupyter
 pip install -q --upgrade pip
 pip --version
 pip install -e ".[test]"
+pip install -U --pre jupyterlab_server
 jlpm versions
 jlpm config current
 jupyter serverextension enable --py jupyterlab

+ 3 - 0
scripts/travis_script.sh

@@ -194,6 +194,9 @@ if [[ $GROUP == usage ]]; then
 
     # Make sure core mode works
     jlpm run build:core
+    # Make sure we have a final released version of JupyterLab server
+    pip uninstall -y jupyterlab_server
+    pip install jupyterlab_server
     python -m jupyterlab.browser_check --core-mode
 
     # Make sure we can run the built app.

+ 1 - 1
setup.py

@@ -133,7 +133,7 @@ setup_args = dict(
 setup_args['install_requires'] = [
     'notebook>=4.3.1',
     'tornado<6',
-    'jupyterlab_server>=0.3.4,<0.4.0'
+    'jupyterlab_server>=0.3.4'
 ]
 
 setup_args['extras_require'] = {

+ 1 - 1
tests/test-services/src/setting/manager.spec.ts

@@ -13,7 +13,7 @@ init();
 describe('setting', () => {
   describe('SettingManager', () => {
     const manager = new SettingManager({
-      serverSettings: ServerConnection.makeSettings({ pageUrl: 'lab' })
+      serverSettings: ServerConnection.makeSettings({ appUrl: 'lab' })
     });
 
     describe('#constructor()', () => {

+ 1 - 1
tests/test-services/src/workspace/manager.spec.ts

@@ -13,7 +13,7 @@ init();
 describe('workspace', () => {
   describe('WorkspaceManager', () => {
     const manager = new WorkspaceManager({
-      serverSettings: ServerConnection.makeSettings({ pageUrl: 'lab' })
+      serverSettings: ServerConnection.makeSettings({ appUrl: 'lab' })
     });
 
     describe('#constructor()', () => {