diff options
author | Sérgio Almeida <mephx@thedude.(none)> | 2009-06-17 18:45:31 +0100 |
---|---|---|
committer | Sérgio Almeida <mephx@thedude.(none)> | 2009-06-17 18:45:31 +0100 |
commit | 5e561c1bb476977119fb947a4e21fe6dd4e3c314 (patch) | |
tree | edc9261465523b884f869145aa97a0b7dd9ccd2b /umodule.py | |
download | uselect-5e561c1bb476977119fb947a4e21fe6dd4e3c314.tar.gz uselect-5e561c1bb476977119fb947a4e21fe6dd4e3c314.tar.bz2 uselect-5e561c1bb476977119fb947a4e21fe6dd4e3c314.zip |
Initial Universal Select Tool Commit
Diffstat (limited to 'umodule.py')
-rw-r--r-- | umodule.py | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/umodule.py b/umodule.py new file mode 100644 index 0000000..11bbf35 --- /dev/null +++ b/umodule.py @@ -0,0 +1,274 @@ +#!/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 = '<target>' + 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 = '<target>' + 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 + + |