##// END OF EJS Templates
Misc changes to the notebook....
Brian E. Granger -
Show More
@@ -1,250 +1,250 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An application for managing IPython profiles.
3 An application for managing IPython profiles.
4
4
5 To be invoked as the `ipython profile` subcommand.
5 To be invoked as the `ipython profile` subcommand.
6
6
7 Authors:
7 Authors:
8
8
9 * Min RK
9 * Min RK
10
10
11 """
11 """
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008-2011 The IPython Development Team
14 # Copyright (C) 2008-2011 The IPython Development Team
15 #
15 #
16 # Distributed under the terms of the BSD License. The full license is in
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
17 # the file COPYING, distributed as part of this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 import logging
24 import logging
25 import os
25 import os
26
26
27 from IPython.config.application import Application, boolean_flag
27 from IPython.config.application import Application, boolean_flag
28 from IPython.core.application import (
28 from IPython.core.application import (
29 BaseIPythonApplication, base_flags, base_aliases
29 BaseIPythonApplication, base_flags, base_aliases
30 )
30 )
31 from IPython.core.profiledir import ProfileDir
31 from IPython.core.profiledir import ProfileDir
32 from IPython.utils.path import get_ipython_dir
32 from IPython.utils.path import get_ipython_dir
33 from IPython.utils.traitlets import Unicode, Bool, Dict
33 from IPython.utils.traitlets import Unicode, Bool, Dict
34
34
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 # Constants
36 # Constants
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38
38
39 create_help = """Create an IPython profile by name
39 create_help = """Create an IPython profile by name
40
40
41 Create an ipython profile directory by its name or
41 Create an ipython profile directory by its name or
42 profile directory path. Profile directories contain
42 profile directory path. Profile directories contain
43 configuration, log and security related files and are named
43 configuration, log and security related files and are named
44 using the convention 'profile_<name>'. By default they are
44 using the convention 'profile_<name>'. By default they are
45 located in your ipython directory. Once created, you will
45 located in your ipython directory. Once created, you will
46 can edit the configuration files in the profile
46 can edit the configuration files in the profile
47 directory to configure IPython. Most users will create a
47 directory to configure IPython. Most users will create a
48 profile directory by name,
48 profile directory by name,
49 `ipython profile create myprofile`, which will put the directory
49 `ipython profile create myprofile`, which will put the directory
50 in `<ipython_dir>/profile_myprofile`.
50 in `<ipython_dir>/profile_myprofile`.
51 """
51 """
52 list_help = """List available IPython profiles
52 list_help = """List available IPython profiles
53
53
54 List all available profiles, by profile location, that can
54 List all available profiles, by profile location, that can
55 be found in the current working directly or in the ipython
55 be found in the current working directly or in the ipython
56 directory. Profile directories are named using the convention
56 directory. Profile directories are named using the convention
57 'profile_<profile>'.
57 'profile_<profile>'.
58 """
58 """
59 profile_help = """Manage IPython profiles
59 profile_help = """Manage IPython profiles
60
60
61 Profile directories contain
61 Profile directories contain
62 configuration, log and security related files and are named
62 configuration, log and security related files and are named
63 using the convention 'profile_<name>'. By default they are
63 using the convention 'profile_<name>'. By default they are
64 located in your ipython directory. You can create profiles
64 located in your ipython directory. You can create profiles
65 with `ipython profile create <name>`, or see the profiles you
65 with `ipython profile create <name>`, or see the profiles you
66 already have with `ipython profile list`
66 already have with `ipython profile list`
67
67
68 To get started configuring IPython, simply do:
68 To get started configuring IPython, simply do:
69
69
70 $> ipython profile create
70 $> ipython profile create
71
71
72 and IPython will create the default profile in <ipython_dir>/profile_default,
72 and IPython will create the default profile in <ipython_dir>/profile_default,
73 where you can edit ipython_config.py to start configuring IPython.
73 where you can edit ipython_config.py to start configuring IPython.
74
74
75 """
75 """
76
76
77 _list_examples = "ipython profile list # list all profiles"
77 _list_examples = "ipython profile list # list all profiles"
78
78
79 _create_examples = """
79 _create_examples = """
80 ipython profile create foo # create profile foo w/ default config files
80 ipython profile create foo # create profile foo w/ default config files
81 ipython profile create foo --reset # restage default config files over current
81 ipython profile create foo --reset # restage default config files over current
82 ipython profile create foo --parallel # also stage parallel config files
82 ipython profile create foo --parallel # also stage parallel config files
83 """
83 """
84
84
85 _main_examples = """
85 _main_examples = """
86 ipython profile create -h # show the help string for the create subcommand
86 ipython profile create -h # show the help string for the create subcommand
87 ipython profile list -h # show the help string for the list subcommand
87 ipython profile list -h # show the help string for the list subcommand
88 """
88 """
89
89
90 #-----------------------------------------------------------------------------
90 #-----------------------------------------------------------------------------
91 # Profile Application Class (for `ipython profile` subcommand)
91 # Profile Application Class (for `ipython profile` subcommand)
92 #-----------------------------------------------------------------------------
92 #-----------------------------------------------------------------------------
93
93
94
94
95 class ProfileList(Application):
95 class ProfileList(Application):
96 name = u'ipython-profile'
96 name = u'ipython-profile'
97 description = list_help
97 description = list_help
98 examples = _list_examples
98 examples = _list_examples
99
99
100 aliases = Dict({
100 aliases = Dict({
101 'ipython-dir' : 'ProfileList.ipython_dir',
101 'ipython-dir' : 'ProfileList.ipython_dir',
102 'log-level' : 'Application.log_level',
102 'log-level' : 'Application.log_level',
103 })
103 })
104 flags = Dict(dict(
104 flags = Dict(dict(
105 debug = ({'Application' : {'log_level' : 0}},
105 debug = ({'Application' : {'log_level' : 0}},
106 "Set Application.log_level to 0, maximizing log output."
106 "Set Application.log_level to 0, maximizing log output."
107 )
107 )
108 ))
108 ))
109
109
110 ipython_dir = Unicode(get_ipython_dir(), config=True,
110 ipython_dir = Unicode(get_ipython_dir(), config=True,
111 help="""
111 help="""
112 The name of the IPython directory. This directory is used for logging
112 The name of the IPython directory. This directory is used for logging
113 configuration (through profiles), history storage, etc. The default
113 configuration (through profiles), history storage, etc. The default
114 is usually $HOME/.ipython. This options can also be specified through
114 is usually $HOME/.ipython. This options can also be specified through
115 the environment variable IPYTHON_DIR.
115 the environment variable IPYTHON_DIR.
116 """
116 """
117 )
117 )
118
118
119 def list_profile_dirs(self):
119 def list_profile_dirs(self):
120 # Find the search paths
120 # Find the search paths
121 paths = [os.getcwdu(), self.ipython_dir]
121 paths = [os.getcwdu(), self.ipython_dir]
122
122
123 self.log.warn('Searching for IPython profiles in paths: %r' % paths)
123 self.log.warn('Searching for IPython profiles in paths: %r' % paths)
124 for path in paths:
124 for path in paths:
125 files = os.listdir(path)
125 files = os.listdir(path)
126 for f in files:
126 for f in files:
127 full_path = os.path.join(path, f)
127 full_path = os.path.join(path, f)
128 if os.path.isdir(full_path) and f.startswith('profile_'):
128 if os.path.isdir(full_path) and f.startswith('profile_'):
129 profile = f.split('_',1)[-1]
129 profile = f.split('_',1)[-1]
130 start_cmd = 'ipython profile=%s' % profile
130 start_cmd = 'ipython profile=%s' % profile
131 print start_cmd + " ==> " + full_path
131 print start_cmd + " ==> " + full_path
132
132
133 def start(self):
133 def start(self):
134 self.list_profile_dirs()
134 self.list_profile_dirs()
135
135
136
136
137 create_flags = {}
137 create_flags = {}
138 create_flags.update(base_flags)
138 create_flags.update(base_flags)
139 # don't include '--init' flag, which implies running profile create in other apps
139 # don't include '--init' flag, which implies running profile create in other apps
140 create_flags.pop('init')
140 create_flags.pop('init')
141 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
141 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
142 "reset config files in this profile to the defaults.")
142 "reset config files in this profile to the defaults.")
143 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
143 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
144 "Include the config files for parallel "
144 "Include the config files for parallel "
145 "computing apps (ipengine, ipcontroller, etc.)")
145 "computing apps (ipengine, ipcontroller, etc.)")
146
146
147
147
148 class ProfileCreate(BaseIPythonApplication):
148 class ProfileCreate(BaseIPythonApplication):
149 name = u'ipython-profile'
149 name = u'ipython-profile'
150 description = create_help
150 description = create_help
151 examples = _create_examples
151 examples = _create_examples
152 auto_create = Bool(True, config=False)
152 auto_create = Bool(True, config=False)
153
153
154 def _copy_config_files_default(self):
154 def _copy_config_files_default(self):
155 return True
155 return True
156
156
157 parallel = Bool(False, config=True,
157 parallel = Bool(False, config=True,
158 help="whether to include parallel computing config files")
158 help="whether to include parallel computing config files")
159 def _parallel_changed(self, name, old, new):
159 def _parallel_changed(self, name, old, new):
160 parallel_files = [ 'ipcontroller_config.py',
160 parallel_files = [ 'ipcontroller_config.py',
161 'ipengine_config.py',
161 'ipengine_config.py',
162 'ipcluster_config.py'
162 'ipcluster_config.py'
163 ]
163 ]
164 if new:
164 if new:
165 for cf in parallel_files:
165 for cf in parallel_files:
166 self.config_files.append(cf)
166 self.config_files.append(cf)
167 else:
167 else:
168 for cf in parallel_files:
168 for cf in parallel_files:
169 if cf in self.config_files:
169 if cf in self.config_files:
170 self.config_files.remove(cf)
170 self.config_files.remove(cf)
171
171
172 def parse_command_line(self, argv):
172 def parse_command_line(self, argv):
173 super(ProfileCreate, self).parse_command_line(argv)
173 super(ProfileCreate, self).parse_command_line(argv)
174 # accept positional arg as profile name
174 # accept positional arg as profile name
175 if self.extra_args:
175 if self.extra_args:
176 self.profile = self.extra_args[0]
176 self.profile = self.extra_args[0]
177
177
178 flags = Dict(create_flags)
178 flags = Dict(create_flags)
179
179
180 classes = [ProfileDir]
180 classes = [ProfileDir]
181
181
182 def init_config_files(self):
182 def init_config_files(self):
183 super(ProfileCreate, self).init_config_files()
183 super(ProfileCreate, self).init_config_files()
184 # use local imports, since these classes may import from here
184 # use local imports, since these classes may import from here
185 from IPython.frontend.terminal.ipapp import TerminalIPythonApp
185 from IPython.frontend.terminal.ipapp import TerminalIPythonApp
186 apps = [TerminalIPythonApp]
186 apps = [TerminalIPythonApp]
187 try:
187 try:
188 from IPython.frontend.qt.console.qtconsoleapp import IPythonQtConsoleApp
188 from IPython.frontend.qt.console.qtconsoleapp import IPythonQtConsoleApp
189 except Exception:
189 except Exception:
190 # this should be ImportError, but under weird circumstances
190 # this should be ImportError, but under weird circumstances
191 # this might be an AttributeError, or possibly others
191 # this might be an AttributeError, or possibly others
192 # in any case, nothing should cause the profile creation to crash.
192 # in any case, nothing should cause the profile creation to crash.
193 pass
193 pass
194 else:
194 else:
195 apps.append(IPythonQtConsoleApp)
195 apps.append(IPythonQtConsoleApp)
196 try:
196 try:
197 from IPython.frontend.html.notebook.notebookapp import IPythonNotebookApp
197 from IPython.frontend.html.notebook.notebookapp import NotebookApp
198 except ImportError:
198 except ImportError:
199 pass
199 pass
200 except Exception:
200 except Exception:
201 self.log.debug('Unexpected error when importing IPythonNotebookApp',
201 self.log.debug('Unexpected error when importing NotebookApp',
202 exc_info=True
202 exc_info=True
203 )
203 )
204 else:
204 else:
205 apps.append(IPythonNotebookApp)
205 apps.append(NotebookApp)
206 if self.parallel:
206 if self.parallel:
207 from IPython.parallel.apps.ipcontrollerapp import IPControllerApp
207 from IPython.parallel.apps.ipcontrollerapp import IPControllerApp
208 from IPython.parallel.apps.ipengineapp import IPEngineApp
208 from IPython.parallel.apps.ipengineapp import IPEngineApp
209 from IPython.parallel.apps.ipclusterapp import IPClusterStart
209 from IPython.parallel.apps.ipclusterapp import IPClusterStart
210 from IPython.parallel.apps.iploggerapp import IPLoggerApp
210 from IPython.parallel.apps.iploggerapp import IPLoggerApp
211 apps.extend([
211 apps.extend([
212 IPControllerApp,
212 IPControllerApp,
213 IPEngineApp,
213 IPEngineApp,
214 IPClusterStart,
214 IPClusterStart,
215 IPLoggerApp,
215 IPLoggerApp,
216 ])
216 ])
217 for App in apps:
217 for App in apps:
218 app = App()
218 app = App()
219 app.config.update(self.config)
219 app.config.update(self.config)
220 app.log = self.log
220 app.log = self.log
221 app.overwrite = self.overwrite
221 app.overwrite = self.overwrite
222 app.copy_config_files=True
222 app.copy_config_files=True
223 app.profile = self.profile
223 app.profile = self.profile
224 app.init_profile_dir()
224 app.init_profile_dir()
225 app.init_config_files()
225 app.init_config_files()
226
226
227 def stage_default_config_file(self):
227 def stage_default_config_file(self):
228 pass
228 pass
229
229
230
230
231 class ProfileApp(Application):
231 class ProfileApp(Application):
232 name = u'ipython-profile'
232 name = u'ipython-profile'
233 description = profile_help
233 description = profile_help
234 examples = _main_examples
234 examples = _main_examples
235
235
236 subcommands = Dict(dict(
236 subcommands = Dict(dict(
237 create = (ProfileCreate, "Create a new profile dir with default config files"),
237 create = (ProfileCreate, "Create a new profile dir with default config files"),
238 list = (ProfileList, "List existing profiles")
238 list = (ProfileList, "List existing profiles")
239 ))
239 ))
240
240
241 def start(self):
241 def start(self):
242 if self.subapp is None:
242 if self.subapp is None:
243 print "No subcommand specified. Must specify one of: %s"%(self.subcommands.keys())
243 print "No subcommand specified. Must specify one of: %s"%(self.subcommands.keys())
244 print
244 print
245 self.print_description()
245 self.print_description()
246 self.print_subcommands()
246 self.print_subcommands()
247 self.exit(1)
247 self.exit(1)
248 else:
248 else:
249 return self.subapp.start()
249 return self.subapp.start()
250
250
@@ -1,315 +1,315 b''
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 import errno
19 import errno
20 import logging
20 import logging
21 import os
21 import os
22 import signal
22 import signal
23 import socket
23 import socket
24 import sys
24 import sys
25 import webbrowser
25 import webbrowser
26
26
27 import zmq
27 import zmq
28
28
29 # Install the pyzmq ioloop. This has to be done before anything else from
29 # Install the pyzmq ioloop. This has to be done before anything else from
30 # tornado is imported.
30 # tornado is imported.
31 from zmq.eventloop import ioloop
31 from zmq.eventloop import ioloop
32 import tornado.ioloop
32 import tornado.ioloop
33 tornado.ioloop.IOLoop = ioloop.IOLoop
33 tornado.ioloop.IOLoop = ioloop.IOLoop
34
34
35 from tornado import httpserver
35 from tornado import httpserver
36 from tornado import web
36 from tornado import web
37
37
38 from .kernelmanager import MappingKernelManager
38 from .kernelmanager import MappingKernelManager
39 from .handlers import (LoginHandler,
39 from .handlers import (LoginHandler,
40 NBBrowserHandler, NewHandler, NamedNotebookHandler,
40 NBBrowserHandler, NewHandler, NamedNotebookHandler,
41 MainKernelHandler, KernelHandler, KernelActionHandler, IOPubHandler,
41 MainKernelHandler, KernelHandler, KernelActionHandler, IOPubHandler,
42 ShellHandler, NotebookRootHandler, NotebookHandler, RSTHandler
42 ShellHandler, NotebookRootHandler, NotebookHandler, RSTHandler
43 )
43 )
44 from .notebookmanager import NotebookManager
44 from .notebookmanager import NotebookManager
45
45
46 from IPython.core.application import BaseIPythonApplication
46 from IPython.core.application import BaseIPythonApplication
47 from IPython.core.profiledir import ProfileDir
47 from IPython.core.profiledir import ProfileDir
48 from IPython.zmq.session import Session, default_secure
48 from IPython.zmq.session import Session, default_secure
49 from IPython.zmq.zmqshell import ZMQInteractiveShell
49 from IPython.zmq.zmqshell import ZMQInteractiveShell
50 from IPython.zmq.ipkernel import (
50 from IPython.zmq.ipkernel import (
51 flags as ipkernel_flags,
51 flags as ipkernel_flags,
52 aliases as ipkernel_aliases,
52 aliases as ipkernel_aliases,
53 IPKernelApp
53 IPKernelApp
54 )
54 )
55 from IPython.utils.traitlets import Dict, Unicode, Int, List, Enum, Bool
55 from IPython.utils.traitlets import Dict, Unicode, Int, List, Enum, Bool
56
56
57 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
58 # Module globals
58 # Module globals
59 #-----------------------------------------------------------------------------
59 #-----------------------------------------------------------------------------
60
60
61 _kernel_id_regex = r"(?P<kernel_id>\w+-\w+-\w+-\w+-\w+)"
61 _kernel_id_regex = r"(?P<kernel_id>\w+-\w+-\w+-\w+-\w+)"
62 _kernel_action_regex = r"(?P<action>restart|interrupt)"
62 _kernel_action_regex = r"(?P<action>restart|interrupt)"
63 _notebook_id_regex = r"(?P<notebook_id>\w+-\w+-\w+-\w+-\w+)"
63 _notebook_id_regex = r"(?P<notebook_id>\w+-\w+-\w+-\w+-\w+)"
64
64
65 LOCALHOST = '127.0.0.1'
65 LOCALHOST = '127.0.0.1'
66
66
67 _examples = """
67 _examples = """
68 ipython notebook # start the notebook
68 ipython notebook # start the notebook
69 ipython notebook --profile=sympy # use the sympy profile
69 ipython notebook --profile=sympy # use the sympy profile
70 ipython notebook --pylab=inline # pylab in inline plotting mode
70 ipython notebook --pylab=inline # pylab in inline plotting mode
71 ipython notebook --certfile=mycert.pem # use SSL/TLS certificate
71 ipython notebook --certfile=mycert.pem # use SSL/TLS certificate
72 ipython notebook --port=5555 --ip=* # Listen on port 5555, all interfaces
72 ipython notebook --port=5555 --ip=* # Listen on port 5555, all interfaces
73 """
73 """
74
74
75 #-----------------------------------------------------------------------------
75 #-----------------------------------------------------------------------------
76 # The Tornado web application
76 # The Tornado web application
77 #-----------------------------------------------------------------------------
77 #-----------------------------------------------------------------------------
78
78
79 class NotebookWebApplication(web.Application):
79 class NotebookWebApplication(web.Application):
80
80
81 def __init__(self, ipython_app, kernel_manager, notebook_manager, log):
81 def __init__(self, ipython_app, kernel_manager, notebook_manager, log):
82 handlers = [
82 handlers = [
83 (r"/", NBBrowserHandler),
83 (r"/", NBBrowserHandler),
84 (r"/login", LoginHandler),
84 (r"/login", LoginHandler),
85 (r"/new", NewHandler),
85 (r"/new", NewHandler),
86 (r"/%s" % _notebook_id_regex, NamedNotebookHandler),
86 (r"/%s" % _notebook_id_regex, NamedNotebookHandler),
87 (r"/kernels", MainKernelHandler),
87 (r"/kernels", MainKernelHandler),
88 (r"/kernels/%s" % _kernel_id_regex, KernelHandler),
88 (r"/kernels/%s" % _kernel_id_regex, KernelHandler),
89 (r"/kernels/%s/%s" % (_kernel_id_regex, _kernel_action_regex), KernelActionHandler),
89 (r"/kernels/%s/%s" % (_kernel_id_regex, _kernel_action_regex), KernelActionHandler),
90 (r"/kernels/%s/iopub" % _kernel_id_regex, IOPubHandler),
90 (r"/kernels/%s/iopub" % _kernel_id_regex, IOPubHandler),
91 (r"/kernels/%s/shell" % _kernel_id_regex, ShellHandler),
91 (r"/kernels/%s/shell" % _kernel_id_regex, ShellHandler),
92 (r"/notebooks", NotebookRootHandler),
92 (r"/notebooks", NotebookRootHandler),
93 (r"/notebooks/%s" % _notebook_id_regex, NotebookHandler),
93 (r"/notebooks/%s" % _notebook_id_regex, NotebookHandler),
94 (r"/rstservice/render", RSTHandler)
94 (r"/rstservice/render", RSTHandler)
95 ]
95 ]
96 settings = dict(
96 settings = dict(
97 template_path=os.path.join(os.path.dirname(__file__), "templates"),
97 template_path=os.path.join(os.path.dirname(__file__), "templates"),
98 static_path=os.path.join(os.path.dirname(__file__), "static"),
98 static_path=os.path.join(os.path.dirname(__file__), "static"),
99 cookie_secret=os.urandom(1024),
99 cookie_secret=os.urandom(1024),
100 login_url="/login",
100 login_url="/login",
101 )
101 )
102 web.Application.__init__(self, handlers, **settings)
102 web.Application.__init__(self, handlers, **settings)
103
103
104 self.kernel_manager = kernel_manager
104 self.kernel_manager = kernel_manager
105 self.log = log
105 self.log = log
106 self.notebook_manager = notebook_manager
106 self.notebook_manager = notebook_manager
107 self.ipython_app = ipython_app
107 self.ipython_app = ipython_app
108
108
109
109
110 #-----------------------------------------------------------------------------
110 #-----------------------------------------------------------------------------
111 # Aliases and Flags
111 # Aliases and Flags
112 #-----------------------------------------------------------------------------
112 #-----------------------------------------------------------------------------
113
113
114 flags = dict(ipkernel_flags)
114 flags = dict(ipkernel_flags)
115 flags['no-browser']=(
115 flags['no-browser']=(
116 {'IPythonNotebookApp' : {'open_browser' : False}},
116 {'IPythonNotebookApp' : {'open_browser' : False}},
117 "Don't open the notebook in a browser after startup."
117 "Don't open the notebook in a browser after startup."
118 )
118 )
119
119
120 # the flags that are specific to the frontend
120 # the flags that are specific to the frontend
121 # these must be scrubbed before being passed to the kernel,
121 # these must be scrubbed before being passed to the kernel,
122 # or it will raise an error on unrecognized flags
122 # or it will raise an error on unrecognized flags
123 notebook_flags = ['no-browser']
123 notebook_flags = ['no-browser']
124
124
125 aliases = dict(ipkernel_aliases)
125 aliases = dict(ipkernel_aliases)
126
126
127 aliases.update({
127 aliases.update({
128 'ip': 'IPythonNotebookApp.ip',
128 'ip': 'NotebookApp.ip',
129 'port': 'IPythonNotebookApp.port',
129 'port': 'NotebookApp.port',
130 'keyfile': 'IPythonNotebookApp.keyfile',
130 'keyfile': 'NotebookApp.keyfile',
131 'certfile': 'IPythonNotebookApp.certfile',
131 'certfile': 'NotebookApp.certfile',
132 'ws-hostname': 'IPythonNotebookApp.ws_hostname',
132 'ws-hostname': 'NotebookApp.ws_hostname',
133 'notebook-dir': 'NotebookManager.notebook_dir',
133 'notebook-dir': 'NotebookManager.notebook_dir',
134 })
134 })
135
135
136 # remove ipkernel flags that are singletons, and don't make sense in
136 # remove ipkernel flags that are singletons, and don't make sense in
137 # multi-kernel evironment:
137 # multi-kernel evironment:
138 aliases.pop('f', None)
138 aliases.pop('f', None)
139
139
140 notebook_aliases = [u'port', u'ip', u'keyfile', u'certfile', u'ws-hostname',
140 notebook_aliases = [u'port', u'ip', u'keyfile', u'certfile', u'ws-hostname',
141 u'notebook-dir']
141 u'notebook-dir']
142
142
143 #-----------------------------------------------------------------------------
143 #-----------------------------------------------------------------------------
144 # IPythonNotebookApp
144 # NotebookApp
145 #-----------------------------------------------------------------------------
145 #-----------------------------------------------------------------------------
146
146
147 class IPythonNotebookApp(BaseIPythonApplication):
147 class NotebookApp(BaseIPythonApplication):
148
148
149 name = 'ipython-notebook'
149 name = 'ipython-notebook'
150 default_config_file_name='ipython_notebook_config.py'
150 default_config_file_name='ipython_notebook_config.py'
151
151
152 description = """
152 description = """
153 The IPython HTML Notebook.
153 The IPython HTML Notebook.
154
154
155 This launches a Tornado based HTML Notebook Server that serves up an
155 This launches a Tornado based HTML Notebook Server that serves up an
156 HTML5/Javascript Notebook client.
156 HTML5/Javascript Notebook client.
157 """
157 """
158 examples = _examples
158 examples = _examples
159
159
160 classes = [IPKernelApp, ZMQInteractiveShell, ProfileDir, Session,
160 classes = [IPKernelApp, ZMQInteractiveShell, ProfileDir, Session,
161 MappingKernelManager, NotebookManager]
161 MappingKernelManager, NotebookManager]
162 flags = Dict(flags)
162 flags = Dict(flags)
163 aliases = Dict(aliases)
163 aliases = Dict(aliases)
164
164
165 kernel_argv = List(Unicode)
165 kernel_argv = List(Unicode)
166
166
167 log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'),
167 log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'),
168 default_value=logging.INFO,
168 default_value=logging.INFO,
169 config=True,
169 config=True,
170 help="Set the log level by value or name.")
170 help="Set the log level by value or name.")
171
171
172 # Network related information.
172 # Network related information.
173
173
174 ip = Unicode(LOCALHOST, config=True,
174 ip = Unicode(LOCALHOST, config=True,
175 help="The IP address the notebook server will listen on."
175 help="The IP address the notebook server will listen on."
176 )
176 )
177
177
178 def _ip_changed(self, name, old, new):
178 def _ip_changed(self, name, old, new):
179 if new == u'*': self.ip = u''
179 if new == u'*': self.ip = u''
180
180
181 port = Int(8888, config=True,
181 port = Int(8888, config=True,
182 help="The port the notebook server will listen on."
182 help="The port the notebook server will listen on."
183 )
183 )
184
184
185 ws_hostname = Unicode(LOCALHOST, config=True,
185 ws_hostname = Unicode(LOCALHOST, config=True,
186 help="""The FQDN or IP for WebSocket connections. The default will work
186 help="""The FQDN or IP for WebSocket connections. The default will work
187 fine when the server is listening on localhost, but this needs to
187 fine when the server is listening on localhost, but this needs to
188 be set if the ip option is used. It will be used as the hostname part
188 be set if the ip option is used. It will be used as the hostname part
189 of the WebSocket url: ws://hostname/path."""
189 of the WebSocket url: ws://hostname/path."""
190 )
190 )
191
191
192 certfile = Unicode(u'', config=True,
192 certfile = Unicode(u'', config=True,
193 help="""The full path to an SSL/TLS certificate file."""
193 help="""The full path to an SSL/TLS certificate file."""
194 )
194 )
195
195
196 keyfile = Unicode(u'', config=True,
196 keyfile = Unicode(u'', config=True,
197 help="""The full path to a private key file for usage with SSL/TLS."""
197 help="""The full path to a private key file for usage with SSL/TLS."""
198 )
198 )
199
199
200 password = Unicode(u'', config=True,
200 password = Unicode(u'', config=True,
201 help="""Password to use for web authentication"""
201 help="""Password to use for web authentication"""
202 )
202 )
203
203
204 open_browser = Bool(True, config=True,
204 open_browser = Bool(True, config=True,
205 help="Whether to open in a browser after starting.")
205 help="Whether to open in a browser after starting.")
206
206
207 def get_ws_url(self):
207 def get_ws_url(self):
208 """Return the WebSocket URL for this server."""
208 """Return the WebSocket URL for this server."""
209 if self.certfile:
209 if self.certfile:
210 prefix = u'wss://'
210 prefix = u'wss://'
211 else:
211 else:
212 prefix = u'ws://'
212 prefix = u'ws://'
213 return prefix + self.ws_hostname + u':' + unicode(self.port)
213 return prefix + self.ws_hostname + u':' + unicode(self.port)
214
214
215 def parse_command_line(self, argv=None):
215 def parse_command_line(self, argv=None):
216 super(IPythonNotebookApp, self).parse_command_line(argv)
216 super(NotebookApp, self).parse_command_line(argv)
217 if argv is None:
217 if argv is None:
218 argv = sys.argv[1:]
218 argv = sys.argv[1:]
219
219
220 self.kernel_argv = list(argv) # copy
220 self.kernel_argv = list(argv) # copy
221 # Kernel should inherit default config file from frontend
221 # Kernel should inherit default config file from frontend
222 self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name)
222 self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name)
223 # Scrub frontend-specific flags
223 # Scrub frontend-specific flags
224 for a in argv:
224 for a in argv:
225 if a.startswith('-') and a.lstrip('-') in notebook_flags:
225 if a.startswith('-') and a.lstrip('-') in notebook_flags:
226 self.kernel_argv.remove(a)
226 self.kernel_argv.remove(a)
227 swallow_next = False
227 swallow_next = False
228 for a in argv:
228 for a in argv:
229 if swallow_next:
229 if swallow_next:
230 self.kernel_argv.remove(a)
230 self.kernel_argv.remove(a)
231 swallow_next = False
231 swallow_next = False
232 continue
232 continue
233 if a.startswith('-'):
233 if a.startswith('-'):
234 split = a.lstrip('-').split('=')
234 split = a.lstrip('-').split('=')
235 alias = split[0]
235 alias = split[0]
236 if alias in notebook_aliases:
236 if alias in notebook_aliases:
237 self.kernel_argv.remove(a)
237 self.kernel_argv.remove(a)
238 if len(split) == 1:
238 if len(split) == 1:
239 # alias passed with arg via space
239 # alias passed with arg via space
240 swallow_next = True
240 swallow_next = True
241
241
242 def init_configurables(self):
242 def init_configurables(self):
243 # Don't let Qt or ZMQ swallow KeyboardInterupts.
243 # Don't let Qt or ZMQ swallow KeyboardInterupts.
244 signal.signal(signal.SIGINT, signal.SIG_DFL)
244 signal.signal(signal.SIGINT, signal.SIG_DFL)
245
245
246 # force Session default to be secure
246 # force Session default to be secure
247 default_secure(self.config)
247 default_secure(self.config)
248 # Create a KernelManager and start a kernel.
248 # Create a KernelManager and start a kernel.
249 self.kernel_manager = MappingKernelManager(
249 self.kernel_manager = MappingKernelManager(
250 config=self.config, log=self.log, kernel_argv=self.kernel_argv,
250 config=self.config, log=self.log, kernel_argv=self.kernel_argv,
251 connection_dir = self.profile_dir.security_dir,
251 connection_dir = self.profile_dir.security_dir,
252 )
252 )
253 self.notebook_manager = NotebookManager(config=self.config, log=self.log)
253 self.notebook_manager = NotebookManager(config=self.config, log=self.log)
254 self.notebook_manager.list_notebooks()
254 self.notebook_manager.list_notebooks()
255
255
256 def init_logging(self):
256 def init_logging(self):
257 super(IPythonNotebookApp, self).init_logging()
257 super(NotebookApp, self).init_logging()
258 # This prevents double log messages because tornado use a root logger that
258 # This prevents double log messages because tornado use a root logger that
259 # self.log is a child of. The logging module dipatches log messages to a log
259 # self.log is a child of. The logging module dipatches log messages to a log
260 # and all of its ancenstors until propagate is set to False.
260 # and all of its ancenstors until propagate is set to False.
261 self.log.propagate = False
261 self.log.propagate = False
262
262
263 def initialize(self, argv=None):
263 def initialize(self, argv=None):
264 super(IPythonNotebookApp, self).initialize(argv)
264 super(NotebookApp, self).initialize(argv)
265 self.init_configurables()
265 self.init_configurables()
266 self.web_app = NotebookWebApplication(
266 self.web_app = NotebookWebApplication(
267 self, self.kernel_manager, self.notebook_manager, self.log
267 self, self.kernel_manager, self.notebook_manager, self.log
268 )
268 )
269 if self.certfile:
269 if self.certfile:
270 ssl_options = dict(certfile=self.certfile)
270 ssl_options = dict(certfile=self.certfile)
271 if self.keyfile:
271 if self.keyfile:
272 ssl_options['keyfile'] = self.keyfile
272 ssl_options['keyfile'] = self.keyfile
273 else:
273 else:
274 ssl_options = None
274 ssl_options = None
275 self.web_app.password = self.password
275 self.web_app.password = self.password
276 self.http_server = httpserver.HTTPServer(self.web_app, ssl_options=ssl_options)
276 self.http_server = httpserver.HTTPServer(self.web_app, ssl_options=ssl_options)
277 if ssl_options is None and not self.ip:
277 if ssl_options is None and not self.ip:
278 self.log.critical('WARNING: the notebook server is listening on all IP addresses '
278 self.log.critical('WARNING: the notebook server is listening on all IP addresses '
279 'but not using any encryption or authentication. This is highly '
279 'but not using any encryption or authentication. This is highly '
280 'insecure and not recommended.')
280 'insecure and not recommended.')
281
281
282 # Try random ports centered around the default.
282 # Try random ports centered around the default.
283 from random import randint
283 from random import randint
284 n = 50 # Max number of attempts, keep reasonably large.
284 n = 50 # Max number of attempts, keep reasonably large.
285 for port in [self.port] + [self.port + randint(-2*n, 2*n) for i in range(n)]:
285 for port in [self.port] + [self.port + randint(-2*n, 2*n) for i in range(n)]:
286 try:
286 try:
287 self.http_server.listen(port, self.ip)
287 self.http_server.listen(port, self.ip)
288 except socket.error, e:
288 except socket.error, e:
289 if e.errno != errno.EADDRINUSE:
289 if e.errno != errno.EADDRINUSE:
290 raise
290 raise
291 self.log.info('The port %i is already in use, trying another random port.' % port)
291 self.log.info('The port %i is already in use, trying another random port.' % port)
292 else:
292 else:
293 self.port = port
293 self.port = port
294 break
294 break
295
295
296 def start(self):
296 def start(self):
297 ip = self.ip if self.ip else '[all ip addresses on your system]'
297 ip = self.ip if self.ip else '[all ip addresses on your system]'
298 proto = 'https' if self.certfile else 'http'
298 proto = 'https' if self.certfile else 'http'
299 self.log.info("The IPython Notebook is running at: %s://%s:%i" % (proto,
299 self.log.info("The IPython Notebook is running at: %s://%s:%i" % (proto,
300 ip,
300 ip,
301 self.port))
301 self.port))
302 if self.open_browser:
302 if self.open_browser:
303 ip = self.ip or '127.0.0.1'
303 ip = self.ip or '127.0.0.1'
304 webbrowser.open("%s://%s:%i" % (proto, ip, self.port), new=2)
304 webbrowser.open("%s://%s:%i" % (proto, ip, self.port), new=2)
305 ioloop.IOLoop.instance().start()
305 ioloop.IOLoop.instance().start()
306
306
307 #-----------------------------------------------------------------------------
307 #-----------------------------------------------------------------------------
308 # Main entry point
308 # Main entry point
309 #-----------------------------------------------------------------------------
309 #-----------------------------------------------------------------------------
310
310
311 def launch_new_instance():
311 def launch_new_instance():
312 app = IPythonNotebookApp()
312 app = NotebookApp()
313 app.initialize()
313 app.initialize()
314 app.start()
314 app.start()
315
315
@@ -1,157 +1,157 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2011 The IPython Development Team
2 // Copyright (C) 2008-2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // SaveWidget
9 // SaveWidget
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 var utils = IPython.utils;
14 var utils = IPython.utils;
15
15
16 var SaveWidget = function (selector) {
16 var SaveWidget = function (selector) {
17 this.selector = selector;
17 this.selector = selector;
18 this.notebook_name_blacklist_re = /[\/\\]/
18 this.notebook_name_blacklist_re = /[\/\\]/
19 this.last_saved_name = '';
19 this.last_saved_name = '';
20 if (this.selector !== undefined) {
20 if (this.selector !== undefined) {
21 this.element = $(selector);
21 this.element = $(selector);
22 this.style();
22 this.style();
23 this.bind_events();
23 this.bind_events();
24 }
24 }
25 };
25 };
26
26
27
27
28 SaveWidget.prototype.style = function () {
28 SaveWidget.prototype.style = function () {
29 this.element.find('input#notebook_name').addClass('ui-widget ui-widget-content');
29 this.element.find('input#notebook_name').addClass('ui-widget ui-widget-content');
30 this.element.find('input#notebook_name').attr('tabindex','1');
30 this.element.find('input#notebook_name').attr('tabindex','1');
31 this.element.find('button#save_notebook').button();
31 this.element.find('button#save_notebook').button();
32 this.element.find('button#save_notebook').attr('title', 'Save the Notebook');
32 this.element.find('button#save_notebook').attr('title', 'Save the Notebook');
33 var left_panel_width = $('div#left_panel').outerWidth();
33 var left_panel_width = $('div#left_panel').outerWidth();
34 var left_panel_splitter_width = $('div#left_panel_splitter').outerWidth();
34 var left_panel_splitter_width = $('div#left_panel_splitter').outerWidth();
35 $('span#save_widget').css({marginLeft:left_panel_width+left_panel_splitter_width});
35 $('span#save_widget').css({marginLeft:left_panel_width+left_panel_splitter_width});
36
36
37 };
37 };
38
38
39
39
40 SaveWidget.prototype.bind_events = function () {
40 SaveWidget.prototype.bind_events = function () {
41 var that = this;
41 var that = this;
42 this.element.find('button#save_notebook').click(function () {
42 this.element.find('button#save_notebook').click(function () {
43 that.save_notebook();
43 that.save_notebook();
44 });
44 });
45 this.element.find('input#notebook_name').keyup(function () {
45 this.element.find('input#notebook_name').keyup(function () {
46 that.is_renaming();
46 that.is_renaming();
47 });
47 });
48 };
48 };
49
49
50
50
51 SaveWidget.prototype.save_notebook = function () {
51 SaveWidget.prototype.save_notebook = function () {
52 IPython.notebook.save_notebook();
52 IPython.notebook.save_notebook();
53 };
53 };
54
54
55
55
56 SaveWidget.prototype.notebook_saved = function () {
56 SaveWidget.prototype.notebook_saved = function () {
57 this.set_document_title();
57 this.set_document_title();
58 this.last_saved_name = this.get_notebook_name();
58 this.last_saved_name = this.get_notebook_name();
59 };
59 };
60
60
61
61
62 SaveWidget.prototype.is_renaming = function () {
62 SaveWidget.prototype.is_renaming = function () {
63 if (this.get_notebook_name() !== this.last_saved_name) {
63 if (this.get_notebook_name() !== this.last_saved_name) {
64 this.status_rename();
64 this.status_rename();
65 } else {
65 } else {
66 this.status_save();
66 this.status_save();
67 };
67 };
68 };
68 };
69
69
70
70
71 SaveWidget.prototype.get_notebook_name = function () {
71 SaveWidget.prototype.get_notebook_name = function () {
72 return this.element.find('input#notebook_name').attr('value');
72 return this.element.find('input#notebook_name').attr('value');
73 }
73 }
74
74
75
75
76 SaveWidget.prototype.set_notebook_name = function (nbname) {
76 SaveWidget.prototype.set_notebook_name = function (nbname) {
77 this.element.find('input#notebook_name').attr('value',nbname);
77 this.element.find('input#notebook_name').attr('value',nbname);
78 this.set_document_title();
78 this.set_document_title();
79 this.last_saved_name = nbname;
79 this.last_saved_name = nbname;
80 }
80 }
81
81
82
82
83 SaveWidget.prototype.set_document_title = function () {
83 SaveWidget.prototype.set_document_title = function () {
84 nbname = this.get_notebook_name();
84 nbname = this.get_notebook_name();
85 document.title = 'IPy: ' + nbname;
85 document.title = nbname;
86 };
86 };
87
87
88
88
89 SaveWidget.prototype.get_notebook_id = function () {
89 SaveWidget.prototype.get_notebook_id = function () {
90 return $('body').data('notebookId');
90 return $('body').data('notebookId');
91 };
91 };
92
92
93
93
94 SaveWidget.prototype.update_url = function () {
94 SaveWidget.prototype.update_url = function () {
95 var notebook_id = this.get_notebook_id();
95 var notebook_id = this.get_notebook_id();
96 if (notebook_id !== '') {
96 if (notebook_id !== '') {
97 window.history.replaceState({}, '', notebook_id);
97 window.history.replaceState({}, '', notebook_id);
98 };
98 };
99 };
99 };
100
100
101
101
102 SaveWidget.prototype.test_notebook_name = function () {
102 SaveWidget.prototype.test_notebook_name = function () {
103 var nbname = this.get_notebook_name();
103 var nbname = this.get_notebook_name();
104 if (this.notebook_name_blacklist_re.test(nbname) == false) {
104 if (this.notebook_name_blacklist_re.test(nbname) == false) {
105 return true;
105 return true;
106 } else {
106 } else {
107 var bad_name = $('<div/>');
107 var bad_name = $('<div/>');
108 bad_name.html(
108 bad_name.html(
109 "The notebook name you entered (" +
109 "The notebook name you entered (" +
110 nbname +
110 nbname +
111 ") is not valid. Notebook names can contain any characters except / and \\."
111 ") is not valid. Notebook names can contain any characters except / and \\."
112 );
112 );
113 bad_name.dialog({title: 'Invalid name', modal: true});
113 bad_name.dialog({title: 'Invalid name', modal: true});
114 return false;
114 return false;
115 };
115 };
116 };
116 };
117
117
118
118
119 SaveWidget.prototype.reset_status = function () {
119 SaveWidget.prototype.reset_status = function () {
120 this.is_renaming();
120 this.is_renaming();
121 };
121 };
122
122
123
123
124 SaveWidget.prototype.status_save = function () {
124 SaveWidget.prototype.status_save = function () {
125 this.element.find('button#save_notebook').button('option', 'label', '<u>S</u>ave');
125 this.element.find('button#save_notebook').button('option', 'label', '<u>S</u>ave');
126 this.element.find('button#save_notebook').button('enable');
126 this.element.find('button#save_notebook').button('enable');
127 IPython.print_widget.enable();
127 IPython.print_widget.enable();
128 };
128 };
129
129
130
130
131 SaveWidget.prototype.status_saving = function () {
131 SaveWidget.prototype.status_saving = function () {
132 this.element.find('button#save_notebook').button('option', 'label', 'Saving');
132 this.element.find('button#save_notebook').button('option', 'label', 'Saving');
133 this.element.find('button#save_notebook').button('disable');
133 this.element.find('button#save_notebook').button('disable');
134 IPython.print_widget.disable();
134 IPython.print_widget.disable();
135 };
135 };
136
136
137
137
138 SaveWidget.prototype.status_loading = function () {
138 SaveWidget.prototype.status_loading = function () {
139 this.element.find('button#save_notebook').button('option', 'label', 'Loading');
139 this.element.find('button#save_notebook').button('option', 'label', 'Loading');
140 this.element.find('button#save_notebook').button('disable');
140 this.element.find('button#save_notebook').button('disable');
141 IPython.print_widget.disable();
141 IPython.print_widget.disable();
142 };
142 };
143
143
144
144
145 SaveWidget.prototype.status_rename = function () {
145 SaveWidget.prototype.status_rename = function () {
146 this.element.find('button#save_notebook').button('option', 'label', 'Rename');
146 this.element.find('button#save_notebook').button('option', 'label', 'Rename');
147 this.element.find('button#save_notebook').button('enable');
147 this.element.find('button#save_notebook').button('enable');
148 IPython.print_widget.enable();
148 IPython.print_widget.enable();
149 };
149 };
150
150
151
151
152 IPython.SaveWidget = SaveWidget;
152 IPython.SaveWidget = SaveWidget;
153
153
154 return IPython;
154 return IPython;
155
155
156 }(IPython));
156 }(IPython));
157
157
@@ -1,65 +1,62 b''
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 <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/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
11 <!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
12
13 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
10 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
14 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
11 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
15 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
12 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
16 <script type="text/javascript" charset="utf-8">
13 <script type="text/javascript" charset="utf-8">
17 function add_next_to_action(){
14 function add_next_to_action(){
18 // add 'next' argument to action url, to preserve redirect
15 // add 'next' argument to action url, to preserve redirect
19 var query = location.search.substring(1);
16 var query = location.search.substring(1);
20 var form = document.forms[0];
17 var form = document.forms[0];
21 var action = form.getAttribute("action");
18 var action = form.getAttribute("action");
22 form.setAttribute("action", action + '?' + query);
19 form.setAttribute("action", action + '?' + query);
23 }
20 }
24 </script>
21 </script>
25 </head>
22 </head>
26
23
27 <body onload="add_next_to_action()">
24 <body onload="add_next_to_action()">
28
25
29 <div id="header">
26 <div id="header">
30 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
27 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
31 </div>
28 </div>
32
29
33 <div id="header_border"></div>
30 <div id="header_border"></div>
34
31
35 <div id="main_app">
32 <div id="main_app">
36
33
37 <div id="app_hbox">
34 <div id="app_hbox">
38
35
39 <div id="left_panel">
36 <div id="left_panel">
40 </div>
37 </div>
41
38
42 <div id="content_panel">
39 <div id="content_panel">
43 <form action="/login" method="post">
40 <form action="/login" method="post">
44 Password: <input type="password" name="password">
41 Password: <input type="password" name="password">
45 <input type="submit" value="Sign in">
42 <input type="submit" value="Sign in">
46 </form>
43 </form>
47 </div>
44 </div>
48 <div id="right_panel">
45 <div id="right_panel">
49 </div>
46 </div>
50
47
51 </div>
48 </div>
52
49
53 </div>
50 </div>
54
51
55 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
52 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
56 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
53 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
57 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
54 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
58 <script src="static/js/notebooklist.js" type="text/javascript" charset="utf-8"></script>
55 <script src="static/js/notebooklist.js" type="text/javascript" charset="utf-8"></script>
59 <script src="static/js/nbbrowser_main.js" type="text/javascript" charset="utf-8"></script>
56 <script src="static/js/nbbrowser_main.js" type="text/javascript" charset="utf-8"></script>
60
57
61 </body>
58 </body>
62
59
63 </html>
60 </html>
64
61
65
62
@@ -1,65 +1,62 b''
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 <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/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
11 <!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
12
13 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
10 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
14 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
11 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
15 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
12 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
16 <link rel="stylesheet" href="static/css/nbbrowser.css" type="text/css" />
13 <link rel="stylesheet" href="static/css/nbbrowser.css" type="text/css" />
17
14
18 </head>
15 </head>
19
16
20 <body data-base-project-url={{base_project_url}} data-base-kernel-url={{base_kernel_url}}>
17 <body data-base-project-url={{base_project_url}} data-base-kernel-url={{base_kernel_url}}>
21
18
22 <div id="header">
19 <div id="header">
23 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
20 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
24 </div>
21 </div>
25
22
26 <div id="header_border"></div>
23 <div id="header_border"></div>
27
24
28 <div id="main_app">
25 <div id="main_app">
29
26
30 <div id="app_hbox">
27 <div id="app_hbox">
31
28
32 <div id="left_panel">
29 <div id="left_panel">
33 </div>
30 </div>
34
31
35 <div id="content_panel">
32 <div id="content_panel">
36 <div id="content_toolbar">
33 <div id="content_toolbar">
37 <span id="drag_info">Drag files onto the list to import notebooks.</span>
34 <span id="drag_info">Drag files onto the list to import notebooks.</span>
38 <span id="notebooks_buttons">
35 <span id="notebooks_buttons">
39 <button id="new_notebook">New Notebook</button>
36 <button id="new_notebook">New Notebook</button>
40 </span>
37 </span>
41 </div>
38 </div>
42 <div id="notebook_list">
39 <div id="notebook_list">
43 <div id="project_name"><h2>{{project}}</h2></div>
40 <div id="project_name"><h2>{{project}}</h2></div>
44 </div>
41 </div>
45
42
46 </div>
43 </div>
47
44
48 <div id="right_panel">
45 <div id="right_panel">
49 </div>
46 </div>
50
47
51 </div>
48 </div>
52
49
53 </div>
50 </div>
54
51
55 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
52 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
56 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
53 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
57 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
54 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
58 <script src="static/js/notebooklist.js" type="text/javascript" charset="utf-8"></script>
55 <script src="static/js/notebooklist.js" type="text/javascript" charset="utf-8"></script>
59 <script src="static/js/nbbrowser_main.js" type="text/javascript" charset="utf-8"></script>
56 <script src="static/js/nbbrowser_main.js" type="text/javascript" charset="utf-8"></script>
60
57
61 </body>
58 </body>
62
59
63 </html>
60 </html>
64
61
65
62
@@ -1,280 +1,277 b''
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 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
10 <!-- <link rel="stylesheet" href="static/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
11 <!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
12
13 <!-- <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" charset="utf-8"></script> -->
9 <!-- <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" charset="utf-8"></script> -->
14 <script type='text/javascript' src='static/mathjax/MathJax.js?config=TeX-AMS_HTML' charset='utf-8'></script>
10 <script type='text/javascript' src='static/mathjax/MathJax.js?config=TeX-AMS_HTML' charset='utf-8'></script>
15 <script type="text/javascript">
11 <script type="text/javascript">
16 function CheckMathJax(){
12 function CheckMathJax(){
17 var div=document.getElementById("MathJaxFetchingWarning")
13 var div=document.getElementById("MathJaxFetchingWarning")
18 if(window.MathJax){
14 if(window.MathJax){
19 document.body.removeChild(div)
15 document.body.removeChild(div)
20 }
16 }
21 else{
17 else{
22 div.style.display = "block";
18 div.style.display = "block";
23 }
19 }
24 }
20 }
25 if (typeof MathJax == 'undefined') {
21 if (typeof MathJax == 'undefined') {
26 console.log("No local MathJax, loading from CDN");
22 console.log("No local MathJax, loading from CDN");
27 document.write(unescape("%3Cscript type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js%3Fconfig=TeX-AMS_HTML' charset='utf-8'%3E%3C/script%3E"));
23 document.write(unescape("%3Cscript type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js%3Fconfig=TeX-AMS_HTML' charset='utf-8'%3E%3C/script%3E"));
28 }else{
24 }else{
29 console.log("Using local MathJax");
25 console.log("Using local MathJax");
30 }
26 }
31 </script>
27 </script>
32
28
29 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
33 <link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
30 <link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
34 <link rel="stylesheet" href="static/codemirror/mode/markdown/markdown.css">
31 <link rel="stylesheet" href="static/codemirror/mode/markdown/markdown.css">
35 <link rel="stylesheet" href="static/codemirror/mode/rst/rst.css">
32 <link rel="stylesheet" href="static/codemirror/mode/rst/rst.css">
36 <link rel="stylesheet" href="static/codemirror/theme/ipython.css">
33 <link rel="stylesheet" href="static/codemirror/theme/ipython.css">
37 <link rel="stylesheet" href="static/codemirror/theme/default.css">
34 <link rel="stylesheet" href="static/codemirror/theme/default.css">
38
35
39 <link rel="stylesheet" href="static/prettify/prettify.css"/>
36 <link rel="stylesheet" href="static/prettify/prettify.css"/>
40
37
41 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
38 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
42 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
39 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
43 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
40 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
44 <link rel="stylesheet" href="static/css/notebook.css" type="text/css" />
41 <link rel="stylesheet" href="static/css/notebook.css" type="text/css" />
45 <link rel="stylesheet" href="static/css/renderedhtml.css" type="text/css" />
42 <link rel="stylesheet" href="static/css/renderedhtml.css" type="text/css" />
46
43
47
44
48 </head>
45 </head>
49
46
50 <body data-base-project-url={{base_project_url}} data-base-kernel-url={{base_kernel_url}}
47 <body data-base-project-url={{base_project_url}} data-base-kernel-url={{base_kernel_url}}
51 data-notebook-id={{notebook_id}} onload='CheckMathJax();'>
48 data-notebook-id={{notebook_id}} onload='CheckMathJax();'>
52
49
53 <div id="header">
50 <div id="header">
54 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
51 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
55 <span id="save_widget">
52 <span id="save_widget">
56 <input type="text" id="notebook_name" size="20"></textarea>
53 <input type="text" id="notebook_name" size="20"></textarea>
57 <button id="save_notebook"><u>S</u>ave</button>
54 <button id="save_notebook"><u>S</u>ave</button>
58 </span>
55 </span>
59 <span id="quick_help_area">
56 <span id="quick_help_area">
60 <button id="quick_help">Quick<u>H</u>elp</button>
57 <button id="quick_help">Quick<u>H</u>elp</button>
61 </span>
58 </span>
62 <span id="kernel_status">Idle</span>
59 <span id="kernel_status">Idle</span>
63 </div>
60 </div>
64
61
65 <div id="MathJaxFetchingWarning"
62 <div id="MathJaxFetchingWarning"
66 style="width:80%; margin:auto;padding-top:20%;text-align: justify; display:none">
63 style="width:80%; margin:auto;padding-top:20%;text-align: justify; display:none">
67 <p style="font-size:26px;">There was an issue trying to fetch MathJax.js
64 <p style="font-size:26px;">There was an issue trying to fetch MathJax.js
68 from the internet.</p>
65 from the internet.</p>
69
66
70 <p style="padding:0.2em"> With a working internet connection, you can run
67 <p style="padding:0.2em"> With a working internet connection, you can run
71 the following at a Python or IPython prompt, which will install a local
68 the following at a Python or IPython prompt, which will install a local
72 copy of MathJax:</p>
69 copy of MathJax:</p>
73
70
74 <pre style="background-color:lightblue;border:thin silver solid;padding:0.4em">
71 <pre style="background-color:lightblue;border:thin silver solid;padding:0.4em">
75 from IPython.external import mathjax; mathjax.install_mathjax()
72 from IPython.external import mathjax; mathjax.install_mathjax()
76 </pre>
73 </pre>
77 This will try to install MathJax into the directory where you installed
74 This will try to install MathJax into the directory where you installed
78 IPython. If you installed IPython to a location that requires
75 IPython. If you installed IPython to a location that requires
79 administrative privileges to write, you will need to make this call as
76 administrative privileges to write, you will need to make this call as
80 an administrator. On OSX/Linux/Unix, this can be done at the
77 an administrator. On OSX/Linux/Unix, this can be done at the
81 command-line via:
78 command-line via:
82 <pre style="background-color:lightblue;border:thin silver solid;padding:0.4em">
79 <pre style="background-color:lightblue;border:thin silver solid;padding:0.4em">
83 sudo python -c "from IPython.external import mathjax; mathjax.install_mathjax()"
80 sudo python -c "from IPython.external import mathjax; mathjax.install_mathjax()"
84 </pre>
81 </pre>
85 </p>
82 </p>
86 </div>
83 </div>
87
84
88 <div id="main_app">
85 <div id="main_app">
89
86
90 <div id="left_panel">
87 <div id="left_panel">
91
88
92 <div id="notebook_section">
89 <div id="notebook_section">
93 <h3 class="section_header">Notebook</h3>
90 <h3 class="section_header">Notebook</h3>
94 <div class="section_content">
91 <div class="section_content">
95 <div class="section_row">
92 <div class="section_row">
96 <span id="new_open" class="section_row_buttons">
93 <span id="new_open" class="section_row_buttons">
97 <button id="new_notebook">New</button>
94 <button id="new_notebook">New</button>
98 <button id="open_notebook">Open</button>
95 <button id="open_notebook">Open</button>
99 </span>
96 </span>
100 <span class="section_row_header">Actions</span>
97 <span class="section_row_header">Actions</span>
101 </div>
98 </div>
102 <div class="section_row">
99 <div class="section_row">
103 <span>
100 <span>
104 <select id="download_format">
101 <select id="download_format">
105 <option value="json">ipynb</option>
102 <option value="json">ipynb</option>
106 <option value="py">py</option>
103 <option value="py">py</option>
107 </select>
104 </select>
108 </span>
105 </span>
109 <span class="section_row_buttons">
106 <span class="section_row_buttons">
110 <button id="download_notebook">Download</button>
107 <button id="download_notebook">Download</button>
111 </span>
108 </span>
112 </div>
109 </div>
113 <div class="section_row">
110 <div class="section_row">
114 <span class="section_row_buttons">
111 <span class="section_row_buttons">
115 <span id="print_widget">
112 <span id="print_widget">
116 <button id="print_notebook">Print</button>
113 <button id="print_notebook">Print</button>
117 </span>
114 </span>
118 </span>
115 </span>
119 </div>
116 </div>
120 </div>
117 </div>
121 </div>
118 </div>
122
119
123 <div id="cell_section">
120 <div id="cell_section">
124 <h3 class="section_header">Cell</h3>
121 <h3 class="section_header">Cell</h3>
125 <div class="section_content">
122 <div class="section_content">
126 <div class="section_row">
123 <div class="section_row">
127 <span class="section_row_buttons">
124 <span class="section_row_buttons">
128 <button id="delete_cell"><u>D</u>elete</button>
125 <button id="delete_cell"><u>D</u>elete</button>
129 </span>
126 </span>
130 <span class="section_row_header">Actions</span>
127 <span class="section_row_header">Actions</span>
131 </div>
128 </div>
132 <div class="section_row">
129 <div class="section_row">
133 <span id="cell_type" class="section_row_buttons">
130 <span id="cell_type" class="section_row_buttons">
134 <button id="to_code"><u>C</u>ode</button>
131 <button id="to_code"><u>C</u>ode</button>
135 <!-- <button id="to_html">HTML</button>-->
132 <!-- <button id="to_html">HTML</button>-->
136 <button id="to_markdown"><u>M</u>arkdown</button>
133 <button id="to_markdown"><u>M</u>arkdown</button>
137 </span>
134 </span>
138 <span class="button_label">Format</span>
135 <span class="button_label">Format</span>
139 </div>
136 </div>
140 <div class="section_row">
137 <div class="section_row">
141 <span id="cell_output" class="section_row_buttons">
138 <span id="cell_output" class="section_row_buttons">
142 <button id="toggle_output"><u>T</u>oggle</button>
139 <button id="toggle_output"><u>T</u>oggle</button>
143 <button id="clear_all_output">ClearAll</button>
140 <button id="clear_all_output">ClearAll</button>
144 </span>
141 </span>
145 <span class="button_label">Output</span>
142 <span class="button_label">Output</span>
146 </div>
143 </div>
147 <div class="section_row">
144 <div class="section_row">
148 <span id="insert" class="section_row_buttons">
145 <span id="insert" class="section_row_buttons">
149 <button id="insert_cell_above"><u>A</u>bove</button>
146 <button id="insert_cell_above"><u>A</u>bove</button>
150 <button id="insert_cell_below"><u>B</u>elow</button>
147 <button id="insert_cell_below"><u>B</u>elow</button>
151 </span>
148 </span>
152 <span class="button_label">Insert</span>
149 <span class="button_label">Insert</span>
153 </div>
150 </div>
154 <div class="section_row">
151 <div class="section_row">
155 <span id="move" class="section_row_buttons">
152 <span id="move" class="section_row_buttons">
156 <button id="move_cell_up">Up</button>
153 <button id="move_cell_up">Up</button>
157 <button id="move_cell_down">Down</button>
154 <button id="move_cell_down">Down</button>
158 </span>
155 </span>
159 <span class="button_label">Move</span>
156 <span class="button_label">Move</span>
160 </div>
157 </div>
161 <div class="section_row">
158 <div class="section_row">
162 <span id="run_cells" class="section_row_buttons">
159 <span id="run_cells" class="section_row_buttons">
163 <button id="run_selected_cell">Selected</button>
160 <button id="run_selected_cell">Selected</button>
164 <button id="run_all_cells">All</button>
161 <button id="run_all_cells">All</button>
165 </span>
162 </span>
166 <span class="button_label">Run</span>
163 <span class="button_label">Run</span>
167 </div>
164 </div>
168 <div class="section_row">
165 <div class="section_row">
169 <span id="autoindent_span">
166 <span id="autoindent_span">
170 <input type="checkbox" id="autoindent" checked="true"></input>
167 <input type="checkbox" id="autoindent" checked="true"></input>
171 </span>
168 </span>
172 <span class="checkbox_label" id="autoindent_label">Autoindent:</span>
169 <span class="checkbox_label" id="autoindent_label">Autoindent:</span>
173 </div>
170 </div>
174 </div>
171 </div>
175 </div>
172 </div>
176
173
177 <div id="kernel_section">
174 <div id="kernel_section">
178 <h3 class="section_header">Kernel</h3>
175 <h3 class="section_header">Kernel</h3>
179 <div class="section_content">
176 <div class="section_content">
180 <div class="section_row">
177 <div class="section_row">
181 <span id="int_restart" class="section_row_buttons">
178 <span id="int_restart" class="section_row_buttons">
182 <button id="int_kernel"><u>I</u>nterrupt</button>
179 <button id="int_kernel"><u>I</u>nterrupt</button>
183 <button id="restart_kernel">Restart</button>
180 <button id="restart_kernel">Restart</button>
184 </span>
181 </span>
185 <span class="section_row_header">Actions</span>
182 <span class="section_row_header">Actions</span>
186 </div>
183 </div>
187 <div class="section_row">
184 <div class="section_row">
188 <span id="kernel_persist">
185 <span id="kernel_persist">
189 <input type="checkbox" id="kill_kernel"></input>
186 <input type="checkbox" id="kill_kernel"></input>
190 </span>
187 </span>
191 <span class="checkbox_label" id="kill_kernel_label">Kill kernel upon exit:</span>
188 <span class="checkbox_label" id="kill_kernel_label">Kill kernel upon exit:</span>
192 </div>
189 </div>
193 </div>
190 </div>
194 </div>
191 </div>
195
192
196 <div id="help_section">
193 <div id="help_section">
197 <h3 class="section_header">Help</h3>
194 <h3 class="section_header">Help</h3>
198 <div class="section_content">
195 <div class="section_content">
199 <div class="section_row">
196 <div class="section_row">
200 <span id="help_buttons0" class="section_row_buttons">
197 <span id="help_buttons0" class="section_row_buttons">
201 <a id="python_help" href="http://docs.python.org" target="_blank">Python</a>
198 <a id="python_help" href="http://docs.python.org" target="_blank">Python</a>
202 <a id="ipython_help" href="http://ipython.org/documentation.html" target="_blank">IPython</a>
199 <a id="ipython_help" href="http://ipython.org/documentation.html" target="_blank">IPython</a>
203 </span>
200 </span>
204 <span class="section_row_header">Links</span>
201 <span class="section_row_header">Links</span>
205 </div>
202 </div>
206 <div class="section_row">
203 <div class="section_row">
207 <span id="help_buttons1" class="section_row_buttons">
204 <span id="help_buttons1" class="section_row_buttons">
208 <a id="numpy_help" href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a>
205 <a id="numpy_help" href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a>
209 <a id="scipy_help" href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a>
206 <a id="scipy_help" href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a>
210 </span>
207 </span>
211 </div>
208 </div>
212 <div class="section_row">
209 <div class="section_row">
213 <span id="help_buttons2" class="section_row_buttons">
210 <span id="help_buttons2" class="section_row_buttons">
214 <a id="matplotlib_help" href="http://matplotlib.sourceforge.net/" target="_blank">MPL</a>
211 <a id="matplotlib_help" href="http://matplotlib.sourceforge.net/" target="_blank">MPL</a>
215 <a id="sympy_help" href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a>
212 <a id="sympy_help" href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a>
216 </span>
213 </span>
217 </div>
214 </div>
218 <div class="section_row">
215 <div class="section_row">
219 <span class="help_string">run selected cell</span>
216 <span class="help_string">run selected cell</span>
220 <span class="help_string_label">Shift-Enter :</span>
217 <span class="help_string_label">Shift-Enter :</span>
221 </div>
218 </div>
222 <div class="section_row">
219 <div class="section_row">
223 <span class="help_string">run selected cell in-place</span>
220 <span class="help_string">run selected cell in-place</span>
224 <span class="help_string_label">Ctrl-Enter :</span>
221 <span class="help_string_label">Ctrl-Enter :</span>
225 </div>
222 </div>
226 <div class="section_row">
223 <div class="section_row">
227 <span class="help_string">show keyboard shortcuts</span>
224 <span class="help_string">show keyboard shortcuts</span>
228 <span class="help_string_label">Ctrl-m h :</span>
225 <span class="help_string_label">Ctrl-m h :</span>
229 </div>
226 </div>
230 </div>
227 </div>
231 </div>
228 </div>
232
229
233 </div>
230 </div>
234 <div id="left_panel_splitter"></div>
231 <div id="left_panel_splitter"></div>
235 <div id="notebook_panel">
232 <div id="notebook_panel">
236 <div id="notebook"></div>
233 <div id="notebook"></div>
237 <div id="pager_splitter"></div>
234 <div id="pager_splitter"></div>
238 <div id="pager"></div>
235 <div id="pager"></div>
239 </div>
236 </div>
240
237
241 </div>
238 </div>
242
239
243 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
240 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
244 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
241 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
245 <script src="static/jquery/js/jquery.autogrow.js" type="text/javascript" charset="utf-8"></script>
242 <script src="static/jquery/js/jquery.autogrow.js" type="text/javascript" charset="utf-8"></script>
246
243
247 <script src="static/codemirror/lib/codemirror.js" charset="utf-8"></script>
244 <script src="static/codemirror/lib/codemirror.js" charset="utf-8"></script>
248 <script src="static/codemirror/mode/python/python.js" charset="utf-8"></script>
245 <script src="static/codemirror/mode/python/python.js" charset="utf-8"></script>
249 <script src="static/codemirror/mode/htmlmixed/htmlmixed.js" charset="utf-8"></script>
246 <script src="static/codemirror/mode/htmlmixed/htmlmixed.js" charset="utf-8"></script>
250 <script src="static/codemirror/mode/xml/xml.js" charset="utf-8"></script>
247 <script src="static/codemirror/mode/xml/xml.js" charset="utf-8"></script>
251 <script src="static/codemirror/mode/javascript/javascript.js" charset="utf-8"></script>
248 <script src="static/codemirror/mode/javascript/javascript.js" charset="utf-8"></script>
252 <script src="static/codemirror/mode/css/css.js" charset="utf-8"></script>
249 <script src="static/codemirror/mode/css/css.js" charset="utf-8"></script>
253 <script src="static/codemirror/mode/rst/rst.js" charset="utf-8"></script>
250 <script src="static/codemirror/mode/rst/rst.js" charset="utf-8"></script>
254 <script src="static/codemirror/mode/markdown/markdown.js" charset="utf-8"></script>
251 <script src="static/codemirror/mode/markdown/markdown.js" charset="utf-8"></script>
255
252
256 <script src="static/pagedown/Markdown.Converter.js" charset="utf-8"></script>
253 <script src="static/pagedown/Markdown.Converter.js" charset="utf-8"></script>
257
254
258 <script src="static/prettify/prettify.js" charset="utf-8"></script>
255 <script src="static/prettify/prettify.js" charset="utf-8"></script>
259
256
260 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
257 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
261 <script src="static/js/utils.js" type="text/javascript" charset="utf-8"></script>
258 <script src="static/js/utils.js" type="text/javascript" charset="utf-8"></script>
262 <script src="static/js/cell.js" type="text/javascript" charset="utf-8"></script>
259 <script src="static/js/cell.js" type="text/javascript" charset="utf-8"></script>
263 <script src="static/js/codecell.js" type="text/javascript" charset="utf-8"></script>
260 <script src="static/js/codecell.js" type="text/javascript" charset="utf-8"></script>
264 <script src="static/js/textcell.js" type="text/javascript" charset="utf-8"></script>
261 <script src="static/js/textcell.js" type="text/javascript" charset="utf-8"></script>
265 <script src="static/js/kernel.js" type="text/javascript" charset="utf-8"></script>
262 <script src="static/js/kernel.js" type="text/javascript" charset="utf-8"></script>
266 <script src="static/js/kernelstatus.js" type="text/javascript" charset="utf-8"></script>
263 <script src="static/js/kernelstatus.js" type="text/javascript" charset="utf-8"></script>
267 <script src="static/js/layout.js" type="text/javascript" charset="utf-8"></script>
264 <script src="static/js/layout.js" type="text/javascript" charset="utf-8"></script>
268 <script src="static/js/savewidget.js" type="text/javascript" charset="utf-8"></script>
265 <script src="static/js/savewidget.js" type="text/javascript" charset="utf-8"></script>
269 <script src="static/js/quickhelp.js" type="text/javascript" charset="utf-8"></script>
266 <script src="static/js/quickhelp.js" type="text/javascript" charset="utf-8"></script>
270 <script src="static/js/pager.js" type="text/javascript" charset="utf-8"></script>
267 <script src="static/js/pager.js" type="text/javascript" charset="utf-8"></script>
271 <script src="static/js/panelsection.js" type="text/javascript" charset="utf-8"></script>
268 <script src="static/js/panelsection.js" type="text/javascript" charset="utf-8"></script>
272 <script src="static/js/printwidget.js" type="text/javascript" charset="utf-8"></script>
269 <script src="static/js/printwidget.js" type="text/javascript" charset="utf-8"></script>
273 <script src="static/js/leftpanel.js" type="text/javascript" charset="utf-8"></script>
270 <script src="static/js/leftpanel.js" type="text/javascript" charset="utf-8"></script>
274 <script src="static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
271 <script src="static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
275 <script src="static/js/notebook_main.js" type="text/javascript" charset="utf-8"></script>
272 <script src="static/js/notebook_main.js" type="text/javascript" charset="utf-8"></script>
276
273
277
274
278 </body>
275 </body>
279
276
280 </html>
277 </html>
@@ -1,395 +1,395 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 The :class:`~IPython.core.application.Application` object for the command
4 The :class:`~IPython.core.application.Application` object for the command
5 line :command:`ipython` program.
5 line :command:`ipython` program.
6
6
7 Authors
7 Authors
8 -------
8 -------
9
9
10 * Brian Granger
10 * Brian Granger
11 * Fernando Perez
11 * Fernando Perez
12 * Min Ragan-Kelley
12 * Min Ragan-Kelley
13 """
13 """
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2010 The IPython Development Team
16 # Copyright (C) 2008-2010 The IPython Development Team
17 #
17 #
18 # Distributed under the terms of the BSD License. The full license is in
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Imports
23 # Imports
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 from __future__ import absolute_import
26 from __future__ import absolute_import
27
27
28 import logging
28 import logging
29 import os
29 import os
30 import sys
30 import sys
31
31
32 from IPython.config.loader import (
32 from IPython.config.loader import (
33 Config, PyFileConfigLoader, ConfigFileNotFound
33 Config, PyFileConfigLoader, ConfigFileNotFound
34 )
34 )
35 from IPython.config.application import boolean_flag
35 from IPython.config.application import boolean_flag
36 from IPython.core import release
36 from IPython.core import release
37 from IPython.core import usage
37 from IPython.core import usage
38 from IPython.core.completer import Completer
38 from IPython.core.completer import Completer
39 from IPython.core.crashhandler import CrashHandler
39 from IPython.core.crashhandler import CrashHandler
40 from IPython.core.formatters import PlainTextFormatter
40 from IPython.core.formatters import PlainTextFormatter
41 from IPython.core.application import (
41 from IPython.core.application import (
42 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
42 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
43 )
43 )
44 from IPython.core.shellapp import (
44 from IPython.core.shellapp import (
45 InteractiveShellApp, shell_flags, shell_aliases
45 InteractiveShellApp, shell_flags, shell_aliases
46 )
46 )
47 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
47 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
48 from IPython.lib import inputhook
48 from IPython.lib import inputhook
49 from IPython.utils import warn
49 from IPython.utils import warn
50 from IPython.utils.path import get_ipython_dir, check_for_old_config
50 from IPython.utils.path import get_ipython_dir, check_for_old_config
51 from IPython.utils.traitlets import (
51 from IPython.utils.traitlets import (
52 Bool, List, Dict, CaselessStrEnum
52 Bool, List, Dict, CaselessStrEnum
53 )
53 )
54
54
55 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
56 # Globals, utilities and helpers
56 # Globals, utilities and helpers
57 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
58
58
59 #: The default config file name for this application.
59 #: The default config file name for this application.
60 default_config_file_name = u'ipython_config.py'
60 default_config_file_name = u'ipython_config.py'
61
61
62 _examples = """
62 _examples = """
63 ipython --pylab # start in pylab mode
63 ipython --pylab # start in pylab mode
64 ipython --pylab=qt # start in pylab mode with the qt4 backend
64 ipython --pylab=qt # start in pylab mode with the qt4 backend
65 ipython --log-level=DEBUG # set logging to DEBUG
65 ipython --log-level=DEBUG # set logging to DEBUG
66 ipython --profile=foo # start with profile foo
66 ipython --profile=foo # start with profile foo
67
67
68 ipython qtconsole # start the qtconsole GUI application
68 ipython qtconsole # start the qtconsole GUI application
69 ipython qtconsole -h # show the help string for the qtconsole subcmd
69 ipython qtconsole -h # show the help string for the qtconsole subcmd
70
70
71 ipython profile create foo # create profile foo w/ default config files
71 ipython profile create foo # create profile foo w/ default config files
72 ipython profile -h # show the help string for the profile subcmd
72 ipython profile -h # show the help string for the profile subcmd
73 """
73 """
74
74
75 #-----------------------------------------------------------------------------
75 #-----------------------------------------------------------------------------
76 # Crash handler for this application
76 # Crash handler for this application
77 #-----------------------------------------------------------------------------
77 #-----------------------------------------------------------------------------
78
78
79 class IPAppCrashHandler(CrashHandler):
79 class IPAppCrashHandler(CrashHandler):
80 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
80 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
81
81
82 def __init__(self, app):
82 def __init__(self, app):
83 contact_name = release.authors['Fernando'][0]
83 contact_name = release.authors['Fernando'][0]
84 contact_email = release.authors['Fernando'][1]
84 contact_email = release.authors['Fernando'][1]
85 bug_tracker = 'http://github.com/ipython/ipython/issues'
85 bug_tracker = 'http://github.com/ipython/ipython/issues'
86 super(IPAppCrashHandler,self).__init__(
86 super(IPAppCrashHandler,self).__init__(
87 app, contact_name, contact_email, bug_tracker
87 app, contact_name, contact_email, bug_tracker
88 )
88 )
89
89
90 def make_report(self,traceback):
90 def make_report(self,traceback):
91 """Return a string containing a crash report."""
91 """Return a string containing a crash report."""
92
92
93 sec_sep = self.section_sep
93 sec_sep = self.section_sep
94 # Start with parent report
94 # Start with parent report
95 report = [super(IPAppCrashHandler, self).make_report(traceback)]
95 report = [super(IPAppCrashHandler, self).make_report(traceback)]
96 # Add interactive-specific info we may have
96 # Add interactive-specific info we may have
97 rpt_add = report.append
97 rpt_add = report.append
98 try:
98 try:
99 rpt_add(sec_sep+"History of session input:")
99 rpt_add(sec_sep+"History of session input:")
100 for line in self.app.shell.user_ns['_ih']:
100 for line in self.app.shell.user_ns['_ih']:
101 rpt_add(line)
101 rpt_add(line)
102 rpt_add('\n*** Last line of input (may not be in above history):\n')
102 rpt_add('\n*** Last line of input (may not be in above history):\n')
103 rpt_add(self.app.shell._last_input_line+'\n')
103 rpt_add(self.app.shell._last_input_line+'\n')
104 except:
104 except:
105 pass
105 pass
106
106
107 return ''.join(report)
107 return ''.join(report)
108
108
109 #-----------------------------------------------------------------------------
109 #-----------------------------------------------------------------------------
110 # Aliases and Flags
110 # Aliases and Flags
111 #-----------------------------------------------------------------------------
111 #-----------------------------------------------------------------------------
112 flags = dict(base_flags)
112 flags = dict(base_flags)
113 flags.update(shell_flags)
113 flags.update(shell_flags)
114 addflag = lambda *args: flags.update(boolean_flag(*args))
114 addflag = lambda *args: flags.update(boolean_flag(*args))
115 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
115 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
116 'Turn on auto editing of files with syntax errors.',
116 'Turn on auto editing of files with syntax errors.',
117 'Turn off auto editing of files with syntax errors.'
117 'Turn off auto editing of files with syntax errors.'
118 )
118 )
119 addflag('banner', 'TerminalIPythonApp.display_banner',
119 addflag('banner', 'TerminalIPythonApp.display_banner',
120 "Display a banner upon starting IPython.",
120 "Display a banner upon starting IPython.",
121 "Don't display a banner upon starting IPython."
121 "Don't display a banner upon starting IPython."
122 )
122 )
123 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
123 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
124 """Set to confirm when you try to exit IPython with an EOF (Control-D
124 """Set to confirm when you try to exit IPython with an EOF (Control-D
125 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
125 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
126 you can force a direct exit without any confirmation.""",
126 you can force a direct exit without any confirmation.""",
127 "Don't prompt the user when exiting."
127 "Don't prompt the user when exiting."
128 )
128 )
129 addflag('term-title', 'TerminalInteractiveShell.term_title',
129 addflag('term-title', 'TerminalInteractiveShell.term_title',
130 "Enable auto setting the terminal title.",
130 "Enable auto setting the terminal title.",
131 "Disable auto setting the terminal title."
131 "Disable auto setting the terminal title."
132 )
132 )
133 classic_config = Config()
133 classic_config = Config()
134 classic_config.InteractiveShell.cache_size = 0
134 classic_config.InteractiveShell.cache_size = 0
135 classic_config.PlainTextFormatter.pprint = False
135 classic_config.PlainTextFormatter.pprint = False
136 classic_config.InteractiveShell.prompt_in1 = '>>> '
136 classic_config.InteractiveShell.prompt_in1 = '>>> '
137 classic_config.InteractiveShell.prompt_in2 = '... '
137 classic_config.InteractiveShell.prompt_in2 = '... '
138 classic_config.InteractiveShell.prompt_out = ''
138 classic_config.InteractiveShell.prompt_out = ''
139 classic_config.InteractiveShell.separate_in = ''
139 classic_config.InteractiveShell.separate_in = ''
140 classic_config.InteractiveShell.separate_out = ''
140 classic_config.InteractiveShell.separate_out = ''
141 classic_config.InteractiveShell.separate_out2 = ''
141 classic_config.InteractiveShell.separate_out2 = ''
142 classic_config.InteractiveShell.colors = 'NoColor'
142 classic_config.InteractiveShell.colors = 'NoColor'
143 classic_config.InteractiveShell.xmode = 'Plain'
143 classic_config.InteractiveShell.xmode = 'Plain'
144
144
145 flags['classic']=(
145 flags['classic']=(
146 classic_config,
146 classic_config,
147 "Gives IPython a similar feel to the classic Python prompt."
147 "Gives IPython a similar feel to the classic Python prompt."
148 )
148 )
149 # # log doesn't make so much sense this way anymore
149 # # log doesn't make so much sense this way anymore
150 # paa('--log','-l',
150 # paa('--log','-l',
151 # action='store_true', dest='InteractiveShell.logstart',
151 # action='store_true', dest='InteractiveShell.logstart',
152 # help="Start logging to the default log file (./ipython_log.py).")
152 # help="Start logging to the default log file (./ipython_log.py).")
153 #
153 #
154 # # quick is harder to implement
154 # # quick is harder to implement
155 flags['quick']=(
155 flags['quick']=(
156 {'TerminalIPythonApp' : {'quick' : True}},
156 {'TerminalIPythonApp' : {'quick' : True}},
157 "Enable quick startup with no config files."
157 "Enable quick startup with no config files."
158 )
158 )
159
159
160 flags['i'] = (
160 flags['i'] = (
161 {'TerminalIPythonApp' : {'force_interact' : True}},
161 {'TerminalIPythonApp' : {'force_interact' : True}},
162 """If running code from the command line, become interactive afterwards.
162 """If running code from the command line, become interactive afterwards.
163 Note: can also be given simply as '-i.'"""
163 Note: can also be given simply as '-i.'"""
164 )
164 )
165 flags['pylab'] = (
165 flags['pylab'] = (
166 {'TerminalIPythonApp' : {'pylab' : 'auto'}},
166 {'TerminalIPythonApp' : {'pylab' : 'auto'}},
167 """Pre-load matplotlib and numpy for interactive use with
167 """Pre-load matplotlib and numpy for interactive use with
168 the default matplotlib backend."""
168 the default matplotlib backend."""
169 )
169 )
170
170
171 aliases = dict(base_aliases)
171 aliases = dict(base_aliases)
172 aliases.update(shell_aliases)
172 aliases.update(shell_aliases)
173
173
174 # it's possible we don't want short aliases for *all* of these:
174 # it's possible we don't want short aliases for *all* of these:
175 aliases.update(dict(
175 aliases.update(dict(
176 gui='TerminalIPythonApp.gui',
176 gui='TerminalIPythonApp.gui',
177 pylab='TerminalIPythonApp.pylab',
177 pylab='TerminalIPythonApp.pylab',
178 ))
178 ))
179
179
180 #-----------------------------------------------------------------------------
180 #-----------------------------------------------------------------------------
181 # Main classes and functions
181 # Main classes and functions
182 #-----------------------------------------------------------------------------
182 #-----------------------------------------------------------------------------
183
183
184 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
184 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
185 name = u'ipython'
185 name = u'ipython'
186 description = usage.cl_usage
186 description = usage.cl_usage
187 default_config_file_name = default_config_file_name
187 default_config_file_name = default_config_file_name
188 crash_handler_class = IPAppCrashHandler
188 crash_handler_class = IPAppCrashHandler
189 examples = _examples
189 examples = _examples
190
190
191 flags = Dict(flags)
191 flags = Dict(flags)
192 aliases = Dict(aliases)
192 aliases = Dict(aliases)
193 classes = List()
193 classes = List()
194 def _classes_default(self):
194 def _classes_default(self):
195 """This has to be in a method, for TerminalIPythonApp to be available."""
195 """This has to be in a method, for TerminalIPythonApp to be available."""
196 return [
196 return [
197 InteractiveShellApp, # ShellApp comes before TerminalApp, because
197 InteractiveShellApp, # ShellApp comes before TerminalApp, because
198 self.__class__, # it will also affect subclasses (e.g. QtConsole)
198 self.__class__, # it will also affect subclasses (e.g. QtConsole)
199 TerminalInteractiveShell,
199 TerminalInteractiveShell,
200 ProfileDir,
200 ProfileDir,
201 PlainTextFormatter,
201 PlainTextFormatter,
202 Completer,
202 Completer,
203 ]
203 ]
204
204
205 subcommands = Dict(dict(
205 subcommands = Dict(dict(
206 qtconsole=('IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp',
206 qtconsole=('IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp',
207 """Launch the IPython Qt Console."""
207 """Launch the IPython Qt Console."""
208 ),
208 ),
209 notebook=('IPython.frontend.html.notebook.notebookapp.IPythonNotebookApp',
209 notebook=('IPython.frontend.html.notebook.notebookapp.NotebookApp',
210 """Launch the IPython HTML Notebook Server"""
210 """Launch the IPython HTML Notebook Server"""
211 ),
211 ),
212 profile = ("IPython.core.profileapp.ProfileApp",
212 profile = ("IPython.core.profileapp.ProfileApp",
213 "Create and manage IPython profiles."
213 "Create and manage IPython profiles."
214 ),
214 ),
215 kernel = ("IPython.zmq.ipkernel.IPKernelApp",
215 kernel = ("IPython.zmq.ipkernel.IPKernelApp",
216 "Start a kernel without an attached frontend."
216 "Start a kernel without an attached frontend."
217 ),
217 ),
218 ))
218 ))
219
219
220 # *do* autocreate requested profile, but don't create the config file.
220 # *do* autocreate requested profile, but don't create the config file.
221 auto_create=Bool(True)
221 auto_create=Bool(True)
222 # configurables
222 # configurables
223 ignore_old_config=Bool(False, config=True,
223 ignore_old_config=Bool(False, config=True,
224 help="Suppress warning messages about legacy config files"
224 help="Suppress warning messages about legacy config files"
225 )
225 )
226 quick = Bool(False, config=True,
226 quick = Bool(False, config=True,
227 help="""Start IPython quickly by skipping the loading of config files."""
227 help="""Start IPython quickly by skipping the loading of config files."""
228 )
228 )
229 def _quick_changed(self, name, old, new):
229 def _quick_changed(self, name, old, new):
230 if new:
230 if new:
231 self.load_config_file = lambda *a, **kw: None
231 self.load_config_file = lambda *a, **kw: None
232 self.ignore_old_config=True
232 self.ignore_old_config=True
233
233
234 gui = CaselessStrEnum(('qt', 'wx', 'gtk', 'glut', 'pyglet'), config=True,
234 gui = CaselessStrEnum(('qt', 'wx', 'gtk', 'glut', 'pyglet'), config=True,
235 help="Enable GUI event loop integration ('qt', 'wx', 'gtk', 'glut', 'pyglet')."
235 help="Enable GUI event loop integration ('qt', 'wx', 'gtk', 'glut', 'pyglet')."
236 )
236 )
237 pylab = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'auto'],
237 pylab = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'auto'],
238 config=True,
238 config=True,
239 help="""Pre-load matplotlib and numpy for interactive use,
239 help="""Pre-load matplotlib and numpy for interactive use,
240 selecting a particular matplotlib backend and loop integration.
240 selecting a particular matplotlib backend and loop integration.
241 """
241 """
242 )
242 )
243 display_banner = Bool(True, config=True,
243 display_banner = Bool(True, config=True,
244 help="Whether to display a banner upon starting IPython."
244 help="Whether to display a banner upon starting IPython."
245 )
245 )
246
246
247 # if there is code of files to run from the cmd line, don't interact
247 # if there is code of files to run from the cmd line, don't interact
248 # unless the --i flag (App.force_interact) is true.
248 # unless the --i flag (App.force_interact) is true.
249 force_interact = Bool(False, config=True,
249 force_interact = Bool(False, config=True,
250 help="""If a command or file is given via the command-line,
250 help="""If a command or file is given via the command-line,
251 e.g. 'ipython foo.py"""
251 e.g. 'ipython foo.py"""
252 )
252 )
253 def _force_interact_changed(self, name, old, new):
253 def _force_interact_changed(self, name, old, new):
254 if new:
254 if new:
255 self.interact = True
255 self.interact = True
256
256
257 def _file_to_run_changed(self, name, old, new):
257 def _file_to_run_changed(self, name, old, new):
258 if new and not self.force_interact:
258 if new and not self.force_interact:
259 self.interact = False
259 self.interact = False
260 _code_to_run_changed = _file_to_run_changed
260 _code_to_run_changed = _file_to_run_changed
261
261
262 # internal, not-configurable
262 # internal, not-configurable
263 interact=Bool(True)
263 interact=Bool(True)
264
264
265
265
266 def parse_command_line(self, argv=None):
266 def parse_command_line(self, argv=None):
267 """override to allow old '-pylab' flag with deprecation warning"""
267 """override to allow old '-pylab' flag with deprecation warning"""
268
268
269 argv = sys.argv[1:] if argv is None else argv
269 argv = sys.argv[1:] if argv is None else argv
270
270
271 if '-pylab' in argv:
271 if '-pylab' in argv:
272 # deprecated `-pylab` given,
272 # deprecated `-pylab` given,
273 # warn and transform into current syntax
273 # warn and transform into current syntax
274 argv = argv[:] # copy, don't clobber
274 argv = argv[:] # copy, don't clobber
275 idx = argv.index('-pylab')
275 idx = argv.index('-pylab')
276 warn.warn("`-pylab` flag has been deprecated.\n"
276 warn.warn("`-pylab` flag has been deprecated.\n"
277 " Use `--pylab` instead, or `--pylab=foo` to specify a backend.")
277 " Use `--pylab` instead, or `--pylab=foo` to specify a backend.")
278 sub = '--pylab'
278 sub = '--pylab'
279 if len(argv) > idx+1:
279 if len(argv) > idx+1:
280 # check for gui arg, as in '-pylab qt'
280 # check for gui arg, as in '-pylab qt'
281 gui = argv[idx+1]
281 gui = argv[idx+1]
282 if gui in ('wx', 'qt', 'qt4', 'gtk', 'auto'):
282 if gui in ('wx', 'qt', 'qt4', 'gtk', 'auto'):
283 sub = '--pylab='+gui
283 sub = '--pylab='+gui
284 argv.pop(idx+1)
284 argv.pop(idx+1)
285 argv[idx] = sub
285 argv[idx] = sub
286
286
287 return super(TerminalIPythonApp, self).parse_command_line(argv)
287 return super(TerminalIPythonApp, self).parse_command_line(argv)
288
288
289 def initialize(self, argv=None):
289 def initialize(self, argv=None):
290 """Do actions after construct, but before starting the app."""
290 """Do actions after construct, but before starting the app."""
291 super(TerminalIPythonApp, self).initialize(argv)
291 super(TerminalIPythonApp, self).initialize(argv)
292 if self.subapp is not None:
292 if self.subapp is not None:
293 # don't bother initializing further, starting subapp
293 # don't bother initializing further, starting subapp
294 return
294 return
295 if not self.ignore_old_config:
295 if not self.ignore_old_config:
296 check_for_old_config(self.ipython_dir)
296 check_for_old_config(self.ipython_dir)
297 # print self.extra_args
297 # print self.extra_args
298 if self.extra_args:
298 if self.extra_args:
299 self.file_to_run = self.extra_args[0]
299 self.file_to_run = self.extra_args[0]
300 # create the shell
300 # create the shell
301 self.init_shell()
301 self.init_shell()
302 # and draw the banner
302 # and draw the banner
303 self.init_banner()
303 self.init_banner()
304 # Now a variety of things that happen after the banner is printed.
304 # Now a variety of things that happen after the banner is printed.
305 self.init_gui_pylab()
305 self.init_gui_pylab()
306 self.init_extensions()
306 self.init_extensions()
307 self.init_code()
307 self.init_code()
308
308
309 def init_shell(self):
309 def init_shell(self):
310 """initialize the InteractiveShell instance"""
310 """initialize the InteractiveShell instance"""
311 # I am a little hesitant to put these into InteractiveShell itself.
311 # I am a little hesitant to put these into InteractiveShell itself.
312 # But that might be the place for them
312 # But that might be the place for them
313 sys.path.insert(0, '')
313 sys.path.insert(0, '')
314
314
315 # Create an InteractiveShell instance.
315 # Create an InteractiveShell instance.
316 # shell.display_banner should always be False for the terminal
316 # shell.display_banner should always be False for the terminal
317 # based app, because we call shell.show_banner() by hand below
317 # based app, because we call shell.show_banner() by hand below
318 # so the banner shows *before* all extension loading stuff.
318 # so the banner shows *before* all extension loading stuff.
319 self.shell = TerminalInteractiveShell.instance(config=self.config,
319 self.shell = TerminalInteractiveShell.instance(config=self.config,
320 display_banner=False, profile_dir=self.profile_dir,
320 display_banner=False, profile_dir=self.profile_dir,
321 ipython_dir=self.ipython_dir)
321 ipython_dir=self.ipython_dir)
322
322
323 def init_banner(self):
323 def init_banner(self):
324 """optionally display the banner"""
324 """optionally display the banner"""
325 if self.display_banner and self.interact:
325 if self.display_banner and self.interact:
326 self.shell.show_banner()
326 self.shell.show_banner()
327 # Make sure there is a space below the banner.
327 # Make sure there is a space below the banner.
328 if self.log_level <= logging.INFO: print
328 if self.log_level <= logging.INFO: print
329
329
330
330
331 def init_gui_pylab(self):
331 def init_gui_pylab(self):
332 """Enable GUI event loop integration, taking pylab into account."""
332 """Enable GUI event loop integration, taking pylab into account."""
333 gui = self.gui
333 gui = self.gui
334
334
335 # Using `pylab` will also require gui activation, though which toolkit
335 # Using `pylab` will also require gui activation, though which toolkit
336 # to use may be chosen automatically based on mpl configuration.
336 # to use may be chosen automatically based on mpl configuration.
337 if self.pylab:
337 if self.pylab:
338 activate = self.shell.enable_pylab
338 activate = self.shell.enable_pylab
339 if self.pylab == 'auto':
339 if self.pylab == 'auto':
340 gui = None
340 gui = None
341 else:
341 else:
342 gui = self.pylab
342 gui = self.pylab
343 else:
343 else:
344 # Enable only GUI integration, no pylab
344 # Enable only GUI integration, no pylab
345 activate = inputhook.enable_gui
345 activate = inputhook.enable_gui
346
346
347 if gui or self.pylab:
347 if gui or self.pylab:
348 try:
348 try:
349 self.log.info("Enabling GUI event loop integration, "
349 self.log.info("Enabling GUI event loop integration, "
350 "toolkit=%s, pylab=%s" % (gui, self.pylab) )
350 "toolkit=%s, pylab=%s" % (gui, self.pylab) )
351 if self.pylab:
351 if self.pylab:
352 activate(gui, import_all=self.pylab_import_all)
352 activate(gui, import_all=self.pylab_import_all)
353 else:
353 else:
354 activate(gui)
354 activate(gui)
355 except:
355 except:
356 self.log.warn("Error in enabling GUI event loop integration:")
356 self.log.warn("Error in enabling GUI event loop integration:")
357 self.shell.showtraceback()
357 self.shell.showtraceback()
358
358
359 def start(self):
359 def start(self):
360 if self.subapp is not None:
360 if self.subapp is not None:
361 return self.subapp.start()
361 return self.subapp.start()
362 # perform any prexec steps:
362 # perform any prexec steps:
363 if self.interact:
363 if self.interact:
364 self.log.debug("Starting IPython's mainloop...")
364 self.log.debug("Starting IPython's mainloop...")
365 self.shell.mainloop()
365 self.shell.mainloop()
366 else:
366 else:
367 self.log.debug("IPython not interactive...")
367 self.log.debug("IPython not interactive...")
368
368
369
369
370 def load_default_config(ipython_dir=None):
370 def load_default_config(ipython_dir=None):
371 """Load the default config file from the default ipython_dir.
371 """Load the default config file from the default ipython_dir.
372
372
373 This is useful for embedded shells.
373 This is useful for embedded shells.
374 """
374 """
375 if ipython_dir is None:
375 if ipython_dir is None:
376 ipython_dir = get_ipython_dir()
376 ipython_dir = get_ipython_dir()
377 profile_dir = os.path.join(ipython_dir, 'profile_default')
377 profile_dir = os.path.join(ipython_dir, 'profile_default')
378 cl = PyFileConfigLoader(default_config_file_name, profile_dir)
378 cl = PyFileConfigLoader(default_config_file_name, profile_dir)
379 try:
379 try:
380 config = cl.load_config()
380 config = cl.load_config()
381 except ConfigFileNotFound:
381 except ConfigFileNotFound:
382 # no config found
382 # no config found
383 config = Config()
383 config = Config()
384 return config
384 return config
385
385
386
386
387 def launch_new_instance():
387 def launch_new_instance():
388 """Create and run a full blown IPython instance"""
388 """Create and run a full blown IPython instance"""
389 app = TerminalIPythonApp.instance()
389 app = TerminalIPythonApp.instance()
390 app.initialize()
390 app.initialize()
391 app.start()
391 app.start()
392
392
393
393
394 if __name__ == '__main__':
394 if __name__ == '__main__':
395 launch_new_instance()
395 launch_new_instance()
General Comments 0
You need to be logged in to leave comments. Login now