rtcat.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 display component information.
00018 
00019 '''
00020 
00021 
00022 import optparse
00023 import os
00024 import os.path
00025 import rtctree.exceptions
00026 import rtctree.tree
00027 import rtctree.path
00028 import rtctree.utils
00029 import SDOPackage
00030 import sys
00031 import traceback
00032 
00033 import path
00034 import rts_exceptions
00035 import rtshell
00036 
00037 
00038 def format_port(port, comp, start_indent=0, use_colour=True, long=0):
00039     result = []
00040     indent = start_indent
00041     if long > 0:
00042         tag = '-'
00043     else:
00044         tag = '+'
00045     name_string = rtctree.utils.build_attr_string('bold',
00046             supported=use_colour) + port.name + \
00047                 rtctree.utils.build_attr_string('reset', supported=use_colour)
00048     result.append('{0}{1}: {2}'.format(tag.rjust(indent), port.porttype,
00049                                        name_string))
00050     if long > 0:
00051         indent += 2
00052         keys = port.properties.keys()
00053         keys.sort()
00054         pad_length = max([len(key) for key in keys]) + 2
00055         for key in keys:
00056             result.append('{0}{1}{2}'.format(''.ljust(indent),
00057                     key.ljust(pad_length), port.properties[key]))
00058         if port.porttype == 'CorbaPort' and port.interfaces:
00059             for intf in port.interfaces:
00060                 result.append('{0}Interface:'.format(''.ljust(indent)))
00061                 pad_length = 15 # = len('Instance name') + 2
00062                 indent += 2
00063                 result.append('{0}{1}{2}'.format(''.ljust(indent),
00064                         'Instance name'.ljust(pad_length),
00065                         intf.instance_name))
00066                 result.append('{0}{1}{2}'.format(''.ljust(indent),
00067                         'Type name'.ljust(pad_length),
00068                         intf.type_name))
00069                 result.append('{0}{1}{2}'.format(''.ljust(indent),
00070                         'Polarity'.ljust(pad_length),
00071                         intf.polarity_as_string(add_colour=use_colour)))
00072                 indent -= 2
00073         num_conns = len(port.connections)
00074         for conn in port.connections:
00075             if long > 1:
00076                 tag2 = '-'
00077             else:
00078                 tag2 = '+'
00079             dest_ports = []
00080             for name, p in conn.ports:
00081                 # Handle the case of unknown port owners
00082                 if not p:
00083                     dest_ports.append(name)
00084                     num_conns -= 1
00085                 # Filter out ports belonging to this comp
00086                 elif not comp.get_port_by_ref(p.object):
00087                     dest_ports.append(name)
00088                     num_conns -= 1
00089             if dest_ports:
00090                 result.append('{0}Connected to  {1}'.format(
00091                     tag2.rjust(indent), rtctree.utils.build_attr_string('bold',
00092                         supported=use_colour) + dest_ports[0] + \
00093                         rtctree.utils.build_attr_string('reset',
00094                             supported=use_colour)))
00095                 if len(dest_ports) > 1:
00096                     for dp in dest_ports[1:]:
00097                         result.append('{0}{1}{2}'.format(''.ljust(indent),
00098                             ''.ljust(14),
00099                         rtctree.utils.build_attr_string('bold',
00100                             supported=use_colour) + dp + \
00101                                 rtctree.utils.build_attr_string('reset',
00102                                     supported=use_colour)))
00103                 if long > 1:
00104                     indent += 2
00105                     keys = [k for k in conn.properties.keys() \
00106                             if not k.endswith('inport_ref') \
00107                             if not k.endswith('inport_ior')]
00108                     pad_length = max([len('Name')] + \
00109                                      [len(key) for key in keys]) + 2
00110                     result.append('{0}{1}{2}'.format(''.ljust(indent),
00111                             'Name'.ljust(pad_length), conn.name))
00112                     result.append('{0}{1}{2}'.format(''.ljust(indent),
00113                             'ID'.ljust(pad_length), conn.id))
00114                     for key in keys:
00115                         result.append('{0}{1}{2}'.format(''.ljust(indent),
00116                                 key.ljust(pad_length),
00117                                 conn.properties[key]))
00118                     indent -= 2
00119         if num_conns > 0:
00120             if num_conns > 1:
00121                 plural = 's'
00122             else:
00123                 plural = ''
00124             result.append('{0}({1} other connection{2})'.format(\
00125                     ''.rjust(indent), num_conns, plural))
00126         indent -= 2
00127     return result
00128 
00129 
00130 def find_composite_comp(tree, member, inst_name):
00131     def get_fp(mgr, args):
00132         for c in mgr.components:
00133             if c.instance_name == inst_name:
00134                 return c.full_path_str
00135         return None
00136     def is_correct_mgr(node):
00137         has_member = False
00138         has_inst_name = False
00139         for c in node.components:
00140             if c.instance_name == inst_name:
00141                 has_inst_name = True
00142             elif c.instance_name == member.instance_name:
00143                 has_member = True
00144         return has_member and has_inst_name
00145     return tree.iterate(get_fp, filter=['is_manager', is_correct_mgr])
00146 
00147 
00148 def format_composite(comp, tree, start_indent=0, use_colour=True, long=0):
00149     result = []
00150     indent = start_indent
00151     for o in comp.organisations:
00152         if not o.sdo_id:
00153             sdo_id = 'Unknown'
00154         else:
00155             sdo_id = o.sdo_id
00156         id_str = rtctree.utils.build_attr_string('bold',
00157                 supported=use_colour) + sdo_id + \
00158                         rtctree.utils.build_attr_string('reset',
00159                         supported=use_colour)
00160         if long > 0:
00161             tag = '-'
00162         else:
00163             tag = '+'
00164         result.append('{0}Composition {1}'.format(tag.rjust(indent),
00165             id_str))
00166         if long > 0:
00167             indent += 2
00168             padding = 8 # = len('Member') + 2
00169             result.append('{0}{1}{2}'.format(''.ljust(indent),
00170                 'ID'.ljust(padding), o.org_id))
00171             for m in o.members:
00172                 c_path = find_composite_comp(tree, comp, m)
00173                 if c_path:
00174                     result.append('{0}{1}{2}'.format(''.ljust(indent),
00175                         'Member'.ljust(padding), c_path[0]))
00176                 else:
00177                     result.append('{0}{1}{2}'.format(''.ljust(indent),
00178                         'Member'.ljust(padding), 'Unknown'))
00179             indent -= 2
00180     return result
00181 
00182 
00183 def format_comp_member(comp, tree, start_indent=0, use_colour=True, long=0):
00184     result = []
00185     indent = start_indent
00186     for po in comp.parent_organisations:
00187         if not po.sdo_id:
00188             sdo_id = 'Unknown'
00189         else:
00190             sdo_id = po.sdo_id
00191         id_str = rtctree.utils.build_attr_string('bold',
00192                 supported=use_colour) + sdo_id + \
00193                         rtctree.utils.build_attr_string('reset',
00194                         supported=use_colour)
00195         if long > 0:
00196             tag = '-'
00197         else:
00198             tag = '+'
00199         result.append('{0}Parent composition {1}'.format(tag.rjust(indent),
00200             id_str))
00201         if long > 0:
00202             indent += 2
00203             padding = 6 # = len('Path') + 2
00204             result.append('{0}{1}{2}'.format(''.ljust(indent),
00205                 'ID'.ljust(padding), po.org_id))
00206             composite_path = find_composite_comp(tree, comp, po.sdo_id)
00207             if composite_path:
00208                 result.append('{0}{1}{2}'.format(''.ljust(indent),
00209                     'Path'.ljust(padding), composite_path[0]))
00210             else:
00211                 result.append('{0}{1}{2}'.format(''.ljust(indent),
00212                     'Path'.ljust(padding), 'Unknown'))
00213             indent -= 2
00214     return result
00215 
00216 
00217 def format_ec(ec, start_indent=0, use_colour=True, long=0):
00218     result = []
00219     indent = start_indent
00220     handle_str = rtctree.utils.build_attr_string('bold',
00221             supported=use_colour) + str(ec.handle) + \
00222                     rtctree.utils.build_attr_string('reset',
00223                     supported=use_colour)
00224     if long > 0:
00225         result.append('{0}Execution Context {1}'.format(\
00226                 '-'.rjust(indent), handle_str))
00227         padding = 7 # = len('State') + 2
00228         indent += 2
00229         result.append('{0}{1}{2}'.format(''.ljust(indent),
00230             'State'.ljust(padding),
00231             ec.running_as_string(add_colour=use_colour)))
00232         result.append('{0}{1}{2}'.format(''.ljust(indent),
00233             'Kind'.ljust(padding),
00234             ec.kind_as_string(add_colour=use_colour)))
00235         result.append('{0}{1}{2}'.format(''.ljust(indent),
00236             'Rate'.ljust(padding), ec.rate))
00237         if ec.owner_name:
00238             result.append('{0}{1}{2}'.format(''.ljust(indent),
00239                 'Owner'.ljust(padding), ec.owner_name))
00240         if ec.participant_names:
00241             if long > 1:
00242                     result.append('{0}{1}'.format('-'.rjust(indent),
00243                         'Participants'.ljust(padding)))
00244                     indent += 2
00245                     for pn in ec.participant_names:
00246                         result.append('{0}{1}'.format(''.ljust(indent),
00247                             pn))
00248                     indent -= 2
00249             else:
00250                 result.append('{0}{1}'.format('+'.rjust(indent),
00251                     'Participants'.ljust(padding)))
00252         if ec.properties:
00253             if long > 1:
00254                 result.append('{0}{1}'.format('-'.rjust(indent),
00255                     'Extra properties'.ljust(padding)))
00256                 indent += 2
00257                 keys = ec.properties.keys()
00258                 keys.sort()
00259                 pad_length = max([len(key) for key in keys]) + 2
00260                 for key in keys:
00261                     result.append('{0}{1}{2}'.format(''.ljust(indent),
00262                          key.ljust(pad_length), ec.properties[key]))
00263                 indent -= 2
00264             else:
00265                 result.append('{0}{1}'.format('+'.rjust(indent),
00266                     'Extra properties'.ljust(padding)))
00267         indent -= 2
00268     else:
00269         result.append('{0}Execution Context {1}'.format(\
00270                 '+'.rjust(indent), handle_str))
00271     return result
00272 
00273 
00274 def format_component(comp, tree, use_colour=True, long=0):
00275     result = []
00276     result.append('{0}  {1}'.format(comp.name,
00277             comp.get_state_string(add_colour=use_colour)))
00278 
00279     indent = 2
00280     profile_items = [('Category', comp.category),
00281                      ('Description', comp.description),
00282                      ('Instance name', comp.instance_name),
00283                      ('Type name', comp.type_name),
00284                      ('Vendor', comp.vendor),
00285                      ('Version', comp.version)]
00286     if comp.parent:
00287         profile_items.append(('Parent', comp.parent_object))
00288     if comp.is_composite:
00289         if comp.is_composite_member:
00290             profile_items.append(('Type', 'Composite composite member'))
00291         else:
00292             profile_items.append(('Type', 'Composite'))
00293     elif comp.is_composite_member:
00294         profile_items.append(('Type', 'Monolithic composite member'))
00295     else:
00296         profile_items.append(('Type', 'Monolithic'))
00297     pad_length = max([len(item[0]) for item in profile_items]) + 2
00298     for item in profile_items:
00299         result.append('{0}{1}{2}'.format(''.ljust(indent),
00300                                          item[0].ljust(pad_length),
00301                                          item[1]))
00302 
00303     if comp.properties:
00304         if long > 1:
00305             result.append('{0}Extra properties:'.format(''.ljust(indent)))
00306             indent += 2
00307             extra_props = comp.properties
00308             keys = extra_props.keys()
00309             keys.sort()
00310             pad_length = max([len(key) for key in keys]) + 2
00311             for key in keys:
00312                 result.append('{0}{1}{2}'.format(''.ljust(indent),
00313                                                  key.ljust(pad_length),
00314                                                  extra_props[key]))
00315         else:
00316             result.append('{0}{1}'.format('+'.rjust(indent),
00317                 'Extra properties'))
00318         indent -= 2
00319 
00320     if comp.is_composite:
00321         result += format_composite(comp, tree, start_indent=indent,
00322                 use_colour=use_colour, long=long)
00323     if comp.is_composite_member:
00324         result += format_comp_member(comp, tree, start_indent=indent,
00325                 use_colour=use_colour, long=long)
00326     for ec in comp.owned_ecs:
00327         result += format_ec(ec, start_indent=indent,
00328                 use_colour=use_colour, long=long)
00329     for p in comp.ports:
00330         result += format_port(p, comp, start_indent=indent,
00331                 use_colour=use_colour, long=long)
00332 
00333     return result
00334 
00335 
00336 def format_manager(mgr, use_colour=True, long=0):
00337     def add_profile_entry(dest, title, key):
00338         if key in mgr.profile:
00339             dest.append('{0}: {1}'.format(title, mgr.profile[key]))
00340         else:
00341             print >>sys.stderr, '{0}: Warning: "{1}" profile entry is \
00342 missing. Possible version conflict between rtshell and OpenRTM-aist.'.format(\
00343                     sys.argv[0], key)
00344 
00345     result = []
00346     add_profile_entry(result, 'Name', 'name')
00347     add_profile_entry(result, 'Instance name', 'instance_name')
00348     add_profile_entry(result, 'Process ID', 'pid')
00349     add_profile_entry(result, 'Naming format', 'naming_formats')
00350     add_profile_entry(result, 'Refstring path', 'refstring_path')
00351     add_profile_entry(result, 'Components precreate', 'components.precreate')
00352     result.append('Modules:')
00353     add_profile_entry(result, '  Load path', 'modules.load_path')
00354     add_profile_entry(result, '  Config path', 'modules.config_path')
00355     add_profile_entry(result, '  Preload', 'modules.preload')
00356     add_profile_entry(result, '  Init function prefix',
00357             'modules.init_func_prefix')
00358     add_profile_entry(result, '  Init function suffix',
00359             'modules.init_func_suffix')
00360     add_profile_entry(result, '  Download allowed',
00361             'modules.download_allowed')
00362     add_profile_entry(result, '  Absolute path allowed',
00363             'modules.abs_path_allowed')
00364     result.append('OS:')
00365     add_profile_entry(result, '  Version', 'os.version')
00366     add_profile_entry(result, '  Architecture', 'os.arch')
00367     add_profile_entry(result, '  Release', 'os.release')
00368     add_profile_entry(result, '  Host name', 'os.hostname')
00369     add_profile_entry(result, '  Name', 'os.name')
00370     # List loaded libraries
00371     result.append('Loaded modules:')
00372     for lm in mgr.loaded_modules:
00373         result.append('  Filepath: {0}'.format(lm['file_path']))
00374     # List loadable libraries
00375     result.append('Loadable modules:')
00376     for lm in mgr.loadable_modules:
00377         result.append('  {0}'.format(lm['module_file_path']))
00378 
00379     return result
00380 
00381 
00382 def cat_target(cmd_path, full_path, options, tree=None):
00383     use_colour = rtctree.utils.colour_supported(sys.stdout)
00384 
00385     path, port = rtctree.path.parse_path(full_path)
00386     if not path[-1]:
00387         # There was a trailing slash
00388         trailing_slash = True
00389         path = path[:-1]
00390     else:
00391         trailing_slash = False
00392 
00393     if not tree:
00394         if options.long > 0:
00395             # Longer output needs to look around the tree, so don't filter
00396             filter = []
00397         else:
00398             filter = [path]
00399         tree = rtctree.tree.RTCTree(paths=path, filter=filter)
00400 
00401     if not tree.has_path(path):
00402         raise rts_exceptions.NoSuchObjectError(cmd_path)
00403     object = tree.get_node(path)
00404     if port:
00405         if not object.is_component:
00406             raise rts_exceptions.NotAComponentError(cmd_path)
00407         if trailing_slash:
00408             raise rts_exceptions.NoSuchObjectError(cmd_path)
00409         p = object.get_port_by_name(port)
00410         if not p:
00411             raise rts_exceptions.PortNotFoundError(path, port)
00412         return format_port(p, object, start_indent=0,
00413                 use_colour=use_colour, long=options.long)
00414     else:
00415         if object.is_component:
00416             if trailing_slash:
00417                 raise rts_exceptions.NoSuchObjectError(cmd_path)
00418             return format_component(object, tree, use_colour=use_colour,
00419                     long=options.long)
00420         elif object.is_manager:
00421             return format_manager(object, use_colour=use_colour,
00422                     long=options.long)
00423         elif object.is_zombie:
00424             raise rts_exceptions.ZombieObjectError(cmd_path)
00425         else:
00426             raise rts_exceptions.NoSuchObjectError(cmd_path)
00427 
00428 
00429 def main(argv=None, tree=None):
00430     usage = '''Usage: %prog [options] [path]
00431 Display information about a manager or component.'''
00432     version = rtshell.RTSH_VERSION
00433     parser = optparse.OptionParser(usage=usage, version=version)
00434     parser.add_option('-l', dest='long', action='count', default=0,
00435             help='Show more information. Specify multiple times for even '\
00436             'more information. [Default: False]')
00437     parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
00438             default=False,
00439             help='Output verbose information. [Default: %default]')
00440 
00441     if argv:
00442         sys.argv = [sys.argv[0]] + argv
00443     try:
00444         options, args = parser.parse_args()
00445     except optparse.OptionError, e:
00446         print >>sys.stderr, 'OptionError:', e
00447         return 1, []
00448 
00449     if not args:
00450         # If no path given then can't do anything.
00451         print >>sys.stderr, '{0}: Cannot cat a directory.'.format(
00452                 os.path.basename(sys.argv[0]))
00453         return 1, []
00454     elif len(args) == 1:
00455         cmd_path = args[0]
00456     else:
00457         print >>sys.stderr, usage
00458         return 1, []
00459     full_path = path.cmd_path_to_full_path(cmd_path)
00460 
00461     result = []
00462     try:
00463         result = cat_target(cmd_path, full_path, options, tree=tree)
00464     except Exception, e:
00465         if options.verbose:
00466             traceback.print_exc()
00467         print >>sys.stderr, '{0}: {1}'.format(os.path.basename(sys.argv[0]), e)
00468         return 1, []
00469     return 0, result
00470 
00471 
00472 # vim: tw=79
00473 


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