Commit 4afe9b4c authored by Devaev Maxim's avatar Devaev Maxim

Validators library, application module and control for service startup

parent 60ae6262
[service] [service]
bus_type = session bus_type = session
[hello]
enabled = yes
import sys import sys
sys.path.append("..") # path hook sys.path.append("..") # path hook
import settingsd.service import settingsd.service
import settingsd.validators
class Hello(settingsd.service.NativeObject) : class Hello(settingsd.service.FunctionObject) :
@settingsd.service.nativeMethod("test") @settingsd.service.functionMethod("test")
def hello(self) : def hello(self) :
return "Hello, World!" return "Hello, World!"
@settingsd.service.nativeMethod("test") @settingsd.service.functionMethod("test")
def echo(self, text) : def echo(self, text) :
return text return text
...@@ -16,10 +17,21 @@ class Hello(settingsd.service.NativeObject) : ...@@ -16,10 +17,21 @@ class Hello(settingsd.service.NativeObject) :
def dump(self) : def dump(self) :
return str(self) return str(self)
class Requisites(settingsd.service.Requisites) :
@classmethod
def serviceName(self) :
return "hello"
@classmethod
def options(self) :
return [
("hello", "hello_string", "Hello, World!", settingsd.validators.string)
]
class Service(settingsd.service.Service) : class Service(settingsd.service.Service) :
def initService(self) : def init(self) :
self.addSharedObject(Hello("hello")) self.Functions.addSharedObject("Hello", Hello("hello"))
def closeService(self) : def close(self) :
pass pass
import sys import sys
import os import os
import dbus
import dbus.service
import dbus.glib
import gobject
from settingsd import const from settingsd import application
from settingsd import config
if __name__ == "__main__" : if __name__ == "__main__" :
config.loadConfigFiles() app = application.Application()
app.init()
if config.value("service", "bus_type") == const.CONFIG_SERVICE_BUS_TYPE_SYSTEM :
bus = dbus.SystemBus()
else :
bus = dbus.SessionBus()
bus_name = dbus.service.BusName(config.value("service", "name"), bus = bus)
config.setValue("runtime", "bus_name", bus_name)
sys.path.append(const.PLUGINS_DIR)
services_list = []
for module_name in [ item[:-3] for item in os.listdir(const.PLUGINS_DIR) if item.endswith(".py") ] :
services_list.append(__import__(module_name, globals(), locals(), [""]).Service())
services_list[-1].initService()
main_loop = gobject.MainLoop()
print >> sys.stderr, "Initialized" print >> sys.stderr, "Initialized"
try : try :
main_loop.run() app.run()
except KeyboardInterrupt : except KeyboardInterrupt :
for services_list_item in services_list : app.close()
services_list_item.closeService()
main_loop.quit()
print >> sys.stderr, "\nClosed" print >> sys.stderr, "\nClosed"
# -*- coding: utf-8 -*-
import sys
import os
import dbus
import dbus.service
import dbus.glib
import gobject
import const
import config
import validators
#####
class Application(object) :
def __init__(self) :
object.__init__(self)
self._bus_name = None
self._modules_list = []
self._services_dict = {}
self._main_loop = gobject.MainLoop()
def init(self) :
self.loadModules()
self.loadConfigs()
self.initBus()
self.initServices()
def run(self) :
self._main_loop.run()
def close(self) :
self.closeServices()
self._main_loop.quit()
def loadModules(self) :
sys.path.append(const.FUNCTIONS_DIR)
sys.path.append(const.ACTIONS_DIR)
for modules_path_list_item in (const.FUNCTIONS_DIR, const.ACTIONS_DIR) :
for module_name in [ item[:-3] for item in os.listdir(modules_path_list_item) if item.endswith(".py") ] :
self._modules_list.append(__import__(module_name, globals(), locals(), [""]))
if self._modules_list[-1].Requisites.serviceName() != None :
self._services_dict[self._modules_list[-1].Requisites.serviceName()] = {
"requisites" : self._modules_list[-1].Requisites,
"service" : self._modules_list[-1].Service,
"instance" : None
}
else :
print >> sys.stderr, "Anonymous modules does not acceped"
sys.path.remove(const.FUNCTIONS_DIR)
sys.path.remove(const.ACTIONS_DIR)
def loadConfigs(self) :
for service_name in self._services_dict.keys() :
service_options_list = list(self._services_dict[service_name]["requisites"].options())
service_options_list.append((service_name, "enabled", "no", validators.validBool))
for service_options_list_item in service_options_list :
config.setValue(*service_options_list_item)
config.loadConfig()
def initBus(self) :
if config.value("service", "bus_type") == const.CONFIG_SERVICE_BUS_TYPE_SYSTEM :
bus = dbus.SystemBus()
else :
bus = dbus.SessionBus()
self._bus_name = dbus.service.BusName(config.value("service", "name"), bus = bus)
config.setValue("runtime", "bus_name", self._bus_name)
def initServices(self) :
for service_name in self._services_dict.keys() :
if config.value(service_name, "enabled") :
self._services_dict[service_name]["instance"] = self._services_dict[service_name]["service"]()
self._services_dict[service_name]["instance"].init()
def closeServices(self) :
for service_name in self._services_dict.keys() :
if self._services_dict[service_name]["instance"] != None :
self._services_dict[service_name]["instance"].close()
del self._services_dict[service_name]["instance"]
self._services_dict[service_name]["instance"] = None
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os import os
import ConfigParser import ConfigParser
import const import const
import config import config
import validators
##### #####
ConfigDictObject = { ConfigDictObject = {
"service" : { "service" : {
"name" : (const.DEFAULT_CONFIG_SERVICE_NAME, str, None), "name" : (const.DEFAULT_CONFIG_SERVICE_NAME, validators.string),
"path" : (const.DEFAULT_CONFIG_SERVICE_PATH, str, None), "path" : (const.DEFAULT_CONFIG_SERVICE_PATH, validators.string),
"bus_type" : (const.DEFAULT_CONFIG_SERVICE_BUS_TYPE, str, const.CONFIG_VALID_SERVICE_BUS_TYPES_LIST) "bus_type" : ( const.DEFAULT_CONFIG_SERVICE_BUS_TYPE,
( lambda arg : validators.validRange(arg, const.CONFIG_VALID_SERVICE_BUS_TYPES_LIST) ) )
} }
} }
#####
class ValidatorError(Exception) :
pass
class ValueError(Exception) :
pass
##### Public ##### ##### Public #####
def setValue(section, option, value, validator = None, valid_values_list = None) : def setValue(section, option, value, validator = None) :
global ConfigDictObject global ConfigDictObject
if not ConfigDictObject.has_key(section) : if not ConfigDictObject.has_key(section) :
...@@ -34,18 +29,14 @@ def setValue(section, option, value, validator = None, valid_values_list = None) ...@@ -34,18 +29,14 @@ def setValue(section, option, value, validator = None, valid_values_list = None)
if ConfigDictObject[section].has_key(option) : if ConfigDictObject[section].has_key(option) :
validator = ConfigDictObject[section][option][1] validator = ConfigDictObject[section][option][1]
valid_values_list = ConfigDictObject[section][option][2]
if valid_values_list != None and not value in valid_values_list :
raise ValueError("Option \"%s::%s = %s\" not in list %s" % (section, option, value, valid_values_list))
if validator != None : if validator != None :
try : try :
value = validator(value) value = validator(value)
except Exception, err1 : except Exception, err1 :
raise ValidatorError("Incorrect option \"%s::%s = %s\" by validator \"%s\": %s" % ( raise validators.ValidatorError("Incorrect config option \"%s :: %s = %s\"" % (section, option, value, str(err1)))
section, option, value, validator.__name__, str(err1) ))
ConfigDictObject[section][option] = (value, validator, valid_values_list) ConfigDictObject[section][option] = (value, validator)
def value(section, option) : def value(section, option) :
return ConfigDictObject[section][option][0] return ConfigDictObject[section][option][0]
...@@ -53,10 +44,7 @@ def value(section, option) : ...@@ -53,10 +44,7 @@ def value(section, option) :
def validator(section, option) : def validator(section, option) :
return ConfigDictObject[section][option][1] return ConfigDictObject[section][option][1]
def validValues(section, option) : def loadConfig() :
return ConfigDictObject[section][option][2]
def loadConfigFiles() :
for config_files_list_item in os.listdir(const.CONFIGS_DIR) : for config_files_list_item in os.listdir(const.CONFIGS_DIR) :
if not config_files_list_item.endswith(const.CONFIG_FILE_POSTFIX) : if not config_files_list_item.endswith(const.CONFIG_FILE_POSTFIX) :
continue continue
...@@ -68,5 +56,3 @@ def loadConfigFiles() : ...@@ -68,5 +56,3 @@ def loadConfigFiles() :
for option in config_parser.options(section): for option in config_parser.options(section):
setValue(section, option, config_parser.get(section, option)) setValue(section, option, config_parser.get(section, option))
print ConfigDictObject
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
MY_NAME = "settingsd" MY_NAME = "settingsd"
PLUGINS_DIR = "plugins" FUNCTIONS_DIR = "functions"
ACTIONS_DIR = "actions"
CONFIGS_DIR = "configs" CONFIGS_DIR = "configs"
CONFIG_FILE_POSTFIX = ".conf" CONFIG_FILE_POSTFIX = ".conf"
......
# -*- coding: utf-8 -*-
import dbus import dbus
import dbus.service import dbus.service
import dbus.glib import dbus.glib
import abc import abc
import config import config
import tools import shared
import dbus_tools
#####
class Requisites(object) :
@classmethod
def serviceName(self) :
return None
@classmethod
def options(self) :
return []
#####
class Service(object) : class Service(object) :
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
def __init__(self) : Functions = shared.Functions
self.__shared_objects_list = [] Actions = shared.Actions
@abc.abstractmethod @abc.abstractmethod
def initService(self) : def init(self) :
pass pass
@abc.abstractmethod @abc.abstractmethod
def closeService(self) : def close(self) :
pass pass
def addSharedObject(self, shared_object) :
self.__shared_objects_list = []
def sharedObjects(self) :
return self.__shared_objects_list
#####
class CustomObject(dbus.service.Object) : class CustomObject(dbus.service.Object) :
def __init__(self, object_path) : def __init__(self, object_path) :
dbus.service.Object.__init__(self, config.value("runtime", "bus_name"), object_path) dbus.service.Object.__init__(self, config.value("runtime", "bus_name"), object_path)
self.__object_path = object_path self._object_path = object_path
def objectPath(self) : def objectPath(self) :
self.__object_path self._object_path
class NativeObject(CustomObject) : class FunctionObject(CustomObject) :
def __init__(self, object_path) : def __init__(self, object_path) :
CustomObject.__init__(self, tools.joinPath(config.value("service", "path"), object_path)) CustomObject.__init__(self, dbus_tools.joinPath(config.value("service", "path"), "functions", object_path))
class ActionObject(CustomObject) :
def __init__(self, object_path) :
CustomObject.__init__(self, dbus_tools.joinPath(config.value("service", "path"), "actions", object_path))
######
def customMethod(interface_name) : def customMethod(interface_name) :
def decorator(function) : def decorator(function) :
return dbus.service.method(interface_name)(function) return dbus.service.method(interface_name)(function)
return decorator return decorator
def nativeMethod(interface_name) : def functionMethod(interface_name) :
def decorator(function) :
return customMethod(dbus_tools.joinMethod(config.value("service", "name"), "functions", interface_name))(function)
return decorator
def actionsMethod(interface_name) :
def decorator(function) : def decorator(function) :
return customMethod(tools.joinMethod(config.value("service", "name"), interface_name))(function) return customMethod(dbus_tools.joinMethod(config.value("service", "name"), "actions", interface_name))(function)
return decorator return decorator
# -*- coding: utf-8 -*-
#####
class SharedConflict(Exception) :
pass
#####
class SharedMeta(type) :
def __init__(cls, name, bases_list, attrs_dict) :
cls._shared_objects_dict = {}
def addSharedObject(cls, shared_object_name, shared_object) :
if cls._shared_objects_dict.has_key(shared_object_name) :
raise SharedConflict("Shared \"%s\" is already exists in collection \"%s\"" % (shared_object_name, cls.__name__))
cls._shared_objects_dict[shared_object_name] = shared_object
setattr(cls, shared_object_name, shared_object)
def removeSharedObject(cls, shared_object_name) :
if cls._shared_objects_dict.has_key(shared_object_name) :
cls._shared_objects_dict.pop(shared_object_name)
def hasSharedObject(cls, shared_object) :
return ( shared_object in cls._shared_objects_dict.keys() or shared_object in cls._shared_objects_dict.values() )
def sharedObject(cls, shared_object_name) :
return cls._shared_objects_dict[shared_object_name]
def sharedObjectsList(cls) :
return cls._shared_objects_dict
class Functions(object) :
__metaclass__ = SharedMeta
class Actions(object) :
__metaclass__ = SharedMeta
# -*- coding: utf-8 -*-
#####
class ValidatorError(Exception) :
pass
##### Public #####
def string(arg) :
return str(arg)
def validBool(arg) :
arg = str(arg).lower()
true_args_list = ("1", "true", "yes")
false_args_list = ("0", "false", "no")
if not arg in true_args_list + false_args_list :
raise ValidatorError("Argument \"%s\" not in list %s or %s" % (arg, true_args_list, false_args_list))
return ( arg in true_args_list )
def validRange(arg, valid_args_list) :
if not arg in valid_args_list :
raise ValidatorError("Argument \"%s\" not in list %s" % (arg, valid_args_list))
return ( arg in valid_args_list )
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment