13 log = logging.getLogger( __name__ )
14 log.setLevel( logging.INFO )
16 handler = logging.StreamHandler()
17 format =
"%(levelname)s:%(name)s: %(message)s"
18 handler.setFormatter( logging.Formatter( format ) )
19 log.addHandler( handler )
22 historyFile =
'.coolconsole_hist'
26 This class extends InteractiveConsole with command line history. The
27 history can be accessed with the usual CURSOR UP keystroke. It is also
28 stored to a file '%s' in the user's home directory.
33 filename = "<console>",
34 histfile = os.path.join( os.environ[
"HOME"], historyFile) ):
35 code.InteractiveConsole.__init__( self )
39 readline.parse_and_bind(
"tab: complete" )
40 readline.set_history_length( 100 )
41 if hasattr( readline,
"read_history_file" ):
43 readline.read_history_file( histfile )
49 readline.write_history_file( histfile )
55 commands = {
'help' :
'help overview',
56 'less' :
'list contents of folders, e.g. less "/a"',
57 'more' :
'list contents of folders (ATLAS specific)',
58 'ls' :
'list contents of foldersets, e.g. ls "/"',
59 'll' :
'list contents of foldersets with entry count',
60 'exit' :
'quit the interpreter session',
61 'quit' :
'alias for exit',
62 'open' :
"open the specified database, "
63 "e.g. open 'sqlite://...'",
64 'cd' :
'change directory',
65 'pwd' :
'print current directory',
66 'rmdir' :
'remove a folder or folderset',
67 'usetag' :
'set subsequent list operations (less) to use given COOL tag',
68 'usechan' :
'set subsequent list operations (less) to display given COOL channel number only',
69 'userunlumi' :
'set limits for run/lumi blocks in more/less',
70 'usetimes' :
'set limits for timestamps in more/less',
71 'pws' :
'print current tag and channel selections used by less',
72 'listtags' :
'list tags in folder / folder set',
73 'listchans' :
'list channels in folder',
74 'listinfo' :
'list info about folder (type, columns)',
75 'filtertags' :
'list tags in folder / folder set with filtering',
76 'settag' :
'set hierarchical tag for a folder+parent',
77 'settginfo' :
'set tag description string',
78 'setchan' :
'set channel name/description',
79 'clonetag' :
'clone data from one tag to another',
80 'setdesc' :
'set folder description (meta-data) string',
81 'rmtag' :
'remove tag or hierarchical tag relation to a parent',
82 'locktag' :
'lock a tag so the contents cannot be changed',
83 'headtag' :
'apply HEAD-style tag to a folder',
84 'tracetags':
'list tags defined in subfolders for parent'
87 banner =
"Welcome to AtlCoolConsole. Type 'help' for instructions."
90 HistoryConsole.__init__( self )
95 self.
push(
'from CoolConvUtilities import AtlCoolTool' )
96 if connectString
is not None:
98 self.
push(
'print (this)' )
100 print (
"Not connected. Use the 'open' command to connect to "
102 HistoryConsole.interact( self, self.
banner )
108 res=re.search(
'^' + command +
r'($|\s+(?P<remainder>.*))', line )
110 return command, res.group(
'remainder')
or ""
115 if command ==
'less':
117 elif command ==
'more':
119 elif command ==
'ls':
120 return self.
command_ls( argumentString,
False )
121 elif command ==
'll':
123 elif command ==
'help':
125 elif command ==
'exit':
127 elif command ==
'quit':
129 elif command ==
'open':
131 elif command ==
'listtags':
133 elif command ==
'filtertags':
135 elif command ==
'listchans':
137 elif command ==
'listinfo':
139 elif command ==
'rmdir':
141 elif command ==
'usetag':
143 elif command ==
'usechan':
145 elif command ==
'settag':
147 elif command ==
'settginfo':
149 elif command ==
'setchan':
151 elif command ==
'userunlumi':
153 elif command ==
'usetimes':
155 elif command ==
'clonetag':
157 elif command ==
'rmtag':
159 elif command ==
'locktag':
161 elif command ==
'headtag':
163 elif command ==
'tracetags':
165 elif command ==
'setdesc':
169 elif command ==
'pwd':
171 elif command ==
'pws':
178 if argumentString
is None:
179 raise Exception(
"usage: less <folder>" )
180 argumentString = argumentString.strip()
181 nodes = argumentString.split()
184 cmds.append(
'this.less("%s", header=True)' % node )
185 return ';'.
join( cmds )
188 if argumentString
is None:
189 raise Exception(
"usage: more <folder>" )
190 argumentString = argumentString.strip()
191 nodes = argumentString.split()
194 cmds.append(
'this.more("%s", header=True)' % node )
195 return ';'.
join( cmds )
199 if argumentString
is None: argumentString =
'.'
200 argumentString = argumentString.strip()
201 if argumentString ==
'': argumentString =
'.'
202 nodes = argumentString.split()
205 if (doCount): tof=
'True'
207 cmds.append(
'this.ls("%s", header=True, doCount=%s)' % (node,tof) )
208 return ';'.
join( cmds )
211 return ';'.
join([
'this.pwd()'])
214 return ';'.
join([
'this.pws()'])
217 if argumentString
is None: argumentString =
'.'
218 argumentString = argumentString.strip()
219 if argumentString
is None: argumentString =
'.'
220 nodes = argumentString.split()
223 cmds.append(
'this.lstags("%s")' % node )
224 return ';'.
join( cmds )
227 if argumentString
is None or argumentString==
"": argumentString =
'.'
228 argumentString = argumentString.strip()
229 if argumentString
is None: argumentString =
'.'
230 args = argumentString.split()
236 cmds.append(
'this.lstags("%s",pattern="%s")' % (node,pattern))
237 return ';'.
join(cmds)
241 if argumentString
is None: argumentString =
'.'
242 argumentString = argumentString.strip()
243 if argumentString
is None: argumentString =
'.'
244 nodes = argumentString.split()
247 cmds.append(
'this.listchans("%s")' % node )
248 return ';'.
join( cmds )
251 if argumentString
is None: argumentString =
'.'
252 argumentString = argumentString.strip()
253 if argumentString
is None: argumentString =
'.'
254 nodes = argumentString.split()
257 cmds.append(
'this.listinfo("%s")' % node )
258 return ';'.
join( cmds )
261 argumentString = argumentString.strip()
263 cmds.append(
'this.rmdir("%s")' % argumentString)
264 return ';'.
join( cmds )
267 argumentString = argumentString.strip()
269 cmds.append(
'this.usetag("%s")' % argumentString)
270 return ';'.
join( cmds )
273 argumentString = argumentString.strip()
275 cmds.append(
'this.usechan("%s")' % argumentString)
276 return ';'.
join( cmds )
279 if argumentString
is None: argumentString =
'/'
280 argumentString = argumentString.strip()
281 if argumentString ==
'': argumentString =
'/'
283 cmds.append(
'this.cd("%s")' % argumentString)
284 return ';'.
join( cmds )
287 args=argumentString.split()
289 print (
'Usage: settag <folder> <foldertag> <parenttag>')
292 cmds.append(
'this.settag("%s")' % argumentString)
293 return ';'.
join(cmds)
296 args=argumentString.split()
298 print (
'Usage: settginfo <folder> <tag> <description>')
301 cmds.append(
'this.settginfo("%s")' % argumentString)
302 return ';'.
join(cmds)
305 args=argumentString.split()
307 print (
'Usage: setchan <folder> <chanID> <chanName> {<chanDescr>}')
310 cmds.append(
'this.setchan("%s")' % argumentString)
311 return ';'.
join(cmds)
314 args=argumentString.split()
315 if len(args)!=1
and len(args)<4:
316 print (
'Usage: userunlumi <run1> {<LB1> <run2> <LB2>}')
319 cmds.append(
'this.userunlumi("%s")' % argumentString)
320 return ';'.
join(cmds)
323 args=argumentString.split()
325 print (
'Usage: usetimes <time1> <time2>')
328 cmds.append(
'this.usetimes("%s")' % argumentString)
329 return ';'.
join(cmds)
332 args=argumentString.split()
334 print (
'Usage: clonetag <folder> <sourcetag> <desttag>')
337 cmds.append(
'this.clonetag("%s")' % argumentString)
338 return ';'.
join(cmds)
342 args=argumentString.split()
344 print (
'Usage: rmtag <folder> <leaf or parent tag>')
347 cmds.append(
'this.rmtag("%s")' % argumentString)
348 return ';'.
join(cmds)
351 args=argumentString.split()
353 print (
'Usage: locktag <folder> <tag> {action=l|p|u|r}')
356 cmds.append(
'this.locktag("%s")' % argumentString)
357 return ';'.
join(cmds)
360 args=argumentString.split()
362 print (
'Usage: headtag <folder> <tag>')
365 cmds.append(
'this.headtag("%s")' % argumentString)
366 return ';'.
join(cmds)
370 args=argumentString.split()
372 print (
'Usage: tracetags <folder> <foldertag>')
375 cmds.append(
'this.tracetags("%s")' % argumentString)
376 return ';'.
join(cmds)
380 args=argumentString.split()
382 print (
'Usage: setdesc <folder> {<newdesc>}')
385 cmds.append(
'this.setdesc("%s")' % argumentString)
386 return ';'.
join(cmds)
390 if argumentString
is not None and argumentString !=
'':
393 return 'help ' + argumentString
394 print (
'Available commands:')
398 print (
' %(key)-8s : %(value)s' % {
'key' : key,
400 print (
"These commands are shortcuts that are forwarded to a CoolTool")
401 print (
"instance 'this', referring to the currently connected database.")
402 print (
"Since this environment is a fully functional python shell,")
403 print (
"'this' can be used like any python object, e.g.:")
404 print (
" this.ls( '/' )")
409 return 'import sys ; sys.exit(0)'
413 log.debug(
'argumentString: ' + argumentString )
414 if (
not argumentString.startswith(
'"')
and
415 not argumentString.startswith(
"'") ):
416 argumentString =
"'" + argumentString +
"'"
417 log.debug(
'argumentString: ' + argumentString )
418 return 'this = AtlCoolTool.AtlCoolTool(%s)' % argumentString
422 command, remainder = self.
parseLine( line )
423 log.debug(
'command: %s' % command )
424 log.debug(
'remainder: %s' % remainder )
428 log.debug(
'command: "%s"' % res )
429 interpreterCommand = res
431 interpreterCommand = line
434 return HistoryConsole.push( self, interpreterCommand )
439 if __name__ ==
'__main__':
442 usage = (
'Usage: %s <connect string>\n'
443 '\t<connect string>: a RAL connect string\n'
447 if len( sys.argv ) == 2:
448 connectString = sys.argv[1]