##// END OF EJS Templates
catch unicode error listing profiles...
MinRK -
Show More
@@ -1,310 +1,313 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 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 os
25 25
26 26 from IPython.config.application import Application
27 27 from IPython.core.application import (
28 28 BaseIPythonApplication, base_flags
29 29 )
30 30 from IPython.core.profiledir import ProfileDir
31 31 from IPython.utils.importstring import import_item
32 32 from IPython.utils.path import get_ipython_dir, get_ipython_package_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 ipython locate profile foo # print the path to the directory for profile 'foo'
90 90 """
91 91
92 92 #-----------------------------------------------------------------------------
93 93 # Profile Application Class (for `ipython profile` subcommand)
94 94 #-----------------------------------------------------------------------------
95 95
96 96
97 97 def list_profiles_in(path):
98 98 """list profiles in a given root directory"""
99 99 files = os.listdir(path)
100 100 profiles = []
101 101 for f in files:
102 try:
102 103 full_path = os.path.join(path, f)
104 except UnicodeError:
105 continue
103 106 if os.path.isdir(full_path) and f.startswith('profile_'):
104 107 profiles.append(f.split('_',1)[-1])
105 108 return profiles
106 109
107 110
108 111 def list_bundled_profiles():
109 112 """list profiles that are bundled with IPython."""
110 113 path = os.path.join(get_ipython_package_dir(), u'config', u'profile')
111 114 files = os.listdir(path)
112 115 profiles = []
113 116 for profile in files:
114 117 full_path = os.path.join(path, profile)
115 118 if os.path.isdir(full_path) and profile != "__pycache__":
116 119 profiles.append(profile)
117 120 return profiles
118 121
119 122
120 123 class ProfileLocate(BaseIPythonApplication):
121 124 description = """print the path an IPython profile dir"""
122 125
123 126 def parse_command_line(self, argv=None):
124 127 super(ProfileLocate, self).parse_command_line(argv)
125 128 if self.extra_args:
126 129 self.profile = self.extra_args[0]
127 130
128 131 def start(self):
129 132 print self.profile_dir.location
130 133
131 134
132 135 class ProfileList(Application):
133 136 name = u'ipython-profile'
134 137 description = list_help
135 138 examples = _list_examples
136 139
137 140 aliases = Dict({
138 141 'ipython-dir' : 'ProfileList.ipython_dir',
139 142 'log-level' : 'Application.log_level',
140 143 })
141 144 flags = Dict(dict(
142 145 debug = ({'Application' : {'log_level' : 0}},
143 146 "Set Application.log_level to 0, maximizing log output."
144 147 )
145 148 ))
146 149
147 150 ipython_dir = Unicode(get_ipython_dir(), config=True,
148 151 help="""
149 152 The name of the IPython directory. This directory is used for logging
150 153 configuration (through profiles), history storage, etc. The default
151 154 is usually $HOME/.ipython. This options can also be specified through
152 155 the environment variable IPYTHONDIR.
153 156 """
154 157 )
155 158
156 159
157 160 def _print_profiles(self, profiles):
158 161 """print list of profiles, indented."""
159 162 for profile in profiles:
160 163 print ' %s' % profile
161 164
162 165 def list_profile_dirs(self):
163 166 profiles = list_bundled_profiles()
164 167 if profiles:
165 168 print
166 169 print "Available profiles in IPython:"
167 170 self._print_profiles(profiles)
168 171 print
169 172 print " The first request for a bundled profile will copy it"
170 173 print " into your IPython directory (%s)," % self.ipython_dir
171 174 print " where you can customize it."
172 175
173 176 profiles = list_profiles_in(self.ipython_dir)
174 177 if profiles:
175 178 print
176 179 print "Available profiles in %s:" % self.ipython_dir
177 180 self._print_profiles(profiles)
178 181
179 182 profiles = list_profiles_in(os.getcwdu())
180 183 if profiles:
181 184 print
182 185 print "Available profiles in current directory (%s):" % os.getcwdu()
183 186 self._print_profiles(profiles)
184 187
185 188 print
186 189 print "To use any of the above profiles, start IPython with:"
187 190 print " ipython --profile=<name>"
188 191 print
189 192
190 193 def start(self):
191 194 self.list_profile_dirs()
192 195
193 196
194 197 create_flags = {}
195 198 create_flags.update(base_flags)
196 199 # don't include '--init' flag, which implies running profile create in other apps
197 200 create_flags.pop('init')
198 201 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
199 202 "reset config files in this profile to the defaults.")
200 203 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
201 204 "Include the config files for parallel "
202 205 "computing apps (ipengine, ipcontroller, etc.)")
203 206
204 207
205 208 class ProfileCreate(BaseIPythonApplication):
206 209 name = u'ipython-profile'
207 210 description = create_help
208 211 examples = _create_examples
209 212 auto_create = Bool(True, config=False)
210 213 def _log_format_default(self):
211 214 return "[%(name)s] %(message)s"
212 215
213 216 def _copy_config_files_default(self):
214 217 return True
215 218
216 219 parallel = Bool(False, config=True,
217 220 help="whether to include parallel computing config files")
218 221 def _parallel_changed(self, name, old, new):
219 222 parallel_files = [ 'ipcontroller_config.py',
220 223 'ipengine_config.py',
221 224 'ipcluster_config.py'
222 225 ]
223 226 if new:
224 227 for cf in parallel_files:
225 228 self.config_files.append(cf)
226 229 else:
227 230 for cf in parallel_files:
228 231 if cf in self.config_files:
229 232 self.config_files.remove(cf)
230 233
231 234 def parse_command_line(self, argv):
232 235 super(ProfileCreate, self).parse_command_line(argv)
233 236 # accept positional arg as profile name
234 237 if self.extra_args:
235 238 self.profile = self.extra_args[0]
236 239
237 240 flags = Dict(create_flags)
238 241
239 242 classes = [ProfileDir]
240 243
241 244 def _import_app(self, app_path):
242 245 """import an app class"""
243 246 app = None
244 247 name = app_path.rsplit('.', 1)[-1]
245 248 try:
246 249 app = import_item(app_path)
247 250 except ImportError as e:
248 251 self.log.info("Couldn't import %s, config file will be excluded", name)
249 252 except Exception:
250 253 self.log.warn('Unexpected error importing %s', name, exc_info=True)
251 254 return app
252 255
253 256 def init_config_files(self):
254 257 super(ProfileCreate, self).init_config_files()
255 258 # use local imports, since these classes may import from here
256 259 from IPython.terminal.ipapp import TerminalIPythonApp
257 260 apps = [TerminalIPythonApp]
258 261 for app_path in (
259 262 'IPython.qt.console.qtconsoleapp.IPythonQtConsoleApp',
260 263 'IPython.html.notebookapp.NotebookApp',
261 264 'IPython.nbconvert.nbconvertapp.NbConvertApp',
262 265 ):
263 266 app = self._import_app(app_path)
264 267 if app is not None:
265 268 apps.append(app)
266 269 if self.parallel:
267 270 from IPython.parallel.apps.ipcontrollerapp import IPControllerApp
268 271 from IPython.parallel.apps.ipengineapp import IPEngineApp
269 272 from IPython.parallel.apps.ipclusterapp import IPClusterStart
270 273 from IPython.parallel.apps.iploggerapp import IPLoggerApp
271 274 apps.extend([
272 275 IPControllerApp,
273 276 IPEngineApp,
274 277 IPClusterStart,
275 278 IPLoggerApp,
276 279 ])
277 280 for App in apps:
278 281 app = App()
279 282 app.config.update(self.config)
280 283 app.log = self.log
281 284 app.overwrite = self.overwrite
282 285 app.copy_config_files=True
283 286 app.profile = self.profile
284 287 app.init_profile_dir()
285 288 app.init_config_files()
286 289
287 290 def stage_default_config_file(self):
288 291 pass
289 292
290 293
291 294 class ProfileApp(Application):
292 295 name = u'ipython-profile'
293 296 description = profile_help
294 297 examples = _main_examples
295 298
296 299 subcommands = Dict(dict(
297 300 create = (ProfileCreate, ProfileCreate.description.splitlines()[0]),
298 301 list = (ProfileList, ProfileList.description.splitlines()[0]),
299 302 ))
300 303
301 304 def start(self):
302 305 if self.subapp is None:
303 306 print "No subcommand specified. Must specify one of: %s"%(self.subcommands.keys())
304 307 print
305 308 self.print_description()
306 309 self.print_subcommands()
307 310 self.exit(1)
308 311 else:
309 312 return self.subapp.start()
310 313
General Comments 0
You need to be logged in to leave comments. Login now