0
0
mirror of https://github.com/Doodle3D/doodle3d-firmware.git synced 2024-11-04 21:53:24 +01:00
doodle3d-firmware/src/util/settings.lua

116 lines
3.3 KiB
Lua
Raw Normal View History

2013-07-17 17:43:33 +02:00
--[[
This settings interface reads and writes its configuration using UCI.
The corresponding config file is /etc/config/wifibox. To have an initial
set of reasonable settings (and allow users to easily return to them),
any key not found in the UCI configuration is looked up in the (immutable)
'base configuration' (base_config.lua). This file also contains constraints
to check if newly set values are valid.
]]--
local u = require('util.utils')
local baseconfig = require('conf_defaults')
local uci = require('uci').cursor()
local M = {}
local UCI_CONFIG_NAME = 'wifibox' -- the file under /etc/config
local UCI_CONFIG_FILE = '/etc/config/' .. UCI_CONFIG_NAME
local UCI_CONFIG_TYPE = 'settings' -- the section type that will be used in UCI_CONFIG_FILE
local UCI_CONFIG_SECTION = 'general' -- the section name that will be used in UCI_CONFIG_FILE
local ERR_NO_SUCH_KEY = "key does not exist"
local function toUciValue(v, type)
if type == 'bool' then return v and '1' or '0' end
return tostring(v)
end
local function fromUciValue(v, type)
if type == 'bool' then
return (v == '1') and true or false
elseif type == 'float' or type == 'int' then
return tonumber(v)
else
return v
end
end
local function isValid(value, baseTable)
local type, min, max, regex = baseTable.type, baseTable.min, baseTable.max, baseTable.regex
if type == 'bool' then
return isboolean(value) or nil,"invalid bool value"
elseif type == 'int' or type == 'float' then
local ok = isnumber(value)
ok = ok and (type == 'float' or math.floor(value) == value)
if min then ok = ok and value >= min end
if max then ok = ok and value <= max end
return ok or nil,"invalid int/float value"
elseif type == 'string' then
local ok = true
if min then ok = ok and value:len() >= min end
if max then ok = ok and value:len() <= max end
if regex then ok = ok and value:match(regex) ~= nil end
return ok or nil,"invalid string value"
end
return true
end
local function getBaseKeyTable(key)
local base = baseconfig[key]
return type(base) == 'table' and base.default ~= nil and base or nil
end
function M.get(key)
local base = getBaseKeyTable(key)
if not base then return nil,ERR_NO_SUCH_KEY end
local v = base.default
local uciV = fromUciValue(uci:get(UCI_CONFIG_NAME, UCI_CONFIG_SECTION, key))
return uciV or v
end
function M.exists(key)
return getBaseKeyTable(key) ~= nil
end
function M.isDefault(key)
if not M.exists(key) then return nil,ERR_NO_SUCH_KEY end
return uci:get(UCI_CONFIG_NAME, UCI_CONFIG_SECTION, key) == nil
end
-- pass nil as value to restore default
function M.set(key, value)
local r = u.create(UCI_CONFIG_FILE)
uci:set(UCI_CONFIG_NAME, UCI_CONFIG_SECTION, UCI_CONFIG_TYPE)
local base = getBaseKeyTable(key)
if not base then return nil,ERR_NO_SUCH_KEY end
if M.isDefault(key) and value == nil then return true end -- key is default already
local current = uci:get(UCI_CONFIG_NAME, UCI_CONFIG_SECTION, key)
if fromUciValue(current) == value then return true end
if value ~= nil then
local valid,m = isValid(value, base)
if (valid) then
uci:set(UCI_CONFIG_NAME, UCI_CONFIG_SECTION, key, toUciValue(value, base.type))
else
return nil,m
end
else
uci:delete(UCI_CONFIG_NAME, UCI_CONFIG_SECTION, key)
end
uci:commit(UCI_CONFIG_NAME)
return true
end
return M