Package topo :: Package misc :: Module commandline
[hide private]
[frames] | no frames]

Source Code for Module topo.misc.commandline

  1  """ 
  2  Support functions for parsing command-line arguments and providing 
  3  the Topographica command prompt.  Typically called from the 
  4  './topographica' script, but can be called directly if using 
  5  Topographica files within a separate Python. 
  6   
  7  $Id: commandline.py 9177 2008-09-10 15:51:38Z jbednar $ 
  8  """ 
  9  __version__='$Revision: 9177 $' 
 10   
 11   
 12  from optparse import OptionParser 
 13   
 14  import sys, __main__, math, os, re 
 15   
 16  import topo 
 17   
 18  matplotlib_imported=False 
 19  try: 
 20      # Import matplotlib, if available, and use a non-GUI backend by default 
 21      import matplotlib 
 22      matplotlib_imported=True 
 23      from matplotlib import rcParams 
 24      rcParams['backend']='Agg' 
 25  except ImportError: 
 26      print "Warning: Could not import matplotlib; pylab plots will not work." 
 27   
 28  # Startup banner 
 29  BANNER = """ 
 30  Welcome to Topographica! 
 31   
 32  Type help() for interactive help with python, help(topo) for general 
 33  information about Topographica, help(commandname) for info on a 
 34  specific command, or topo.about() for info on this release, including 
 35  licensing information. 
 36  """ 
37 38 39 40 ##### Command-prompt formatting 41 # 42 -class IPCommandPromptHandler(object):
43 """ 44 Allows control over IPython's dynamic command prompts. 45 """ 46 _format = '' 47 _prompt = '' 48 49 @classmethod
50 - def set_format(cls,format):
51 """ 52 Set IPython's prompt template to format. 53 """ 54 import __main__ 55 IP = __main__.__dict__['__IP'] 56 prompt = getattr(IP.outputcache,cls._prompt) 57 prompt.p_template = format 58 prompt.set_p_str() 59 cls._format = format
60 61 @classmethod
62 - def get_format(cls):
63 """ 64 Return the current template. 65 """ 66 return cls._format
67
68 69 -class CommandPrompt(IPCommandPromptHandler):
70 """ 71 Control over input prompt. 72 73 Several predefined formats are provided, and any of these (or any 74 arbitrary string) can be used by calling set_format() with their 75 values. 76 77 See the IPython manual for details: 78 http://ipython.scipy.org/doc/manual/html/config/index.html 79 80 Examples: 81 # Use one of the predefined formats: 82 CommandPrompt.set_format(CommandPrompt.basic_format) 83 # Just print the command number: 84 CommandPrompt.set_format('\# ') 85 # Print the command number but don't use color: 86 CommandPrompt.set_format('\N ') 87 # Print the value of my_var at each prompt: 88 CommandPrompt.set_format('${my_var}>>> ') 89 """ 90 _prompt = 'prompt1' 91 92 # Predefined alternatives 93 basic_format = 'Topographica>>> ' 94 simtime_format = 'topo_t${topo.sim.timestr()}>>> ' 95 simtimecmd_format = 'topo_t${topo.sim.timestr()}_c\\#>>> ' 96 97 _format = simtimecmd_format
98
99 100 -class CommandPrompt2(IPCommandPromptHandler):
101 """ 102 Control over continuation prompt. 103 104 (See CommandPrompt.) 105 """ 106 _prompt = 'prompt2' 107 basic_format = ' .\\D.: ' 108 _format = basic_format
109
110 111 -class OutputPrompt(IPCommandPromptHandler):
112 """ 113 Control over output prompt. 114 115 (See CommandPrompt.) 116 """ 117 _prompt = 'prompt_out' 118 basic_format = 'Out[\#]:' 119 _format = basic_format
120 121 ##### 122 123 124 125 # Use to define global constants 126 global_constants = {'pi':math.pi} 127 128 # Create the topographica parser. 129 usage = "usage: topographica ([<option>]:[<filename>])*\n\ 130 where any combination of options and Python script filenames will be\n\ 131 processed in order left to right." 132 topo_parser = OptionParser(usage=usage)
133 134 135 -def sim_name_from_filename(filename):
136 """ 137 Set the simulation title from the given filename, if none has been 138 set already. 139 """ 140 if topo.sim.name is None: 141 topo.sim.name=re.sub('.ty$','',os.path.basename(filename))
142
143 144 -def boolean_option_action(option,opt_str,value,parser):
145 """Callback function for boolean-valued options that apply to the entire run.""" 146 #print "Processing %s" % (opt_str) 147 setattr(parser.values,option.dest,True)
148
149 150 -def interactive():
151 os.environ['PYTHONINSPECT']='1'
152
153 # CB: note that topographica should stay open if an error occurs 154 # anywhere after a -i (i.e. in a -c command or script) 155 -def i_action(option,opt_str,value,parser):
156 """Callback function for the -i option.""" 157 boolean_option_action(option,opt_str,value,parser) 158 interactive()
159 160 topo_parser.add_option("-i","--interactive",action="callback",callback=i_action, 161 dest="interactive",default=False, 162 help="provide an interactive prompt even if stdin does not appear to be a terminal.")
163 164 165 -def v_action(option,opt_str,value,parser):
166 """Callback function for the -v option.""" 167 import topo.param.parameterized 168 topo.param.parameterized.min_print_level=topo.param.parameterized.VERBOSE 169 print "Enabling verbose message output."
170 171 topo_parser.add_option("-v","--verbose",action="callback",callback=v_action,dest="verbose",default=False,help="""\ 172 enable verbose messaging output.""")
173 174 175 -def d_action(option,opt_str,value,parser):
176 """Callback function for the -d option.""" 177 import topo.param.parameterized 178 topo.param.parameterized.min_print_level=topo.param.parameterized.DEBUG 179 print "Enabling debugging message output."
180 181 topo_parser.add_option("-d","--debug",action="callback",callback=d_action,dest="debug",default=False,help="""\ 182 enable debugging message output (implies --verbose).""")
183 184 185 186 -def l_action(option,opt_str,value,parser):
187 """Callback function for the -l option.""" 188 boolean_option_action(option,opt_str,value,parser) 189 from topo.misc.legacy import install_legacy_support 190 print "Enabling legacy support." 191 install_legacy_support()
192 193 topo_parser.add_option("-l","--legacy",action="callback",callback=l_action,dest="legacy",default=False,help="""\ 194 launch Topographica with legacy support enabled.""")
195 196 197 -def gui(start=True):
198 """Start the GUI as if -g were supplied in the command used to launch Topographica.""" 199 if matplotlib_imported: 200 from matplotlib import rcParams 201 rcParams['backend']='TkAgg' 202 auto_import_commands() 203 if start: 204 import topo.tkgui 205 topo.tkgui.start()
206
207 208 ###### CB: TESTING (Jun 2008) 209 -def start_gui_from_ide_newthread():
210 # e.g. from IDLE 211 auto_import_commands() 212 from threading import Thread 213 from topo.tkgui import start 214 t = Thread(target=start,kwargs={'mainloop':True}) 215 t.start()
216
217 -def start_gui_from_ide(root=None):
218 # e.g. from IPython in Tkinter 219 auto_import_commands() 220 from topo.tkgui import start 221 start(mainloop=True,root=root)
222 ######
223 224 225 # Topographica stays open if an error occurs after -g 226 # (see comment by i_action) 227 -def g_action(option,opt_str,value,parser):
228 """Callback function for the -g option.""" 229 boolean_option_action(option,opt_str,value,parser) 230 interactive() 231 gui()
232 233 234 topo_parser.add_option("-g","--gui",action="callback",callback=g_action,dest="gui",default=False,help="""\ 235 launch an interactive graphical user interface; \ 236 equivalent to -c 'from topo.misc.commandline import gui ; gui()'. \ 237 Implies -a.""")
238 239 240 241 -def G_action(option,opt_str,value,parser):
242 """Callback function for the -mg option.""" 243 boolean_option_action(option,opt_str,value,parser) 244 interactive() 245 gui(start=False)
246 247 248 topo_parser.add_option("-G","--more_gui",action="callback",callback=G_action,dest="more_gui",default=False,help="""\ 249 EXPERIMENTAL: launch a more interactive graphical user interface...; \ 250 Implies -a.""")
251 252 253 254 # Keeps track of whether something has been performed, when deciding whether to assume -i 255 something_executed=False 256 257 -def c_action(option,opt_str,value,parser):
258 """Callback function for the -c option.""" 259 #print "Processing %s '%s'" % (opt_str,value) 260 exec value in __main__.__dict__ 261 global something_executed 262 something_executed=True
263 264 topo_parser.add_option("-c","--command",action = "callback",callback=c_action,type="string", 265 default=[],dest="commands",metavar="\"<command>\"", 266 help="string of arbitrary Python code to be executed in the main namespace.")
267 268 269 -def auto_import_commands():
270 """Import the contents of all files in the topo/command/ directory.""" 271 import re,os 272 from filepath import application_path 273 import __main__ 274 275 for f in os.listdir(os.path.join(application_path,"topo/command")): 276 if re.match('^[^_].*\.py$',f): 277 modulename = re.sub('\.py$','',f) 278 exec "from topo.command."+modulename+" import *" in __main__.__dict__
279
280 -def a_action(option,opt_str,value,parser):
281 """Callback function for the -a option.""" 282 auto_import_commands()
283 284 topo_parser.add_option("-a","--auto-import-commands",action="callback",callback=a_action,help="""\ 285 import everything from commands/*.py into the main namespace, for convenience; \ 286 equivalent to -c 'from topo.misc.commandline import auto_import_commands ; auto_import_commands()'.""")
287 288 289 290 -def exec_startup_files():
291 """ 292 Execute startup files, looking at appropriate locations for many different platforms. 293 """ 294 home = os.path.expanduser("~") # dotfiles on unix 295 appdata = os.path.expandvars("$APPDATA") # application data on windows 296 appsupport = os.path.join(home,"Library","Application Support") # application support on OS X 297 298 rcpath = os.path.join(home,'.topographicarc') 299 inipath = os.path.join(appdata,'Topographica','topographica.ini') 300 configpath = os.path.join(appsupport,'Topographica','topographica.config') 301 302 for startup_file in (rcpath,configpath,inipath): 303 if os.path.exists(startup_file): 304 print "Executing user startup file %s" % (startup_file) 305 execfile(startup_file,__main__.__dict__)
306
307 308 ### Notes about choices for topographica.rc equivalents on different platforms 309 # 310 ## Windows: 311 # Location -- Most programs use the registry or a folder in %appdata% (which is typically 312 # ~\Application Data). The registry is not easily accessible for users, and %appdata% is 313 # a hidden folder, which means it doesn't appear in Explorer (or file-open dialogs). 314 # Most programs do not have any user-editable configuration files, so this does not matter 315 # to them. Maybe we should just use ~\topographica.ini? 316 # 317 # Name -- Considered topographica.rc, topographica.dat, topographica.cfg, topographica.ini. 318 # Of those, only .ini is registered as standard in Windows. According to Winows Explorer: 319 # "Files with extension 'INI' are of type 'Configuration Settings'" 320 # Importantly, this means they are already setup to be editable by notepad by default, so 321 # they can be double clicked. 322 # 323 # http://mail.python.org/pipermail/python-list/2005-September/341702.html 324 # 325 ## Mac OS: 326 # Location -- Seems like programs use either ~/Library/AppName or (more commonly) 327 # ~/Library/Application Support/AppName (CEBALERT: is there a var. for that on OS X?). 328 # 329 # Name -- there are many different extensions (e.g. dat, config, cfg, ini), none of which 330 # opens with any application by default. Some applications use xml. 331 332 333 334 335 ### Execute what is specified by the options. 336 337 -def process_argv(argv):
338 """ 339 Process command-line arguments (minus argv[0]!), rearrange and execute. 340 """ 341 # Initial preparation 342 import __main__ 343 for (k,v) in global_constants.items(): 344 exec '%s = %s' % (k,v) in __main__.__dict__ 345 346 exec_startup_files() 347 348 # Repeatedly process options, if any, followed by filenames, if any, until nothing is left 349 topo_parser.disable_interspersed_args() 350 args=argv 351 option=None 352 global something_executed 353 while True: 354 # Process options up until the first filename 355 (option,args) = topo_parser.parse_args(args,option) 356 357 # Handle filename 358 if args: 359 filename=args.pop(0) 360 #print "Executing %s" % (filename) 361 filedir = os.path.dirname(os.path.abspath(filename)) 362 sys.path.insert(0,filedir) # Allow imports relative to this file's path 363 sim_name_from_filename(filename) # Default value of topo.sim.name 364 365 execfile(filename,__main__.__dict__) 366 something_executed=True 367 368 if not args: 369 break 370 371 372 # If no scripts and no commands were given, pretend -i was given. 373 if not something_executed: interactive() 374 375 if option.gui: topo.guimain.title(topo.sim.name) 376 377 ## INTERACTIVE SESSION BEGINS HERE (i.e. can't have anything but 378 ## some kind of cleanup code afterwards) 379 if option.more_gui: 380 from topo.tkgui import start 381 382 # CB: also need to redirect messages from the standard console 383 # to the graphical console 384 385 # Stop IPython namespace hack? 386 # http://www.nabble.com/__main__-vs-__main__-td14606612.html 387 __main__.__name__="__mynamespace__" 388 389 root = start(console_has_console=True) 390 topo.guimain.title(topo.sim.name) 391 root.mainloop() 392 393 394 elif os.environ.