Based on RawConfigParser, the usage and implementation is almost the same, however this is not a subclass of it because it doesn't need to.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | #!/usr/bin/env python
# regconfig.py
import _winreg
import os.path as path
class RegConfig:
""" Class that encapsulates a registry (path) as a configuration store.
section = registry key
option = registry valuename
value = registry value
Storage model = dictionary
"""
def __init__(self, reg_path=None, autowrite=False):
self._regpath = reg_path
self._autowrite = autowrite
self._store = {}
# Autowrite is available only if a registry path is provided.
if not self._regpath: self._autowrite = False
# read the registry and store values if path given.
if self._regpath: self.read(self._regpath)
def add_section(self, section):
""" Add a section named section to the instance. If a section by the
given name already exists, ValueError is raised. """
if not self.has_section(section):
self._store[section] = {}
else:
raise ValueError("Section already exists")
def get(self, section, option):
""" Get an option value for the named section. """
if self.has_option(section, option):
return self._store[section][option][0]
def _get_default_regkey(self, regpath=None, forwriting=False):
""" Get the registry key handle for registry operations. provided the
registry path. """
if regpath:
key = regpath
subkey = ''
while path.split(key)[0]:
key, tmp = path.split(key)
subkey = '\\'.join([tmp, subkey])
if key == 'HKEY_CLASSES_ROOT':
key = _winreg.HKEY_CLASSES_ROOT
elif key == 'HKEY_CURRENT_CONFIG':
key = _winreg.HKEY_CURRENT_CONFIG
elif key == 'HKEY_CURRENT_USER':
key = _winreg.HKEY_CURRENT_USER
elif key == 'HKEY_DYN_DATA':
key = _winreg.HKEY_DYN_DATA
elif key == 'HKEY_LOCAL_MACHINE':
key = _winreg.HKEY_LOCAL_MACHINE
elif key == 'HKEY_PERFORMANCE_DATA':
key = _winreg.HKEY_PERFORMANCE_DATA
elif key == 'HKEY_USERS':
key = _winreg.HKEY_USERS
else:
raise TypeError('Invalid registry key (HKEY_)')
try:
if forwriting:
hkey = _winreg.CreateKey(key, subkey)
else:
hkey = _winreg.OpenKey(key, subkey)
except:
raise WindowsError('Cannot open registry path')
else:
return hkey
def items(self, section):
""" Return a list of (name, value) pairs for each option in the given
section. """
if self.has_section(section):
sectiondict = self._store[section]
ret = []
for option in sectiondict.keys():
value, type = sectiondict[option]
ret.append((option, value))
return ret
def has_option(self, section, option):
""" If the given section exists, and contains the given option. """
if self._store.has_key(section):
sectiondict = self._store[section]
return sectiondict.has_key(option)
def has_section(self, section):
""" Indicates whether the named section is present in the
configuration. """
return self._store.has_key(section)
def options(self, section):
""" Returns a list of options available in the specified section. """
if self._store.has_key(section):
sectiondict = self._store[section]
if sectiondict:
return sectiondict.keys()
def read(self, regpath=None):
""" Can be a single or a list of registry paths. When multiple registry
keys are read, options and values are overwritten in a FIFO
fashion ordered from the list. """
if regpath:
try:
if isinstance(regpath, list):
for rp in regpath:
self._read(self._get_default_regkey(rp))
else:
self._read(self._get_default_regkey(regpath))
except Exception, e:
if not self._autowrite: raise e
def _read(self, regkey=None):
""" Parses a registry path into sections, options and values. """
if regkey:
index = 0
while 1:
try:
section = _winreg.EnumKey(regkey, index)
except:
break
else:
try:
self.add_section(section)
except:
pass
index += 1
for section in self.sections():
index = 0
while 1:
try:
hkey = _winreg.OpenKey(regkey, section)
valuename, data, type = _winreg.EnumValue(hkey, index)
except:
break
else:
self.set(section, valuename, (data, type), readop=True)
index += 1
if hkey: _winreg.CloseKey(hkey)
if regkey: _winreg.CloseKey(regkey)
def remove_option(self, section, option):
if self.has_option(section, option):
del self._store[section][option]
def remove_section(self, section):
if self.has_section(section):
del self._store[section]
def sections(self):
""" Return a list of the sections available. """
return self._store.keys()
def set(self, section, option, value, check=True, readop=False):
""" If the given section exists, set the given option to the specified
value; if check=True ValueError is raised if it nonexistent
otherwise the section is written. """
if not self.has_section(section):
if check and not self._autowrite:
raise ValueError('Section does not exist')
self.add_section(section)
sectiondict = self._store[section]
if isinstance(value, tuple):
pass
else:
value = self._valueregform(value)
# Automatically write to rgistry if specified.
if self._autowrite and not readop:
self._write_reg(self._regpath, section, option, value)
sectiondict[option] = value
def _valueregform(self, value):
""" Converts values set by the user to a from to be stored in the
registry. """
if isinstance(value, str) or isinstance(value, unicode):
value = (value, _winreg.REG_SZ)
elif isinstance(value, int):
value = (value, _winreg.REG_DWORD)
elif isinstance(value, list):
for s in value:
if not isinstance(s, str) or isinstance(s, unicode):
raise TypeError(
"Values in list must be of type str or unicode.")
value = (value, _winreg.REG_MULTI_SZ)
else:
raise TypeError('Invalid value')
return value
def write(self, regpath=None):
""" Writes configuration to the registry path. """
if not regpath:
regpath = self._regpath
if regpath:
for section in self.sections():
sectiondict = self._store[section]
for option in sectiondict.keys():
apply(self._write_reg, (regpath, section, option,
sectiondict[option]))
def _write_reg(self, regpath, section, option, value):
""" Writes to the registry path. """
hkey = _winreg.CreateKey(self._get_default_regkey(regpath, True),
section)
_winreg.SetValueEx(hkey, option, 0, value[1], value[0])
if hkey: _winreg.CloseKey(hkey)
if __name__ == '__main__':
rc = RegConfig(r"HKEY_LOCAL_MACHINE\SOFTWARE\mysoftware", autowrite=True)
rc.set('configuration', 'configparser', 0)
rc.set('configuration', 'regconfig', 'it works')
rc.set('settings', 'users', ['jack', 'john', 'who else?'])
# Can u store a pickle? yes...however...
""" Quote - Value lengths are limited by available memory. Long values
(more than 2048 bytes) should be stored as files with the filenames
stored in the configuration registry. This helps the registry perform
efficiently."""
import pickle
x = {'hi': 'im going to be pickled...' }
pick = pickle.dumps(x, pickle.HIGHEST_PROTOCOL)
rc.set('pickle', 'pickleobject', (pick, _winreg.REG_BINARY))
rc.write()
#get sections and items
for section in rc.sections():
print section
for item in rc.items(section):
print '\t', item
# Call this to write to registry path use it to configure different users..
rc.write(r"HKEY_LOCAL_MACHINE\SOFTWARE\mysoftwareagain")
# let's try reading the data only
rc = RegConfig(r"HKEY_LOCAL_MACHINE\SOFTWARE\mysoftware")
# let unpickle the pickle
pick = rc.get('pickle', 'pickleobject')
print pickle.loads(pick)
|
Ever wanted to use the registry for you application configurations. Use this class, it's very easy to use and is modelled after RawConfigParser.
Tags: sysadmin
apply()
is deprecated.apply(self._write_reg, (regpath, section, option, sectiondict[option]))
should be changed toself._write_reg(regpath, section, option, sectiondict[option])