##// END OF EJS Templates
use absolute URLs for static files
MinRK -
Show More
@@ -1,387 +1,387
1 """A tornado based IPython notebook server.
1 """A tornado based IPython notebook server.
2
2
3 Authors:
3 Authors:
4
4
5 * Brian Granger
5 * Brian Granger
6 """
6 """
7
7
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2008-2011 The IPython Development Team
9 # Copyright (C) 2008-2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 # stdlib
19 # stdlib
20 import errno
20 import errno
21 import logging
21 import logging
22 import os
22 import os
23 import signal
23 import signal
24 import socket
24 import socket
25 import sys
25 import sys
26 import threading
26 import threading
27 import webbrowser
27 import webbrowser
28
28
29 # Third party
29 # Third party
30 import zmq
30 import zmq
31
31
32 # Install the pyzmq ioloop. This has to be done before anything else from
32 # Install the pyzmq ioloop. This has to be done before anything else from
33 # tornado is imported.
33 # tornado is imported.
34 from zmq.eventloop import ioloop
34 from zmq.eventloop import ioloop
35 # FIXME: ioloop.install is new in pyzmq-2.1.7, so remove this conditional
35 # FIXME: ioloop.install is new in pyzmq-2.1.7, so remove this conditional
36 # when pyzmq dependency is updated beyond that.
36 # when pyzmq dependency is updated beyond that.
37 if hasattr(ioloop, 'install'):
37 if hasattr(ioloop, 'install'):
38 ioloop.install()
38 ioloop.install()
39 else:
39 else:
40 import tornado.ioloop
40 import tornado.ioloop
41 tornado.ioloop.IOLoop = ioloop.IOLoop
41 tornado.ioloop.IOLoop = ioloop.IOLoop
42
42
43 from tornado import httpserver
43 from tornado import httpserver
44 from tornado import web
44 from tornado import web
45
45
46 # Our own libraries
46 # Our own libraries
47 from .kernelmanager import MappingKernelManager
47 from .kernelmanager import MappingKernelManager
48 from .handlers import (LoginHandler, LogoutHandler,
48 from .handlers import (LoginHandler, LogoutHandler,
49 ProjectDashboardHandler, NewHandler, NamedNotebookHandler,
49 ProjectDashboardHandler, NewHandler, NamedNotebookHandler,
50 MainKernelHandler, KernelHandler, KernelActionHandler, IOPubHandler,
50 MainKernelHandler, KernelHandler, KernelActionHandler, IOPubHandler,
51 ShellHandler, NotebookRootHandler, NotebookHandler, RSTHandler,
51 ShellHandler, NotebookRootHandler, NotebookHandler, RSTHandler,
52 AuthenticatedFileHandler,
52 AuthenticatedFileHandler,
53 )
53 )
54 from .notebookmanager import NotebookManager
54 from .notebookmanager import NotebookManager
55
55
56 from IPython.config.application import catch_config_error, boolean_flag
56 from IPython.config.application import catch_config_error, boolean_flag
57 from IPython.core.application import BaseIPythonApplication
57 from IPython.core.application import BaseIPythonApplication
58 from IPython.core.profiledir import ProfileDir
58 from IPython.core.profiledir import ProfileDir
59 from IPython.lib.kernel import swallow_argv
59 from IPython.lib.kernel import swallow_argv
60 from IPython.zmq.session import Session, default_secure
60 from IPython.zmq.session import Session, default_secure
61 from IPython.zmq.zmqshell import ZMQInteractiveShell
61 from IPython.zmq.zmqshell import ZMQInteractiveShell
62 from IPython.zmq.ipkernel import (
62 from IPython.zmq.ipkernel import (
63 flags as ipkernel_flags,
63 flags as ipkernel_flags,
64 aliases as ipkernel_aliases,
64 aliases as ipkernel_aliases,
65 IPKernelApp
65 IPKernelApp
66 )
66 )
67 from IPython.utils.traitlets import Dict, Unicode, Integer, List, Enum, Bool
67 from IPython.utils.traitlets import Dict, Unicode, Integer, List, Enum, Bool
68
68
69 #-----------------------------------------------------------------------------
69 #-----------------------------------------------------------------------------
70 # Module globals
70 # Module globals
71 #-----------------------------------------------------------------------------
71 #-----------------------------------------------------------------------------
72
72
73 _kernel_id_regex = r"(?P<kernel_id>\w+-\w+-\w+-\w+-\w+)"
73 _kernel_id_regex = r"(?P<kernel_id>\w+-\w+-\w+-\w+-\w+)"
74 _kernel_action_regex = r"(?P<action>restart|interrupt)"
74 _kernel_action_regex = r"(?P<action>restart|interrupt)"
75 _notebook_id_regex = r"(?P<notebook_id>\w+-\w+-\w+-\w+-\w+)"
75 _notebook_id_regex = r"(?P<notebook_id>\w+-\w+-\w+-\w+-\w+)"
76
76
77 LOCALHOST = '127.0.0.1'
77 LOCALHOST = '127.0.0.1'
78
78
79 _examples = """
79 _examples = """
80 ipython notebook # start the notebook
80 ipython notebook # start the notebook
81 ipython notebook --profile=sympy # use the sympy profile
81 ipython notebook --profile=sympy # use the sympy profile
82 ipython notebook --pylab=inline # pylab in inline plotting mode
82 ipython notebook --pylab=inline # pylab in inline plotting mode
83 ipython notebook --certfile=mycert.pem # use SSL/TLS certificate
83 ipython notebook --certfile=mycert.pem # use SSL/TLS certificate
84 ipython notebook --port=5555 --ip=* # Listen on port 5555, all interfaces
84 ipython notebook --port=5555 --ip=* # Listen on port 5555, all interfaces
85 """
85 """
86
86
87 #-----------------------------------------------------------------------------
87 #-----------------------------------------------------------------------------
88 # The Tornado web application
88 # The Tornado web application
89 #-----------------------------------------------------------------------------
89 #-----------------------------------------------------------------------------
90
90
91 class NotebookWebApplication(web.Application):
91 class NotebookWebApplication(web.Application):
92
92
93 def __init__(self, ipython_app, kernel_manager, notebook_manager, log, settings_overrides):
93 def __init__(self, ipython_app, kernel_manager, notebook_manager, log, settings_overrides):
94 handlers = [
94 handlers = [
95 (r"/", ProjectDashboardHandler),
95 (r"/", ProjectDashboardHandler),
96 (r"/login", LoginHandler),
96 (r"/login", LoginHandler),
97 (r"/logout", LogoutHandler),
97 (r"/logout", LogoutHandler),
98 (r"/new", NewHandler),
98 (r"/new", NewHandler),
99 (r"/%s" % _notebook_id_regex, NamedNotebookHandler),
99 (r"/%s" % _notebook_id_regex, NamedNotebookHandler),
100 (r"/kernels", MainKernelHandler),
100 (r"/kernels", MainKernelHandler),
101 (r"/kernels/%s" % _kernel_id_regex, KernelHandler),
101 (r"/kernels/%s" % _kernel_id_regex, KernelHandler),
102 (r"/kernels/%s/%s" % (_kernel_id_regex, _kernel_action_regex), KernelActionHandler),
102 (r"/kernels/%s/%s" % (_kernel_id_regex, _kernel_action_regex), KernelActionHandler),
103 (r"/kernels/%s/iopub" % _kernel_id_regex, IOPubHandler),
103 (r"/kernels/%s/iopub" % _kernel_id_regex, IOPubHandler),
104 (r"/kernels/%s/shell" % _kernel_id_regex, ShellHandler),
104 (r"/kernels/%s/shell" % _kernel_id_regex, ShellHandler),
105 (r"/notebooks", NotebookRootHandler),
105 (r"/notebooks", NotebookRootHandler),
106 (r"/notebooks/%s" % _notebook_id_regex, NotebookHandler),
106 (r"/notebooks/%s" % _notebook_id_regex, NotebookHandler),
107 (r"/rstservice/render", RSTHandler),
107 (r"/rstservice/render", RSTHandler),
108 (r"/local/(.*)", AuthenticatedFileHandler, {'path' : notebook_manager.notebook_dir}),
108 (r"/local/(.*)", AuthenticatedFileHandler, {'path' : notebook_manager.notebook_dir}),
109 ]
109 ]
110 settings = dict(
110 settings = dict(
111 template_path=os.path.join(os.path.dirname(__file__), "templates"),
111 template_path=os.path.join(os.path.dirname(__file__), "templates"),
112 static_path=os.path.join(os.path.dirname(__file__), "static"),
112 static_path=os.path.join(os.path.dirname(__file__), "static"),
113 cookie_secret=os.urandom(1024),
113 cookie_secret=os.urandom(1024),
114 login_url="/login",
114 login_url="/login",
115 )
115 )
116
116
117 # allow custom overrides for the tornado web app.
117 # allow custom overrides for the tornado web app.
118 settings.update(settings_overrides)
118 settings.update(settings_overrides)
119
119
120 super(NotebookWebApplication, self).__init__(handlers, **settings)
120 super(NotebookWebApplication, self).__init__(handlers, **settings)
121
121
122 self.kernel_manager = kernel_manager
122 self.kernel_manager = kernel_manager
123 self.log = log
123 self.log = log
124 self.notebook_manager = notebook_manager
124 self.notebook_manager = notebook_manager
125 self.ipython_app = ipython_app
125 self.ipython_app = ipython_app
126 self.read_only = self.ipython_app.read_only
126 self.read_only = self.ipython_app.read_only
127
127
128
128
129 #-----------------------------------------------------------------------------
129 #-----------------------------------------------------------------------------
130 # Aliases and Flags
130 # Aliases and Flags
131 #-----------------------------------------------------------------------------
131 #-----------------------------------------------------------------------------
132
132
133 flags = dict(ipkernel_flags)
133 flags = dict(ipkernel_flags)
134 flags['no-browser']=(
134 flags['no-browser']=(
135 {'NotebookApp' : {'open_browser' : False}},
135 {'NotebookApp' : {'open_browser' : False}},
136 "Don't open the notebook in a browser after startup."
136 "Don't open the notebook in a browser after startup."
137 )
137 )
138 flags['no-mathjax']=(
138 flags['no-mathjax']=(
139 {'NotebookApp' : {'enable_mathjax' : False}},
139 {'NotebookApp' : {'enable_mathjax' : False}},
140 """Disable MathJax
140 """Disable MathJax
141
141
142 MathJax is the javascript library IPython uses to render math/LaTeX. It is
142 MathJax is the javascript library IPython uses to render math/LaTeX. It is
143 very large, so you may want to disable it if you have a slow internet
143 very large, so you may want to disable it if you have a slow internet
144 connection, or for offline use of the notebook.
144 connection, or for offline use of the notebook.
145
145
146 When disabled, equations etc. will appear as their untransformed TeX source.
146 When disabled, equations etc. will appear as their untransformed TeX source.
147 """
147 """
148 )
148 )
149 flags['read-only'] = (
149 flags['read-only'] = (
150 {'NotebookApp' : {'read_only' : True}},
150 {'NotebookApp' : {'read_only' : True}},
151 """Allow read-only access to notebooks.
151 """Allow read-only access to notebooks.
152
152
153 When using a password to protect the notebook server, this flag
153 When using a password to protect the notebook server, this flag
154 allows unauthenticated clients to view the notebook list, and
154 allows unauthenticated clients to view the notebook list, and
155 individual notebooks, but not edit them, start kernels, or run
155 individual notebooks, but not edit them, start kernels, or run
156 code.
156 code.
157
157
158 If no password is set, the server will be entirely read-only.
158 If no password is set, the server will be entirely read-only.
159 """
159 """
160 )
160 )
161
161
162 # Add notebook manager flags
162 # Add notebook manager flags
163 flags.update(boolean_flag('script', 'NotebookManager.save_script',
163 flags.update(boolean_flag('script', 'NotebookManager.save_script',
164 'Auto-save a .py script everytime the .ipynb notebook is saved',
164 'Auto-save a .py script everytime the .ipynb notebook is saved',
165 'Do not auto-save .py scripts for every notebook'))
165 'Do not auto-save .py scripts for every notebook'))
166
166
167 # the flags that are specific to the frontend
167 # the flags that are specific to the frontend
168 # these must be scrubbed before being passed to the kernel,
168 # these must be scrubbed before being passed to the kernel,
169 # or it will raise an error on unrecognized flags
169 # or it will raise an error on unrecognized flags
170 notebook_flags = ['no-browser', 'no-mathjax', 'read-only', 'script', 'no-script']
170 notebook_flags = ['no-browser', 'no-mathjax', 'read-only', 'script', 'no-script']
171
171
172 aliases = dict(ipkernel_aliases)
172 aliases = dict(ipkernel_aliases)
173
173
174 aliases.update({
174 aliases.update({
175 'ip': 'NotebookApp.ip',
175 'ip': 'NotebookApp.ip',
176 'port': 'NotebookApp.port',
176 'port': 'NotebookApp.port',
177 'keyfile': 'NotebookApp.keyfile',
177 'keyfile': 'NotebookApp.keyfile',
178 'certfile': 'NotebookApp.certfile',
178 'certfile': 'NotebookApp.certfile',
179 'notebook-dir': 'NotebookManager.notebook_dir',
179 'notebook-dir': 'NotebookManager.notebook_dir',
180 })
180 })
181
181
182 # remove ipkernel flags that are singletons, and don't make sense in
182 # remove ipkernel flags that are singletons, and don't make sense in
183 # multi-kernel evironment:
183 # multi-kernel evironment:
184 aliases.pop('f', None)
184 aliases.pop('f', None)
185
185
186 notebook_aliases = [u'port', u'ip', u'keyfile', u'certfile',
186 notebook_aliases = [u'port', u'ip', u'keyfile', u'certfile',
187 u'notebook-dir']
187 u'notebook-dir']
188
188
189 #-----------------------------------------------------------------------------
189 #-----------------------------------------------------------------------------
190 # NotebookApp
190 # NotebookApp
191 #-----------------------------------------------------------------------------
191 #-----------------------------------------------------------------------------
192
192
193 class NotebookApp(BaseIPythonApplication):
193 class NotebookApp(BaseIPythonApplication):
194
194
195 name = 'ipython-notebook'
195 name = 'ipython-notebook'
196 default_config_file_name='ipython_notebook_config.py'
196 default_config_file_name='ipython_notebook_config.py'
197
197
198 description = """
198 description = """
199 The IPython HTML Notebook.
199 The IPython HTML Notebook.
200
200
201 This launches a Tornado based HTML Notebook Server that serves up an
201 This launches a Tornado based HTML Notebook Server that serves up an
202 HTML5/Javascript Notebook client.
202 HTML5/Javascript Notebook client.
203 """
203 """
204 examples = _examples
204 examples = _examples
205
205
206 classes = [IPKernelApp, ZMQInteractiveShell, ProfileDir, Session,
206 classes = [IPKernelApp, ZMQInteractiveShell, ProfileDir, Session,
207 MappingKernelManager, NotebookManager]
207 MappingKernelManager, NotebookManager]
208 flags = Dict(flags)
208 flags = Dict(flags)
209 aliases = Dict(aliases)
209 aliases = Dict(aliases)
210
210
211 kernel_argv = List(Unicode)
211 kernel_argv = List(Unicode)
212
212
213 log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'),
213 log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'),
214 default_value=logging.INFO,
214 default_value=logging.INFO,
215 config=True,
215 config=True,
216 help="Set the log level by value or name.")
216 help="Set the log level by value or name.")
217
217
218 # Network related information.
218 # Network related information.
219
219
220 ip = Unicode(LOCALHOST, config=True,
220 ip = Unicode(LOCALHOST, config=True,
221 help="The IP address the notebook server will listen on."
221 help="The IP address the notebook server will listen on."
222 )
222 )
223
223
224 def _ip_changed(self, name, old, new):
224 def _ip_changed(self, name, old, new):
225 if new == u'*': self.ip = u''
225 if new == u'*': self.ip = u''
226
226
227 port = Integer(8888, config=True,
227 port = Integer(8888, config=True,
228 help="The port the notebook server will listen on."
228 help="The port the notebook server will listen on."
229 )
229 )
230
230
231 certfile = Unicode(u'', config=True,
231 certfile = Unicode(u'', config=True,
232 help="""The full path to an SSL/TLS certificate file."""
232 help="""The full path to an SSL/TLS certificate file."""
233 )
233 )
234
234
235 keyfile = Unicode(u'', config=True,
235 keyfile = Unicode(u'', config=True,
236 help="""The full path to a private key file for usage with SSL/TLS."""
236 help="""The full path to a private key file for usage with SSL/TLS."""
237 )
237 )
238
238
239 password = Unicode(u'', config=True,
239 password = Unicode(u'', config=True,
240 help="""Hashed password to use for web authentication.
240 help="""Hashed password to use for web authentication.
241
241
242 To generate, type in a python/IPython shell:
242 To generate, type in a python/IPython shell:
243
243
244 from IPython.lib import passwd; passwd()
244 from IPython.lib import passwd; passwd()
245
245
246 The string should be of the form type:salt:hashed-password.
246 The string should be of the form type:salt:hashed-password.
247 """
247 """
248 )
248 )
249
249
250 open_browser = Bool(True, config=True,
250 open_browser = Bool(True, config=True,
251 help="Whether to open in a browser after starting.")
251 help="Whether to open in a browser after starting.")
252
252
253 read_only = Bool(False, config=True,
253 read_only = Bool(False, config=True,
254 help="Whether to prevent editing/execution of notebooks."
254 help="Whether to prevent editing/execution of notebooks."
255 )
255 )
256
256
257 webapp_settings = Dict(config=True,
257 webapp_settings = Dict(config=True,
258 help="Supply overrides for the tornado.web.Application that the "
258 help="Supply overrides for the tornado.web.Application that the "
259 "IPython notebook uses.")
259 "IPython notebook uses.")
260
260
261 enable_mathjax = Bool(True, config=True,
261 enable_mathjax = Bool(True, config=True,
262 help="""Whether to enable MathJax for typesetting math/TeX
262 help="""Whether to enable MathJax for typesetting math/TeX
263
263
264 MathJax is the javascript library IPython uses to render math/LaTeX. It is
264 MathJax is the javascript library IPython uses to render math/LaTeX. It is
265 very large, so you may want to disable it if you have a slow internet
265 very large, so you may want to disable it if you have a slow internet
266 connection, or for offline use of the notebook.
266 connection, or for offline use of the notebook.
267
267
268 When disabled, equations etc. will appear as their untransformed TeX source.
268 When disabled, equations etc. will appear as their untransformed TeX source.
269 """
269 """
270 )
270 )
271 def _enable_mathjax_changed(self, name, old, new):
271 def _enable_mathjax_changed(self, name, old, new):
272 """set mathjax url to empty if mathjax is disabled"""
272 """set mathjax url to empty if mathjax is disabled"""
273 if not new:
273 if not new:
274 self.mathjax_url = u''
274 self.mathjax_url = u''
275
275
276 mathjax_url = Unicode("", config=True,
276 mathjax_url = Unicode("", config=True,
277 help="""The url for MathJax.js."""
277 help="""The url for MathJax.js."""
278 )
278 )
279 def _mathjax_url_default(self):
279 def _mathjax_url_default(self):
280 if not self.enable_mathjax:
280 if not self.enable_mathjax:
281 return u''
281 return u''
282 static_path = self.webapp_settings.get("static_path", os.path.join(os.path.dirname(__file__), "static"))
282 static_path = self.webapp_settings.get("static_path", os.path.join(os.path.dirname(__file__), "static"))
283 if os.path.exists(os.path.join(static_path, 'mathjax', "MathJax.js")):
283 if os.path.exists(os.path.join(static_path, 'mathjax', "MathJax.js")):
284 self.log.info("Using local MathJax")
284 self.log.info("Using local MathJax")
285 return u"static/mathjax/MathJax.js"
285 return u"/static/mathjax/MathJax.js"
286 else:
286 else:
287 self.log.info("Using MathJax from CDN")
287 self.log.info("Using MathJax from CDN")
288 return u"http://cdn.mathjax.org/mathjax/latest/MathJax.js"
288 return u"http://cdn.mathjax.org/mathjax/latest/MathJax.js"
289
289
290 def _mathjax_url_changed(self, name, old, new):
290 def _mathjax_url_changed(self, name, old, new):
291 if new and not self.enable_mathjax:
291 if new and not self.enable_mathjax:
292 # enable_mathjax=False overrides mathjax_url
292 # enable_mathjax=False overrides mathjax_url
293 self.mathjax_url = u''
293 self.mathjax_url = u''
294 else:
294 else:
295 self.log.info("Using MathJax: %s", new)
295 self.log.info("Using MathJax: %s", new)
296
296
297 def parse_command_line(self, argv=None):
297 def parse_command_line(self, argv=None):
298 super(NotebookApp, self).parse_command_line(argv)
298 super(NotebookApp, self).parse_command_line(argv)
299 if argv is None:
299 if argv is None:
300 argv = sys.argv[1:]
300 argv = sys.argv[1:]
301
301
302 # Scrub frontend-specific flags
302 # Scrub frontend-specific flags
303 self.kernel_argv = swallow_argv(argv, notebook_aliases, notebook_flags)
303 self.kernel_argv = swallow_argv(argv, notebook_aliases, notebook_flags)
304 # Kernel should inherit default config file from frontend
304 # Kernel should inherit default config file from frontend
305 self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name)
305 self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name)
306
306
307 def init_configurables(self):
307 def init_configurables(self):
308 # Don't let Qt or ZMQ swallow KeyboardInterupts.
308 # Don't let Qt or ZMQ swallow KeyboardInterupts.
309 signal.signal(signal.SIGINT, signal.SIG_DFL)
309 signal.signal(signal.SIGINT, signal.SIG_DFL)
310
310
311 # force Session default to be secure
311 # force Session default to be secure
312 default_secure(self.config)
312 default_secure(self.config)
313 # Create a KernelManager and start a kernel.
313 # Create a KernelManager and start a kernel.
314 self.kernel_manager = MappingKernelManager(
314 self.kernel_manager = MappingKernelManager(
315 config=self.config, log=self.log, kernel_argv=self.kernel_argv,
315 config=self.config, log=self.log, kernel_argv=self.kernel_argv,
316 connection_dir = self.profile_dir.security_dir,
316 connection_dir = self.profile_dir.security_dir,
317 )
317 )
318 self.notebook_manager = NotebookManager(config=self.config, log=self.log)
318 self.notebook_manager = NotebookManager(config=self.config, log=self.log)
319 self.notebook_manager.list_notebooks()
319 self.notebook_manager.list_notebooks()
320
320
321 def init_logging(self):
321 def init_logging(self):
322 super(NotebookApp, self).init_logging()
322 super(NotebookApp, self).init_logging()
323 # This prevents double log messages because tornado use a root logger that
323 # This prevents double log messages because tornado use a root logger that
324 # self.log is a child of. The logging module dipatches log messages to a log
324 # self.log is a child of. The logging module dipatches log messages to a log
325 # and all of its ancenstors until propagate is set to False.
325 # and all of its ancenstors until propagate is set to False.
326 self.log.propagate = False
326 self.log.propagate = False
327
327
328 @catch_config_error
328 @catch_config_error
329 def initialize(self, argv=None):
329 def initialize(self, argv=None):
330 super(NotebookApp, self).initialize(argv)
330 super(NotebookApp, self).initialize(argv)
331 self.init_configurables()
331 self.init_configurables()
332 self.web_app = NotebookWebApplication(
332 self.web_app = NotebookWebApplication(
333 self, self.kernel_manager, self.notebook_manager, self.log,
333 self, self.kernel_manager, self.notebook_manager, self.log,
334 self.webapp_settings
334 self.webapp_settings
335 )
335 )
336 if self.certfile:
336 if self.certfile:
337 ssl_options = dict(certfile=self.certfile)
337 ssl_options = dict(certfile=self.certfile)
338 if self.keyfile:
338 if self.keyfile:
339 ssl_options['keyfile'] = self.keyfile
339 ssl_options['keyfile'] = self.keyfile
340 else:
340 else:
341 ssl_options = None
341 ssl_options = None
342 self.web_app.password = self.password
342 self.web_app.password = self.password
343 self.http_server = httpserver.HTTPServer(self.web_app, ssl_options=ssl_options)
343 self.http_server = httpserver.HTTPServer(self.web_app, ssl_options=ssl_options)
344 if ssl_options is None and not self.ip:
344 if ssl_options is None and not self.ip:
345 self.log.critical('WARNING: the notebook server is listening on all IP addresses '
345 self.log.critical('WARNING: the notebook server is listening on all IP addresses '
346 'but not using any encryption or authentication. This is highly '
346 'but not using any encryption or authentication. This is highly '
347 'insecure and not recommended.')
347 'insecure and not recommended.')
348
348
349 # Try random ports centered around the default.
349 # Try random ports centered around the default.
350 from random import randint
350 from random import randint
351 n = 50 # Max number of attempts, keep reasonably large.
351 n = 50 # Max number of attempts, keep reasonably large.
352 for port in range(self.port, self.port+5) + [self.port + randint(-2*n, 2*n) for i in range(n-5)]:
352 for port in range(self.port, self.port+5) + [self.port + randint(-2*n, 2*n) for i in range(n-5)]:
353 try:
353 try:
354 self.http_server.listen(port, self.ip)
354 self.http_server.listen(port, self.ip)
355 except socket.error, e:
355 except socket.error, e:
356 if e.errno != errno.EADDRINUSE:
356 if e.errno != errno.EADDRINUSE:
357 raise
357 raise
358 self.log.info('The port %i is already in use, trying another random port.' % port)
358 self.log.info('The port %i is already in use, trying another random port.' % port)
359 else:
359 else:
360 self.port = port
360 self.port = port
361 break
361 break
362
362
363 def start(self):
363 def start(self):
364 ip = self.ip if self.ip else '[all ip addresses on your system]'
364 ip = self.ip if self.ip else '[all ip addresses on your system]'
365 proto = 'https' if self.certfile else 'http'
365 proto = 'https' if self.certfile else 'http'
366 info = self.log.info
366 info = self.log.info
367 info("The IPython Notebook is running at: %s://%s:%i" %
367 info("The IPython Notebook is running at: %s://%s:%i" %
368 (proto, ip, self.port) )
368 (proto, ip, self.port) )
369 info("Use Control-C to stop this server and shut down all kernels.")
369 info("Use Control-C to stop this server and shut down all kernels.")
370
370
371 if self.open_browser:
371 if self.open_browser:
372 ip = self.ip or '127.0.0.1'
372 ip = self.ip or '127.0.0.1'
373 b = lambda : webbrowser.open("%s://%s:%i" % (proto, ip, self.port),
373 b = lambda : webbrowser.open("%s://%s:%i" % (proto, ip, self.port),
374 new=2)
374 new=2)
375 threading.Thread(target=b).start()
375 threading.Thread(target=b).start()
376
376
377 ioloop.IOLoop.instance().start()
377 ioloop.IOLoop.instance().start()
378
378
379 #-----------------------------------------------------------------------------
379 #-----------------------------------------------------------------------------
380 # Main entry point
380 # Main entry point
381 #-----------------------------------------------------------------------------
381 #-----------------------------------------------------------------------------
382
382
383 def launch_new_instance():
383 def launch_new_instance():
384 app = NotebookApp()
384 app = NotebookApp()
385 app.initialize()
385 app.initialize()
386 app.start()
386 app.start()
387
387
@@ -1,85 +1,85
1 <!DOCTYPE HTML>
1 <!DOCTYPE HTML>
2 <html>
2 <html>
3
3
4 <head>
4 <head>
5 <meta charset="utf-8">
5 <meta charset="utf-8">
6
6
7 <title>{% block title %}IPython Notebook{% end %}</title>
7 <title>{% block title %}IPython Notebook{% end %}</title>
8
8
9 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
9 <link rel="stylesheet" href="/static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
10 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
10 <link rel="stylesheet" href="/static/css/boilerplate.css" type="text/css" />
11 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
11 <link rel="stylesheet" href="/static/css/layout.css" type="text/css" />
12 <link rel="stylesheet" href="static/css/base.css" type="text/css"/>
12 <link rel="stylesheet" href="/static/css/base.css" type="text/css"/>
13 {% block stylesheet %}
13 {% block stylesheet %}
14 {% end %}
14 {% end %}
15
15
16 {% block meta %}
16 {% block meta %}
17 {% end %}
17 {% end %}
18
18
19 </head>
19 </head>
20
20
21 <body {% block params %}{% end %}>
21 <body {% block params %}{% end %}>
22
22
23 <div id="header">
23 <div id="header">
24 <span id="ipython_notebook"><h1><img src='static/ipynblogo.png' alt='IPython Notebook'/></h1></span>
24 <span id="ipython_notebook"><h1><img src='/static/ipynblogo.png' alt='IPython Notebook'/></h1></span>
25
25
26 {% block login_widget %}
26 {% block login_widget %}
27
27
28 <span id="login_widget">
28 <span id="login_widget">
29 {% if logged_in %}
29 {% if logged_in %}
30 <button id="logout">Logout</button>
30 <button id="logout">Logout</button>
31 {% elif login_available and not logged_in %}
31 {% elif login_available and not logged_in %}
32 <button id="login">Login</button>
32 <button id="login">Login</button>
33 {% end %}
33 {% end %}
34 </span>
34 </span>
35
35
36 {% end %}
36 {% end %}
37
37
38 {% block header %}
38 {% block header %}
39 {% end %}
39 {% end %}
40 </div>
40 </div>
41
41
42 <div id="header_border"></div>
42 <div id="header_border"></div>
43
43
44 <div id="main_app">
44 <div id="main_app">
45
45
46 <div id="app_hbox">
46 <div id="app_hbox">
47
47
48 <div id="left_panel">
48 <div id="left_panel">
49 {% block left_panel %}
49 {% block left_panel %}
50 {% end %}
50 {% end %}
51 </div>
51 </div>
52
52
53 <div id="content_panel">
53 <div id="content_panel">
54 {% if message %}
54 {% if message %}
55
55
56 {% for key in message %}
56 {% for key in message %}
57 <div class="message {{key}}">
57 <div class="message {{key}}">
58 {{message[key]}}
58 {{message[key]}}
59 </div>
59 </div>
60 {% end %}
60 {% end %}
61 {% end %}
61 {% end %}
62
62
63 {% block content_panel %}
63 {% block content_panel %}
64 {% end %}
64 {% end %}
65 </div>
65 </div>
66 <div id="right_panel">
66 <div id="right_panel">
67 {% block right_panel %}
67 {% block right_panel %}
68 {% end %}
68 {% end %}
69 </div>
69 </div>
70
70
71 </div>
71 </div>
72
72
73 </div>
73 </div>
74
74
75 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
75 <script src="/static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
76 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
76 <script src="/static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
77 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
77 <script src="/static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
78 <script src="static/js/loginmain.js" type="text/javascript" charset="utf-8"></script>
78 <script src="/static/js/loginmain.js" type="text/javascript" charset="utf-8"></script>
79 <script src="static/js/loginwidget.js" type="text/javascript" charset="utf-8"></script>
79 <script src="/static/js/loginwidget.js" type="text/javascript" charset="utf-8"></script>
80 {% block script %}
80 {% block script %}
81 {% end %}
81 {% end %}
82
82
83 </body>
83 </body>
84
84
85 </html>
85 </html>
@@ -1,298 +1,298
1 <!DOCTYPE HTML>
1 <!DOCTYPE HTML>
2 <html>
2 <html>
3
3
4 <head>
4 <head>
5 <meta charset="utf-8">
5 <meta charset="utf-8">
6
6
7 <title>IPython Notebook</title>
7 <title>IPython Notebook</title>
8
8
9 {% if mathjax_url %}
9 {% if mathjax_url %}
10 <script type="text/javascript" src="{{mathjax_url}}?config=TeX-AMS_HTML" charset="utf-8"></script>
10 <script type="text/javascript" src="{{mathjax_url}}?config=TeX-AMS_HTML" charset="utf-8"></script>
11 {% end %}
11 {% end %}
12 <script type="text/javascript">
12 <script type="text/javascript">
13 // MathJax disabled, set as null to distingish from *missing* MathJax,
13 // MathJax disabled, set as null to distingish from *missing* MathJax,
14 // where it will be undefined, and should prompt a dialog later.
14 // where it will be undefined, and should prompt a dialog later.
15 window.mathjax_url = "{{mathjax_url}}";
15 window.mathjax_url = "{{mathjax_url}}";
16 </script>
16 </script>
17
17
18 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
18 <link rel="stylesheet" href="/static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
19 <link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
19 <link rel="stylesheet" href="/static/codemirror/lib/codemirror.css">
20 <link rel="stylesheet" href="static/codemirror/mode/markdown/markdown.css">
20 <link rel="stylesheet" href="/static/codemirror/mode/markdown/markdown.css">
21 <link rel="stylesheet" href="static/codemirror/mode/rst/rst.css">
21 <link rel="stylesheet" href="/static/codemirror/mode/rst/rst.css">
22 <link rel="stylesheet" href="static/codemirror/theme/ipython.css">
22 <link rel="stylesheet" href="/static/codemirror/theme/ipython.css">
23 <link rel="stylesheet" href="static/codemirror/theme/default.css">
23 <link rel="stylesheet" href="/static/codemirror/theme/default.css">
24
24
25 <link rel="stylesheet" href="static/prettify/prettify.css"/>
25 <link rel="stylesheet" href="/static/prettify/prettify.css"/>
26
26
27 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
27 <link rel="stylesheet" href="/static/css/boilerplate.css" type="text/css" />
28 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
28 <link rel="stylesheet" href="/static/css/layout.css" type="text/css" />
29 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
29 <link rel="stylesheet" href="/static/css/base.css" type="text/css" />
30 <link rel="stylesheet" href="static/css/notebook.css" type="text/css" />
30 <link rel="stylesheet" href="/static/css/notebook.css" type="text/css" />
31 <link rel="stylesheet" href="static/css/renderedhtml.css" type="text/css" />
31 <link rel="stylesheet" href="/static/css/renderedhtml.css" type="text/css" />
32
32
33 {% comment In the notebook, the read-only flag is used to determine %}
33 {% comment In the notebook, the read-only flag is used to determine %}
34 {% comment whether to hide the side panels and switch off input %}
34 {% comment whether to hide the side panels and switch off input %}
35 <meta name="read_only" content="{{read_only and not logged_in}}"/>
35 <meta name="read_only" content="{{read_only and not logged_in}}"/>
36
36
37 </head>
37 </head>
38
38
39 <body
39 <body
40 data-project={{project}} data-notebook-id={{notebook_id}}
40 data-project={{project}} data-notebook-id={{notebook_id}}
41 data-base-project-url={{base_project_url}} data-base-kernel-url={{base_kernel_url}}
41 data-base-project-url={{base_project_url}} data-base-kernel-url={{base_kernel_url}}
42 >
42 >
43
43
44 <div id="header">
44 <div id="header">
45 <span id="ipython_notebook"><h1><a href='..' alt='dashboard'><img src='static/ipynblogo.png' alt='IPython Notebook'/></a></h1></span>
45 <span id="ipython_notebook"><h1><a href='..' alt='dashboard'><img src='/static/ipynblogo.png' alt='IPython Notebook'/></a></h1></span>
46 <span id="save_widget">
46 <span id="save_widget">
47 <input type="text" id="notebook_name" size="20"></textarea>
47 <input type="text" id="notebook_name" size="20"></textarea>
48 <button id="save_notebook"><u>S</u>ave</button>
48 <button id="save_notebook"><u>S</u>ave</button>
49 </span>
49 </span>
50 <span id="quick_help_area">
50 <span id="quick_help_area">
51 <button id="quick_help">Quick<u>H</u>elp</button>
51 <button id="quick_help">Quick<u>H</u>elp</button>
52 </span>
52 </span>
53
53
54 <span id="login_widget">
54 <span id="login_widget">
55 {% comment This is a temporary workaround to hide the logout button %}
55 {% comment This is a temporary workaround to hide the logout button %}
56 {% comment when appropriate until notebook.html is templated %}
56 {% comment when appropriate until notebook.html is templated %}
57 {% if logged_in %}
57 {% if logged_in %}
58 <button id="logout">Logout</button>
58 <button id="logout">Logout</button>
59 {% elif not logged_in and login_available %}
59 {% elif not logged_in and login_available %}
60 <button id="login">Login</button>
60 <button id="login">Login</button>
61 {% end %}
61 {% end %}
62 </span>
62 </span>
63
63
64 <span id="kernel_status">Idle</span>
64 <span id="kernel_status">Idle</span>
65 </div>
65 </div>
66
66
67 <div id="main_app">
67 <div id="main_app">
68
68
69 <div id="left_panel">
69 <div id="left_panel">
70
70
71 <div id="notebook_section">
71 <div id="notebook_section">
72 <div class="section_header">
72 <div class="section_header">
73 <h3>Notebook</h3>
73 <h3>Notebook</h3>
74 </div>
74 </div>
75 <div class="section_content">
75 <div class="section_content">
76 <div class="section_row">
76 <div class="section_row">
77 <span id="new_open" class="section_row_buttons">
77 <span id="new_open" class="section_row_buttons">
78 <button id="new_notebook">New</button>
78 <button id="new_notebook">New</button>
79 <button id="open_notebook">Open</button>
79 <button id="open_notebook">Open</button>
80 </span>
80 </span>
81 <span class="section_row_header">Actions</span>
81 <span class="section_row_header">Actions</span>
82 </div>
82 </div>
83 <div class="section_row">
83 <div class="section_row">
84 <span>
84 <span>
85 <select id="download_format">
85 <select id="download_format">
86 <option value="json">ipynb</option>
86 <option value="json">ipynb</option>
87 <option value="py">py</option>
87 <option value="py">py</option>
88 </select>
88 </select>
89 </span>
89 </span>
90 <span class="section_row_buttons">
90 <span class="section_row_buttons">
91 <button id="download_notebook">Download</button>
91 <button id="download_notebook">Download</button>
92 </span>
92 </span>
93 </div>
93 </div>
94 <div class="section_row">
94 <div class="section_row">
95 <span class="section_row_buttons">
95 <span class="section_row_buttons">
96 <span id="print_widget">
96 <span id="print_widget">
97 <button id="print_notebook">Print</button>
97 <button id="print_notebook">Print</button>
98 </span>
98 </span>
99 </span>
99 </span>
100 </div>
100 </div>
101 </div>
101 </div>
102 </div>
102 </div>
103
103
104 <div id="cell_section">
104 <div id="cell_section">
105 <div class="section_header">
105 <div class="section_header">
106 <h3>Cell</h3>
106 <h3>Cell</h3>
107 </div>
107 </div>
108 <div class="section_content">
108 <div class="section_content">
109 <div class="section_row">
109 <div class="section_row">
110 <span class="section_row_buttons">
110 <span class="section_row_buttons">
111 <button id="delete_cell"><u>D</u>elete</button>
111 <button id="delete_cell"><u>D</u>elete</button>
112 </span>
112 </span>
113 <span class="section_row_header">Actions</span>
113 <span class="section_row_header">Actions</span>
114 </div>
114 </div>
115 <div class="section_row">
115 <div class="section_row">
116 <span id="cell_type" class="section_row_buttons">
116 <span id="cell_type" class="section_row_buttons">
117 <button id="to_code"><u>C</u>ode</button>
117 <button id="to_code"><u>C</u>ode</button>
118 <!-- <button id="to_html">HTML</button>-->
118 <!-- <button id="to_html">HTML</button>-->
119 <button id="to_markdown"><u>M</u>arkdown</button>
119 <button id="to_markdown"><u>M</u>arkdown</button>
120 </span>
120 </span>
121 <span class="button_label">Format</span>
121 <span class="button_label">Format</span>
122 </div>
122 </div>
123 <div class="section_row">
123 <div class="section_row">
124 <span id="cell_output" class="section_row_buttons">
124 <span id="cell_output" class="section_row_buttons">
125 <button id="toggle_output"><u>T</u>oggle</button>
125 <button id="toggle_output"><u>T</u>oggle</button>
126 <button id="clear_all_output">ClearAll</button>
126 <button id="clear_all_output">ClearAll</button>
127 </span>
127 </span>
128 <span class="button_label">Output</span>
128 <span class="button_label">Output</span>
129 </div>
129 </div>
130 <div class="section_row">
130 <div class="section_row">
131 <span id="insert" class="section_row_buttons">
131 <span id="insert" class="section_row_buttons">
132 <button id="insert_cell_above"><u>A</u>bove</button>
132 <button id="insert_cell_above"><u>A</u>bove</button>
133 <button id="insert_cell_below"><u>B</u>elow</button>
133 <button id="insert_cell_below"><u>B</u>elow</button>
134 </span>
134 </span>
135 <span class="button_label">Insert</span>
135 <span class="button_label">Insert</span>
136 </div>
136 </div>
137 <div class="section_row">
137 <div class="section_row">
138 <span id="move" class="section_row_buttons">
138 <span id="move" class="section_row_buttons">
139 <button id="move_cell_up">Up</button>
139 <button id="move_cell_up">Up</button>
140 <button id="move_cell_down">Down</button>
140 <button id="move_cell_down">Down</button>
141 </span>
141 </span>
142 <span class="button_label">Move</span>
142 <span class="button_label">Move</span>
143 </div>
143 </div>
144 <div class="section_row">
144 <div class="section_row">
145 <span id="run_cells" class="section_row_buttons">
145 <span id="run_cells" class="section_row_buttons">
146 <button id="run_selected_cell">Selected</button>
146 <button id="run_selected_cell">Selected</button>
147 <button id="run_all_cells">All</button>
147 <button id="run_all_cells">All</button>
148 </span>
148 </span>
149 <span class="button_label">Run</span>
149 <span class="button_label">Run</span>
150 </div>
150 </div>
151 <div class="section_row">
151 <div class="section_row">
152 <span id="autoindent_span">
152 <span id="autoindent_span">
153 <input type="checkbox" id="autoindent" checked="true"></input>
153 <input type="checkbox" id="autoindent" checked="true"></input>
154 </span>
154 </span>
155 <span class="checkbox_label" id="autoindent_label">Autoindent:</span>
155 <span class="checkbox_label" id="autoindent_label">Autoindent:</span>
156 </div>
156 </div>
157 </div>
157 </div>
158 </div>
158 </div>
159
159
160 <div id="kernel_section">
160 <div id="kernel_section">
161 <div class="section_header">
161 <div class="section_header">
162 <h3>Kernel</h3>
162 <h3>Kernel</h3>
163 </div>
163 </div>
164 <div class="section_content">
164 <div class="section_content">
165 <div class="section_row">
165 <div class="section_row">
166 <span id="int_restart" class="section_row_buttons">
166 <span id="int_restart" class="section_row_buttons">
167 <button id="int_kernel"><u>I</u>nterrupt</button>
167 <button id="int_kernel"><u>I</u>nterrupt</button>
168 <button id="restart_kernel">Restart</button>
168 <button id="restart_kernel">Restart</button>
169 </span>
169 </span>
170 <span class="section_row_header">Actions</span>
170 <span class="section_row_header">Actions</span>
171 </div>
171 </div>
172 <div class="section_row">
172 <div class="section_row">
173 <span id="kernel_persist">
173 <span id="kernel_persist">
174 {% if kill_kernel %}
174 {% if kill_kernel %}
175 <input type="checkbox" id="kill_kernel" checked="true"></input>
175 <input type="checkbox" id="kill_kernel" checked="true"></input>
176 {% else %}
176 {% else %}
177 <input type="checkbox" id="kill_kernel"></input>
177 <input type="checkbox" id="kill_kernel"></input>
178 {% end %}
178 {% end %}
179 </span>
179 </span>
180 <span class="checkbox_label" id="kill_kernel_label">Kill kernel upon exit:</span>
180 <span class="checkbox_label" id="kill_kernel_label">Kill kernel upon exit:</span>
181 </div>
181 </div>
182 </div>
182 </div>
183 </div>
183 </div>
184
184
185 <div id="help_section">
185 <div id="help_section">
186 <div class="section_header">
186 <div class="section_header">
187 <h3>Help</h3>
187 <h3>Help</h3>
188 </div>
188 </div>
189 <div class="section_content">
189 <div class="section_content">
190 <div class="section_row">
190 <div class="section_row">
191 <span id="help_buttons0" class="section_row_buttons">
191 <span id="help_buttons0" class="section_row_buttons">
192 <a id="python_help" href="http://docs.python.org" target="_blank">Python</a>
192 <a id="python_help" href="http://docs.python.org" target="_blank">Python</a>
193 <a id="ipython_help" href="http://ipython.org/documentation.html" target="_blank">IPython</a>
193 <a id="ipython_help" href="http://ipython.org/documentation.html" target="_blank">IPython</a>
194 </span>
194 </span>
195 <span class="section_row_header">Links</span>
195 <span class="section_row_header">Links</span>
196 </div>
196 </div>
197 <div class="section_row">
197 <div class="section_row">
198 <span id="help_buttons1" class="section_row_buttons">
198 <span id="help_buttons1" class="section_row_buttons">
199 <a id="numpy_help" href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a>
199 <a id="numpy_help" href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a>
200 <a id="scipy_help" href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a>
200 <a id="scipy_help" href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a>
201 </span>
201 </span>
202 </div>
202 </div>
203 <div class="section_row">
203 <div class="section_row">
204 <span id="help_buttons2" class="section_row_buttons">
204 <span id="help_buttons2" class="section_row_buttons">
205 <a id="matplotlib_help" href="http://matplotlib.sourceforge.net/" target="_blank">MPL</a>
205 <a id="matplotlib_help" href="http://matplotlib.sourceforge.net/" target="_blank">MPL</a>
206 <a id="sympy_help" href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a>
206 <a id="sympy_help" href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a>
207 </span>
207 </span>
208 </div>
208 </div>
209 <div class="section_row">
209 <div class="section_row">
210 <span class="help_string">run selected cell</span>
210 <span class="help_string">run selected cell</span>
211 <span class="help_string_label">Shift-Enter :</span>
211 <span class="help_string_label">Shift-Enter :</span>
212 </div>
212 </div>
213 <div class="section_row">
213 <div class="section_row">
214 <span class="help_string">run selected cell in-place</span>
214 <span class="help_string">run selected cell in-place</span>
215 <span class="help_string_label">Ctrl-Enter :</span>
215 <span class="help_string_label">Ctrl-Enter :</span>
216 </div>
216 </div>
217 <div class="section_row">
217 <div class="section_row">
218 <span class="help_string">show keyboard shortcuts</span>
218 <span class="help_string">show keyboard shortcuts</span>
219 <span class="help_string_label">Ctrl-m h :</span>
219 <span class="help_string_label">Ctrl-m h :</span>
220 </div>
220 </div>
221 </div>
221 </div>
222 </div>
222 </div>
223
223
224 <div id="config_section">
224 <div id="config_section">
225 <div class="section_header">
225 <div class="section_header">
226 <h3>Configuration</h3>
226 <h3>Configuration</h3>
227 </div>
227 </div>
228 <div class="section_content">
228 <div class="section_content">
229 <div class="section_row">
229 <div class="section_row">
230 <span id="tooltipontab_span">
230 <span id="tooltipontab_span">
231 <input type="checkbox" id="tooltipontab" checked="true"></input>
231 <input type="checkbox" id="tooltipontab" checked="true"></input>
232 </span>
232 </span>
233 <span class="checkbox_label" id="tooltipontab_label">Tooltip on tab:</span>
233 <span class="checkbox_label" id="tooltipontab_label">Tooltip on tab:</span>
234 </div>
234 </div>
235 <div class="section_row">
235 <div class="section_row">
236 <span id="smartcompleter_span">
236 <span id="smartcompleter_span">
237 <input type="checkbox" id="smartcompleter" checked="true"></input>
237 <input type="checkbox" id="smartcompleter" checked="true"></input>
238 </span>
238 </span>
239 <span class="checkbox_label" id="smartcompleter_label">Smart completer:</span>
239 <span class="checkbox_label" id="smartcompleter_label">Smart completer:</span>
240 </div>
240 </div>
241 <div class="section_row">
241 <div class="section_row">
242 <span id="timebeforetooltip_span">
242 <span id="timebeforetooltip_span">
243 <input type="text" id="timebeforetooltip" value="1200" size='6'></input>
243 <input type="text" id="timebeforetooltip" value="1200" size='6'></input>
244 <span class="numeric_input_label" id="timebeforetooltip_unit">milliseconds</span>
244 <span class="numeric_input_label" id="timebeforetooltip_unit">milliseconds</span>
245 </span>
245 </span>
246 <span class="numeric_input_label" id="timebeforetooltip_label">Time before tooltip : </span>
246 <span class="numeric_input_label" id="timebeforetooltip_label">Time before tooltip : </span>
247 </div>
247 </div>
248 </div>
248 </div>
249 </div>
249 </div>
250
250
251 </div>
251 </div>
252 <div id="left_panel_splitter"></div>
252 <div id="left_panel_splitter"></div>
253 <div id="notebook_panel">
253 <div id="notebook_panel">
254 <div id="notebook"></div>
254 <div id="notebook"></div>
255 <div id="pager_splitter"></div>
255 <div id="pager_splitter"></div>
256 <div id="pager"></div>
256 <div id="pager"></div>
257 </div>
257 </div>
258
258
259 </div>
259 </div>
260
260
261 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
261 <script src="/static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
262 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
262 <script src="/static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
263 <script src="static/jquery/js/jquery.autogrow.js" type="text/javascript" charset="utf-8"></script>
263 <script src="/static/jquery/js/jquery.autogrow.js" type="text/javascript" charset="utf-8"></script>
264
264
265 <script src="static/codemirror/lib/codemirror.js" charset="utf-8"></script>
265 <script src="/static/codemirror/lib/codemirror.js" charset="utf-8"></script>
266 <script src="static/codemirror/mode/python/python.js" charset="utf-8"></script>
266 <script src="/static/codemirror/mode/python/python.js" charset="utf-8"></script>
267 <script src="static/codemirror/mode/htmlmixed/htmlmixed.js" charset="utf-8"></script>
267 <script src="/static/codemirror/mode/htmlmixed/htmlmixed.js" charset="utf-8"></script>
268 <script src="static/codemirror/mode/xml/xml.js" charset="utf-8"></script>
268 <script src="/static/codemirror/mode/xml/xml.js" charset="utf-8"></script>
269 <script src="static/codemirror/mode/javascript/javascript.js" charset="utf-8"></script>
269 <script src="/static/codemirror/mode/javascript/javascript.js" charset="utf-8"></script>
270 <script src="static/codemirror/mode/css/css.js" charset="utf-8"></script>
270 <script src="/static/codemirror/mode/css/css.js" charset="utf-8"></script>
271 <script src="static/codemirror/mode/rst/rst.js" charset="utf-8"></script>
271 <script src="/static/codemirror/mode/rst/rst.js" charset="utf-8"></script>
272 <script src="static/codemirror/mode/markdown/markdown.js" charset="utf-8"></script>
272 <script src="/static/codemirror/mode/markdown/markdown.js" charset="utf-8"></script>
273
273
274 <script src="static/pagedown/Markdown.Converter.js" charset="utf-8"></script>
274 <script src="/static/pagedown/Markdown.Converter.js" charset="utf-8"></script>
275
275
276 <script src="static/prettify/prettify.js" charset="utf-8"></script>
276 <script src="/static/prettify/prettify.js" charset="utf-8"></script>
277
277
278 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
278 <script src="/static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
279 <script src="static/js/utils.js" type="text/javascript" charset="utf-8"></script>
279 <script src="/static/js/utils.js" type="text/javascript" charset="utf-8"></script>
280 <script src="static/js/cell.js" type="text/javascript" charset="utf-8"></script>
280 <script src="/static/js/cell.js" type="text/javascript" charset="utf-8"></script>
281 <script src="static/js/codecell.js" type="text/javascript" charset="utf-8"></script>
281 <script src="/static/js/codecell.js" type="text/javascript" charset="utf-8"></script>
282 <script src="static/js/textcell.js" type="text/javascript" charset="utf-8"></script>
282 <script src="/static/js/textcell.js" type="text/javascript" charset="utf-8"></script>
283 <script src="static/js/kernel.js" type="text/javascript" charset="utf-8"></script>
283 <script src="/static/js/kernel.js" type="text/javascript" charset="utf-8"></script>
284 <script src="static/js/kernelstatus.js" type="text/javascript" charset="utf-8"></script>
284 <script src="/static/js/kernelstatus.js" type="text/javascript" charset="utf-8"></script>
285 <script src="static/js/layout.js" type="text/javascript" charset="utf-8"></script>
285 <script src="/static/js/layout.js" type="text/javascript" charset="utf-8"></script>
286 <script src="static/js/savewidget.js" type="text/javascript" charset="utf-8"></script>
286 <script src="/static/js/savewidget.js" type="text/javascript" charset="utf-8"></script>
287 <script src="static/js/quickhelp.js" type="text/javascript" charset="utf-8"></script>
287 <script src="/static/js/quickhelp.js" type="text/javascript" charset="utf-8"></script>
288 <script src="static/js/loginwidget.js" type="text/javascript" charset="utf-8"></script>
288 <script src="/static/js/loginwidget.js" type="text/javascript" charset="utf-8"></script>
289 <script src="static/js/pager.js" type="text/javascript" charset="utf-8"></script>
289 <script src="/static/js/pager.js" type="text/javascript" charset="utf-8"></script>
290 <script src="static/js/panelsection.js" type="text/javascript" charset="utf-8"></script>
290 <script src="/static/js/panelsection.js" type="text/javascript" charset="utf-8"></script>
291 <script src="static/js/printwidget.js" type="text/javascript" charset="utf-8"></script>
291 <script src="/static/js/printwidget.js" type="text/javascript" charset="utf-8"></script>
292 <script src="static/js/leftpanel.js" type="text/javascript" charset="utf-8"></script>
292 <script src="/static/js/leftpanel.js" type="text/javascript" charset="utf-8"></script>
293 <script src="static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
293 <script src="/static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
294 <script src="static/js/notebookmain.js" type="text/javascript" charset="utf-8"></script>
294 <script src="/static/js/notebookmain.js" type="text/javascript" charset="utf-8"></script>
295
295
296 </body>
296 </body>
297
297
298 </html>
298 </html>
@@ -1,43 +1,43
1 {% extends layout.html %}
1 {% extends layout.html %}
2
2
3 {% block title %}
3 {% block title %}
4 IPython Dashboard
4 IPython Dashboard
5 {% end %}
5 {% end %}
6
6
7 {% block stylesheet %}
7 {% block stylesheet %}
8 <link rel="stylesheet" href="static/css/projectdashboard.css" type="text/css" />
8 <link rel="stylesheet" href="/static/css/projectdashboard.css" type="text/css" />
9 {% end %}
9 {% end %}
10
10
11 {% block meta %}
11 {% block meta %}
12 <meta name="read_only" content="{{read_only}}"/>
12 <meta name="read_only" content="{{read_only}}"/>
13 {% end %}
13 {% end %}
14
14
15 {% block params %}
15 {% block params %}
16 data-project={{project}}
16 data-project={{project}}
17 data-base-project-url={{base_project_url}}
17 data-base-project-url={{base_project_url}}
18 data-base-kernel-url={{base_kernel_url}}
18 data-base-kernel-url={{base_kernel_url}}
19 {% end %}
19 {% end %}
20
20
21 {% block content_panel %}
21 {% block content_panel %}
22 {% if logged_in or not read_only %}
22 {% if logged_in or not read_only %}
23
23
24 <div id="content_toolbar">
24 <div id="content_toolbar">
25 <span id="drag_info">Drag files onto the list to import
25 <span id="drag_info">Drag files onto the list to import
26 notebooks.</span>
26 notebooks.</span>
27
27
28 <span id="notebooks_buttons">
28 <span id="notebooks_buttons">
29 <button id="new_notebook">New Notebook</button>
29 <button id="new_notebook">New Notebook</button>
30 </span>
30 </span>
31 </div>
31 </div>
32
32
33 {% end %}
33 {% end %}
34
34
35 <div id="notebook_list">
35 <div id="notebook_list">
36 <div id="project_name"><h2>{{project}}</h2></div>
36 <div id="project_name"><h2>{{project}}</h2></div>
37 </div>
37 </div>
38 {% end %}
38 {% end %}
39
39
40 {% block script %}
40 {% block script %}
41 <script src="static/js/notebooklist.js" type="text/javascript" charset="utf-8"></script>
41 <script src="/static/js/notebooklist.js" type="text/javascript" charset="utf-8"></script>
42 <script src="static/js/projectdashboardmain.js" type="text/javascript" charset="utf-8"></script>
42 <script src="/static/js/projectdashboardmain.js" type="text/javascript" charset="utf-8"></script>
43 {% end %}
43 {% end %}
General Comments 0
You need to be logged in to leave comments. Login now