diff options
author | Frederic Lepied <flepied@mandriva.com> | 2002-01-17 19:56:19 +0000 |
---|---|---|
committer | Frederic Lepied <flepied@mandriva.com> | 2002-01-17 19:56:19 +0000 |
commit | 68ebfc5fc46591d84ed1b0887c1c0b19ba7aa47d (patch) | |
tree | 4e2d7e6f16f8bb65f61c2913dfe35fd767e62040 /share/ConfigFile.py | |
parent | 1ff71ce4eb92eeeb629ce2669a8db801f182249c (diff) | |
download | msec-68ebfc5fc46591d84ed1b0887c1c0b19ba7aa47d.tar msec-68ebfc5fc46591d84ed1b0887c1c0b19ba7aa47d.tar.gz msec-68ebfc5fc46591d84ed1b0887c1c0b19ba7aa47d.tar.bz2 msec-68ebfc5fc46591d84ed1b0887c1c0b19ba7aa47d.tar.xz msec-68ebfc5fc46591d84ed1b0887c1c0b19ba7aa47d.zip |
0.17
Diffstat (limited to 'share/ConfigFile.py')
-rw-r--r-- | share/ConfigFile.py | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/share/ConfigFile.py b/share/ConfigFile.py new file mode 100644 index 0000000..3e24b9b --- /dev/null +++ b/share/ConfigFile.py @@ -0,0 +1,376 @@ +#--------------------------------------------------------------- +# Project : Mandrake Linux +# Module : msec2 +# File : ConfigFile.py +# Version : $Id$ +# Author : Frederic Lepied +# Created On : Wed Dec 5 21:42:49 2001 +# Purpose : class abstraction to handle configuration +# files. +#--------------------------------------------------------------- + +import re +import string +import os +import stat +import Config +import commands +from Log import * +import gettext + +try: + cat = gettext.Catalog('msec') + _ = cat.gettext +except IOError: + _ = str + +BEFORE=0 +INSIDE=1 +AFTER=2 + +space = re.compile('\s') + +class ConfigFiles: + def __init__(self): + self.files = {} + self.modified_files = [] + self.action_assoc = [] + + def add(self, file, path): + self.files[path] = file + + def modified(self, path): + if not path in self.modified_files: + self.modified_files.append(path) + + def get_config_file(self, path, suffix): + try: + return self.files[path] + except KeyError: + return ConfigFile(path, suffix, self) + + def add_config_assoc(self, regex, action): + self.action_assoc.append((re.compile(regex), action)) + +all_files=ConfigFiles() + +def move(old, new): + try: + os.unlink(new) + except OSError: + pass + os.rename(old, new) + +class ConfigFile: + def __init__(self, path, suffix=None, meta=all_files): + self.meta=meta + self.path = Config.get_config('root', '') + path + self.is_modified = 0 + self.is_touched = 0 + self.is_deleted = 0 + self.is_moved = 0 + self.suffix = suffix + self.lines = None + self.sym_link = None + self.meta.add(self, path) + + def get_lines(self): + if self.lines == None: + file=None + try: + file = open(self.path, 'r') + except IOError: + if self.suffix: + try: + moved = self.path + self.suffix + file = open(moved, 'r') + move(moved, self.path) + self.meta.modified(self.path) + except IOError: + self.lines = [] + else: + self.lines = [] + if file: + self.lines = string.split(file.read(), "\n") + file.close() + return self.lines + + def append(self, value): + lines = self.lines + l = len(lines) + if l > 0 and lines[l - 1] == '': + lines.insert(l - 1, value) + else: + lines.append(value) + lines.append('') + + def modified(self): + self.is_modified = 1 + return self + + def touch(self): + self.is_touched = 1 + return self + + def symlink(self, link): + self.sym_link = link + return self + + def exists(self): + return os.path.exists(self.path) or (self.suffix and os.path.exists(self.path + self.suffix)) + + def move(self, suffix): + self.suffix = suffix + self.is_moved = 1 + + def unlink(self): + self.is_deleted = 1 + self.lines=[] + return self + + def write(self): + if self.is_deleted: + if self.exists(): + os.unlink(self.path) + log(_('deleted %s') % (self.path,)) + elif self.is_modified: + content = string.join(self.lines, "\n") + file = open(self.path, 'w') + file.write(content) + file.close() + self.meta.modified(self.path) + elif self.is_touched: + if os.path.exists(self.path): + os.utime(self.path, None) + elif self.suffix and os.path.exists(self.path + self.suffix): + move(self.path + self.suffix, self.path) + os.utime(self.path, None) + else: + self.lines = [] + self.is_modified = 1 + file = open(self.path, 'w') + file.close() + log(_('touched file %s') % (self.path,)) + elif self.sym_link: + done = 0 + if self.exists(): + full = os.lstat(self.path) + if stat.S_ISLNK(full[stat.ST_MODE]): + link = os.readlink(self.path) + # to be fixed: resolv relative symlink + done = (link == self.sym_link) + if not done: + os.unlink(self.path) + log(_('deleted %s') % (self.path,)) + if not done: + os.symlink(self.sym_link, self.path) + log(_('made symbolic link from %s to %s') % (self.sym_link, self.path)) + + if self.is_moved: + move(self.path, self.path + self.suffix) + log(_('moved file %s to %s') % (self.path, self.path + self.suffix)) + self.meta.modified(self.path) + self.is_touched = 0 + self.is_modified = 0 + self.is_deleted = 0 + self.is_moved = 0 + + def set_shell_variable(self, var, value, start=None, end=None): + regex = re.compile('^' + var + '="?([^#"]+)"?(.*)') + lines = self.get_lines() + idx=0 + value=str(value) + + if start: + status = BEFORE + start = re.compile(start) + else: + status = INSIDE + + if end: + end = re.compile(end) + + idx = None + for idx in range(0, len(lines)): + line = lines[idx] + if status == BEFORE: + if start.search(line): + status = INSIDE + else: + continue + elif end and end.search(line): + break + res = regex.search(line) + if res: + if res.group(1) != value: + if space.search(value): + lines[idx] = var + '="' + value + '"' + res.group(2) + else: + lines[idx] = var + '=' + value + res.group(2) + self.modified() + log(_('set variable %s to %s in %s') % (var, value, self.path,)) + return self + if space.search(value): + s = var + '="' + value + '"' + else: + s = var + '=' + value + if idx == None or idx == len(lines): + self.append(s) + else: + lines.insert(idx, s) + + self.modified() + log(_('set variable %s to %s in %s') % (var, value, self.path,)) + return self + + def get_shell_variable(self, var): + regex = re.compile('^' + var + '="?([^#"]+)"?(.*)') + lines = self.get_lines() + for idx in range(0, len(lines)): + res = regex.search(lines[idx]) + if res: + return res.group(1) + return None + + def get_match(self, regex, replace=None): + r=re.compile(regex) + lines = self.get_lines() + matches = 0 + for idx in range(0, len(lines)): + res = r.search(lines[idx]) + if res: + s = substitute_re_result(res, replace) + return s + return None + + def replace_line_matching(self, regex, value, at_end_if_not_found=0, all=0, start=None, end=None): + r=re.compile(regex) + lines = self.get_lines() + matches = 0 + + if start: + status = BEFORE + start = re.compile(start) + else: + status = INSIDE + + if end: + end = re.compile(end) + + idx = None + for idx in range(0, len(lines)): + line = lines[idx] + if status == BEFORE: + if start.search(line): + status = INSIDE + else: + continue + elif end and end.search(line): + break + res = r.search(line) + if res: + s = substitute_re_result(res, value) + matches = matches + 1 + if s != line: + log(_("replaced in %s the line %d:\n%s\nwith the line:\n%s") % (self.path, idx, line, s)) + lines[idx] = s + self.modified() + if not all: + return matches + if matches == 0 and at_end_if_not_found: + log(_("appended in %s the line:\n%s") % (self.path, value)) + if idx == None or idx == len(lines): + self.append(value) + else: + lines.insert(idx, value) + self.modified() + matches = matches + 1 + return matches + + def insert_after(self, regex, value, at_end_if_not_found=0, all=0): + matches = 0 + r=re.compile(regex) + lines = self.get_lines() + for idx in range(0, len(lines)): + res = r.search(lines[idx]) + if res: + s = substitute_re_result(res, value) + log(_("inserted in %s after the line %d:\n%s\nthe line:\n%s") % (self.path, idx, lines[idx], s)) + lines.insert(idx+1, s) + self.modified() + matches = matches + 1 + if not all: + return matches + if matches == 0 and at_end_if_not_found: + log(_("appended in %s the line:\n%s") % (self.path, value)) + self.append(value) + self.modified() + matches = matches + 1 + return matches + + def insert_at(self, idx, value): + lines = self.get_lines() + try: + lines.insert(idx, value) + log(_("inserted in %s at the line %d:\n%s") % (self.path, idx, value)) + self.modified() + return 1 + except KeyError: + return 0 + + def remove_line_matching(self, regex, all=0): + matches = 0 + r=re.compile(regex) + lines = self.get_lines() + for idx in range(len(lines) - 1, -1, -1): + res = r.search(lines[idx]) + if res: + log(_("removing in %s the line %d:\n%s") % (self.path, idx, lines[idx])) + lines.pop(idx) + self.modified() + matches = matches + 1 + if not all: + return matches + return matches + +# utility funtions + +def substitute_re_result(res, s): + for idx in range(0, (res.lastindex or 0) + 1): + subst = res.group(idx) or '' + s = string.replace(s, '@' + str(idx), subst) + return s + +def write_files(): + global all_files + + run_commands = Config.get_config('run_commands', 0) + for f in all_files.files.values(): + f.write() + + for f in all_files.modified_files: + for a in all_files.action_assoc: + res = a[0].search(f) + if res: + s = substitute_re_result(res, a[1]) + if run_commands != '0': + log(_('%s modified so launched command: %s') % (f, s)) + cmd = commands.getstatusoutput(s) + if cmd[0] == 0: + log(cmd[1]) + else: + error(cmd[1]) + else: + log(_('%s modified so should have run command: %s') % (f, s)) + +def get_config_file(path, suffix=None): + global all_files + + return all_files.get_config_file(path, suffix) + +def add_config_assoc(regex, action): + global all_files + + return all_files.add_config_assoc(regex, action) + +# ConfigFile.py ends here |