summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'umodule.py')
-rw-r--r--umodule.py274
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
+
+