1*179860b2SJed Browntry: 2*179860b2SJed Brown import readline 3*179860b2SJed Brownexcept ImportError: pass 4*179860b2SJed Brown 5*179860b2SJed Browndef getInteractive(): 6*179860b2SJed Brown return isInteractive 7*179860b2SJed Brown 8*179860b2SJed Browndef setInteractive(interactive): 9*179860b2SJed Brown global isInteractive 10*179860b2SJed Brown isInteractive = interactive 11*179860b2SJed Brown return 12*179860b2SJed Brown 13*179860b2SJed Browndef checkInteractive(key): 14*179860b2SJed Brown if not isInteractive: 15*179860b2SJed Brown raise ValueError('Value not set for key '+str(key)) 16*179860b2SJed Brown return 17*179860b2SJed BrownsetInteractive(1) 18*179860b2SJed Brown 19*179860b2SJed Brownclass Arg(object): 20*179860b2SJed Brown '''This is the base class for all objects contained in RDict. Access to the raw argument values is 21*179860b2SJed Brownprovided by getValue() and setValue(). These objects can be thought of as type objects for the 22*179860b2SJed Brownvalues themselves. It is possible to set an Arg in the RDict which has not yet been assigned a value 23*179860b2SJed Brownin order to declare the type of that option. 24*179860b2SJed Brown 25*179860b2SJed BrownInputs which cannot be converted to the correct type will cause TypeError, those failing validation 26*179860b2SJed Browntests will cause ValueError. 27*179860b2SJed Brown''' 28*179860b2SJed Brown def __init__(self, key, value = None, help = '', isTemporary = False, deprecated = False): 29*179860b2SJed Brown self.key = key 30*179860b2SJed Brown self.help = help 31*179860b2SJed Brown self.isTemporary = isTemporary 32*179860b2SJed Brown self.deprecated = False 33*179860b2SJed Brown if not value is None: 34*179860b2SJed Brown self.setValue(value) 35*179860b2SJed Brown self.deprecated = deprecated 36*179860b2SJed Brown return 37*179860b2SJed Brown 38*179860b2SJed Brown def isValueSet(self): 39*179860b2SJed Brown '''Determines whether the value of this argument has been set''' 40*179860b2SJed Brown return hasattr(self, 'value') 41*179860b2SJed Brown 42*179860b2SJed Brown def getTemporary(self): 43*179860b2SJed Brown '''Retrieve the flag indicating whether the item should be persistent''' 44*179860b2SJed Brown return self.isTemporary 45*179860b2SJed Brown 46*179860b2SJed Brown def setTemporary(self, isTemporary): 47*179860b2SJed Brown '''Set the flag indicating whether the item should be persistent''' 48*179860b2SJed Brown self.isTemporary = isTemporary 49*179860b2SJed Brown return 50*179860b2SJed Brown 51*179860b2SJed Brown def parseValue(arg): 52*179860b2SJed Brown '''Return the object represented by the value portion of a string argument''' 53*179860b2SJed Brown # Should I replace this with a lexer? 54*179860b2SJed Brown if arg: arg = arg.strip() 55*179860b2SJed Brown if arg and arg[0] == '[' and arg[-1] == ']': 56*179860b2SJed Brown if len(arg) > 2: value = arg[1:-1].split(',') 57*179860b2SJed Brown else: value = [] 58*179860b2SJed Brown elif arg and arg[0] == '{' and arg[-1] == '}': 59*179860b2SJed Brown value = {} 60*179860b2SJed Brown idx = 1 61*179860b2SJed Brown oldIdx = idx 62*179860b2SJed Brown while idx < len(arg)-1: 63*179860b2SJed Brown if arg[oldIdx] == ',': 64*179860b2SJed Brown oldIdx += 1 65*179860b2SJed Brown while not arg[idx] == ':': idx += 1 66*179860b2SJed Brown key = arg[oldIdx:idx] 67*179860b2SJed Brown idx += 1 68*179860b2SJed Brown oldIdx = idx 69*179860b2SJed Brown nesting = 0 70*179860b2SJed Brown while not (arg[idx] == ',' or arg[idx] == '}') or nesting: 71*179860b2SJed Brown if arg[idx] == '[': 72*179860b2SJed Brown nesting += 1 73*179860b2SJed Brown elif arg[idx] == ']': 74*179860b2SJed Brown nesting -= 1 75*179860b2SJed Brown idx += 1 76*179860b2SJed Brown value[key] = Arg.parseValue(arg[oldIdx:idx]) 77*179860b2SJed Brown oldIdx = idx 78*179860b2SJed Brown else: 79*179860b2SJed Brown value = arg 80*179860b2SJed Brown return value 81*179860b2SJed Brown parseValue = staticmethod(parseValue) 82*179860b2SJed Brown 83*179860b2SJed Brown def parseArgument(arg, ignoreDouble = 0): 84*179860b2SJed Brown '''Split an argument into a (key, value) tuple, stripping off the leading dashes. Return (None, None) on failure.''' 85*179860b2SJed Brown start = 0 86*179860b2SJed Brown if arg and arg[0] == '-': 87*179860b2SJed Brown start = 1 88*179860b2SJed Brown if arg[1] == '-' and not ignoreDouble: 89*179860b2SJed Brown start = 2 90*179860b2SJed Brown if arg.find('=') >= 0: 91*179860b2SJed Brown (key, value) = arg[start:].split('=', 1) 92*179860b2SJed Brown else: 93*179860b2SJed Brown if start == 0: 94*179860b2SJed Brown (key, value) = (None, arg) 95*179860b2SJed Brown else: 96*179860b2SJed Brown (key, value) = (arg[start:], '1') 97*179860b2SJed Brown return (key, Arg.parseValue(value)) 98*179860b2SJed Brown 99*179860b2SJed Brown parseArgument = staticmethod(parseArgument) 100*179860b2SJed Brown 101*179860b2SJed Brown def findArgument(key, argList): 102*179860b2SJed Brown '''Locate an argument with the given key in argList, returning the value or None on failure 103*179860b2SJed Brown - This is generally used to process arguments which must take effect before canonical argument parsing''' 104*179860b2SJed Brown if not isinstance(argList, list): return None 105*179860b2SJed Brown # Reverse the list so that we preserve the semantics which state that the last 106*179860b2SJed Brown # argument with a given key takes effect 107*179860b2SJed Brown l = argList[:] 108*179860b2SJed Brown l.reverse() 109*179860b2SJed Brown for arg in l: 110*179860b2SJed Brown (k, value) = Arg.parseArgument(arg) 111*179860b2SJed Brown if k == key: 112*179860b2SJed Brown return value 113*179860b2SJed Brown return None 114*179860b2SJed Brown findArgument = staticmethod(findArgument) 115*179860b2SJed Brown 116*179860b2SJed Brown def processAlternatePrefixes(argList): 117*179860b2SJed Brown '''Convert alternate prefixes to our normal form''' 118*179860b2SJed Brown for l in range(0, len(argList)): 119*179860b2SJed Brown name = argList[l] 120*179860b2SJed Brown if name.find('enable-') >= 0: 121*179860b2SJed Brown argList[l] = name.replace('enable-','with-') 122*179860b2SJed Brown if name.find('=') == -1: argList[l] = argList[l]+'=1' 123*179860b2SJed Brown if name.find('disable-') >= 0: 124*179860b2SJed Brown argList[l] = name.replace('disable-','with-') 125*179860b2SJed Brown if name.find('=') == -1: argList[l] = argList[l]+'=0' 126*179860b2SJed Brown elif name.endswith('=1'): argList[l].replace('=1','=0') 127*179860b2SJed Brown if name.find('without-') >= 0: 128*179860b2SJed Brown argList[l] = name.replace('without-','with-') 129*179860b2SJed Brown if name.find('=') == -1: argList[l] = argList[l]+'=0' 130*179860b2SJed Brown elif name.endswith('=1'): argList[l].replace('=1','=0') 131*179860b2SJed Brown return 132*179860b2SJed Brown processAlternatePrefixes = staticmethod(processAlternatePrefixes) 133*179860b2SJed Brown 134*179860b2SJed Brown def __str__(self): 135*179860b2SJed Brown if not self.isValueSet(): 136*179860b2SJed Brown return 'Empty '+str(self.__class__) 137*179860b2SJed Brown elif isinstance(self.value, list): 138*179860b2SJed Brown return str(map(str, self.value)) 139*179860b2SJed Brown return str(self.value) 140*179860b2SJed Brown 141*179860b2SJed Brown def getEntryPrompt(self): 142*179860b2SJed Brown return 'Please enter value for '+str(self.key)+': ' 143*179860b2SJed Brown 144*179860b2SJed Brown def getKey(self): 145*179860b2SJed Brown '''Returns the key. SHOULD MAKE THIS A PROPERTY''' 146*179860b2SJed Brown return self.key 147*179860b2SJed Brown 148*179860b2SJed Brown def setKey(self, key): 149*179860b2SJed Brown '''Set the key. SHOULD MAKE THIS A PROPERTY''' 150*179860b2SJed Brown self.key = key 151*179860b2SJed Brown return 152*179860b2SJed Brown 153*179860b2SJed Brown def getValue(self): 154*179860b2SJed Brown '''Returns the value. SHOULD MAKE THIS A PROPERTY''' 155*179860b2SJed Brown if not self.isValueSet(): 156*179860b2SJed Brown checkInteractive(self.key) 157*179860b2SJed Brown if self.help: print self.help 158*179860b2SJed Brown while 1: 159*179860b2SJed Brown try: 160*179860b2SJed Brown self.setValue(Arg.parseValue(raw_input(self.getEntryPrompt()))) 161*179860b2SJed Brown break 162*179860b2SJed Brown except KeyboardInterrupt: 163*179860b2SJed Brown raise KeyError('Could not find value for key '+str(self.key)) 164*179860b2SJed Brown except TypeError, e: 165*179860b2SJed Brown print str(e) 166*179860b2SJed Brown return self.value 167*179860b2SJed Brown 168*179860b2SJed Brown def checkKey(self): 169*179860b2SJed Brown if self.deprecated: 170*179860b2SJed Brown if isinstance(self.deprecated, str): 171*179860b2SJed Brown raise KeyError('Deprecated option '+self.key+' should be '+self.deprecated) 172*179860b2SJed Brown raise KeyError('Deprecated option '+self.key) 173*179860b2SJed Brown return 174*179860b2SJed Brown 175*179860b2SJed Brown def setValue(self, value): 176*179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 177*179860b2SJed Brown self.checkKey() 178*179860b2SJed Brown self.value = value 179*179860b2SJed Brown return 180*179860b2SJed Brown 181*179860b2SJed Brownclass ArgBool(Arg): 182*179860b2SJed Brown '''Arguments that represent boolean values''' 183*179860b2SJed Brown def __init__(self, key, value = None, help = '', isTemporary = 0, deprecated = False): 184*179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 185*179860b2SJed Brown return 186*179860b2SJed Brown 187*179860b2SJed Brown def getEntryPrompt(self): 188*179860b2SJed Brown return 'Please enter boolean value for '+str(self.key)+': ' 189*179860b2SJed Brown 190*179860b2SJed Brown def setValue(self, value): 191*179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 192*179860b2SJed Brown self.checkKey() 193*179860b2SJed Brown try: 194*179860b2SJed Brown if value == 'no': value = 0 195*179860b2SJed Brown elif value == 'yes': value = 1 196*179860b2SJed Brown elif value == 'true': value = 1 197*179860b2SJed Brown elif value == 'false': value = 0 198*179860b2SJed Brown elif value == 'True': value = 1 199*179860b2SJed Brown elif value == 'False': value = 0 200*179860b2SJed Brown else: value = int(value) 201*179860b2SJed Brown except: 202*179860b2SJed Brown raise TypeError('Invalid boolean value: '+str(value)+' for key '+str(self.key)) 203*179860b2SJed Brown self.value = value 204*179860b2SJed Brown return 205*179860b2SJed Brown 206*179860b2SJed Brownclass ArgFuzzyBool(Arg): 207*179860b2SJed Brown '''Arguments that represent boolean values of an extended set''' 208*179860b2SJed Brown def __init__(self, key, value = None, help = '', isTemporary = 0, deprecated = False): 209*179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 210*179860b2SJed Brown return 211*179860b2SJed Brown 212*179860b2SJed Brown def valueName(self, value): 213*179860b2SJed Brown if value == 0: 214*179860b2SJed Brown return 'no' 215*179860b2SJed Brown elif value == 1: 216*179860b2SJed Brown return 'yes' 217*179860b2SJed Brown elif value == 2: 218*179860b2SJed Brown return 'ifneeded' 219*179860b2SJed Brown return str(value) 220*179860b2SJed Brown 221*179860b2SJed Brown def __str__(self): 222*179860b2SJed Brown if not self.isValueSet(): 223*179860b2SJed Brown return 'Empty '+str(self.__class__) 224*179860b2SJed Brown elif isinstance(self.value, list): 225*179860b2SJed Brown return str(map(self.valueName, self.value)) 226*179860b2SJed Brown return self.valueName(self.value) 227*179860b2SJed Brown 228*179860b2SJed Brown def getEntryPrompt(self): 229*179860b2SJed Brown return 'Please enter fuzzy boolean value for '+str(self.key)+': ' 230*179860b2SJed Brown 231*179860b2SJed Brown def setValue(self, value): 232*179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 233*179860b2SJed Brown self.checkKey() 234*179860b2SJed Brown try: 235*179860b2SJed Brown if value == '0': value = 0 236*179860b2SJed Brown elif value == '1': value = 1 237*179860b2SJed Brown elif value == 'no': value = 0 238*179860b2SJed Brown elif value == 'yes': value = 1 239*179860b2SJed Brown elif value == 'false': value = 0 240*179860b2SJed Brown elif value == 'true': value = 1 241*179860b2SJed Brown elif value == 'maybe': value = 2 242*179860b2SJed Brown elif value == 'ifneeded': value = 2 243*179860b2SJed Brown elif value == 'client': value = 2 244*179860b2SJed Brown elif value == 'server': value = 3 245*179860b2SJed Brown else: value = int(value) 246*179860b2SJed Brown except: 247*179860b2SJed Brown raise TypeError('Invalid fuzzy boolean value: '+str(value)+' for key '+str(self.key)) 248*179860b2SJed Brown self.value = value 249*179860b2SJed Brown return 250*179860b2SJed Brown 251*179860b2SJed Brownclass ArgInt(Arg): 252*179860b2SJed Brown '''Arguments that represent integer numbers''' 253*179860b2SJed Brown def __init__(self, key, value = None, help = '', min = -2147483647L, max = 2147483648L, isTemporary = 0, deprecated = False): 254*179860b2SJed Brown self.min = min 255*179860b2SJed Brown self.max = max 256*179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 257*179860b2SJed Brown return 258*179860b2SJed Brown 259*179860b2SJed Brown def getEntryPrompt(self): 260*179860b2SJed Brown return 'Please enter integer value for '+str(self.key)+': ' 261*179860b2SJed Brown 262*179860b2SJed Brown def setValue(self, value): 263*179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 264*179860b2SJed Brown self.checkKey() 265*179860b2SJed Brown try: 266*179860b2SJed Brown value = int(value) 267*179860b2SJed Brown except: 268*179860b2SJed Brown raise TypeError('Invalid integer number: '+str(value)+' for key '+str(self.key)) 269*179860b2SJed Brown if value < self.min or value >= self.max: 270*179860b2SJed Brown raise ValueError('Number out of range: '+str(value)+' not in ['+str(self.min)+','+str(self.max)+')'+' for key '+str(self.key)) 271*179860b2SJed Brown self.value = value 272*179860b2SJed Brown return 273*179860b2SJed Brown 274*179860b2SJed Brownclass ArgReal(Arg): 275*179860b2SJed Brown '''Arguments that represent floating point numbers''' 276*179860b2SJed Brown def __init__(self, key, value = None, help = '', min = -1.7976931348623157e308, max = 1.7976931348623157e308, isTemporary = 0, deprecated = False): 277*179860b2SJed Brown self.min = min 278*179860b2SJed Brown self.max = max 279*179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 280*179860b2SJed Brown return 281*179860b2SJed Brown 282*179860b2SJed Brown def getEntryPrompt(self): 283*179860b2SJed Brown return 'Please enter floating point value for '+str(self.key)+': ' 284*179860b2SJed Brown 285*179860b2SJed Brown def setValue(self, value): 286*179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 287*179860b2SJed Brown self.checkKey() 288*179860b2SJed Brown try: 289*179860b2SJed Brown value = float(value) 290*179860b2SJed Brown except: 291*179860b2SJed Brown raise TypeError('Invalid floating point number: '+str(value)+' for key '+str(self.key)) 292*179860b2SJed Brown if value < self.min or value >= self.max: 293*179860b2SJed Brown raise ValueError('Number out of range: '+str(value)+' not in ['+str(self.min)+','+str(self.max)+')'+' for key '+str(self.key)) 294*179860b2SJed Brown self.value = value 295*179860b2SJed Brown return 296*179860b2SJed Brown 297*179860b2SJed Brownclass ArgDir(Arg): 298*179860b2SJed Brown '''Arguments that represent directories''' 299*179860b2SJed Brown def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False): 300*179860b2SJed Brown self.mustExist = mustExist 301*179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 302*179860b2SJed Brown return 303*179860b2SJed Brown 304*179860b2SJed Brown def getEntryPrompt(self): 305*179860b2SJed Brown return 'Please enter directory for '+str(self.key)+': ' 306*179860b2SJed Brown 307*179860b2SJed Brown def getValue(self): 308*179860b2SJed Brown '''Returns the value. SHOULD MAKE THIS A PROPERTY''' 309*179860b2SJed Brown if not self.isValueSet(): 310*179860b2SJed Brown checkInteractive(self.key) 311*179860b2SJed Brown try: 312*179860b2SJed Brown import GUI.FileBrowser 313*179860b2SJed Brown import SIDL.Loader 314*179860b2SJed Brown db = GUI.FileBrowser.FileBrowser(SIDL.Loader.createClass('GUI.Default.DefaultFileBrowser')) 315*179860b2SJed Brown if self.help: db.setTitle(self.help) 316*179860b2SJed Brown else: db.setTitle('Select the directory for '+self.key) 317*179860b2SJed Brown db.setMustExist(self.exist) 318*179860b2SJed Brown self.value = db.getDirectory() 319*179860b2SJed Brown except Exception: 320*179860b2SJed Brown return Arg.getValue(self) 321*179860b2SJed Brown return self.value 322*179860b2SJed Brown 323*179860b2SJed Brown def setValue(self, value): 324*179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 325*179860b2SJed Brown import os 326*179860b2SJed Brown self.checkKey() 327*179860b2SJed Brown # Should check whether it is a well-formed path 328*179860b2SJed Brown if not isinstance(value, str): 329*179860b2SJed Brown raise TypeError('Invalid directory: '+str(value)+' for key '+str(self.key)) 330*179860b2SJed Brown value = os.path.expanduser(value) 331*179860b2SJed Brown if self.mustExist and value and not os.path.isdir(value): 332*179860b2SJed Brown raise ValueError('Nonexistent directory: '+str(value)+' for key '+str(self.key)) 333*179860b2SJed Brown self.value = value 334*179860b2SJed Brown return 335*179860b2SJed Brown 336*179860b2SJed Brownclass ArgDirList(Arg): 337*179860b2SJed Brown '''Arguments that represent directory lists''' 338*179860b2SJed Brown def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False): 339*179860b2SJed Brown self.mustExist = mustExist 340*179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 341*179860b2SJed Brown return 342*179860b2SJed Brown 343*179860b2SJed Brown def getEntryPrompt(self): 344*179860b2SJed Brown return 'Please enter directory list for '+str(self.key)+': ' 345*179860b2SJed Brown 346*179860b2SJed Brown def getValue(self): 347*179860b2SJed Brown '''Returns the value. SHOULD MAKE THIS A PROPERTY''' 348*179860b2SJed Brown if not self.isValueSet(): 349*179860b2SJed Brown checkInteractive(self.key) 350*179860b2SJed Brown try: 351*179860b2SJed Brown import GUI.FileBrowser 352*179860b2SJed Brown import SIDL.Loader 353*179860b2SJed Brown db = GUI.FileBrowser.FileBrowser(SIDL.Loader.createClass('GUI.Default.DefaultFileBrowser')) 354*179860b2SJed Brown if self.help: db.setTitle(self.help) 355*179860b2SJed Brown else: db.setTitle('Select the directory for '+self.key) 356*179860b2SJed Brown db.setMustExist(self.exist) 357*179860b2SJed Brown self.value = db.getDirectory() 358*179860b2SJed Brown except Exception: 359*179860b2SJed Brown return Arg.getValue(self) 360*179860b2SJed Brown return self.value 361*179860b2SJed Brown 362*179860b2SJed Brown def setValue(self, value): 363*179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 364*179860b2SJed Brown import os 365*179860b2SJed Brown self.checkKey() 366*179860b2SJed Brown if not isinstance(value, list): 367*179860b2SJed Brown value = [value] 368*179860b2SJed Brown # Should check whether it is a well-formed path 369*179860b2SJed Brown nvalue = [] 370*179860b2SJed Brown for dir in value: 371*179860b2SJed Brown nvalue.append(os.path.expanduser(dir)) 372*179860b2SJed Brown value = nvalue 373*179860b2SJed Brown for dir in value: 374*179860b2SJed Brown if self.mustExist and not os.path.isdir(dir): 375*179860b2SJed Brown raise ValueError('Invalid directory: '+str(dir)+' for key '+str(self.key)) 376*179860b2SJed Brown self.value = value 377*179860b2SJed Brown return 378*179860b2SJed Brown 379*179860b2SJed Brownclass ArgLibrary(Arg): 380*179860b2SJed Brown '''Arguments that represent libraries''' 381*179860b2SJed Brown def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False): 382*179860b2SJed Brown self.mustExist = mustExist 383*179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 384*179860b2SJed Brown return 385*179860b2SJed Brown 386*179860b2SJed Brown def getEntryPrompt(self): 387*179860b2SJed Brown return 'Please enter library for '+str(self.key)+': ' 388*179860b2SJed Brown 389*179860b2SJed Brown def getValue(self): 390*179860b2SJed Brown '''Returns the value. SHOULD MAKE THIS A PROPERTY''' 391*179860b2SJed Brown if not self.isValueSet(): 392*179860b2SJed Brown checkInteractive(self.key) 393*179860b2SJed Brown try: 394*179860b2SJed Brown import GUI.FileBrowser 395*179860b2SJed Brown import SIDL.Loader 396*179860b2SJed Brown db = GUI.FileBrowser.FileBrowser(SIDL.Loader.createClass('GUI.Default.DefaultFileBrowser')) 397*179860b2SJed Brown if self.help: db.setTitle(self.help) 398*179860b2SJed Brown else: db.setTitle('Select the library for '+self.key) 399*179860b2SJed Brown db.setMustExist(self.exist) 400*179860b2SJed Brown self.value = db.getFile() 401*179860b2SJed Brown except Exception: 402*179860b2SJed Brown return Arg.getValue(self) 403*179860b2SJed Brown return self.value 404*179860b2SJed Brown 405*179860b2SJed Brown def setValue(self, value): 406*179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 407*179860b2SJed Brown import os 408*179860b2SJed Brown self.checkKey() 409*179860b2SJed Brown # Should check whether it is a well-formed path and an archive or shared object 410*179860b2SJed Brown if self.mustExist: 411*179860b2SJed Brown if not isinstance(value, list): 412*179860b2SJed Brown value = value.split(' ') 413*179860b2SJed Brown self.value = value 414*179860b2SJed Brown return 415*179860b2SJed Brown 416*179860b2SJed Brownclass ArgExecutable(Arg): 417*179860b2SJed Brown '''Arguments that represent executables''' 418*179860b2SJed Brown def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False): 419*179860b2SJed Brown self.mustExist = mustExist 420*179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 421*179860b2SJed Brown return 422*179860b2SJed Brown 423*179860b2SJed Brown def getEntryPrompt(self): 424*179860b2SJed Brown return 'Please enter executable for '+str(self.key)+': ' 425*179860b2SJed Brown 426*179860b2SJed Brown def getValue(self): 427*179860b2SJed Brown '''Returns the value. SHOULD MAKE THIS A PROPERTY''' 428*179860b2SJed Brown if not self.isValueSet(): 429*179860b2SJed Brown checkInteractive(self.key) 430*179860b2SJed Brown try: 431*179860b2SJed Brown import GUI.FileBrowser 432*179860b2SJed Brown import SIDL.Loader 433*179860b2SJed Brown db = GUI.FileBrowser.FileBrowser(SIDL.Loader.createClass('GUI.Default.DefaultFileBrowser')) 434*179860b2SJed Brown if self.help: db.setTitle(self.help) 435*179860b2SJed Brown else: db.setTitle('Select the executable for '+self.key) 436*179860b2SJed Brown db.setMustExist(self.exist) 437*179860b2SJed Brown self.value = db.getFile() 438*179860b2SJed Brown except Exception: 439*179860b2SJed Brown return Arg.getValue(self) 440*179860b2SJed Brown return self.value 441*179860b2SJed Brown 442*179860b2SJed Brown def checkExecutable(self, dir, name): 443*179860b2SJed Brown import os 444*179860b2SJed Brown prog = os.path.join(dir, name) 445*179860b2SJed Brown return os.path.isfile(prog) and os.access(prog, os.X_OK) 446*179860b2SJed Brown 447*179860b2SJed Brown def setValue(self, value): 448*179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 449*179860b2SJed Brown import os 450*179860b2SJed Brown self.checkKey() 451*179860b2SJed Brown # Should check whether it is a well-formed path 452*179860b2SJed Brown if self.mustExist: 453*179860b2SJed Brown index = value.find(' ') 454*179860b2SJed Brown if index >= 0: 455*179860b2SJed Brown options = value[index:] 456*179860b2SJed Brown value = value[:index] 457*179860b2SJed Brown else: 458*179860b2SJed Brown options = '' 459*179860b2SJed Brown found = self.checkExecutable('', value) 460*179860b2SJed Brown if not found: 461*179860b2SJed Brown for dir in os.environ['PATH'].split(os.path.pathsep): 462*179860b2SJed Brown if self.checkExecutable(dir, value): 463*179860b2SJed Brown found = 1 464*179860b2SJed Brown break 465*179860b2SJed Brown if not found: 466*179860b2SJed Brown raise ValueError('Invalid executable: '+str(value)+' for key '+str(self.key)) 467*179860b2SJed Brown self.value = value+options 468*179860b2SJed Brown return 469*179860b2SJed Brown 470*179860b2SJed Brownclass ArgString(Arg): 471*179860b2SJed Brown '''Arguments that represent strings satisfying a given regular expression''' 472*179860b2SJed Brown def __init__(self, key, value = None, help = '', regExp = None, isTemporary = 0, deprecated = False): 473*179860b2SJed Brown self.regExp = regExp 474*179860b2SJed Brown if self.regExp: 475*179860b2SJed Brown import re 476*179860b2SJed Brown self.re = re.compile(self.regExp) 477*179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 478*179860b2SJed Brown return 479*179860b2SJed Brown 480*179860b2SJed Brown def setValue(self, value): 481*179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 482*179860b2SJed Brown self.checkKey() 483*179860b2SJed Brown if self.regExp and not self.re.match(value): 484*179860b2SJed Brown raise ValueError('Invalid string '+str(value)+'. You must give a string satisfying "'+str(self.regExp)+'"'+' for key '+str(self.key)) 485*179860b2SJed Brown self.value = value 486*179860b2SJed Brown return 487*179860b2SJed Brown 488*179860b2SJed Brownclass ArgDownload(Arg): 489*179860b2SJed Brown '''Arguments that represent software downloads''' 490*179860b2SJed Brown def __init__(self, key, value = None, help = '', isTemporary = 0, deprecated = False): 491*179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 492*179860b2SJed Brown return 493*179860b2SJed Brown 494*179860b2SJed Brown def valueName(self, value): 495*179860b2SJed Brown if value == 0: 496*179860b2SJed Brown return 'no' 497*179860b2SJed Brown elif value == 1: 498*179860b2SJed Brown return 'yes' 499*179860b2SJed Brown return str(value) 500*179860b2SJed Brown 501*179860b2SJed Brown def __str__(self): 502*179860b2SJed Brown if not self.isValueSet(): 503*179860b2SJed Brown return 'Empty '+str(self.__class__) 504*179860b2SJed Brown elif isinstance(self.value, list): 505*179860b2SJed Brown return str(map(self.valueName, self.value)) 506*179860b2SJed Brown return self.valueName(self.value) 507*179860b2SJed Brown 508*179860b2SJed Brown def getEntryPrompt(self): 509*179860b2SJed Brown return 'Please enter download value for '+str(self.key)+': ' 510*179860b2SJed Brown 511*179860b2SJed Brown def setValue(self, value): 512*179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 513*179860b2SJed Brown import os 514*179860b2SJed Brown self.checkKey() 515*179860b2SJed Brown try: 516*179860b2SJed Brown if value == '0': value = 0 517*179860b2SJed Brown elif value == '1': value = 1 518*179860b2SJed Brown elif value == 'no': value = 0 519*179860b2SJed Brown elif value == 'yes': value = 1 520*179860b2SJed Brown elif value == 'false': value = 0 521*179860b2SJed Brown elif value == 'true': value = 1 522*179860b2SJed Brown elif not isinstance(value, int): 523*179860b2SJed Brown value = str(value) 524*179860b2SJed Brown except: 525*179860b2SJed Brown raise TypeError('Invalid download value: '+str(value)+' for key '+str(self.key)) 526*179860b2SJed Brown if isinstance(value, str): 527*179860b2SJed Brown import urlparse 528*179860b2SJed Brown if not urlparse.urlparse(value)[0]: # how do we check if the URL is invalid? 529*179860b2SJed Brown if os.path.isfile(value): 530*179860b2SJed Brown value = 'file://'+os.path.abspath(value) 531*179860b2SJed Brown else: 532*179860b2SJed Brown raise ValueError('Invalid download location: '+str(value)+' for key '+str(self.key)) 533*179860b2SJed Brown self.value = value 534*179860b2SJed Brown return 535