1#!/usr/bin/env python 2 3r""" 4This module provides many valuable functions such as my_parm_file. 5""" 6 7# sys and os are needed to get the program dir path and program name. 8import sys 9import os 10import ConfigParser 11import StringIO 12import re 13import socket 14 15import gen_print as gp 16import gen_cmd as gc 17 18 19robot_env = 1 20try: 21 from robot.libraries.BuiltIn import BuiltIn 22except ImportError: 23 robot_env = 0 24 25 26############################################################################### 27def add_trailing_slash(dir_path): 28 29 r""" 30 Add a trailing slash to the directory path if it doesn't already have one 31 and return it. 32 33 Description of arguments: 34 dir_path A directory path. 35 """ 36 37 return os.path.normpath(dir_path) + os.path.sep 38 39############################################################################### 40 41 42############################################################################### 43def which(file_path): 44 45 r""" 46 Find the full path of an executable file and return it. 47 48 The PATH environment variable dictates the results of this function. 49 50 Description of arguments: 51 file_path The relative file path (e.g. "my_file" or 52 "lib/my_file"). 53 """ 54 55 shell_rc, out_buf = gc.cmd_fnc_u("which " + file_path, quiet=1, 56 print_output=0, show_err=0) 57 if shell_rc != 0: 58 error_message = "Failed to find complete path for file \"" +\ 59 file_path + "\".\n" 60 error_message += gp.sprint_var(shell_rc, 1) 61 error_message += out_buf 62 if robot_env: 63 BuiltIn().fail(gp.sprint_error(error_message)) 64 else: 65 gp.print_error_report(error_message) 66 return False 67 68 file_path = out_buf.rstrip("\n") 69 70 return file_path 71 72############################################################################### 73 74 75############################################################################### 76def dft(value, default): 77 78 r""" 79 Return default if value is None. Otherwise, return value. 80 81 This is really just shorthand as shown below. 82 83 dft(value, default) 84 85 vs 86 87 default if value is None else value 88 89 Description of arguments: 90 value The value to be returned. 91 default The default value to return if value is 92 None. 93 """ 94 95 return default if value is None else value 96 97############################################################################### 98 99 100############################################################################### 101def get_mod_global(var_name, 102 default=None, 103 mod_name="__main__"): 104 105 r""" 106 Get module global variable value and return it. 107 108 If we are running in a robot environment, the behavior will default to 109 calling get_variable_value. 110 111 Description of arguments: 112 var_name The name of the variable whose value is 113 sought. 114 default The value to return if the global does not 115 exist. 116 mod_name The name of the module containing the 117 global variable. 118 """ 119 120 if robot_env: 121 return BuiltIn().get_variable_value("${" + var_name + "}", default) 122 123 try: 124 module = sys.modules[mod_name] 125 except KeyError: 126 gp.print_error_report("Programmer error - The mod_name passed to" + 127 " this function is invalid:\n" + 128 gp.sprint_var(mod_name)) 129 raise ValueError('Programmer error.') 130 131 if default is None: 132 return getattr(module, var_name) 133 else: 134 return getattr(module, var_name, default) 135 136############################################################################### 137 138 139############################################################################### 140def global_default(var_value, 141 default=0): 142 143 r""" 144 If var_value is not None, return it. Otherwise, return the global 145 variable of the same name, if it exists. If not, return default. 146 147 This is meant for use by functions needing help assigning dynamic default 148 values to their parms. Example: 149 150 def func1(parm1=None): 151 152 parm1 = global_default(parm1, 0) 153 154 Description of arguments: 155 var_value The value being evaluated. 156 default The value to be returned if var_value is 157 None AND the global variable of the same 158 name does not exist. 159 """ 160 161 var_name = gp.get_arg_name(0, 1, stack_frame_ix=2) 162 163 return dft(var_value, get_mod_global(var_name, 0)) 164 165############################################################################### 166 167 168############################################################################### 169def set_mod_global(var_value, 170 mod_name="__main__", 171 var_name=None): 172 173 r""" 174 Set a global variable for a given module. 175 176 Description of arguments: 177 var_value The value to set in the variable. 178 mod_name The name of the module whose variable is 179 to be set. 180 var_name The name of the variable to set. This 181 defaults to the name of the variable used 182 for var_value when calling this function. 183 """ 184 185 try: 186 module = sys.modules[mod_name] 187 except KeyError: 188 gp.print_error_report("Programmer error - The mod_name passed to" + 189 " this function is invalid:\n" + 190 gp.sprint_var(mod_name)) 191 raise ValueError('Programmer error.') 192 193 if var_name is None: 194 var_name = gp.get_arg_name(None, 1, 2) 195 196 setattr(module, var_name, var_value) 197 198############################################################################### 199 200 201############################################################################### 202def my_parm_file(prop_file_path): 203 204 r""" 205 Read a properties file, put the keys/values into a dictionary and return 206 the dictionary. 207 208 The properties file must have the following format: 209 var_name<= or :>var_value 210 Comment lines (those beginning with a "#") and blank lines are allowed and 211 will be ignored. Leading and trailing single or double quotes will be 212 stripped from the value. E.g. 213 var1="This one" 214 Quotes are stripped so the resulting value for var1 is: 215 This one 216 217 Description of arguments: 218 prop_file_path The caller should pass the path to the 219 properties file. 220 """ 221 222 # ConfigParser expects at least one section header in the file (or you 223 # get ConfigParser.MissingSectionHeaderError). Properties files don't 224 # need those so I'll write a dummy section header. 225 226 string_file = StringIO.StringIO() 227 # Write the dummy section header to the string file. 228 string_file.write('[dummysection]\n') 229 # Write the entire contents of the properties file to the string file. 230 string_file.write(open(prop_file_path).read()) 231 # Rewind the string file. 232 string_file.seek(0, os.SEEK_SET) 233 234 # Create the ConfigParser object. 235 config_parser = ConfigParser.ConfigParser() 236 # Make the property names case-sensitive. 237 config_parser.optionxform = str 238 # Read the properties from the string file. 239 config_parser.readfp(string_file) 240 # Return the properties as a dictionary. 241 return dict(config_parser.items('dummysection')) 242 243############################################################################### 244 245 246############################################################################### 247def file_to_list(file_path, 248 newlines=0, 249 comments=1, 250 trim=0): 251 252 r""" 253 Return the contents of a file as a list. Each element of the resulting 254 list is one line from the file. 255 256 Description of arguments: 257 file_path The path to the file (relative or 258 absolute). 259 newlines Include newlines from the file in the 260 results. 261 comments Include comment lines and blank lines in 262 the results. Comment lines are any that 263 begin with 0 or more spaces followed by 264 the pound sign ("#"). 265 trim Trim white space from the beginning and 266 end of each line. 267 """ 268 269 lines = [] 270 file = open(file_path) 271 for line in file: 272 if not comments: 273 if re.match(r"[ ]*#|^$", line): 274 continue 275 if not newlines: 276 line = line.rstrip("\n") 277 if trim: 278 line = line.strip() 279 lines.append(line) 280 281 return lines 282 283############################################################################### 284 285 286############################################################################### 287def return_path_list(): 288 289 r""" 290 This function will split the PATH environment variable into a PATH_LIST 291 and return it. Each element in the list will be normalized and have a 292 trailing slash added. 293 """ 294 295 PATH_LIST = os.environ['PATH'].split(":") 296 PATH_LIST = [os.path.normpath(path) + os.sep for path in PATH_LIST] 297 298 return PATH_LIST 299 300############################################################################### 301 302 303############################################################################### 304def quote_bash_parm(parm): 305 306 r""" 307 Return the bash command line parm with single quotes if they are needed. 308 309 Description of arguments: 310 parm The string to be quoted. 311 """ 312 313 # If any of these characters are found in the parm string, then the 314 # string should be quoted. This list is by no means complete and should 315 # be expanded as needed by the developer of this function. 316 bash_special_chars = set(' $') 317 318 if any((char in bash_special_chars) for char in parm): 319 return "'" + parm + "'" 320 321 return parm 322 323############################################################################### 324 325 326############################################################################### 327def get_host_name_ip(host): 328 329 r""" 330 Get the host name and the IP address for the given host and return them as 331 a tuple. 332 333 Description of argument(s): 334 host The host name or IP address to be 335 obtained. 336 """ 337 338 host_host_name = socket.getfqdn(host) 339 host_ip = socket.gethostbyname(host) 340 341 return host_host_name, host_ip 342 343############################################################################### 344