Repository URL to install this package:
|
Version:
0.7.13 ▾
|
# -*- coding: utf-8 -*-
## \package dbr.config
#
# Parsing & writing configuration.
# MIT licensing
# See: docs/LICENSE.txt
import os, wx
from dbr.functions import GetBoolean
from dbr.functions import GetIntTuple
from dbr.language import GT
from globals.fileio import ReadFile
from globals.fileio import WriteFile
from globals.paths import PATH_home
from globals.strings import TextIsEmpty
## Configuration codes
class ConfCode:
SUCCESS = 0
ERR_READ = wx.NewId()
ERR_WRITE = wx.NewId()
FILE_NOT_FOUND = wx.NewId()
WRONG_TYPE = wx.NewId()
KEY_NO_EXIST = wx.NewId()
KEY_NOT_DEFINED = wx.NewId()
string = {
SUCCESS: u'SUCCESS',
ERR_READ: u'ERR_READ',
ERR_WRITE: u'ERR_WRITE',
FILE_NOT_FOUND: u'FILE_NOT_FOUND',
WRONG_TYPE: u'WRONG_TYPE',
KEY_NO_EXIST: u'KEY_NO_EXIST',
KEY_NOT_DEFINED: u'KEY_NOT_DEFINED',
}
# Version of configuration to use
config_version = (1, 1)
# Default configuration
default_config_dir = u'{}/.config/debreate'.format(PATH_home)
default_config = u'{}/config'.format(default_config_dir)
# name = (function, default value)
default_config_values = {
u'center': (GetBoolean, True),
u'maximize': (GetBoolean, False),
u'position': (GetIntTuple, (0, 0)),
u'size': (GetIntTuple, (800, 640)),
u'workingdir': (unicode, PATH_home),
u'tooltips': (GetBoolean, True),
}
## Opens configuration & searches for key
#
# \param k_name
# \b \e unicode|str : Key to search for
# \return
# Value of key if found, otherwise ConfCode
def ReadConfig(k_name, conf=default_config):
#Logger.Debug(__name__, GT(u'Reading configuration file: {}'.format(conf)))
if not os.path.isfile(conf):
#Logger.Warning(__name__, u'Configuration file does not exist: {}'.format(conf))
return ConfCode.FILE_NOT_FOUND
# Use the string '__test__' for test when app is initialized
if k_name == u'__test__':
return ConfCode.SUCCESS
# Only read pre-defined keys
if k_name not in default_config_values:
#Logger.Warning(__name__, u'Undefined key, not attempting to retrieve value: {}'.format(k_name))
return ConfCode.KEY_NOT_DEFINED
conf_lines = ReadFile(conf)
if conf_lines:
conf_lines = conf_lines.split(u'\n')
for L in conf_lines:
if u'=' in L:
key = L.split(u'=')
value = key[1]
key = key[0]
if k_name == key:
value = default_config_values[key][0](value)
#Logger.Debug(__name__, u'Retrieved key-value: {}={}, value type: {}'.format(key, value, type(value)))
return value
if k_name in default_config_values:
#Logger.Debug(__name__, u'Configuration does not contain key, retrieving default value: {}'.format(k_name))
return GetDefaultConfigValue(k_name)
return ConfCode.KEY_NO_EXIST
## Writes a key=value combination to configuration
#
# \param k_name
# \b \e unicode|str : Key to write
# \param k_value
# \b \e unicode|str|tuple|int|bool : Value of key
# \return
# \b \e int : ConfCode
def WriteConfig(k_name, k_value, conf=default_config):
conf_dir = os.path.dirname(conf)
if not os.path.isdir(conf_dir):
if os.path.exists(conf_dir):
print(u'{}: {}: {}'.format(GT(u'Error'), GT(u'Cannot create config directory, file exists'), conf_dir))
return ConfCode.ERR_WRITE
os.makedirs(conf_dir)
# Only write pre-defined keys
if k_name not in default_config_values:
print(u'{}: {}: {}'.format(GT(u'Error'), GT(u'Configuration key not found'), k_name))
return ConfCode.KEY_NOT_DEFINED
# Make sure we are writing the correct type
k_value = default_config_values[k_name][0](k_value)
if k_value == None:
print(u'{}: {}: {}'.format(GT(u'Error'), GT(u'Wrong value type for configuration key'), k_name))
return ConfCode.WRONG_TYPE
# tuple is the only type we need to format
if isinstance(k_value, tuple):
k_value = u'{},{}'.format(unicode(k_value[0]), unicode(k_value[1]))
else:
k_value = unicode(k_value)
conf_text = wx.EmptyString
# Save current config to buffer
if os.path.exists(conf):
if not os.path.isfile(conf):
print(u'{}: {}: {}'.format(GT(u'Error'), GT(u'Cannot open config for writing, directory exists'), conf))
return ConfCode.ERR_WRITE
conf_text = ReadFile(conf)
# FIXME: ReadFile returns None type if config file exists but is empty
if conf_text == None:
conf_text = u''
else:
conf_text = u'[CONFIG-{}.{}]'.format(unicode(config_version[0]), unicode(config_version[1]))
conf_lines = conf_text.split(u'\n')
key_exists = False
for L in conf_lines:
l_index = conf_lines.index(L)
if u'=' in L:
key = L.split(u'=')[0]
if k_name == key:
key_exists = True
conf_lines[l_index] = u'{}={}'.format(k_name, k_value)
if not key_exists:
conf_lines.append(u'{}={}'.format(k_name, k_value))
conf_text = u'\n'.join(conf_lines)
if TextIsEmpty(conf_text):
print(u'{}: {}'.format(GT(u'Warning'), GT(u'Not writing empty text to configuration')))
return ConfCode.ERR_WRITE
# Actual writing to configuration
WriteFile(conf, conf_text)
if os.path.isfile(conf):
return ConfCode.SUCCESS
return ConfCode.ERR_WRITE
## Function used to create the inital configuration file
#
# \param conf
# \b \e unicode|str : File to be written
# \return
# \b \e ConfCode
def InitializeConfig(conf=default_config):
for V in default_config_values:
exit_code = WriteConfig(V, default_config_values[V][1], conf)
if exit_code != ConfCode.SUCCESS:
return exit_code
return ConfCode.SUCCESS
## Retrieves default configuration value for a key
#
# \param key
# \b \e unicode|str : Key to check
# \return
# Default value for the key or ConfCode.KEY_NO_EXIST
def GetDefaultConfigValue(key):
if key in default_config:
return default_config_values[key][1]
return ConfCode.KEY_NO_EXIST
## Checks if value type is correct
def _check_config_values(keys):
for KEY in keys:
try:
if not isinstance(keys[KEY], type(default_config_values[KEY][1])):
return False
except KeyError:
return False
return True
## Reads in all values found in configuration file
#
# \return
# Configuration keys found in config file or None if error occurred
def GetAllConfigKeys():
keys = {}
# Read key/values from configuration file
for KEY in default_config_values:
keys[KEY] = ReadConfig(KEY)
if not _check_config_values(keys):
return None
return keys