Jelajahi Sumber

Finish the shell for lab extension handling

Steven Silvester 8 tahun lalu
induk
melakukan
d619a77fd6
5 mengubah file dengan 80 tambahan dan 40 penghapusan
  1. 46 5
      jupyterlab/__init__.py
  2. 25 26
      jupyterlab/lab.html
  3. 1 1
      jupyterlab/labapp.py
  4. 7 8
      jupyterlab/labextensions.py
  5. 1 0
      jupyterlab/loader.js

+ 46 - 5
jupyterlab/__init__.py

@@ -3,6 +3,8 @@
 # Copyright (c) Jupyter Development Team.
 # Distributed under the terms of the Modified BSD License.
 
+import glob
+import json
 import os
 from tornado import web
 from notebook.base.handlers import IPythonHandler, FileFindHandler
@@ -27,8 +29,29 @@ HERE = os.path.dirname(__file__)
 FILE_LOADER = FileSystemLoader(HERE)
 BUILT_FILES = os.path.join(HERE, 'build')
 PREFIX = '/lab'
+EXTENSION_PREFIX = '/labextension'
 
 
+def get_lab_extension_manifest_data_by_folder(folder):
+    """Get the manifest data for a given lab extension folder
+    """
+    manifest_files = glob.glob(os.path.join(folder, '*.manifest'))
+    manifests = {}
+    for file in manifest_files:
+        with open(file) as fid:
+            manifest = json.load(fid)
+        manifests[manifest['name']] = manifest
+    return manifests
+
+
+def get_lab_extension_manifest_data_by_name(name):
+    """Get the manifest data for a given lab extension folder
+    """
+    for exts in _lab_extension_dirs():
+        full_dest = os.path.join(exts, name)
+        if os.path.exists(full_dest):
+            return get_lab_extension_manifest_data_by_folder(full_dest)
+
 
 class LabHandler(IPythonHandler):
     """Render the Jupyter Lab View."""
@@ -36,13 +59,31 @@ class LabHandler(IPythonHandler):
     @web.authenticated
     def get(self):
         static_prefix = ujoin(self.application.settings['base_url'], PREFIX)
+        lab_extensions = self.application.lab_extensions
 
-        # TODO: gather this data.
+        data = get_lab_extension_manifest_data_by_folder(BUILT_FILES)
         css_files = [ujoin(static_prefix, 'main.css'),
                      ujoin(static_prefix, 'extensions.css')]
