00001
00002
00003
00004 '''rtctree
00005
00006 Copyright (C) 2009-2014
00007 Geoffrey Biggs
00008 RT-Synthesis Research Group
00009 Intelligent Systems Research Institute,
00010 National Institute of Advanced Industrial Science and Technology (AIST),
00011 Japan
00012 All rights reserved.
00013 Licensed under the Eclipse Public License -v 1.0 (EPL)
00014 http://www.opensource.org/licenses/eclipse-1.0.txt
00015
00016 Objects and functions used to build and store a tree representing a hierarchy
00017 of name servers, directories, managers and components.
00018
00019 '''
00020
00021
00022 from omniORB import any
00023 import SDOPackage
00024 import sys
00025
00026
00027
00028
00029
00030
00031 term_attributes = {'reset': '00',
00032 'bold': '01',
00033 'faint': '02',
00034 'underline': '04',
00035 'blink': '05',
00036 'blinkfast': '06',
00037 'negative': '07',
00038 'normal': '22',
00039 'nounderline': '24',
00040 'noblink': '25',
00041 'positive': '27',
00042 'black': '30',
00043 'red': '31',
00044 'green': '32',
00045 'brown': '33',
00046 'blue': '34',
00047 'purple': '35',
00048 'cyan': '36',
00049 'white': '37',
00050 'bgblack': '40',
00051 'bgred': '41',
00052 'bggreen': '42',
00053 'bgbrown': '43',
00054 'bgblue': '44',
00055 'bgpurple': '45',
00056 'bgcyan': '46',
00057 'bgwhite': '47',
00058 }
00059
00060 from traceback import extract_stack
00061
00062 def build_attr_string(attrs, supported=True):
00063 '''Build a string that will turn any ANSI shell output the desired
00064 colour.
00065
00066 attrs should be a list of keys into the term_attributes table.
00067
00068 '''
00069 if not supported:
00070 return ''
00071 if type(attrs) == str:
00072 attrs = [attrs]
00073 result = '\033['
00074 for attr in attrs:
00075 result += term_attributes[attr] + ';'
00076 return result[:-1] + 'm'
00077
00078
00079 def colour_supported(term):
00080 if sys.platform == 'win32':
00081 return False
00082 return term.isatty()
00083
00084
00085 def get_num_columns_and_rows(widths, gap_width, term_width):
00086 '''Given a list of string widths, a width of the minimum gap to place
00087 between them, and the maximum width of the output (such as a terminal
00088 width), calculate the number of columns and rows, and the width of each
00089 column, for the optimal layout.
00090
00091 '''
00092 def calc_longest_width(widths, gap_width, ncols):
00093 longest = 0
00094 rows = [widths[s:s + ncols] for s in range(0, len(widths), ncols)]
00095 col_widths = rows[0]
00096 for r in rows:
00097 for ii, c in enumerate(r):
00098 if c > col_widths[ii]:
00099 col_widths[ii] = c
00100 length = sum(col_widths) + gap_width * (ncols - 1)
00101 if length > longest:
00102 longest = length
00103 return longest, col_widths
00104
00105 def calc_num_rows(num_items, cols):
00106 div, mod = divmod(num_items, cols)
00107 return div + (mod != 0)
00108
00109
00110 ncols = len(widths)
00111
00112
00113
00114 while ncols > 0:
00115 longest_width, col_widths = calc_longest_width(widths, gap_width, ncols)
00116 if longest_width < term_width:
00117
00118 return calc_num_rows(len(widths), ncols), ncols, col_widths
00119 else:
00120
00121 ncols -= 1
00122
00123 return len(widths), 1, 0
00124
00125
00126 def get_terminal_size():
00127 '''Finds the width of the terminal, or returns a suitable default value.'''
00128 def read_terminal_size_by_ioctl(fd):
00129 try:
00130 import struct, fcntl, termios
00131 cr = struct.unpack('hh', fcntl.ioctl(1, termios.TIOCGWINSZ,
00132 '0000'))
00133 except ImportError:
00134 return None
00135 except IOError, e:
00136 return None
00137 return cr[1], cr[0]
00138
00139 cr = read_terminal_size_by_ioctl(0) or \
00140 read_terminal_size_by_ioctl(1) or \
00141 read_terminal_size_by_ioctl(2)
00142 if not cr:
00143 try:
00144 import os
00145 fd = os.open(os.ctermid(), os.O_RDONLY)
00146 cr = read_terminal_size_by_ioctl(fd)
00147 os.close(fd)
00148 except:
00149 pass
00150 if not cr:
00151 import os
00152 cr = [80, 25]
00153 if os.getenv('ROWS'):
00154 cr[1] = int(os.getenv('ROWS'))
00155 if os.getenv('COLUMNS'):
00156 cr[0] = int(os.getenv('COLUMNS'))
00157
00158 return cr[1], cr[0]
00159
00160
00161 def dict_to_nvlist(dict):
00162 '''Convert a dictionary into a CORBA namevalue list.'''
00163 result = []
00164 for item in dict.keys() :
00165 result.append(SDOPackage.NameValue(item, any.to_any(dict[item])))
00166 return result
00167
00168
00169 def nvlist_to_dict(nvlist):
00170 '''Convert a CORBA namevalue list into a dictionary.'''
00171 result = {}
00172 for item in nvlist :
00173 result[item.name] = item.value.value()
00174 return result
00175
00176
00177 def filtered(path, filter):
00178 '''Check if a path is removed by a filter.
00179
00180 Check if a path is in the provided set of paths, @ref filter. If
00181 none of the paths in filter begin with @ref path, then True is
00182 returned to indicate that the path is filtered out. If @ref path is
00183 longer than the filter, and starts with the filter, it is
00184 considered unfiltered (all paths below a filter are unfiltered).
00185
00186 An empty filter ([]) is treated as not filtering any.
00187
00188 '''
00189 if not filter:
00190 return False
00191 for p in filter:
00192 if len(path) > len(p):
00193 if path[:len(p)] == p:
00194 return False
00195 else:
00196 if p[:len(path)] == path:
00197 return False
00198 return True
00199
00200
00201 def trim_filter(filter, levels=1):
00202 '''Trim @ref levels levels from the front of each path in @filter.'''
00203 trimmed = [f[levels:] for f in filter]
00204 return [f for f in trimmed if f]
00205
00206
00207
00208