##// END OF EJS Templates
Merge pull request #3212 from jusic/master...
Min RK -
r10270:e7a98b15 merge
parent child Browse files
Show More
@@ -1,226 +1,230 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
26
27 from IPython.config.configurable import LoggingConfigurable
27 from IPython.config.configurable import LoggingConfigurable
28 from IPython.utils.path import get_ipython_package_dir, expand_path
28 from IPython.utils.path import get_ipython_package_dir, expand_path
29 from IPython.utils.traitlets import Unicode, Bool
29 from IPython.utils.traitlets import Unicode, Bool
30
30
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32 # Classes and functions
32 # Classes and functions
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34
34
35
35
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37 # Module errors
37 # Module errors
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39
39
40 class ProfileDirError(Exception):
40 class ProfileDirError(Exception):
41 pass
41 pass
42
42
43
43
44 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
45 # Class for managing profile directories
45 # Class for managing profile directories
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47
47
48 class ProfileDir(LoggingConfigurable):
48 class ProfileDir(LoggingConfigurable):
49 """An object to manage the profile directory and its resources.
49 """An object to manage the profile directory and its resources.
50
50
51 The profile directory is used by all IPython applications, to manage
51 The profile directory is used by all IPython applications, to manage
52 configuration, logging and security.
52 configuration, logging and security.
53
53
54 This object knows how to find, create and manage these directories. This
54 This object knows how to find, create and manage these directories. This
55 should be used by any code that wants to handle profiles.
55 should be used by any code that wants to handle profiles.
56 """
56 """
57
57
58 security_dir_name = Unicode('security')
58 security_dir_name = Unicode('security')
59 log_dir_name = Unicode('log')
59 log_dir_name = Unicode('log')
60 startup_dir_name = Unicode('startup')
60 startup_dir_name = Unicode('startup')
61 pid_dir_name = Unicode('pid')
61 pid_dir_name = Unicode('pid')
62 security_dir = Unicode(u'')
62 security_dir = Unicode(u'')
63 log_dir = Unicode(u'')
63 log_dir = Unicode(u'')
64 startup_dir = Unicode(u'')
64 startup_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.startup_dir = os.path.join(new, self.startup_dir_name)
84 self.startup_dir = os.path.join(new, self.startup_dir_name)
85 self.pid_dir = os.path.join(new, self.pid_dir_name)
85 self.pid_dir = os.path.join(new, self.pid_dir_name)
86 self.check_dirs()
86 self.check_dirs()
87
87
88 def _log_dir_changed(self, name, old, new):
88 def _log_dir_changed(self, name, old, new):
89 self.check_log_dir()
89 self.check_log_dir()
90
90
91 def check_log_dir(self):
91 def check_log_dir(self):
92 if not os.path.isdir(self.log_dir):
92 if not os.path.isdir(self.log_dir):
93 os.mkdir(self.log_dir)
93 os.mkdir(self.log_dir)
94
94
95 def _startup_dir_changed(self, name, old, new):
95 def _startup_dir_changed(self, name, old, new):
96 self.check_startup_dir()
96 self.check_startup_dir()
97
97
98 def check_startup_dir(self):
98 def check_startup_dir(self):
99 if not os.path.isdir(self.startup_dir):
99 if not os.path.isdir(self.startup_dir):
100 os.mkdir(self.startup_dir)
100 os.mkdir(self.startup_dir)
101 readme = os.path.join(self.startup_dir, 'README')
101 readme = os.path.join(self.startup_dir, 'README')
102 src = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'README_STARTUP')
102 src = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'README_STARTUP')
103 if not os.path.exists(readme):
103
104 if not os.path.exists(src):
105 self.log.warn("Could not copy README_STARTUP to startup dir. Source file %s does not exist." % src)
106
107 if os.path.exists(src) and not os.path.exists(readme):
104 shutil.copy(src, readme)
108 shutil.copy(src, readme)
105
109
106 def _security_dir_changed(self, name, old, new):
110 def _security_dir_changed(self, name, old, new):
107 self.check_security_dir()
111 self.check_security_dir()
108
112
109 def check_security_dir(self):
113 def check_security_dir(self):
110 if not os.path.isdir(self.security_dir):
114 if not os.path.isdir(self.security_dir):
111 os.mkdir(self.security_dir, 0o700)
115 os.mkdir(self.security_dir, 0o700)
112 else:
116 else:
113 try:
117 try:
114 os.chmod(self.security_dir, 0o700)
118 os.chmod(self.security_dir, 0o700)
115 except OSError:
119 except OSError:
116 self.log.warn("Could not set security dir permissions to private.")
120 self.log.warn("Could not set security dir permissions to private.")
117
121
118 def _pid_dir_changed(self, name, old, new):
122 def _pid_dir_changed(self, name, old, new):
119 self.check_pid_dir()
123 self.check_pid_dir()
120
124
121 def check_pid_dir(self):
125 def check_pid_dir(self):
122 if not os.path.isdir(self.pid_dir):
126 if not os.path.isdir(self.pid_dir):
123 os.mkdir(self.pid_dir, 0o700)
127 os.mkdir(self.pid_dir, 0o700)
124 else:
128 else:
125 try:
129 try:
126 os.chmod(self.pid_dir, 0o700)
130 os.chmod(self.pid_dir, 0o700)
127 except OSError:
131 except OSError:
128 self.log.warn("Could not set pid dir permissions to private.")
132 self.log.warn("Could not set pid dir permissions to private.")
129
133
130 def check_dirs(self):
134 def check_dirs(self):
131 self.check_security_dir()
135 self.check_security_dir()
132 self.check_log_dir()
136 self.check_log_dir()
133 self.check_pid_dir()
137 self.check_pid_dir()
134 self.check_startup_dir()
138 self.check_startup_dir()
135
139
136 def copy_config_file(self, config_file, path=None, overwrite=False):
140 def copy_config_file(self, config_file, path=None, overwrite=False):
137 """Copy a default config file into the active profile directory.
141 """Copy a default config file into the active profile directory.
138
142
139 Default configuration files are kept in :mod:`IPython.config.default`.
143 Default configuration files are kept in :mod:`IPython.config.default`.
140 This function moves these from that location to the working profile
144 This function moves these from that location to the working profile
141 directory.
145 directory.
142 """
146 """
143 dst = os.path.join(self.location, config_file)
147 dst = os.path.join(self.location, config_file)
144 if os.path.isfile(dst) and not overwrite:
148 if os.path.isfile(dst) and not overwrite:
145 return False
149 return False
146 if path is None:
150 if path is None:
147 path = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
151 path = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
148 src = os.path.join(path, config_file)
152 src = os.path.join(path, config_file)
149 shutil.copy(src, dst)
153 shutil.copy(src, dst)
150 return True
154 return True
151
155
152 @classmethod
156 @classmethod
153 def create_profile_dir(cls, profile_dir, config=None):
157 def create_profile_dir(cls, profile_dir, config=None):
154 """Create a new profile directory given a full path.
158 """Create a new profile directory given a full path.
155
159
156 Parameters
160 Parameters
157 ----------
161 ----------
158 profile_dir : str
162 profile_dir : str
159 The full path to the profile directory. If it does exist, it will
163 The full path to the profile directory. If it does exist, it will
160 be used. If not, it will be created.
164 be used. If not, it will be created.
161 """
165 """
162 return cls(location=profile_dir, config=config)
166 return cls(location=profile_dir, config=config)
163
167
164 @classmethod
168 @classmethod
165 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
169 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
166 """Create a profile dir by profile name and path.
170 """Create a profile dir by profile name and path.
167
171
168 Parameters
172 Parameters
169 ----------
173 ----------
170 path : unicode
174 path : unicode
171 The path (directory) to put the profile directory in.
175 The path (directory) to put the profile directory in.
172 name : unicode
176 name : unicode
173 The name of the profile. The name of the profile directory will
177 The name of the profile. The name of the profile directory will
174 be "profile_<profile>".
178 be "profile_<profile>".
175 """
179 """
176 if not os.path.isdir(path):
180 if not os.path.isdir(path):
177 raise ProfileDirError('Directory not found: %s' % path)
181 raise ProfileDirError('Directory not found: %s' % path)
178 profile_dir = os.path.join(path, u'profile_' + name)
182 profile_dir = os.path.join(path, u'profile_' + name)
179 return cls(location=profile_dir, config=config)
183 return cls(location=profile_dir, config=config)
180
184
181 @classmethod
185 @classmethod
182 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
186 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
183 """Find an existing profile dir by profile name, return its ProfileDir.
187 """Find an existing profile dir by profile name, return its ProfileDir.
184
188
185 This searches through a sequence of paths for a profile dir. If it
189 This searches through a sequence of paths for a profile dir. If it
186 is not found, a :class:`ProfileDirError` exception will be raised.
190 is not found, a :class:`ProfileDirError` exception will be raised.
187
191
188 The search path algorithm is:
192 The search path algorithm is:
189 1. ``os.getcwdu()``
193 1. ``os.getcwdu()``
190 2. ``ipython_dir``
194 2. ``ipython_dir``
191
195
192 Parameters
196 Parameters
193 ----------
197 ----------
194 ipython_dir : unicode or str
198 ipython_dir : unicode or str
195 The IPython directory to use.
199 The IPython directory to use.
196 name : unicode or str
200 name : unicode or str
197 The name of the profile. The name of the profile directory
201 The name of the profile. The name of the profile directory
198 will be "profile_<profile>".
202 will be "profile_<profile>".
199 """
203 """
200 dirname = u'profile_' + name
204 dirname = u'profile_' + name
201 paths = [os.getcwdu(), ipython_dir]
205 paths = [os.getcwdu(), ipython_dir]
202 for p in paths:
206 for p in paths:
203 profile_dir = os.path.join(p, dirname)
207 profile_dir = os.path.join(p, dirname)
204 if os.path.isdir(profile_dir):
208 if os.path.isdir(profile_dir):
205 return cls(location=profile_dir, config=config)
209 return cls(location=profile_dir, config=config)
206 else:
210 else:
207 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
211 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
208
212
209 @classmethod
213 @classmethod
210 def find_profile_dir(cls, profile_dir, config=None):
214 def find_profile_dir(cls, profile_dir, config=None):
211 """Find/create a profile dir and return its ProfileDir.
215 """Find/create a profile dir and return its ProfileDir.
212
216
213 This will create the profile directory if it doesn't exist.
217 This will create the profile directory if it doesn't exist.
214
218
215 Parameters
219 Parameters
216 ----------
220 ----------
217 profile_dir : unicode or str
221 profile_dir : unicode or str
218 The path of the profile directory. This is expanded using
222 The path of the profile directory. This is expanded using
219 :func:`IPython.utils.genutils.expand_path`.
223 :func:`IPython.utils.genutils.expand_path`.
220 """
224 """
221 profile_dir = expand_path(profile_dir)
225 profile_dir = expand_path(profile_dir)
222 if not os.path.isdir(profile_dir):
226 if not os.path.isdir(profile_dir):
223 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
227 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
224 return cls(location=profile_dir, config=config)
228 return cls(location=profile_dir, config=config)
225
229
226
230
General Comments 0
You need to be logged in to leave comments. Login now