Overview
This page will describe how to create a new setting for settingsctl to use.NOTE: Please read the entire document.
Settings must exist in the settingsctl lib directory.
A settings file must exist as a Python file in the appropriate subdirectory of the lib. For example, a setting
appearance.desktop.wallpaper will be defined in appearance/desktop/wallpaper.py,
which will be a subdirectory of the lib (mentioned above). You might want to look at a sample setting file, which illustrates this documentation in code. Of course, inclusion of your setting into the settingsctl lib would require you to file an issue.
What a setting must define
These are the things that a setting must define in its file:The settings string
The file must define a variable settings that should contain the dot-separated setting name. Example (for setting
example of hello.world):
setting = 'hello.world.example'
validate(data)
This function will receive the list of arguments received from the user (argument data). It should validate and perhaps format (for later use by
set(data)) the data. Any error found during validation should be handled as per Error Handling
For example, if the user gives these arguments:
$ settingsctl set hello.world.example -- abc=xyz -k --po ~ '~' 20
the function will get:
['abc=xyz', '-k', '--po', '/home/username', '~', '20']
It can also just return the data passed to it if no such validation or formatting is needed.get()
This will implement the getting of the setting being handled. Return the value obtained. It will be printed by the
settingsctl utility. info()
This will return the type of data and description of the setting. It should return a dictionary:
return {
'type': ['data', 'types', 'go', 'here'],
'description': 'Short description of the setting',
'data': ['Short', 'descriptions', 'of', 'data'],
}
Where the data types in the 'type' list are one of:
- string -- Python
str - boolean -- Python
bool - decimal -- Python
float - list -- Python
list - integer -- Python
int
set(data)
This will implement the setting being handled. It will get the user's arguments after being run through
validate(data) as the data argument.
Error and Message Handling
Nothing must be printed!
Any errors and messages must be handled through themessage() function, which is made available by settingsctl:
message('error message', level='error')
where error message should be replaced with the error. You can also use
level='info' or level='warning'. In case of errors, exit with code
1:
sys.exit(1)
Process Handling and Command Execution
Use the Process function/object, which provides an easy way to handle
processes and commands.
It allows you to not implement encoding/decoding, whitespace handling and other such things.
Usage:
proc = Process(['ls', '-l'])
proc.stdout # will return ls -l output
proc.return_code # will give return code (in this case, 0)
proc = Process('echo "Hello"', shell=True) # use shell=True to execute in /bin/sh
proc.stdout # will return "Hello"
proc.stderr # will be empty, as there is no message on stderr
Arguments:
cmd- The command to execute. Should be a string if
shellisTrueelse a list. shell- Whether to execute in
/bin/sh. Default:False. strip- Whether to strip extra newlines and whitespace from end of output. Default:
True
What a setting may define
There are also various options that may be defined in a setting.The read_only option
The read_only variable, if defined, causes the setting to become read-only. Read-only settings are not required to define
validate(data)
or set(data) functions. settingsctl will produce an error on an attempt to set a read-only setting (you do not have to handle it).
Example:
read_only = True
Read-only settings are useful for things which cannot be changed, like the display.monitors listing. Sample Setting File
Defines a sample setting "sample.setting", which takes an integer and a string (path to a file, for instance).File
sample/setting.py:
# < license header here⦠>
import os
import sys
setting = 'sample.setting'
def validate(data):
# data will be data as given by user
# here you should handle validation of the data
# and also any "formatting" (changing of types, etc) for use by set()
try:
int(data[0])
except ValueError:
# not a valid integer
message('first argument must be an integer', level='error')
sys.exit(1)
if not os.path.isfile(data[1]):
message('file "%s" does not exist' % data[1], level='error')
sys.exit(1)
# return the data, converting first argument to an integer
return [int(data[0]), data[1]]
def info():
# here you should return a dictionary in the format shown below
return {
'type': ['integer', 'string'],
'description': 'A sample setting',
'data': ['any number', 'path to a file'] # descriptions of data received, in order
}
def get():
# here you should handle getting the value of the setting
# as this is just a sample setting, we do nothing much here
return 'Sample'
def set(data):
# here you should handle setting the data
# data will be the data as given by validate(data)
# as this is just a sample setting, we do nothing here
pass
