rtls.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- Python -*-
00003 # -*- coding: utf-8 -*-
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             # Managers are not handled yet
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             # Zombies are treated like unknowns, but tagged with *
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             # Other types are unknowns
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         # There was a trailing slash
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         # Path points to a single object: print it like 'ls <file>'.
00263         if trailing_slash:
00264             # If there was a trailing slash, complain that the object is not a
00265             # directory.
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                 # Assume unknown
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         # If recursing, need to list this directory and all its children
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 # vim: tw=79
00356 


rtshell
Author(s): Geoffrey Biggs
autogenerated on Fri Aug 28 2015 12:55:12