Show More
@@ -2,11 +2,43 b'' | |||||
2 |
|
2 | |||
3 | # Copyright (c) IPython Development Team. |
|
3 | # Copyright (c) IPython Development Team. | |
4 | # Distributed under the terms of the Modified BSD License. |
|
4 | # Distributed under the terms of the Modified BSD License. | |
|
5 | ||||
|
6 | import glob | |||
5 | import json |
|
7 | import json | |
|
8 | import os | |||
|
9 | pjoin = os.path.join | |||
|
10 | ||||
6 | from tornado import web |
|
11 | from tornado import web | |
7 |
|
12 | |||
8 | from ...base.handlers import IPythonHandler, json_errors |
|
13 | from ...base.handlers import IPythonHandler, json_errors | |
|
14 | from ...utils import url_path_join | |||
9 |
|
15 | |||
|
16 | def kernelspec_model(handler, name): | |||
|
17 | """Load a KernelSpec by name and return the REST API model""" | |||
|
18 | ksm = handler.kernel_spec_manager | |||
|
19 | spec = ksm.get_kernel_spec(name) | |||
|
20 | d = {'name': name} | |||
|
21 | d['spec'] = spec.to_dict() | |||
|
22 | d['resources'] = resources = {} | |||
|
23 | resource_dir = spec.resource_dir | |||
|
24 | for resource in ['kernel.js', 'kernel.css']: | |||
|
25 | if os.path.exists(pjoin(resource_dir, resource)): | |||
|
26 | resources[resource] = url_path_join( | |||
|
27 | handler.base_url, | |||
|
28 | 'kernelspecs', | |||
|
29 | name, | |||
|
30 | resource | |||
|
31 | ) | |||
|
32 | for logo_file in glob.glob(pjoin(resource_dir, 'logo-*')): | |||
|
33 | fname = os.path.basename(logo_file) | |||
|
34 | no_ext, _ = os.path.splitext(fname) | |||
|
35 | resources[no_ext] = url_path_join( | |||
|
36 | handler.base_url, | |||
|
37 | 'kernelspecs', | |||
|
38 | name, | |||
|
39 | fname | |||
|
40 | ) | |||
|
41 | return d | |||
10 |
|
42 | |||
11 | class MainKernelSpecHandler(IPythonHandler): |
|
43 | class MainKernelSpecHandler(IPythonHandler): | |
12 | SUPPORTED_METHODS = ('GET',) |
|
44 | SUPPORTED_METHODS = ('GET',) | |
@@ -21,13 +53,11 b' class MainKernelSpecHandler(IPythonHandler):' | |||||
21 | model['kernelspecs'] = specs = {} |
|
53 | model['kernelspecs'] = specs = {} | |
22 | for kernel_name in ksm.find_kernel_specs(): |
|
54 | for kernel_name in ksm.find_kernel_specs(): | |
23 | try: |
|
55 | try: | |
24 |
d = |
|
56 | d = kernelspec_model(self, kernel_name) | |
25 | except Exception: |
|
57 | except Exception: | |
26 | self.log.error("Failed to load kernel spec: '%s'", kernel_name, exc_info=True) |
|
58 | self.log.error("Failed to load kernel spec: '%s'", kernel_name, exc_info=True) | |
27 | continue |
|
59 | continue | |
28 | d['name'] = kernel_name |
|
|||
29 | specs[kernel_name] = d |
|
60 | specs[kernel_name] = d | |
30 |
|
||||
31 | self.set_header("Content-Type", 'application/json') |
|
61 | self.set_header("Content-Type", 'application/json') | |
32 | self.finish(json.dumps(model)) |
|
62 | self.finish(json.dumps(model)) | |
33 |
|
63 | |||
@@ -38,13 +68,12 b' class KernelSpecHandler(IPythonHandler):' | |||||
38 | @web.authenticated |
|
68 | @web.authenticated | |
39 | @json_errors |
|
69 | @json_errors | |
40 | def get(self, kernel_name): |
|
70 | def get(self, kernel_name): | |
41 | ksm = self.kernel_spec_manager |
|
|||
42 | try: |
|
71 | try: | |
43 |
|
|
72 | model = kernelspec_model(self, kernel_name) | |
44 | except KeyError: |
|
73 | except KeyError: | |
45 | raise web.HTTPError(404, u'Kernel spec %s not found' % kernel_name) |
|
74 | raise web.HTTPError(404, u'Kernel spec %s not found' % kernel_name) | |
46 | self.set_header("Content-Type", 'application/json') |
|
75 | self.set_header("Content-Type", 'application/json') | |
47 |
self.finish( |
|
76 | self.finish(json.dumps(model)) | |
48 |
|
77 | |||
49 |
|
78 | |||
50 | # URL to handler mappings |
|
79 | # URL to handler mappings |
@@ -35,8 +35,8 b' define([' | |||||
35 | var change_kernel_submenu = $("#menu-change-kernel-submenu"); |
|
35 | var change_kernel_submenu = $("#menu-change-kernel-submenu"); | |
36 | var keys = Object.keys(data.kernelspecs).sort(function (a, b) { |
|
36 | var keys = Object.keys(data.kernelspecs).sort(function (a, b) { | |
37 | // sort by display_name |
|
37 | // sort by display_name | |
38 | var da = data.kernelspecs[a].display_name; |
|
38 | var da = data.kernelspecs[a].spec.display_name; | |
39 | var db = data.kernelspecs[b].display_name; |
|
39 | var db = data.kernelspecs[b].spec.display_name; | |
40 | if (da === db) { |
|
40 | if (da === db) { | |
41 | return 0; |
|
41 | return 0; | |
42 | } else if (da > db) { |
|
42 | } else if (da > db) { | |
@@ -50,7 +50,7 b' define([' | |||||
50 | var ks_submenu_entry = $("<li>").attr("id", "kernel-submenu-"+ks.name).append($('<a>') |
|
50 | var ks_submenu_entry = $("<li>").attr("id", "kernel-submenu-"+ks.name).append($('<a>') | |
51 | .attr('href', '#') |
|
51 | .attr('href', '#') | |
52 | .click($.proxy(this.change_kernel, this, ks.name)) |
|
52 | .click($.proxy(this.change_kernel, this, ks.name)) | |
53 | .text(ks.display_name)); |
|
53 | .text(ks.spec.display_name)); | |
54 | change_kernel_submenu.append(ks_submenu_entry); |
|
54 | change_kernel_submenu.append(ks_submenu_entry); | |
55 | } |
|
55 | } | |
56 | }; |
|
56 | }; | |
@@ -59,25 +59,17 b' define([' | |||||
59 | /** |
|
59 | /** | |
60 | * TODO, have a methods to set kernel spec directly ? |
|
60 | * TODO, have a methods to set kernel spec directly ? | |
61 | **/ |
|
61 | **/ | |
62 | var that = this; |
|
|||
63 | if (kernel_name === this.current_selection) { |
|
62 | if (kernel_name === this.current_selection) { | |
64 | return; |
|
63 | return; | |
65 | } |
|
64 | } | |
66 | var ks = this.kernelspecs[kernel_name]; |
|
65 | var ks = this.kernelspecs[kernel_name]; | |
67 | var new_mode_url = 'kernelspecs/'+ks.name+'/kernel'; |
|
66 | ||
68 |
|
67 | var css_url = ks.resources['kernel.css']; | ||
69 | var css_url = this.notebook.base_url+new_mode_url+'.css'; |
|
68 | if (css_url) { | |
70 | $.ajax({ |
|
69 | $('#kernel-css').attr('href', css_url); | |
71 | type: 'HEAD', |
|
70 | } else { | |
72 | url: css_url, |
|
71 | $('#kernel-css').attr('href', ''); | |
73 | success: function(){ |
|
72 | } | |
74 | $('#kernel-css') |
|
|||
75 | .attr('href',css_url); |
|
|||
76 | }, |
|
|||
77 | error:function(){ |
|
|||
78 | console.info("No custom kernel.css at URL:", css_url) |
|
|||
79 | } |
|
|||
80 | }); |
|
|||
81 |
|
73 | |||
82 | try { |
|
74 | try { | |
83 | this.notebook.start_session(kernel_name); |
|
75 | this.notebook.start_session(kernel_name); | |
@@ -92,26 +84,23 b' define([' | |||||
92 | return; |
|
84 | return; | |
93 | } |
|
85 | } | |
94 | this.events.trigger('spec_changed.Kernel', ks); |
|
86 | this.events.trigger('spec_changed.Kernel', ks); | |
95 |
|
87 | |||
96 |
|
88 | if (ks.resources['kernel.js']) { | ||
97 | // load new mode kernel.js if exist |
|
89 | require([ks.resources['kernel.js']], | |
98 | require([new_mode_url], |
|
90 | function (kernel_mod) { | |
99 | // if new mode has custom.js |
|
91 | if (kernel_mod && kernel_mod.onload) { | |
100 | function(new_mode){ |
|
92 | kernel_mod.onload(); | |
101 | that.lock_switch(); |
|
93 | } else { | |
102 | if(new_mode && new_mode.onload){ |
|
94 | console.warn("Kernel " + ks.name + " has a kernel.js file that does not contain "+ | |
103 | new_mode.onload(); |
|
95 | "any asynchronous module definition. This is undefined behavior "+ | |
104 | } else { |
|
96 | "and not recommended."); | |
105 | console.warn("The current kernel defined a kernel.js file but does not contain "+ |
|
97 | } | |
106 | "any asynchronous module definition. This is undefined behavior "+ |
|
98 | }, function (err) { | |
107 | "which is not recommended"); |
|
99 | console.warn("Failed to load kernel.js from ", ks.resources['kernel.js'], err); | |
108 | } |
|
100 | } | |
109 |
|
|
101 | ); | |
110 | function(err){ |
|
102 | } | |
111 | // if new mode does not have custom.js |
|
103 | ||
112 | console.info("No custom kernel.css at URL:", new_mode_url) |
|
|||
113 | } |
|
|||
114 | ); |
|
|||
115 | }; |
|
104 | }; | |
116 |
|
105 | |||
117 | KernelSelector.prototype.lock_switch = function() { |
|
106 | KernelSelector.prototype.lock_switch = function() { | |
@@ -123,10 +112,16 b' define([' | |||||
123 |
|
112 | |||
124 | KernelSelector.prototype.bind_events = function() { |
|
113 | KernelSelector.prototype.bind_events = function() { | |
125 | var that = this; |
|
114 | var that = this; | |
|
115 | var logo_img = this.element.find("img.current_kernel_logo"); | |||
126 | this.events.on('spec_changed.Kernel', function(event, data) { |
|
116 | this.events.on('spec_changed.Kernel', function(event, data) { | |
127 | that.current_selection = data.name; |
|
117 | that.current_selection = data.name; | |
128 | $("#kernel_indicator").find('.kernel_indicator_name').text(data.display_name); |
|
118 | $("#kernel_indicator").find('.kernel_indicator_name').text(data.spec.display_name); | |
129 | that.element.find("img.current_kernel_logo").attr("src", that.notebook.base_url + "kernelspecs/" + data.name + "/logo-64x64.png"); |
|
119 | if (data.resources['logo-64x64']) { | |
|
120 | logo_img.attr("src", data.resources['logo-64x64']); | |||
|
121 | logo_img.show(); | |||
|
122 | } else { | |||
|
123 | logo_img.hide(); | |||
|
124 | } | |||
130 | }); |
|
125 | }); | |
131 |
|
126 | |||
132 | this.events.on('kernel_created.Session', function(event, data) { |
|
127 | this.events.on('kernel_created.Session', function(event, data) { | |
@@ -139,7 +134,6 b' define([' | |||||
139 | } |
|
134 | } | |
140 | }); |
|
135 | }); | |
141 |
|
136 | |||
142 | var logo_img = this.element.find("img.current_kernel_logo"); |
|
|||
143 | logo_img.on("load", function() { |
|
137 | logo_img.on("load", function() { | |
144 | logo_img.show(); |
|
138 | logo_img.show(); | |
145 | }); |
|
139 | }); |
@@ -247,7 +247,7 b' define([' | |||||
247 |
|
247 | |||
248 | this.events.on('spec_changed.Kernel', function(event, data) { |
|
248 | this.events.on('spec_changed.Kernel', function(event, data) { | |
249 | that.metadata.kernelspec = |
|
249 | that.metadata.kernelspec = | |
250 | {name: data.name, display_name: data.display_name}; |
|
250 | {name: data.name, display_name: data.spec.display_name}; | |
251 | }); |
|
251 | }); | |
252 |
|
252 | |||
253 | this.events.on('kernel_ready.Kernel', function(event, data) { |
|
253 | this.events.on('kernel_ready.Kernel', function(event, data) { |
General Comments 0
You need to be logged in to leave comments.
Login now