##// END OF EJS Templates
load bundled profiles without having to use 'profile create' or '--init'...
MinRK -
Show More
@@ -1,293 +1,307 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An application for IPython.
3 An application for IPython.
4
4
5 All top-level applications should use the classes in this module for
5 All top-level applications should use the classes in this module for
6 handling configuration and creating componenets.
6 handling configuration and creating componenets.
7
7
8 The job of an :class:`Application` is to create the master configuration
8 The job of an :class:`Application` is to create the master configuration
9 object and then create the configurable objects, passing the config to them.
9 object and then create the configurable objects, passing the config to them.
10
10
11 Authors:
11 Authors:
12
12
13 * Brian Granger
13 * Brian Granger
14 * Fernando Perez
14 * Fernando Perez
15 * Min RK
15 * Min RK
16
16
17 """
17 """
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Copyright (C) 2008-2011 The IPython Development Team
20 # Copyright (C) 2008-2011 The IPython Development Team
21 #
21 #
22 # Distributed under the terms of the BSD License. The full license is in
22 # Distributed under the terms of the BSD License. The full license is in
23 # the file COPYING, distributed as part of this software.
23 # the file COPYING, distributed as part of this software.
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Imports
27 # Imports
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 import glob
30 import logging
31 import logging
31 import os
32 import os
32 import shutil
33 import shutil
33 import sys
34 import sys
34
35
35 from IPython.config.application import Application
36 from IPython.config.application import Application
36 from IPython.config.configurable import Configurable
37 from IPython.config.configurable import Configurable
37 from IPython.config.loader import Config
38 from IPython.config.loader import Config
38 from IPython.core import release, crashhandler
39 from IPython.core import release, crashhandler
39 from IPython.core.profiledir import ProfileDir, ProfileDirError
40 from IPython.core.profiledir import ProfileDir, ProfileDirError
40 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir
41 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir
41 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict
42 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict
42
43
43 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
44 # Classes and functions
45 # Classes and functions
45 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
46
47
47
48
48 #-----------------------------------------------------------------------------
49 #-----------------------------------------------------------------------------
49 # Base Application Class
50 # Base Application Class
50 #-----------------------------------------------------------------------------
51 #-----------------------------------------------------------------------------
51
52
52 # aliases and flags
53 # aliases and flags
53
54
54 base_aliases = dict(
55 base_aliases = dict(
55 profile='BaseIPythonApplication.profile',
56 profile='BaseIPythonApplication.profile',
56 ipython_dir='BaseIPythonApplication.ipython_dir',
57 ipython_dir='BaseIPythonApplication.ipython_dir',
57 log_level='Application.log_level',
58 log_level='Application.log_level',
58 )
59 )
59
60
60 base_flags = dict(
61 base_flags = dict(
61 debug = ({'Application' : {'log_level' : logging.DEBUG}},
62 debug = ({'Application' : {'log_level' : logging.DEBUG}},
62 "set log level to logging.DEBUG (maximize logging output)"),
63 "set log level to logging.DEBUG (maximize logging output)"),
63 quiet = ({'Application' : {'log_level' : logging.CRITICAL}},
64 quiet = ({'Application' : {'log_level' : logging.CRITICAL}},
64 "set log level to logging.CRITICAL (minimize logging output)"),
65 "set log level to logging.CRITICAL (minimize logging output)"),
65 init = ({'BaseIPythonApplication' : {
66 init = ({'BaseIPythonApplication' : {
66 'copy_config_files' : True,
67 'copy_config_files' : True,
67 'auto_create' : True}
68 'auto_create' : True}
68 }, "Initialize profile with default config files")
69 }, "Initialize profile with default config files")
69 )
70 )
70
71
71
72
72 class BaseIPythonApplication(Application):
73 class BaseIPythonApplication(Application):
73
74
74 name = Unicode(u'ipython')
75 name = Unicode(u'ipython')
75 description = Unicode(u'IPython: an enhanced interactive Python shell.')
76 description = Unicode(u'IPython: an enhanced interactive Python shell.')
76 version = Unicode(release.version)
77 version = Unicode(release.version)
77
78
78 aliases = Dict(base_aliases)
79 aliases = Dict(base_aliases)
79 flags = Dict(base_flags)
80 flags = Dict(base_flags)
80 classes = List([ProfileDir])
81 classes = List([ProfileDir])
81
82
82 # Track whether the config_file has changed,
83 # Track whether the config_file has changed,
83 # because some logic happens only if we aren't using the default.
84 # because some logic happens only if we aren't using the default.
84 config_file_specified = Bool(False)
85 config_file_specified = Bool(False)
85
86
86 config_file_name = Unicode(u'ipython_config.py')
87 config_file_name = Unicode(u'ipython_config.py')
87 def _config_file_name_default(self):
88 def _config_file_name_default(self):
88 return self.name.replace('-','_') + u'_config.py'
89 return self.name.replace('-','_') + u'_config.py'
89 def _config_file_name_changed(self, name, old, new):
90 def _config_file_name_changed(self, name, old, new):
90 if new != old:
91 if new != old:
91 self.config_file_specified = True
92 self.config_file_specified = True
92
93
93 # The directory that contains IPython's builtin profiles.
94 # The directory that contains IPython's builtin profiles.
94 builtin_profile_dir = Unicode(
95 builtin_profile_dir = Unicode(
95 os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
96 os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
96 )
97 )
97
98
98 config_file_paths = List(Unicode)
99 config_file_paths = List(Unicode)
99 def _config_file_paths_default(self):
100 def _config_file_paths_default(self):
100 return [os.getcwdu()]
101 return [os.getcwdu()]
101
102
102 profile = Unicode(u'default', config=True,
103 profile = Unicode(u'default', config=True,
103 help="""The IPython profile to use."""
104 help="""The IPython profile to use."""
104 )
105 )
105 def _profile_changed(self, name, old, new):
106 def _profile_changed(self, name, old, new):
106 self.builtin_profile_dir = os.path.join(
107 self.builtin_profile_dir = os.path.join(
107 get_ipython_package_dir(), u'config', u'profile', new
108 get_ipython_package_dir(), u'config', u'profile', new
108 )
109 )
109
110
110 ipython_dir = Unicode(get_ipython_dir(), config=True,
111 ipython_dir = Unicode(get_ipython_dir(), config=True,
111 help="""
112 help="""
112 The name of the IPython directory. This directory is used for logging
113 The name of the IPython directory. This directory is used for logging
113 configuration (through profiles), history storage, etc. The default
114 configuration (through profiles), history storage, etc. The default
114 is usually $HOME/.ipython. This options can also be specified through
115 is usually $HOME/.ipython. This options can also be specified through
115 the environment variable IPYTHON_DIR.
116 the environment variable IPYTHON_DIR.
116 """
117 """
117 )
118 )
118
119
119 overwrite = Bool(False, config=True,
120 overwrite = Bool(False, config=True,
120 help="""Whether to overwrite existing config files when copying""")
121 help="""Whether to overwrite existing config files when copying""")
121 auto_create = Bool(False, config=True,
122 auto_create = Bool(False, config=True,
122 help="""Whether to create profile dir if it doesn't exist""")
123 help="""Whether to create profile dir if it doesn't exist""")
123
124
124 config_files = List(Unicode)
125 config_files = List(Unicode)
125 def _config_files_default(self):
126 def _config_files_default(self):
126 return [u'ipython_config.py']
127 return [u'ipython_config.py']
127
128
128 copy_config_files = Bool(False, config=True,
129 copy_config_files = Bool(False, config=True,
129 help="""Whether to install the default config files into the profile dir.
130 help="""Whether to install the default config files into the profile dir.
130 If a new profile is being created, and IPython contains config files for that
131 If a new profile is being created, and IPython contains config files for that
131 profile, then they will be staged into the new directory. Otherwise,
132 profile, then they will be staged into the new directory. Otherwise,
132 default config files will be automatically generated.
133 default config files will be automatically generated.
133 """)
134 """)
134
135
135 # The class to use as the crash handler.
136 # The class to use as the crash handler.
136 crash_handler_class = Type(crashhandler.CrashHandler)
137 crash_handler_class = Type(crashhandler.CrashHandler)
137
138
138 def __init__(self, **kwargs):
139 def __init__(self, **kwargs):
139 super(BaseIPythonApplication, self).__init__(**kwargs)
140 super(BaseIPythonApplication, self).__init__(**kwargs)
140 # ensure even default IPYTHON_DIR exists
141 # ensure even default IPYTHON_DIR exists
141 if not os.path.exists(self.ipython_dir):
142 if not os.path.exists(self.ipython_dir):
142 self._ipython_dir_changed('ipython_dir', self.ipython_dir, self.ipython_dir)
143 self._ipython_dir_changed('ipython_dir', self.ipython_dir, self.ipython_dir)
143
144
144 #-------------------------------------------------------------------------
145 #-------------------------------------------------------------------------
145 # Various stages of Application creation
146 # Various stages of Application creation
146 #-------------------------------------------------------------------------
147 #-------------------------------------------------------------------------
147
148
148 def init_crash_handler(self):
149 def init_crash_handler(self):
149 """Create a crash handler, typically setting sys.excepthook to it."""
150 """Create a crash handler, typically setting sys.excepthook to it."""
150 self.crash_handler = self.crash_handler_class(self)
151 self.crash_handler = self.crash_handler_class(self)
151 sys.excepthook = self.crash_handler
152 sys.excepthook = self.crash_handler
152
153
153 def _ipython_dir_changed(self, name, old, new):
154 def _ipython_dir_changed(self, name, old, new):
154 if old in sys.path:
155 if old in sys.path:
155 sys.path.remove(old)
156 sys.path.remove(old)
156 sys.path.append(os.path.abspath(new))
157 sys.path.append(os.path.abspath(new))
157 if not os.path.isdir(new):
158 if not os.path.isdir(new):
158 os.makedirs(new, mode=0777)
159 os.makedirs(new, mode=0777)
159 readme = os.path.join(new, 'README')
160 readme = os.path.join(new, 'README')
160 if not os.path.exists(readme):
161 if not os.path.exists(readme):
161 path = os.path.join(get_ipython_package_dir(), u'config', u'profile')
162 path = os.path.join(get_ipython_package_dir(), u'config', u'profile')
162 shutil.copy(os.path.join(path, 'README'), readme)
163 shutil.copy(os.path.join(path, 'README'), readme)
163 self.log.debug("IPYTHON_DIR set to: %s" % new)
164 self.log.debug("IPYTHON_DIR set to: %s" % new)
164
165
165 def load_config_file(self, suppress_errors=True):
166 def load_config_file(self, suppress_errors=True):
166 """Load the config file.
167 """Load the config file.
167
168
168 By default, errors in loading config are handled, and a warning
169 By default, errors in loading config are handled, and a warning
169 printed on screen. For testing, the suppress_errors option is set
170 printed on screen. For testing, the suppress_errors option is set
170 to False, so errors will make tests fail.
171 to False, so errors will make tests fail.
171 """
172 """
172 base_config = 'ipython_config.py'
173 base_config = 'ipython_config.py'
173 self.log.debug("Attempting to load config file: %s" %
174 self.log.debug("Attempting to load config file: %s" %
174 base_config)
175 base_config)
175 try:
176 try:
176 Application.load_config_file(
177 Application.load_config_file(
177 self,
178 self,
178 base_config,
179 base_config,
179 path=self.config_file_paths
180 path=self.config_file_paths
180 )
181 )
181 except IOError:
182 except IOError:
182 # ignore errors loading parent
183 # ignore errors loading parent
183 pass
184 pass
184 if self.config_file_name == base_config:
185 if self.config_file_name == base_config:
185 # don't load secondary config
186 # don't load secondary config
186 return
187 return
187 self.log.debug("Attempting to load config file: %s" %
188 self.log.debug("Attempting to load config file: %s" %
188 self.config_file_name)
189 self.config_file_name)
189 try:
190 try:
190 Application.load_config_file(
191 Application.load_config_file(
191 self,
192 self,
192 self.config_file_name,
193 self.config_file_name,
193 path=self.config_file_paths
194 path=self.config_file_paths
194 )
195 )
195 except IOError:
196 except IOError:
196 # Only warn if the default config file was NOT being used.
197 # Only warn if the default config file was NOT being used.
197 if self.config_file_specified:
198 if self.config_file_specified:
198 self.log.warn("Config file not found, skipping: %s" %
199 self.log.warn("Config file not found, skipping: %s" %
199 self.config_file_name)
200 self.config_file_name)
200 except:
201 except:
201 # For testing purposes.
202 # For testing purposes.
202 if not suppress_errors:
203 if not suppress_errors:
203 raise
204 raise
204 self.log.warn("Error loading config file: %s" %
205 self.log.warn("Error loading config file: %s" %
205 self.config_file_name, exc_info=True)
206 self.config_file_name, exc_info=True)
206
207
207 def init_profile_dir(self):
208 def init_profile_dir(self):
208 """initialize the profile dir"""
209 """initialize the profile dir"""
209 try:
210 try:
210 # location explicitly specified:
211 # location explicitly specified:
211 location = self.config.ProfileDir.location
212 location = self.config.ProfileDir.location
212 except AttributeError:
213 except AttributeError:
213 # location not specified, find by profile name
214 # location not specified, find by profile name
214 try:
215 try:
215 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
216 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
216 except ProfileDirError:
217 except ProfileDirError:
217 # not found, maybe create it (always create default profile)
218 # not found, maybe create it (always create default profile)
218 if self.auto_create or self.profile=='default':
219 if self.auto_create or self.profile=='default':
219 try:
220 try:
220 p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
221 p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
221 except ProfileDirError:
222 except ProfileDirError:
222 self.log.fatal("Could not create profile: %r"%self.profile)
223 self.log.fatal("Could not create profile: %r"%self.profile)
223 self.exit(1)
224 self.exit(1)
224 else:
225 else:
225 self.log.info("Created profile dir: %r"%p.location)
226 self.log.info("Created profile dir: %r"%p.location)
226 else:
227 else:
227 self.log.fatal("Profile %r not found."%self.profile)
228 self.log.fatal("Profile %r not found."%self.profile)
228 self.exit(1)
229 self.exit(1)
229 else:
230 else:
230 self.log.info("Using existing profile dir: %r"%p.location)
231 self.log.info("Using existing profile dir: %r"%p.location)
231 else:
232 else:
232 # location is fully specified
233 # location is fully specified
233 try:
234 try:
234 p = ProfileDir.find_profile_dir(location, self.config)
235 p = ProfileDir.find_profile_dir(location, self.config)
235 except ProfileDirError:
236 except ProfileDirError:
236 # not found, maybe create it
237 # not found, maybe create it
237 if self.auto_create:
238 if self.auto_create:
238 try:
239 try:
239 p = ProfileDir.create_profile_dir(location, self.config)
240 p = ProfileDir.create_profile_dir(location, self.config)
240 except ProfileDirError:
241 except ProfileDirError:
241 self.log.fatal("Could not create profile directory: %r"%location)
242 self.log.fatal("Could not create profile directory: %r"%location)
242 self.exit(1)
243 self.exit(1)
243 else:
244 else:
244 self.log.info("Creating new profile dir: %r"%location)
245 self.log.info("Creating new profile dir: %r"%location)
245 else:
246 else:
246 self.log.fatal("Profile directory %r not found."%location)
247 self.log.fatal("Profile directory %r not found."%location)
247 self.exit(1)
248 self.exit(1)
248 else:
249 else:
249 self.log.info("Using existing profile dir: %r"%location)
250 self.log.info("Using existing profile dir: %r"%location)
250
251
251 self.profile_dir = p
252 self.profile_dir = p
252 self.config_file_paths.append(p.location)
253 self.config_file_paths.append(p.location)
253
254
254 def init_config_files(self):
255 def init_config_files(self):
255 """[optionally] copy default config files into profile dir."""
256 """[optionally] copy default config files into profile dir."""
256 # copy config files
257 # copy config files
258 path = self.builtin_profile_dir
257 if self.copy_config_files:
259 if self.copy_config_files:
258 path = self.builtin_profile_dir
259 src = self.profile
260 src = self.profile
260
261
261 cfg = self.config_file_name
262 cfg = self.config_file_name
262 if path and os.path.exists(os.path.join(path, cfg)):
263 if path and os.path.exists(os.path.join(path, cfg)):
263 self.log.warn("Staging %r from %s into %r [overwrite=%s]"%(
264 self.log.warn("Staging %r from %s into %r [overwrite=%s]"%(
264 cfg, src, self.profile_dir.location, self.overwrite)
265 cfg, src, self.profile_dir.location, self.overwrite)
265 )
266 )
266 self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite)
267 self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite)
267 else:
268 else:
268 self.stage_default_config_file()
269 self.stage_default_config_file()
270 else:
271 # Still stage *bundled* config files, but not generated ones
272 # This is necessary for `ipython profile=sympy` to load the profile
273 # on the first go
274 files = glob.glob(os.path.join(path, '*.py'))
275 for fullpath in files:
276 cfg = os.path.basename(fullpath)
277 if self.profile_dir.copy_config_file(cfg, path=path, overwrite=False):
278 # file was copied
279 self.log.warn("Staging bundled %s from %s into %r"%(
280 cfg, self.profile, self.profile_dir.location)
281 )
282
269
283
270 def stage_default_config_file(self):
284 def stage_default_config_file(self):
271 """auto generate default config file, and stage it into the profile."""
285 """auto generate default config file, and stage it into the profile."""
272 s = self.generate_config_file()
286 s = self.generate_config_file()
273 fname = os.path.join(self.profile_dir.location, self.config_file_name)
287 fname = os.path.join(self.profile_dir.location, self.config_file_name)
274 if self.overwrite or not os.path.exists(fname):
288 if self.overwrite or not os.path.exists(fname):
275 self.log.warn("Generating default config file: %r"%(fname))
289 self.log.warn("Generating default config file: %r"%(fname))
276 with open(fname, 'w') as f:
290 with open(fname, 'w') as f:
277 f.write(s)
291 f.write(s)
278
292
279
293
280 def initialize(self, argv=None):
294 def initialize(self, argv=None):
281 # don't hook up crash handler before parsing command-line
295 # don't hook up crash handler before parsing command-line
282 self.parse_command_line(argv)
296 self.parse_command_line(argv)
283 self.init_crash_handler()
297 self.init_crash_handler()
284 if self.subapp is not None:
298 if self.subapp is not None:
285 # stop here if subapp is taking over
299 # stop here if subapp is taking over
286 return
300 return
287 cl_config = self.config
301 cl_config = self.config
288 self.init_profile_dir()
302 self.init_profile_dir()
289 self.init_config_files()
303 self.init_config_files()
290 self.load_config_file()
304 self.load_config_file()
291 # enforce cl-opts override configfile opts:
305 # enforce cl-opts override configfile opts:
292 self.update_config(cl_config)
306 self.update_config(cl_config)
293
307
@@ -1,206 +1,207 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An object for managing IPython profile directories.
3 An object for managing IPython profile directories.
4
4
5 Authors:
5 Authors:
6
6
7 * Brian Granger
7 * Brian Granger
8 * Fernando Perez
8 * Fernando Perez
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 os
24 import os
25 import shutil
25 import shutil
26 import sys
26 import sys
27
27
28 from IPython.config.configurable import Configurable
28 from IPython.config.configurable import Configurable
29 from IPython.config.loader import Config
29 from IPython.config.loader import Config
30 from IPython.utils.path import get_ipython_package_dir, expand_path
30 from IPython.utils.path import get_ipython_package_dir, expand_path
31 from IPython.utils.traitlets import List, Unicode, Bool
31 from IPython.utils.traitlets import List, Unicode, Bool
32
32
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 # Classes and functions
34 # Classes and functions
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36
36
37
37
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39 # Module errors
39 # Module errors
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41
41
42 class ProfileDirError(Exception):
42 class ProfileDirError(Exception):
43 pass
43 pass
44
44
45
45
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47 # Class for managing profile directories
47 # Class for managing profile directories
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49
49
50 class ProfileDir(Configurable):
50 class ProfileDir(Configurable):
51 """An object to manage the profile directory and its resources.
51 """An object to manage the profile directory and its resources.
52
52
53 The profile directory is used by all IPython applications, to manage
53 The profile directory is used by all IPython applications, to manage
54 configuration, logging and security.
54 configuration, logging and security.
55
55
56 This object knows how to find, create and manage these directories. This
56 This object knows how to find, create and manage these directories. This
57 should be used by any code that wants to handle profiles.
57 should be used by any code that wants to handle profiles.
58 """
58 """
59
59
60 security_dir_name = Unicode('security')
60 security_dir_name = Unicode('security')
61 log_dir_name = Unicode('log')
61 log_dir_name = Unicode('log')
62 pid_dir_name = Unicode('pid')
62 pid_dir_name = Unicode('pid')
63 security_dir = Unicode(u'')
63 security_dir = Unicode(u'')
64 log_dir = Unicode(u'')
64 log_dir = Unicode(u'')
65 pid_dir = Unicode(u'')
65 pid_dir = Unicode(u'')
66
66
67 location = Unicode(u'', config=True,
67 location = Unicode(u'', config=True,
68 help="""Set the profile location directly. This overrides the logic used by the
68 help="""Set the profile location directly. This overrides the logic used by the
69 `profile` option.""",
69 `profile` option.""",
70 )
70 )
71
71
72 _location_isset = Bool(False) # flag for detecting multiply set location
72 _location_isset = Bool(False) # flag for detecting multiply set location
73
73
74 def _location_changed(self, name, old, new):
74 def _location_changed(self, name, old, new):
75 if self._location_isset:
75 if self._location_isset:
76 raise RuntimeError("Cannot set profile location more than once.")
76 raise RuntimeError("Cannot set profile location more than once.")
77 self._location_isset = True
77 self._location_isset = True
78 if not os.path.isdir(new):
78 if not os.path.isdir(new):
79 os.makedirs(new)
79 os.makedirs(new)
80
80
81 # ensure config files exist:
81 # ensure config files exist:
82 self.security_dir = os.path.join(new, self.security_dir_name)
82 self.security_dir = os.path.join(new, self.security_dir_name)
83 self.log_dir = os.path.join(new, self.log_dir_name)
83 self.log_dir = os.path.join(new, self.log_dir_name)
84 self.pid_dir = os.path.join(new, self.pid_dir_name)
84 self.pid_dir = os.path.join(new, self.pid_dir_name)
85 self.check_dirs()
85 self.check_dirs()
86
86
87 def _log_dir_changed(self, name, old, new):
87 def _log_dir_changed(self, name, old, new):
88 self.check_log_dir()
88 self.check_log_dir()
89
89
90 def check_log_dir(self):
90 def check_log_dir(self):
91 if not os.path.isdir(self.log_dir):
91 if not os.path.isdir(self.log_dir):
92 os.mkdir(self.log_dir)
92 os.mkdir(self.log_dir)
93
93
94 def _security_dir_changed(self, name, old, new):
94 def _security_dir_changed(self, name, old, new):
95 self.check_security_dir()
95 self.check_security_dir()
96
96
97 def check_security_dir(self):
97 def check_security_dir(self):
98 if not os.path.isdir(self.security_dir):
98 if not os.path.isdir(self.security_dir):
99 os.mkdir(self.security_dir, 0700)
99 os.mkdir(self.security_dir, 0700)
100 else:
100 else:
101 os.chmod(self.security_dir, 0700)
101 os.chmod(self.security_dir, 0700)
102
102
103 def _pid_dir_changed(self, name, old, new):
103 def _pid_dir_changed(self, name, old, new):
104 self.check_pid_dir()
104 self.check_pid_dir()
105
105
106 def check_pid_dir(self):
106 def check_pid_dir(self):
107 if not os.path.isdir(self.pid_dir):
107 if not os.path.isdir(self.pid_dir):
108 os.mkdir(self.pid_dir, 0700)
108 os.mkdir(self.pid_dir, 0700)
109 else:
109 else:
110 os.chmod(self.pid_dir, 0700)
110 os.chmod(self.pid_dir, 0700)
111
111
112 def check_dirs(self):
112 def check_dirs(self):
113 self.check_security_dir()
113 self.check_security_dir()
114 self.check_log_dir()
114 self.check_log_dir()
115 self.check_pid_dir()
115 self.check_pid_dir()
116
116
117 def copy_config_file(self, config_file, path=None, overwrite=False):
117 def copy_config_file(self, config_file, path=None, overwrite=False):
118 """Copy a default config file into the active profile directory.
118 """Copy a default config file into the active profile directory.
119
119
120 Default configuration files are kept in :mod:`IPython.config.default`.
120 Default configuration files are kept in :mod:`IPython.config.default`.
121 This function moves these from that location to the working profile
121 This function moves these from that location to the working profile
122 directory.
122 directory.
123 """
123 """
124 dst = os.path.join(self.location, config_file)
124 dst = os.path.join(self.location, config_file)
125 if os.path.isfile(dst) and not overwrite:
125 if os.path.isfile(dst) and not overwrite:
126 return
126 return False
127 if path is None:
127 if path is None:
128 path = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
128 path = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
129 src = os.path.join(path, config_file)
129 src = os.path.join(path, config_file)
130 shutil.copy(src, dst)
130 shutil.copy(src, dst)
131 return True
131
132
132 @classmethod
133 @classmethod
133 def create_profile_dir(cls, profile_dir, config=None):
134 def create_profile_dir(cls, profile_dir, config=None):
134 """Create a new profile directory given a full path.
135 """Create a new profile directory given a full path.
135
136
136 Parameters
137 Parameters
137 ----------
138 ----------
138 profile_dir : str
139 profile_dir : str
139 The full path to the profile directory. If it does exist, it will
140 The full path to the profile directory. If it does exist, it will
140 be used. If not, it will be created.
141 be used. If not, it will be created.
141 """
142 """
142 return cls(location=profile_dir, config=config)
143 return cls(location=profile_dir, config=config)
143
144
144 @classmethod
145 @classmethod
145 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
146 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
146 """Create a profile dir by profile name and path.
147 """Create a profile dir by profile name and path.
147
148
148 Parameters
149 Parameters
149 ----------
150 ----------
150 path : unicode
151 path : unicode
151 The path (directory) to put the profile directory in.
152 The path (directory) to put the profile directory in.
152 name : unicode
153 name : unicode
153 The name of the profile. The name of the profile directory will
154 The name of the profile. The name of the profile directory will
154 be "profile_<profile>".
155 be "profile_<profile>".
155 """
156 """
156 if not os.path.isdir(path):
157 if not os.path.isdir(path):
157 raise ProfileDirError('Directory not found: %s' % path)
158 raise ProfileDirError('Directory not found: %s' % path)
158 profile_dir = os.path.join(path, u'profile_' + name)
159 profile_dir = os.path.join(path, u'profile_' + name)
159 return cls(location=profile_dir, config=config)
160 return cls(location=profile_dir, config=config)
160
161
161 @classmethod
162 @classmethod
162 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
163 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
163 """Find an existing profile dir by profile name, return its ProfileDir.
164 """Find an existing profile dir by profile name, return its ProfileDir.
164
165
165 This searches through a sequence of paths for a profile dir. If it
166 This searches through a sequence of paths for a profile dir. If it
166 is not found, a :class:`ProfileDirError` exception will be raised.
167 is not found, a :class:`ProfileDirError` exception will be raised.
167
168
168 The search path algorithm is:
169 The search path algorithm is:
169 1. ``os.getcwd()``
170 1. ``os.getcwd()``
170 2. ``ipython_dir``
171 2. ``ipython_dir``
171
172
172 Parameters
173 Parameters
173 ----------
174 ----------
174 ipython_dir : unicode or str
175 ipython_dir : unicode or str
175 The IPython directory to use.
176 The IPython directory to use.
176 name : unicode or str
177 name : unicode or str
177 The name of the profile. The name of the profile directory
178 The name of the profile. The name of the profile directory
178 will be "profile_<profile>".
179 will be "profile_<profile>".
179 """
180 """
180 dirname = u'profile_' + name
181 dirname = u'profile_' + name
181 paths = [os.getcwdu(), ipython_dir]
182 paths = [os.getcwdu(), ipython_dir]
182 for p in paths:
183 for p in paths:
183 profile_dir = os.path.join(p, dirname)
184 profile_dir = os.path.join(p, dirname)
184 if os.path.isdir(profile_dir):
185 if os.path.isdir(profile_dir):
185 return cls(location=profile_dir, config=config)
186 return cls(location=profile_dir, config=config)
186 else:
187 else:
187 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
188 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
188
189
189 @classmethod
190 @classmethod
190 def find_profile_dir(cls, profile_dir, config=None):
191 def find_profile_dir(cls, profile_dir, config=None):
191 """Find/create a profile dir and return its ProfileDir.
192 """Find/create a profile dir and return its ProfileDir.
192
193
193 This will create the profile directory if it doesn't exist.
194 This will create the profile directory if it doesn't exist.
194
195
195 Parameters
196 Parameters
196 ----------
197 ----------
197 profile_dir : unicode or str
198 profile_dir : unicode or str
198 The path of the profile directory. This is expanded using
199 The path of the profile directory. This is expanded using
199 :func:`IPython.utils.genutils.expand_path`.
200 :func:`IPython.utils.genutils.expand_path`.
200 """
201 """
201 profile_dir = expand_path(profile_dir)
202 profile_dir = expand_path(profile_dir)
202 if not os.path.isdir(profile_dir):
203 if not os.path.isdir(profile_dir):
203 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
204 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
204 return cls(location=profile_dir, config=config)
205 return cls(location=profile_dir, config=config)
205
206
206
207
General Comments 0
You need to be logged in to leave comments. Login now