Viewing file:
sysconfig.py (11.28 KB) -rw-r--r--Select action/file-type:

(
+) |

(
+) |

(
+) |
Code (
+) |
Session (
+) |

(
+) |
SDB (
+) |

(
+) |

(
+) |

(
+) |

(
+) |

(
+) |
#
# Copyright (c) 2004 Conectiva, Inc.
#
# Written by Gustavo Niemeyer <niemeyer@conectiva.com>
#
# This file is part of Smart Package Manager.
#
# Smart Package Manager is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# Smart Package Manager is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Smart Package Manager; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
import cPickle as pickle
from smart import *
import sys, os
import copy
import re
NOTHING = object()
class SysConfig(object):
"""System configuration class.
It has three different kinds of opition maps, regarding the
persistence and priority that maps are queried.
hard - Options are persistent.
soft - Options are not persistent, and have a higher priority
than persistent options.
weak - Options are not persistent, and have a lower priority
than persistent options.
"""
def __init__(self, root=()):
self._hardmap = {}
self._softmap = {}
self._weakmap = {}
self._readonly = False
self._modified = False
self._config = self
def getReadOnly(self):
return self._readonly
def setReadOnly(self, flag):
self._readonly = flag
def getModified(self):
return self._modified
def resetModified(self):
self._modified = False
def assertWritable(self):
if self._readonly:
raise Error, _("Configuration is in readonly mode.")
def load(self, filepath):
filepath = os.path.expanduser(filepath)
if not os.path.isfile(filepath):
raise Error, _("File not found: %s") % filepath
if os.path.getsize(filepath) == 0:
return
file = open(filepath)
self._hardmap.clear()
try:
self._hardmap.update(pickle.load(file))
except:
filepathold = filepath+".old"
if (os.path.isfile(filepathold) and
os.path.getsize(filepathold) > 0):
iface.warning(_("Broken configuration file at %s") % filepath)
iface.warning(_("Trying backup at %s") % filepathold)
file.close()
file = open(filepathold)
try:
self._hardmap.update(pickle.load(file))
except:
raise Error, _("Broken configuration file at %s") % \
filepathold
else:
raise Error, _("Broken configuration file at %s") % \
filepath
file.close()
def save(self, filepath):
filepath = os.path.expanduser(filepath)
if os.path.isfile(filepath):
os.rename(filepath, filepath+".old")
dirname = os.path.dirname(filepath)
if not os.path.isdir(dirname):
os.makedirs(dirname)
file = open(filepath, "w")
pickle.dump(self._hardmap, file, 2)
file.close()
def _traverse(self, obj, path, default=NOTHING, setvalue=NOTHING):
queue = list(path)
marker = NOTHING
newobj = obj
while queue:
obj = newobj
elem = queue.pop(0)
if type(obj) is dict:
newobj = obj.get(elem, marker)
elif type(obj) in (tuple, list):
if type(elem) is int:
try:
newobj = obj[elem]
except IndexError:
newobj = marker
elif elem in obj:
newobj = elem
else:
newobj = marker
else:
if queue:
path = path[:-len(queue)]
raise Error, "Can't traverse %s (%s): %s" % \
(type(obj), pathTupleToString(path), str(obj))
if newobj is marker:
break
if newobj is not marker:
if setvalue is not marker:
newobj = obj[elem] = setvalue
else:
if setvalue is marker:
newobj = default
else:
while True:
if len(queue) > 0:
if type(queue[0]) is int:
newvalue = []
else:
newvalue = {}
else:
newvalue = setvalue
if type(obj) is dict:
newobj = obj[elem] = newvalue
elif type(obj) is list and type(elem) is int:
lenobj = len(obj)
if lenobj <= elem:
obj.append(None)
elem = lenobj
elif elem < 0 and abs(elem) > lenobj:
obj.insert(0, None)
elem = 0
newobj = obj[elem] = newvalue
else:
raise Error, "Can't traverse %s with %s" % \
(type(obj), type(elem))
if not queue:
break
obj = newobj
elem = queue.pop(0)
return newobj
def _getvalue(self, path, soft=False, hard=False, weak=False):
if type(path) is str:
path = pathStringToTuple(path)
marker = NOTHING
if soft:
value = self._traverse(self._softmap, path, marker)
elif hard:
value = self._traverse(self._hardmap, path, marker)
elif weak:
value = self._traverse(self._weakmap, path, marker)
else:
value = self._traverse(self._softmap, path, marker)
if value is marker:
value = self._traverse(self._hardmap, path, marker)
if value is marker:
value = self._traverse(self._weakmap, path, marker)
return value
def has(self, path, value=NOTHING, soft=False, hard=False, weak=False):
obj = self._getvalue(path, soft, hard, weak)
marker = NOTHING
if obj is marker:
return False
elif value is marker:
return True
elif type(obj) in (dict, list):
return value in obj
else:
raise Error, "Can't check %s for containment" % type(obj)
def keys(self, path, soft=False, hard=False, weak=False):
value = self._getvalue(path, soft, hard, weak)
if value is NOTHING:
return []
if type(value) is dict:
return value.keys()
elif type(value) is list:
return range(len(value))
else:
raise Error, "Can't return keys for %s" % type(value)
def get(self, path, default=None, soft=False, hard=False, weak=False):
value = self._getvalue(path, soft, hard, weak)
if value is NOTHING:
return default
if type(value) in (dict, list):
return copy.deepcopy(value)
return value
def set(self, path, value, soft=False, weak=False):
assert path
if type(path) is str:
path = pathStringToTuple(path)
if soft:
map = self._softmap
elif weak:
map = self._weakmap
else:
self.assertWritable()
self._modified = True
map = self._hardmap
self._traverse(map, path, setvalue=value)
def add(self, path, value, unique=False, soft=False, weak=False):
assert path
if type(path) is str:
path = pathStringToTuple(path)
if soft:
map = self._softmap
elif weak:
map = self._weakmap
else:
self.assertWritable()
self._modified = True
map = self._hardmap
if unique:
current = self._traverse(map, path)
if type(current) is list and value in current:
return
path = path+(sys.maxint,)
self._traverse(map, path, setvalue=value)
def remove(self, path, value=NOTHING, soft=False, weak=False):
assert path
if type(path) is str:
path = pathStringToTuple(path)
if soft:
map = self._softmap
elif weak:
map = self._weakmap
else:
self.assertWritable()
self._modified = True
map = self._hardmap
marker = NOTHING
while path:
if value is marker:
obj = self._traverse(map, path[:-1])
elem = path[-1]
else:
obj = self._traverse(map, path)
elem = value
result = False
if obj is marker:
pass
elif type(obj) is dict:
if elem in obj:
del obj[elem]
result = True
elif type(obj) is list:
if value is marker and type(elem) is int:
try:
del obj[elem]
result = True
except IndexError:
pass
elif elem in obj:
obj[:] = [x for x in obj if x != elem]
result = True
else:
raise Error, "Can't remove %s from %s" % \
(`elem`, type(obj))
if not obj:
if value is not marker:
value = marker
else:
path = path[:-1]
else:
break
return result
def move(self, oldpath, newpath, soft=False, weak=False):
if type(oldpath) is str:
oldpath = pathStringToTuple(oldpath)
if type(newpath) is str:
newpath = pathStringToTuple(newpath)
result = False
marker = NOTHING
value = self._getvalue(oldpath, soft, not (soft or weak), weak)
if value is not marker:
self.remove(oldpath, soft=soft, weak=weak)
self.set(newpath, value, weak, soft)
result = True
return result
SPLITPATH = re.compile(r"(\[-?\d+\])|(?<!\\)\.").split
def pathStringToTuple(path):
if "." not in path and "[" not in path:
return (path,)
result = []
tokens = SPLITPATH(path)
for token in tokens:
if token:
if token[0] == "[" and token[-1] == "]":
try:
result.append(int(token[1:-1]))
except ValueError:
raise Error, "Invalid path index: %s" % token
else:
result.append(token.replace(r"\.", "."))
return tuple(result)
def pathTupleToString(path):
result = []
for elem in path:
if type(elem) is int:
result[-1] += "[%d]" % elem
else:
result.append(str(elem).replace(".", "\."))
return ".".join(result)
# vim:ts=4:sw=4:et