-        main = 'jupyterlab-extension@0.1.0/index.js'
-        bundles = ['lab/main.bundle.js', 'lab/extensions.bundle.js']
-        entries = ['jupyterlab-extension@0.1.0/extensions.js']
+        main = data['main']['entry']
+        bundles = [ujoin(static_prefix, name + '.bundle.js') for name in
+                   ['loader', 'main', 'extensions']]
+        entries = [data['extensions']['entry']]
+
+        # Gather the lab extension files and entry points.
+        for name in lab_extensions:
+            if lab_extensions[name]:
+                data = get_lab_extension_manifest_data_by_name(name)
+                for value in data.values():
+                    if value.get('entry', None):
+                        entries.push(value['entry'])
+                        bundles.push('%s/%s/%s' % (
+                            EXTENSION_PREFIX, name, value['files'][0]
+                        ))
+                    for fname in value['files']:
+                        if os.path.splitext(fname)[1] == '.css':
+                            css_files.push('%s/%s/%s' % (
+                                EXTENSION_PREFIX, name, fname
+                            ))
 
         self.write(self.render_template('lab.html',
             static_prefix=static_prefix,
@@ -88,7 +129,7 @@ def load_jupyter_server_extension(nbapp):
     webapp.add_handlers(".*$",
         [(ujoin(base_url, h[0]),) + h[1:] for h in default_handlers])
     lab_extension_handler = (
-        r"/labextensions/(.*)", FileFindHandler, {
+        r"%s/(.*)" % EXTENSION_PREFIX, FileFindHandler, {
             'path': nbapp.lab_extensions_path,
             'no_cache_paths': ['/'],  # don't cache anything in labbextensions
         }

+ 25 - 26
jupyterlab/lab.html

@@ -7,46 +7,45 @@ Distributed under the terms of the Modified BSD License.
 <html>
 
 <head>
-    <meta charset="utf-8">
-
-    <title>{{page_title}}</title>
-    {% if mathjax_url %}
-    <script type="text/javascript" src="{{mathjax_url}}?config={{mathjax_config}}&amp;delayStartupUntil=configured" charset="utf-8"></script>
-    {% endif %}
-    <!-- These will get templated by the server (it will look for css files) -->
-    <link href="{{static_prefix}}/main.css" rel="stylesheet">
-    <link href="{{static_prefix}}/extensions.css" rel="stylesheet">
-    {% for css_file in jupyterlab_css %}
-    <link href="{{ css_file }}" rel="stylesheet">
-    {% endfor %}
-</head>
-
+  <meta charset="utf-8">
 
+  <title>{{page_title}}</title>
 
-<body>
+  {% for css_file in jupyterlab_css %}
+  <link href="{{ css_file }}" rel="stylesheet">
+  {% endfor %}
 
-<script id='jupyter-config-data' type="application/json">{
+  <script id='jupyter-config-data' type="application/json">{
   "baseUrl": "{{base_url | urlencode}}",
   "wsUrl": "{{ws_url| urlencode}}",
   "notebookPath": "{{notebook_path | urlencode}}"
-}</script>
-<script src="{{static_prefix}}/loader.bundle.js" type="text/javascript" charset="utf-8"></script>
-<script>
-jupyter.requireBundles([
-  {% for jupyterlab_bundle in jupyterlab_bundles %}
-  "{{ jupyterlab_bundle }}",
+  }</script>
+
+  {% for bundle_file in jupyterlab_bundles %}
+  <script src="{{ bundle_file }}" type="text/javascript" charset="utf-8"></script>
   {% endfor %}
-  ]).then(function(require) {
-  var lab = require("{{ jupyterlab_main }}");
+
+  {% if mathjax_url %}
+  <script type="text/javascript" src="{{mathjax_url}}?config={{mathjax_config}}&amp;delayStartupUntil=configured" charset="utf-8"></script>
+  {% endif %}
+
+</head>
+
+<body>
+
+<script>
+  var lab = jupyter.require("{{ jupyterlab_main }}");
   jupyter.lab = lab;
   var plugins = [];
+
   {% for plugin_entry in plugin_entries %}
-  plugins = plugins.concat(require("{{ plugin_entry }}"));
+  plugins = plugins.concat(jupyter.require("{{ plugin_entry }}"));
   {% endfor %}
+
   lab.registerPlugins(plugins);
   lab.start();
-});
 </script>
+
 </body>
 
 </html>

+ 1 - 1
jupyterlab/labapp.py

@@ -32,8 +32,8 @@ class LabApp(NotebookApp):
         return self.extra_lab_extensions_path + jupyter_path('lab_extensions')
 
     def init_webapp(self):
-        self.tornado_settings['lab_extensions'] = self.lab_extensions
         super(LabApp, self).init_webapp()
+        self.web_app.lab_extensions = self.lab_extensions
 
 #-----------------------------------------------------------------------------
 # Main entry point

+ 7 - 8
jupyterlab/labextensions.py

@@ -36,6 +36,11 @@ from traitlets.utils.importstring import import_item
 
 from tornado.log import LogFormatter
 
+from . import (
+    get_lab_extension_manifest_data_by_folder,
+    get_lab_extension_manifest_data_by_name
+)
+
 # Constants for pretty print extension listing function.
 # Window doesn't support coloring in the commandline
 GREEN_ENABLED = '\033[32m enabled \033[0m' if os.name != 'nt' else 'enabled '
@@ -479,14 +484,8 @@ def validate_lab_extension_folder(name, full_dest, logger=None):
 
     hasFiles = True
     hasEntry = False
-    manifest_files = glob.glob(os.path.join(full_dest, '*.manifest'))
-    if not manifest_files:
-        hasFiles = False
-    for file in manifest_files:
-        with open(file) as fid:
-            manifest = json.load(fid)
-        # Make sure there is at least one entry module and that the entry
-        # module and listed files are present.
+    data = get_lab_extension_manifest_data(full_dest)
+    for manifest in data.values():
         if ('entry' in manifest and 'modules' in manifest):
             if (manifest['entry'] in manifest['modules']):
                 hasEntry = True

+ 1 - 0
jupyterlab/loader.js

@@ -196,5 +196,6 @@ requireModule.e = ensureBundle;
 
 module.exports = {
   define: defineModule,
+  require: requireModule,
   requireBundles: requireBundles
 }