#!/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 modules_dir = '/usr/share/uselect/modules/' class Action: def __init__(self, name, lines, _filesystem): self.filesystem = _filesystem self.name = name self.lines = lines self.output = [] self.usage = [] self.options = [] for line in self.lines: match = re.match('description "(.*)"', line.lstrip()) if match: self.description = match.group(1) continue match = re.match('type (.*)', line.lstrip()) if match: type = match.group(1) continue if type == 'runnable': self.__class__ = Runnable elif type == 'sym': if filesystem.uid != 'root': self.__class__ = Path else: self.__class__ = Sym self.build() class Runnable(Action): def do_action(self, args): path = '/tmp/' + self.filename self.filesystem.write_file(path, self.code) self.filesystem.make_exec_file(path) for line in self.filesystem.execute_cmd(path,args): self.output.append(line[:-1]) self.filesystem.delete_file(path) for line in self.output: self.options.append(['bold', line]) def get_code(self): i = 0 for line in self.lines: match = re.match('file (.*) {', line.lstrip()) if match: ident = 1 for char in line: if char == '\t': ident += 1 self.filename = match.group(1) for line in self.lines[i+1:]: line = line.rstrip() line = line.replace('\t', '', ident) match = re.match('} ' + self.filename, line) if match: self.code.append('') break self.code.append(line) i += 1 def build(self): self.code = [] self.get_code() for line in self.lines: match = re.match('parameters "(.*)"', line.lstrip()) if match: self.parameters = match.group(1) continue match = re.match('usage "(.*)"', line.lstrip()) if match: self.usage.append(match.group(1)) continue class Link: def __init__(self, name, source_dir, source_regexp, source_target, \ destination, _filesystem): self.name = name self.destination = destination self.targets = [] self.status = [] self.filesystem = _filesystem for dir in self.filesystem.list_dir(source_dir): match = re.match(source_regexp, dir) if match: source = source_dir + match.group(0) + source_target self.targets.append(source) if self.filesystem.path_exists(destination): if self.filesystem.real_path( \ self.filesystem.environment + self.name) == \ source: self.status.append('notice') elif self.filesystem.real_path(destination) == source: self.status.append('ok') else: self.status.append('warning') else: self.status.append('error') return class Sym(Action): def get_links(self): for line in self.lines: match = re.match('sym (.*) (.*) (.*) (.*) (.*)', line.lstrip()) if match: name = match.group(1) source_dir = match.group(3) source_regexp = match.group(4) if match.group(5) == '*': source_target = '' else: source_target = match.group(5) destination = match.group(2) self.links.append(Link(name, source_dir, source_regexp,\ source_target, destination, self.filesystem)) def do_action(self, args): if len(args) != 0: if args[0] == 'clear': for link in self.links: self.filesystem.delete_file(link.destination) elif len(args) >= 1: targets = [] option = int(args[0]) -1 for link in self.links: for i in range(len(link.targets)): targets.append([link.targets[i], \ link.destination]) if option >= 0 and option < len(targets): self.filesystem.create_symlink(targets[option][0], \ targets[option][1]) self.output.append('Setting ' + targets[option][0] \ + ' success!') else: raise UserWarning('Invalid Option "' \ + args[0] + '"!') else: raise UserWarning('Invalid Option "' + args[0] \ + '"!') else: for link in self.links: for i in range(len(link.targets)): self.options.append([link.status[i],str(i+1) + ' - ' + \ link.targets[i]]) self.parameters = '' self.usage.append('Available ' + self.name + ' targets:' ) def build(self): self.links = [] self.get_links() class Path(Action, Sym): def do_action(self, args): if len(args) != 0: if args[0] == 'clear': home = self.filesystem.get_home() for link in self.links: self.filesystem.delete_file(home + '.uselect/bin/' \ + link.name) elif len(args) >= 1: options = [] choice = int(args[0]) - 1 for link in self.links: for i in range(len(link.targets)): options.append([link.targets[i], \ link.destination]) if choice >= 0 and choice < len(options): self.filesystem.create_symlink( \ options[choice][0], self.filesystem.environment + \ link.name) self.output.append('Setting ' + options[choice][0] \ + ' success!') else: raise UserWarning('Invalid Option "' \ + args[0] + '"!') else: raise UserWarning('Invalid Option "' + args[0] \ + '"!') else: for link in self.links: for i in range(len(link.targets)): self.options.append([link.status[i],str(i+1) + ' - ' + \ link.targets[i]]) self.parameters = '' self.usage.append('Available ' + self.name + ' targets:' ) return class Module(): def __init__(self, name, _filesystem): global filesystem filesystem = _filesystem self.name = name self.version = 'Unknown' self.author = 'Anonymous' self.description = name + ' has no description! ' self.path = modules_dir + self.name + '.uselect' self.lines = filesystem.read_file(self.path) self.parse_module(name) self.actions = [] def parse_module(self, name): for line in self.lines: line = line.lstrip() match = re.match('description "(.*)"', line) if match: self.description = match.group(1) continue match = re.match('version "(.*)"', line) if match: self.version = match.group(1) continue match = re.match('author "(.*)"', line) if match: self.author = match.group(1) continue match = re.match('} ' + name, line) if match: break def get_action(self, name): i = 0 self.get_actions() for action in self.actions: if action.name == name: return action raise Exception('No such action "' + name + '"!') def get_actions(self): i = 0 for line in self.lines: match = re.match('(\w*) action (\w*)', line.lstrip()) if match: wideness = match.group(1) if wideness == "system" and filesystem.uid != "root": continue name = match.group(2) u = 0 for line in self.lines[i:]: match = re.match('} ' + name + '\w*', line) if match: lines = self.lines[i:i+u+1] action = Action(name, lines, filesystem) self.actions.append(action) break u += 1 if name == '(\w*)': break i += 1