import os from pprint import pprint from string import Template from collections import deque class PackagePrioritizer(object): def __init__(self): self.weight = {} self.packages = [] def insert(self, package): self.packages.append(package) def generate_weightmap(self): self.weight = { str(x):[] for x in self.packages } for package in self.packages: for priority in package.precedence: self.weight[str(package)].append(priority.name) class PackageException(Exception): pass class Package(object): def __init__(self, filename, load=True): self.valid_keywords = [ 'Type', 'Requires', 'Precedes', 'Synopsis', 'Description', 'Environment', 'LdLibrary', 'IncPath', 'Root', 'Path', 'ManPath', 'Default', 'Source' ] self.filename = os.path.join(ENVCONFIG_PATH, filename) self.exists = False self.name = '' self.name_internal = '' self.description = '' self.dependencies = [] self.precedence = [] self.priority = 0 # 0 - 99 self.shell = '' self.env = {} self.script = '' self.invisible = False self.mtime = 0 self.data = {} if os.path.exists(self.filename): self.exists = True self.name = os.path.basename(self.filename.replace(' ', '_')) if not load: return if self.filename is not None \ and self.exists: self.data = self.load() self.get_requirements() self.get_precedence() def __repr__(self): return self.name def get_requirements(self): if not self.data: raise PackageException('Package data not loaded.') if 'Requires' in self.data: for next_req in self.data['Requires']: req = Package(next_req) self.dependencies.append(req) if not req.exists: print("Requirement warning, {}: {} does not exist".format(self.name, os.path.basename(req.filename))) def get_precedence(self): if not self.data: raise PackageException('Package data not loaded.') if 'Precedes' in self.data: for next_req in self.data['Precedes']: req = Package(next_req, load=False) self.precedence.append(req) if not req.exists: print("Precedence warning, {}: {} does not exist".format(self.name, os.path.basename(req.filename))) def load(self): pairs = [] comment = '#' delimiter = ':' keyword = '' value = '' with open(self.filename, 'r') as f: for line in f.readlines(): line = line.strip() if not line: continue if not line.find(delimiter): continue if line.startswith(comment): continue keyword = line[0:line.find(delimiter)] if keyword not in self.valid_keywords: continue if keyword == 'Source': continue value = line[line.find(delimiter) + 1:].strip() pairs.append([keyword, value]) # Do source block with open(self.filename, 'r') as f: value = '' shell_type = '' data_block = False for line in f.readlines(): if line.startswith('Source:'): data_block = True shell_type = line[line.find(delimiter) + 1:line.rfind(delimiter)].strip() line = line[line.rfind(delimiter) + 1:-1] if data_block: value += line if line.startswith('"') and line.endswith('\\'): data_block = False pairs.append(['Source', value]) pairs.append(['Shell', shell_type]) pairs = dict(pairs) # Alias the filename to be the same as "Root" value if 'Root' in pairs: pairs[self.name] = pairs['Root'] # Substitute configuration values for key, value in pairs.items(): s = Template(value) pairs[key] = s.safe_substitute(pairs) if 'Requires' in pairs: pairs['Requires'] = str(pairs['Requires']).split() if 'Precedes' in pairs: pairs['Precedes'] = str(pairs['Precedes']).split() return dict(pairs) if __name__ == '__main__': ENVCONFIG_PATH = os.path.abspath(os.path.normpath('../envconfig')) pkgs = [] for r, d, fs in os.walk(ENVCONFIG_PATH): for f in fs: pkgs.append(Package(f)) #pkg = Package('JDK1.6.07') pp = PackagePrioritizer() for pkg in pkgs: pp.insert(pkg) pp.generate_weightmap() pprint(pp.weight) #pprint(pp.packages) #pkg = Package(None) #pprint(pkg.data)