1179860b2SJed Brown'''This module is meant to provide support for information and help systems based upon RDict.''' 2179860b2SJed Brownimport logger 3179860b2SJed Brown 4179860b2SJed Brownclass Info(logger.Logger): 5179860b2SJed Brown '''This basic class provides information independent of RDict''' 6179860b2SJed Brown def __init__(self, argDB = None): 7179860b2SJed Brown '''Creates a dictionary "sections" whose keys are section names, and values are a tuple of (ordinal, nameList)''' 8179860b2SJed Brown logger.Logger.__init__(self, None, argDB) 9179860b2SJed Brown self.sections = {} 10179860b2SJed Brown return 11179860b2SJed Brown 12179860b2SJed Brown def getTitle(self): 13179860b2SJed Brown return self._title 14179860b2SJed Brown 15179860b2SJed Brown def setTitle(self, title): 16179860b2SJed Brown self._title = str(title) 17179860b2SJed Brown title = property(getTitle, setTitle, None, 'Title of the Information Menu') 18179860b2SJed Brown 19179860b2SJed Brown def getDescription(self, section, name): 20179860b2SJed Brown return self._desc[(section, name)] 21179860b2SJed Brown 22179860b2SJed Brown def setDescription(self, section, name, desc): 23179860b2SJed Brown if not hasattr(self, '_desc'): 24179860b2SJed Brown self._desc = {} 25179860b2SJed Brown self._desc[(section, name)] = desc 26179860b2SJed Brown return 27179860b2SJed Brown 28179860b2SJed Brown def addArgument(self, section, name, desc): 29179860b2SJed Brown '''Add an argument with given name and string to an information section''' 30179860b2SJed Brown if not section in self.sections: 31179860b2SJed Brown self.sections[section] = (len(self.sections), []) 32179860b2SJed Brown if name in self.sections[section][1]: 33179860b2SJed Brown name += '@'+str(len(filter(lambda n: name == n.split('@')[0], self.sections[section][1]))+1) 34179860b2SJed Brown self.sections[section][1].append(name) 35179860b2SJed Brown self.setDescription(section, name, desc) 36179860b2SJed Brown return 37179860b2SJed Brown 38179860b2SJed Brown def printBanner(self, f): 39179860b2SJed Brown '''Print a banner for the information screen''' 40179860b2SJed Brown f.write(self.title+'\n') 41179860b2SJed Brown for i in range(max(map(len, self.title.split('\n')))): f.write('-') 42179860b2SJed Brown f.write('\n') 43179860b2SJed Brown return 44179860b2SJed Brown 45179860b2SJed Brown def getTextSizes(self): 46179860b2SJed Brown '''Returns the maximum name and description lengths''' 47179860b2SJed Brown nameLen = 1 48179860b2SJed Brown descLen = 1 49179860b2SJed Brown for section in self.sections: 50179860b2SJed Brown nameLen = max([nameLen, max(map(lambda n: len(n.split('@')[0]), self.sections[section][1]))+1]) 51179860b2SJed Brown descLen = max([descLen, max(map(lambda name: len(self.getDescription(section, name)), self.sections[section][1]))+1]) 52179860b2SJed Brown return (nameLen, descLen) 53179860b2SJed Brown 54179860b2SJed Brown def output(self, f = None): 55179860b2SJed Brown '''Print a help screen with all the argument information.''' 56179860b2SJed Brown if f is None: 57179860b2SJed Brown import sys 58179860b2SJed Brown f = sys.stdout 59179860b2SJed Brown self.printBanner(f) 60179860b2SJed Brown (nameLen, descLen) = self.getTextSizes() 61179860b2SJed Brown format = ' %-'+str(nameLen)+'s: %s\n' 62179860b2SJed Brown items = self.sections.items() 63179860b2SJed Brown items.sort(lambda a, b: a[1][0].__cmp__(b[1][0])) 64179860b2SJed Brown for section, names in items: 65179860b2SJed Brown f.write(section+':\n') 66179860b2SJed Brown for name in names[1]: 67179860b2SJed Brown f.write(format % (name.split('@')[0], self.getDescription(section, name))) 68179860b2SJed Brown return 69179860b2SJed Brown 70179860b2SJed Brownclass Help(Info): 71179860b2SJed Brown '''Help provides a simple help system for RDict''' 72179860b2SJed Brown def __init__(self, argDB): 73179860b2SJed Brown '''Creates a dictionary "sections" whose keys are section names, and values are a tuple of (ordinal, nameList). Also provide the RDict upon which this will be based.''' 74179860b2SJed Brown Info.__init__(self, argDB) 75179860b2SJed Brown self.title = 'Help' 76179860b2SJed Brown return 77179860b2SJed Brown 78179860b2SJed Brown def getDescription(self, section, name): 79179860b2SJed Brown return self.argDB.getType(self.getArgName(name)).help 80179860b2SJed Brown 81179860b2SJed Brown def setDescription(self, section, name, desc): 82179860b2SJed Brown return 83179860b2SJed Brown 84179860b2SJed Brown def getArgName(self, name): 85179860b2SJed Brown '''Return the RDict key corresponding to a more verbose help name. Right now, this means discard everything after "=".''' 86179860b2SJed Brown #return name.split('=')[0].strip('-') 87179860b2SJed Brown argName = name.split('=')[0] 88179860b2SJed Brown while argName[0] == '-': argName = argName[1:] 89179860b2SJed Brown return argName 90179860b2SJed Brown 91179860b2SJed Brown def addArgument(self, section, name, argType, ignoreDuplicates = 0): 92179860b2SJed Brown '''Add an argument with given name and type to a help section. The type, which can also have an initializer and help string, will be put into RDict.''' 93179860b2SJed Brown## super(Info, self).addArgument(section, name, None) 94179860b2SJed Brown if section in self.sections: 95179860b2SJed Brown if name in self.sections[section][1]: 96179860b2SJed Brown if ignoreDuplicates: 97179860b2SJed Brown return 98179860b2SJed Brown raise RuntimeError('Duplicate configure option '+name+' in section '+section) 99179860b2SJed Brown else: 100179860b2SJed Brown self.sections[section] = (len(self.sections), []) 101179860b2SJed Brown if not argType.deprecated: 102179860b2SJed Brown self.sections[section][1].append(name) 103179860b2SJed Brown 104179860b2SJed Brown self.argDB.setType(self.getArgName(name), argType, forceLocal = 1) 105179860b2SJed Brown return 106179860b2SJed Brown 107*75f179b0SBarry Smith def addDownload(self,name,dlist): 108*75f179b0SBarry Smith if not hasattr(self.argDB,'dlist'): 109*75f179b0SBarry Smith self.argDB.dlist = {} 110*75f179b0SBarry Smith else: 111*75f179b0SBarry Smith self.argDB.dlist[name] = dlist 112*75f179b0SBarry Smith 113179860b2SJed Brown def output(self, f = None, sections = None): 114179860b2SJed Brown '''Print a help screen with all the argument information.''' 115179860b2SJed Brown if f is None: 116179860b2SJed Brown import sys 117179860b2SJed Brown f = sys.stdout 118179860b2SJed Brown if sections: sections = [s.lower() for s in sections] 119179860b2SJed Brown self.printBanner(f) 120179860b2SJed Brown (nameLen, descLen) = self.getTextSizes() 121179860b2SJed Brown# format = ' -%-'+str(nameLen)+'s: %s\n' 122179860b2SJed Brown# formatDef = ' -%-'+str(nameLen)+'s: %-'+str(descLen)+'s current: %s\n' 123179860b2SJed Brown format = ' -%s\n %s\n' 124179860b2SJed Brown formatDef = ' -%s\n %s current: %s\n' 125179860b2SJed Brown items = self.sections.items() 126179860b2SJed Brown items.sort(lambda a, b: a[1][0].__cmp__(b[1][0])) 127179860b2SJed Brown for section, names in items: 128179860b2SJed Brown if sections and not section.lower() in sections: continue 129179860b2SJed Brown f.write(section+':\n') 130179860b2SJed Brown for name in names[1]: 131179860b2SJed Brown argName = self.getArgName(name) 132179860b2SJed Brown type = self.argDB.getType(argName) 133179860b2SJed Brown if argName in self.argDB: 134179860b2SJed Brown f.write(formatDef % (name, type.help, str(self.argDB.getType(argName)))) 135179860b2SJed Brown else: 136179860b2SJed Brown f.write(format % (name, type.help)) 137179860b2SJed Brown return 138*75f179b0SBarry Smith 139*75f179b0SBarry Smith def outputDownload(self): 140*75f179b0SBarry Smith import nargs 141*75f179b0SBarry Smith import os 142*75f179b0SBarry Smith import sys 143*75f179b0SBarry Smith pkgdir = nargs.Arg.findArgument('with-packages-dir', self.clArgs) 144*75f179b0SBarry Smith missing = 0 145*75f179b0SBarry Smith print 'Download the following packages to '+pkgdir+' \n' 146*75f179b0SBarry Smith for i in self.argDB.dlist.keys(): 147*75f179b0SBarry Smith if not nargs.Arg.findArgument('download-'+i, self.clArgs) == None and not nargs.Arg.findArgument('download-'+i, self.clArgs) == '0': 148*75f179b0SBarry Smith dlist = self.argDB.dlist[i] 149*75f179b0SBarry Smith found = 0 150*75f179b0SBarry Smith for k in range(0,len(dlist)): 151*75f179b0SBarry Smith fd = os.path.join(pkgdir,os.path.basename(dlist[k])) 152*75f179b0SBarry Smith if os.path.isdir(fd) or os.path.isfile(fd): 153*75f179b0SBarry Smith found = 1 154*75f179b0SBarry Smith for k in range(0,len(self.clArgs)): 155*75f179b0SBarry Smith if self.clArgs[k].startswith('--download-'+i): 156*75f179b0SBarry Smith self.clArgs[k] = 'download-'+i+'='+fd 157*75f179b0SBarry Smith self.argDB.insertArgs([self.clArgs[k]]) 158*75f179b0SBarry Smith break 159*75f179b0SBarry Smith if not found: 160*75f179b0SBarry Smith print i + ' ' + str(self.argDB.dlist[i]) 161*75f179b0SBarry Smith missing = 1 162*75f179b0SBarry Smith if missing: 163*75f179b0SBarry Smith sys.exit() 164*75f179b0SBarry Smith 165*75f179b0SBarry Smith 166