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