00001
00002
00003
00004
00005 '''rtshell
00006
00007 Copyright (C) 2009-2014
00008 Geoffrey Biggs
00009 RT-Synthesis Research Group
00010 Intelligent Systems Research Institute,
00011 National Institute of Advanced Industrial Science and Technology (AIST),
00012 Japan
00013 All rights reserved.
00014 Licensed under the Eclipse Public License -v 1.0 (EPL)
00015 http://www.opensource.org/licenses/eclipse-1.0.txt
00016
00017 Implementation of the command to list naming contexts.
00018
00019 '''
00020
00021
00022 import optparse
00023 import os
00024 import os.path
00025 import rtctree.tree
00026 import rtctree.path
00027 import rtctree.utils
00028 import sys
00029 import traceback
00030
00031 import path
00032 import rts_exceptions
00033 import rtshell
00034
00035
00036 def get_node_long_lines(nodes, use_colour=True):
00037 info_strings = []
00038 state_width = 0
00039 total_width = 0
00040 in_width = 0
00041 out_width = 0
00042 svc_width = 0
00043 for node in nodes:
00044 if node.is_directory:
00045 if state_width == 0:
00046 state_width = 1
00047 if total_width == 0:
00048 total_width = 1
00049 if in_width == 0:
00050 in_width = 1
00051 if out_width == 0:
00052 out_width = 1
00053 if svc_width == 0:
00054 svc_width = 1
00055 name = (rtctree.utils.build_attr_string(['bold', 'blue'],
00056 supported=use_colour) + node.name +
00057 rtctree.utils.build_attr_string(['reset'],
00058 supported=use_colour))
00059 info_strings.append((('-', 0), ('-', 0), ('-', 0),
00060 ('-', 0), ('-', 0), name))
00061 elif node.is_manager:
00062
00063 if state_width == 0:
00064 state_width = 1
00065 if total_width == 0:
00066 total_width = 1
00067 if in_width == 0:
00068 in_width = 1
00069 if out_width == 0:
00070 out_width = 1
00071 if svc_width == 0:
00072 svc_width = 1
00073 name = (rtctree.utils.build_attr_string(['bold', 'green'],
00074 supported=use_colour) + node.name +
00075 rtctree.utils.build_attr_string(['reset'],
00076 supported=use_colour))
00077 info_strings.append((('-', 0), ('-', 0), ('-', 0),
00078 ('-', 0), ('-', 0), name))
00079 elif node.is_component:
00080 state = node.state
00081 state_string = node.plain_state_string
00082 if len(state_string) > state_width:
00083 state_width = len(state_string)
00084 state_string = (node.get_state_string(add_colour=use_colour),
00085 len(node.get_state_string(add_colour=use_colour)) - \
00086 len(state_string))
00087
00088 num_ports = len(node.ports)
00089 num_connected = len(node.connected_ports)
00090 total_string = '{0}/{1}'.format(num_ports, num_connected)
00091 if len(total_string) > total_width:
00092 total_width = len(total_string)
00093 coloured_string = (rtctree.utils.build_attr_string('bold',
00094 supported=use_colour) + str(num_ports) +
00095 rtctree.utils.build_attr_string('reset',
00096 supported=use_colour) + '/' + str(num_connected))
00097 total_string = (coloured_string,
00098 len(coloured_string) - len(total_string))
00099
00100 num_ports = len(node.inports)
00101 num_connected = len(node.connected_inports)
00102 in_string = '{0}/{1}'.format(num_ports, num_connected)
00103 if len(in_string) > in_width:
00104 in_width = len(in_string)
00105 coloured_string = (rtctree.utils.build_attr_string('bold',
00106 supported=use_colour) + str(num_ports) +
00107 rtctree.utils.build_attr_string('reset',
00108 supported=use_colour) + '/' + str(num_connected))
00109 in_string = (coloured_string,
00110 len(coloured_string) - len(in_string))
00111
00112 num_ports = len(node.outports)
00113 num_connected = len(node.connected_outports)
00114 out_string = '{0}/{1}'.format(num_ports, num_connected)
00115 if len(out_string) > out_width:
00116 out_width = len(out_string)
00117 coloured_string = (rtctree.utils.build_attr_string('bold',
00118 supported=use_colour) + str(num_ports) +
00119 rtctree.utils.build_attr_string('reset',
00120 supported=use_colour) + '/' + str(num_connected))
00121 out_string = (coloured_string, len(coloured_string) - \
00122 len(out_string))
00123
00124 num_ports = len(node.svcports)
00125 num_connected = len(node.connected_svcports)
00126 svc_string = '{0}/{1}'.format(num_ports, num_connected)
00127 if len(svc_string) > svc_width:
00128 svc_width = len(svc_string)
00129 coloured_string = (rtctree.utils.build_attr_string('bold',
00130 supported=use_colour) + str(num_ports) +
00131 rtctree.utils.build_attr_string('reset',
00132 supported=use_colour) + '/' + str(num_connected))
00133 svc_string = (coloured_string, len(coloured_string) - \
00134 len(svc_string))
00135
00136 info_strings.append((state_string, total_string, in_string,
00137 out_string, svc_string, node.name))
00138 elif node.is_zombie:
00139
00140 if state_width == 0:
00141 state_width = 1
00142 if total_width == 0:
00143 total_width = 1
00144 if in_width == 0:
00145 in_width = 1
00146 if out_width == 0:
00147 out_width = 1
00148 if svc_width == 0:
00149 svc_width = 1
00150 name = (rtctree.utils.build_attr_string(['faint', 'white'],
00151 supported=use_colour) + '*' + node.name +
00152 rtctree.utils.build_attr_string(['reset'],
00153 supported=use_colour))
00154 info_strings.append((('-', 0), ('-', 0), ('-', 0),
00155 ('-', 0), ('-', 0), name))
00156 else:
00157
00158 if state_width == 0:
00159 state_width = 1
00160 if total_width == 0:
00161 total_width = 1
00162 if in_width == 0:
00163 in_width = 1
00164 if out_width == 0:
00165 out_width = 1
00166 if svc_width == 0:
00167 svc_width = 1
00168 name = (rtctree.utils.build_attr_string(['faint', 'white'],
00169 supported=use_colour) + node.name +
00170 rtctree.utils.build_attr_string(['reset'],
00171 supported=use_colour))
00172 info_strings.append((('-', 0), ('-', 0), ('-', 0),
00173 ('-', 0), ('-', 0), name))
00174 state_width += 2
00175 total_width += 2
00176 in_width += 2
00177 out_width += 2
00178 svc_width += 2
00179
00180 result = []
00181 for string in info_strings:
00182 result.append('{0}{1}{2}{3}{4}{5}'.format(
00183 string[0][0].ljust(state_width + string[0][1]),
00184 string[1][0].ljust(total_width + string[1][1]),
00185 string[2][0].ljust(in_width + string[2][1]),
00186 string[3][0].ljust(out_width + string[3][1]),
00187 string[4][0].ljust(svc_width + string[4][1]),
00188 string[5]))
00189 return result
00190
00191
00192 def format_items_list(items):
00193 gap = ' '
00194 term_rows, term_cols = rtctree.utils.get_terminal_size()
00195 nrows, ncols, col_widths = rtctree.utils.get_num_columns_and_rows(
00196 [len(ii[1]) for ii in items], len(gap), term_cols)
00197 rows = [items[s:s + ncols] for s in range(0, len(items), ncols)]
00198 lines = []
00199 for r in rows:
00200 new_line = ''
00201 for ii, c in enumerate(r):
00202 new_line += '{0:{1}}'.format(c[0], col_widths[ii] + \
00203 (len(c[0]) - len(c[1]))) + gap
00204 lines.append(new_line.rstrip())
00205 return lines
00206
00207
00208 def list_directory(dir_node, long=False):
00209 listing = dir_node.children
00210 use_colour = rtctree.utils.colour_supported(sys.stdout)
00211 if long:
00212 lines = get_node_long_lines(listing, use_colour=use_colour)
00213 return lines
00214 else:
00215 items = []
00216 for entry in listing:
00217 if entry.is_directory:
00218 items.append((rtctree.utils.build_attr_string(['bold', 'blue'],
00219 supported=use_colour) + entry.name + '/' + \
00220 rtctree.utils.build_attr_string(['reset'],
00221 supported=use_colour), entry.name))
00222 elif entry.is_component:
00223 items.append((entry.name, entry.name))
00224 elif entry.is_manager:
00225 items.append((rtctree.utils.build_attr_string(['bold',
00226 'green'], supported=use_colour) + entry.name + \
00227 rtctree.utils.build_attr_string(['reset'],
00228 supported=use_colour), entry.name))
00229 elif entry.is_zombie:
00230 items.append((rtctree.utils.build_attr_string(['faint',
00231 'white'], supported=use_colour) + '*' + entry.name + \
00232 rtctree.utils.build_attr_string(['reset'],
00233 supported=use_colour), '*' + entry.name))
00234 else:
00235 items.append((rtctree.utils.build_attr_string(['faint',
00236 'white'], supported=use_colour) + entry.name + \
00237 rtctree.utils.build_attr_string(['reset'],
00238 supported=use_colour), entry.name))
00239 return format_items_list(items)
00240
00241
00242 def list_target(cmd_path, full_path, options, tree=None):
00243 use_colour = rtctree.utils.colour_supported(sys.stdout)
00244
00245 path, port = rtctree.path.parse_path(full_path)
00246 if port:
00247 raise rts_exceptions.CannotDoToPortError('list')
00248
00249 trailing_slash = False
00250 if not path[-1]:
00251
00252 trailing_slash = True
00253 path = path[:-1]
00254
00255 if not tree:
00256 tree = rtctree.tree.RTCTree(paths=path, filter=[path])
00257
00258 if not tree.has_path(path):
00259 raise rts_exceptions.NoSuchObjectError(cmd_path)
00260 if tree.is_component(path) or tree.is_unknown(path) or \
00261 tree.is_zombie(path):
00262
00263 if trailing_slash:
00264
00265
00266 raise rts_exceptions.NoSuchObjectError(cmd_path)
00267 if options.long:
00268 return get_node_long_lines([tree.get_node(path)], use_colour)
00269 else:
00270 if tree.is_component(path):
00271 return [path[-1]]
00272 elif tree.is_zombie(path):
00273 return [(rtctree.utils.build_attr_string(['faint', 'white'],
00274 supported=use_colour) + '*' + path[-1] +
00275 rtctree.utils.build_attr_string(['reset'],
00276 supported=use_colour))]
00277 else:
00278
00279 return [(rtctree.utils.build_attr_string(['faint', 'white'],
00280 supported=use_colour) + path[-1] +
00281 rtctree.utils.build_attr_string(['reset'],
00282 supported=use_colour))]
00283 elif tree.is_directory(path):
00284
00285 if options.recurse:
00286 recurse_root = tree.get_node(path)
00287 recurse_root_path = recurse_root.full_path_str
00288 def get_name(node, args):
00289 if node.full_path_str.startswith(recurse_root_path):
00290 result = node.full_path_str[len(recurse_root_path):]
00291 else:
00292 result = node.full_path_str
00293 return result.lstrip('/')
00294 dir_names = ['.'] + recurse_root.iterate(get_name,
00295 args=options.long, filter=['is_directory'])[1:]
00296 listings = recurse_root.iterate(list_directory,
00297 args=options.long, filter=['is_directory'])
00298 result = []
00299 for dir, listing in zip(dir_names, listings):
00300 if dir == '.':
00301 result.append('.:')
00302 else:
00303 result.append('./' + dir + ':')
00304 result += listing
00305 result.append('')
00306 return result
00307 else:
00308 dir_node = tree.get_node(path)
00309 return list_directory(dir_node, options.long)
00310 else:
00311 raise rts_exceptions.UnknownObjectError(cmd_path)
00312
00313
00314 def main(argv=None, tree=None):
00315 usage = '''Usage: %prog [options] [path]
00316 List a name server, directory, manager or component.'''
00317 version = rtshell.RTSH_VERSION
00318 parser = optparse.OptionParser(usage=usage, version=version)
00319 parser.add_option('-l', dest='long', action='store_true', default=False,
00320 help='Use a long listing format.')
00321 parser.add_option('-R', '--recurse', dest='recurse', action='store_true',
00322 default=False, help='List recursively. [Default: %default]')
00323 parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
00324 default=False,
00325 help='Output verbose information. [Default: %default]')
00326
00327 if argv:
00328 sys.argv = [sys.argv[0]] + argv
00329 try:
00330 options, args = parser.parse_args()
00331 except optparse.OptionError, e:
00332 print >>sys.stderr, 'OptionError:', e
00333 return 1, []
00334
00335 if not args:
00336 cmd_path = ''
00337 elif len(args) == 1:
00338 cmd_path = args[0]
00339 else:
00340 print >>sys.stderr, usage
00341 return 1, []
00342 full_path = path.cmd_path_to_full_path(cmd_path)
00343
00344 result = []
00345 try:
00346 result = list_target(cmd_path, full_path, options, tree)
00347 except Exception, e:
00348 if options.verbose:
00349 traceback.print_exc()
00350 print >>sys.stderr, '{0}: {1}'.format(os.path.basename(sys.argv[0]), e)
00351 return 1, []
00352 return 0, result
00353
00354
00355
00356