/usr/lib/python2.7/dist-packages/framework/subsystems/opreferencesd/service.py is in fso-frameworkd 0.10.1-2ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | # All the dbus modules
import dbus
import dbus.service
from schema import Schema
from configuration import Configuration
from framework import helpers
import logging
logger = logging.getLogger('opreferencesd')
class NoServiceError(Exception):
pass
class NoValueError(Exception):
pass
class Service(dbus.service.Object):
""" Class that deals with configuration values of a given service
The service can set and get the value of parameters.
The services are used to group related parameters together.
Basically, every application using the config server should use its own service name.
For each service we need a schema file describing the parameters the service provides.
The configurations values are stored in yaml file.
Each conf file contains all the parameters for a given service in a given context.
The conf files are organised with the following file hierachy :
conf/$(service)/$(profile).yaml
All the parameters that are independant of the profile are stored in the 'default' profile file.
When we set or get parameters, the service server takes into account the current profile,
so the applications using the service don't need to know about the current profile.
"""
def __init__(self, manager, name):
self.manager = manager
self.name = name
try:
self.schema = Schema.from_file('%s/%s.yaml' % (self.manager.schema_dir, name))
except IOError:
raise NoServiceError
# Only at this point we can safely register the dbus object
super(Service, self).__init__(manager.bus, '%s/%s' % ('/org/freesmartphone/Preferences', name))
self.confs = {} # all the conf files
def __str__(self):
return self.name
def get_conf(self, profile):
"""Return the conf instance for a given profile"""
if profile in self.confs:
return self.confs[profile]
try:
conf_path = '%s/%s/%s.yaml' % (self.manager.conf_dir, self.name, profile)
conf = Configuration(conf_path)
except IOError:
logger.info("no conf file : '%s'", conf_path)
conf = None
self.confs[profile] = conf
return conf
@dbus.service.method('org.freesmartphone.Preferences.Service', in_signature='', out_signature='as')
def GetKeys(self):
"""Retrieve all the keys of the service
This method should be used only for introspection purpose.
"""
# Here we have to be careful, because if we just return the keys actually in the configuration file,
# we ommit to add the keys that are not set but have default value.
# On the other hand, if we only return the keys defined in the schema, we ommit the keys that are in a dictionary.
# So what we do is return the union of the actual keys and the keys defined in the schema
ret = set(self.schema.keys())
return list(ret)
@dbus.service.method('org.freesmartphone.Preferences.Service', in_signature='s', out_signature='v')
def GetValue(self, key):
"""get a parameter value
arguments:
key -- the name of the key
"""
key = str(key)
logger.debug("Service %s : Getting key %s", self, key)
parameter = self.schema[key]
for profile in self.manager.profiles:
try:
conf = self.get_conf(profile)
if not conf: # There is no conf file for this profile
continue
ret = conf[key]
break
except KeyError:
pass
else:
logger.info("Service %s : can't find key %s, using default", self, key)
ret = parameter.default
if ret is None:
raise NoValueError
# We have to call this method to give the proper type to the ret value
ret = parameter.to_dbus(ret)
return ret
@dbus.service.method('org.freesmartphone.Preferences.Service', in_signature='sv', out_signature='')
@helpers.exceptionlogger
def SetValue(self, key, value):
"""set a parameter value for a service, in the current profile"""
key = str(key)
logger.debug("Service %s : Setting key %s = %s", self, key, value)
parameter = self.schema[key]
# XXX:
# Here we always set the value into the top profile configuration file
# Shouldn't we use the profile that actually defines the value if there is one ?
profile = self.manager.profiles[0] if parameter.profilable else 'default'
value = parameter.from_dbus(value)
conf = self.get_conf(profile)
conf[key] = value
self.Notify(key, value) # We don't forget to notify the listeners
@dbus.service.method('org.freesmartphone.Preferences.Service', in_signature='s', out_signature='b')
def IsProfilable(self, key):
"""Return true if a parameter depends on the current profile"""
key = str(key)
parameter = self.schema[key]
return parameter.profilable
@dbus.service.method('org.freesmartphone.Preferences.Service', in_signature='s', out_signature='s')
def GetType(self, key):
"""Return a string representing the type of the parameter"""
key = str(key)
parameter = self.schema[key]
return Schema.types_to_str[parameter.type]
@dbus.service.signal('org.freesmartphone.Preferences.Service', signature='sv')
def Notify(self, key, value):
"""signal used to notify a parameter change"""
logger.debug("Notify change in value %s/%s", self.name, key)
def on_profile_changed(self, profile):
"""called everytime we the global profile is changed"""
for key in self.GetKeys():
if self.IsProfilable(key):
self.Notify(key, self.GetValue(key))
|