#!/usr/bin/env python # Copyright 1999-2009 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # Universal Select Tool # Uselect Modules/Actions Module # umodule.py mephx.x@gmail.com import re import os #import pdb from uio import Counter from uio import filesystem from uio import printsystem modules_dir = '/usr/share/uselect/modules/' class Action: def __init__(self, name = None, lines = None, description = None, type = None): self.description = description self.name = name self.output = [] self.usage = [] self.options = [] self.type = type if type == 'runnable': self.__class__ = Runnable elif type == 'env': self.__class__ = Env elif type == 'sym': if filesystem.uid != 'root': self.__class__ = Path else: self.__class__ = Sym elif type == 'profile': self.__class__ = ProfileAction else: raise UserWarning('Action "' + name + '" has no type set!') self.setup() class Runnable(Action): def do_action(self, args): if len(args) != 0: path = '/tmp/' + self.name filesystem.write_file(path, self.code) filesystem.make_exec_file(path) for line in filesystem.execute_cmd(path,args).readlines(): self.output.append(line[:-1]) filesystem.delete_file(path) def add_parameter(self, parameter): """ Adds Usage Parameters. """ self.parameters.append(parameter) def add_usage(self, usage): """ Adds Usage Code. """ usage = usage.split('\n') args = [] path = '/tmp/' + self.name filesystem.write_file(path, usage) filesystem.make_exec_file(path) for line in filesystem.execute_cmd(path,args): self.usage.append(line[:-1]) filesystem.delete_file(path) def add_code(self, lines = None): """ Add Code. """ lines = lines.split('\n') self.code = lines def setup(self): self.code = [] self.parameters = [] self.usage = [] def build(self): return class Link: def add_link(self, link = None): """ Add a sub-link. """ self.links.append(link) link.parent = self def __init__(self, lines = None, alias = None, target = None, prefix = None, regexp = None, sufix = ''): self.alias = alias self.target = prefix + alias self.prefix = prefix self.sufix = sufix self.regexp = regexp self.targets = [] self.status = [] self.links = [] self.destination = self.prefix + self.alias def get_links(self, counter = None): """ Builds a nested list with the Link's hierarchy. """ links = [] target = [] if self.links == []: return for link in self.links: if len(link.targets) == 0: raise UserWarning('Link "' + link.alias \ + '" has no targets!') for i in range(len(link.targets)): target.append([counter.count, link, i]) counter.count += 1 sub_links = link.get_links(counter) if sub_links != None: target.append(sub_links) links.append(target) return links def build(self): for link in self.links: link.build() for dir in filesystem.list_dir(self.prefix): match = re.match(self.regexp, dir) if match: source = self.prefix + match.group(0) + self.sufix self.targets.append(source) if filesystem.path_exists(self.destination): if filesystem.real_path(self.destination) == source: self.status.append('ok') else: self.status.append('warning') if filesystem.real_path( \ filesystem.environment + 'bin/' + self.alias) == \ source: status = self.status.pop() status += ' + space + notice' self.status.append(status) else: self.status.append('error') return class Sym(Action): def build_options(self, links): """ Builds available options for PrintSystem. """ options = [] for link in links: if link == []: options.append([0, 'No Targets Found!', 'error']) elif isinstance(link, list) and not isinstance(link[0], int): options.append(self.build_options(link)) else: count = link[0] i = link[2] link = link[1] options.append([count, link.targets[i], link.status[i]]) return options def get_targets(self, links, option = None, target = None, family = None): """ Builds a nested list of targets. """ parent = None for link in links: if isinstance(link, list) and not isinstance(link[0], int): if self.get_targets(link, option = option, family = family, target = target): if target == None: if parent != None: family.append(parent) return family else: del family[:] elif isinstance(link, list) and isinstance(link[0], int): if option == None: if link[1].targets[link[2]] == target: family.append(link) return True else: parent = link else: if option == link[0]: family.append(link) return True else: parent = link def do_action(self, args): """ Implementation of do_action() for Sym. """ links = [] counter = Counter() for link in self.links: target = [] if len(link.targets) == 0: raise UserWarning('Link "' + link.alias \ + '" has no targets!') for i in range(len(link.targets)): target.append([counter.count, link,i]) counter.count +=1 sub_links = link.get_links(counter) if sub_links != None: target.append(sub_links) links.append(target) self.options = self.build_options(links) if len(args) != 0: if len(args) >= 1: for arg in args: try: option = int(arg) target = None except ValueError: option = None target = arg targets = self.get_targets(links, option = option, target = target, family = []) if targets != None: for target in targets: self.do_target(target) else: raise UserWarning('Invalid Option "' + args[0] \ + '"!') else: self.parameters = ['','...',''] self.usage.append('Available ' + self.name + ' targets:' ) def do_target(self, target, clear = False): """ Activate/Deactivate a target. """ i = target[2] link = target[1] if clear: filesystem.delete_file(link.destination) self.output.append('Unsetting ' + link.destination\ + ' success!') else: filesystem.create_symlink(link.targets[i], \ link.destination) self.output.append('Setting ' + link.targets[i]\ + ' success!') def add_link(self, link = None): """ Add sub-link. """ self.links.append(link) def setup(self): self.links = [] def build(self): self.parameters = ['', '(...)', ''] for link in self.links: link.build() class Var(): def __init__(self, var, filesystem): filesystem = filesystem self.name = var self.values = [] def add_values(self, values, separator = ':', active = True): """ Parses a line of values and adds the values. """ values = values.split(separator) for value in values: self.add_value(value, active) def add_value(self, value, active = False): """ Add a value. """ self.values.append([value, active]) def export(self): filesystem.set_env(self) def to_string(self, separator = ':'): """ Builds a line of values. """ string = '' for value in self.values: string += value + separator return string class ProfileAction(Action): def do_action(self, args, modules): if args[0] == 'activate': filesystem.prepare_environment() self.output.append('Setting Folder Profile...') for module in modules: for action in module[1]: _action = module[0].get_action(action[0]) _action.build() for arg in action[1]: args = str(arg).split(" ") _action.do_action(args) for line in _action.output: self.output.append(line) self.output.append('Folder Profile Set!') elif args[0] == 'default': self.output.append('Default Profile Set!') def build(self): return def setup(self): return class Env(Action): def do_action(self, args): for var in self.vars: for value in var.values: if not value[1]: self.usage.append(var.name) for value in var.values: self.usage.append(' ' + value[0]) def get_var(self, name): """ Gets a var by name. Inits the var if not found. """ for var in self.vars: if var.name == name: return var var = Var(name, filesystem) self.vars.append(var) return var def setup(self): self.vars = [] def build(self): env = filesystem.get_env() for var in env: _var = self.get_var(var[0]) _var.add_values(var[1]) self.parameters = ['', '(...)', ''] class Path(Action, Sym): def do_target(self, target, clear = False): """ Implementation of do_target for Path. Activates/Deactivates targets. """ # TODO: implement clear filesystem.prepare_environment() i = target[2] link = target[1] filesystem.create_symlink(link.targets[i], \ filesystem.environment + 'bin/' + link.alias) self.output.append('Setting ' + link.targets[i] \ + ' success!') class Module(): def __init__(self, name = None , description = None , \ version = 'Undefined', author = 'Undefined', \ _filesystem = None, _printsystem = None): self.name = name self.description = description self.version = version self.author = author self.actions = [] return def add_action(self, action = None): """ Adds an action to the module. """ if action != None: self.actions.append(action) else: raise UserWarning('You must not add an empty action!') def get_action(self, name): """ Gets an action by name. """ i = 0 for action in self.actions: if action.name == name: return action raise Exception('No such action "' + name + '"!')