mirror of
https://github.com/yweber/lodel2.git
synced 2026-03-21 02:22:02 +01:00
Plug together Ui <-> client <-> session <-> plugin + bugfixes
Created a new class LodelSession to handle session datas Created an automatic wrapper to acces to session handler plugin function throug SessionHandlerPlugin class methods Bugfixes done for plugins. The plugin type is store in __plugin_type___ and not in __type__
This commit is contained in:
parent
eae2f83891
commit
1453cf49f9
10 changed files with 71 additions and 50 deletions
|
|
@ -29,14 +29,14 @@ class LodelSession(object):
|
||||||
#@warning Cause maybe a performance issue !
|
#@warning Cause maybe a performance issue !
|
||||||
def __token_checker(self):
|
def __token_checker(self):
|
||||||
refcount = sys.getrefcount(self.__token)
|
refcount = sys.getrefcount(self.__token)
|
||||||
if refcount > 1:
|
if self.__token is not None and refcount > 1:
|
||||||
warnings.warn("More than one reference to the session token \
|
warnings.warn("More than one reference to the session token \
|
||||||
exists !")
|
exists ! (exactly %d)" % refcount)
|
||||||
|
|
||||||
##@brief Property. Equals True if a session is started else False
|
##@brief Property. Equals True if a session is started else False
|
||||||
@property
|
@property
|
||||||
def started(self):
|
def started(self):
|
||||||
res = self.__token is None
|
res = self.__token is not None
|
||||||
if res:
|
if res:
|
||||||
self.__token_checker()
|
self.__token_checker()
|
||||||
return res
|
return res
|
||||||
|
|
@ -74,7 +74,8 @@ a session is allready started !!!")
|
||||||
def destroy(self):
|
def destroy(self):
|
||||||
if not self.started:
|
if not self.started:
|
||||||
logger.debug("Destroying a session that is not started")
|
logger.debug("Destroying a session that is not started")
|
||||||
SessionHandler.destroy(self.__token)
|
else:
|
||||||
|
SessionHandler.destroy(self.__token)
|
||||||
self.__token = None
|
self.__token = None
|
||||||
self.__datas = dict()
|
self.__datas = dict()
|
||||||
|
|
||||||
|
|
@ -173,10 +174,8 @@ class Client(object, metaclass = ClientMetaclass):
|
||||||
|
|
||||||
|
|
||||||
##@brief Constructor
|
##@brief Constructor
|
||||||
#@param ui_instance Lodel2Ui child class instance
|
|
||||||
#@param client_infos mixed : Depends on UI implemetation
|
|
||||||
#@param session_token mixed : Session token provided by client to interface
|
#@param session_token mixed : Session token provided by client to interface
|
||||||
def __init__(self,ui_instance, client_infos, session_token = None):
|
def __init__(self,session_token = None):
|
||||||
if self.__class__ == Client:
|
if self.__class__ == Client:
|
||||||
raise NotImplementedError("Abstract class")
|
raise NotImplementedError("Abstract class")
|
||||||
logger.debug("New instance of Client child class %s" %
|
logger.debug("New instance of Client child class %s" %
|
||||||
|
|
@ -189,14 +188,12 @@ class Client(object, metaclass = ClientMetaclass):
|
||||||
else:
|
else:
|
||||||
#first instanciation, fetching settings
|
#first instanciation, fetching settings
|
||||||
self.fetch_settings()
|
self.fetch_settings()
|
||||||
##@brief Stores instance of UI
|
|
||||||
self.__ui_instance = ui_instance
|
|
||||||
##@brief Stores infos for authenticated users (None == anonymous)
|
##@brief Stores infos for authenticated users (None == anonymous)
|
||||||
self.__user = None
|
self.__user = None
|
||||||
##@brief Stores the session handler
|
##@brief Stores the session handler
|
||||||
Client._instance = self
|
Client._instance = self
|
||||||
##@brief Stores LodelSession instance
|
##@brief Stores LodelSession instance
|
||||||
self.__session = LodelSession(token)
|
self.__session = LodelSession(session_token)
|
||||||
logger.debug("New client : %s" % self)
|
logger.debug("New client : %s" % self)
|
||||||
|
|
||||||
##@brief Attempt to restore a session given a session token
|
##@brief Attempt to restore a session given a session token
|
||||||
|
|
@ -249,6 +246,11 @@ class Client(object, metaclass = ClientMetaclass):
|
||||||
if self.is_anon():
|
if self.is_anon():
|
||||||
self.fail() #Security logging
|
self.fail() #Security logging
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def destroy(cls):
|
||||||
|
cls._assert_instance()
|
||||||
|
cls._instance.__session.destroy()
|
||||||
|
|
||||||
##@brief Test wether a client is anonymous or logged in
|
##@brief Test wether a client is anonymous or logged in
|
||||||
#@return True if client is anonymous
|
#@return True if client is anonymous
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ class DatasourcePlugin(Plugin):
|
||||||
'key': 'datasource_connectors',
|
'key': 'datasource_connectors',
|
||||||
'default': None,
|
'default': None,
|
||||||
'validator': SettingValidator('strip', none_is_valid = False) }
|
'validator': SettingValidator('strip', none_is_valid = False) }
|
||||||
|
_type_conf_name = 'datasource'
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
super().__init__(name)
|
super().__init__(name)
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,5 @@ class Extension(Plugin):
|
||||||
'default': [],
|
'default': [],
|
||||||
'validator': SettingValidator('list', none_is_valid = False)}
|
'validator': SettingValidator('list', none_is_valid = False)}
|
||||||
|
|
||||||
|
_type_conf_name = 'extension'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ class InterfacePlugin(Plugin):
|
||||||
'key': 'interface',
|
'key': 'interface',
|
||||||
'default': None,
|
'default': None,
|
||||||
'validator': SettingValidator('strip', none_is_valid = True)}
|
'validator': SettingValidator('strip', none_is_valid = True)}
|
||||||
|
|
||||||
|
_type_conf_name = 'ui'
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
if InterfacePlugin._instance is not None:
|
if InterfacePlugin._instance is not None:
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,7 @@ DEFAULT_PLUGINS_PATH_LIST = ['./plugins']
|
||||||
MANDATORY_VARNAMES = [PLUGIN_NAME_VARNAME, LOADER_FILENAME_VARNAME,
|
MANDATORY_VARNAMES = [PLUGIN_NAME_VARNAME, LOADER_FILENAME_VARNAME,
|
||||||
PLUGIN_VERSION_VARNAME]
|
PLUGIN_VERSION_VARNAME]
|
||||||
|
|
||||||
DEFAULT_PLUGIN_TYPE = 'extension'
|
DEFAULT_PLUGIN_TYPE = 'extension' #Value found in lodel/plugin/extensions.py::Extensions._type_conf_name
|
||||||
PLUGINS_TYPES = [DEFAULT_PLUGIN_TYPE, 'datasource', 'session_handler', 'ui']
|
|
||||||
|
|
||||||
|
|
||||||
##@brief Describe and handle version numbers
|
##@brief Describe and handle version numbers
|
||||||
class PluginVersion(object):
|
class PluginVersion(object):
|
||||||
|
|
@ -149,37 +147,38 @@ to generic PluginVersion comparison function : '%s'" % cmp_fun_name)
|
||||||
return {'major': self.major, 'minor': self.minor,
|
return {'major': self.major, 'minor': self.minor,
|
||||||
'revision': self.revision}
|
'revision': self.revision}
|
||||||
|
|
||||||
##@brief Stores plugin class registered
|
|
||||||
__all_ptypes = list()
|
|
||||||
|
|
||||||
##@brief Plugin metaclass that allows to "catch" child class
|
##@brief Plugin metaclass that allows to "catch" child class
|
||||||
#declaration
|
#declaration
|
||||||
#
|
#
|
||||||
#Automatic script registration on child class declaration
|
#Automatic script registration on child class declaration
|
||||||
class MetaPlugType(type):
|
class MetaPlugType(type):
|
||||||
|
|
||||||
|
##@brief Dict storing all plugin types
|
||||||
|
#
|
||||||
|
#key is the _type_conf_name and value is the class
|
||||||
|
_all_ptypes = dict()
|
||||||
|
|
||||||
def __init__(self, name, bases, attrs):
|
def __init__(self, name, bases, attrs):
|
||||||
#Here we can store all child classes of Plugin
|
#Here we can store all child classes of Plugin
|
||||||
super().__init__(name, bases, attrs)
|
super().__init__(name, bases, attrs)
|
||||||
if len(bases) == 1 and bases[0] == object:
|
if len(bases) == 1 and bases[0] == object:
|
||||||
return
|
return
|
||||||
self.__register_types()
|
#Regitering a new plugin type
|
||||||
#list_name= [cls.__name__ for cls in __all_ptypes]
|
MetaPlugType._all_ptypes[self._type_conf_name] = self
|
||||||
#if self.name in list_name:
|
|
||||||
# return
|
|
||||||
#else:
|
|
||||||
# plug_type_register(self)
|
|
||||||
|
|
||||||
def __register_types(self):
|
@classmethod
|
||||||
plug_type_register(self)
|
def all_types(cls):
|
||||||
|
return copy.copy(cls._all_ptypes)
|
||||||
|
|
||||||
def plug_type_register(cls):
|
@classmethod
|
||||||
__all_ptypes.append(cls)
|
def all_ptype_names(cls):
|
||||||
logger.info("New child class registered : %s" % cls.__name__)
|
return list(cls._all_ptypes.keys())
|
||||||
|
|
||||||
def all_types():
|
|
||||||
return copy.copy(__all_ptypes)
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def type_from_name(cls, ptype_name):
|
||||||
|
if ptype_name not in cls._all_ptypes:
|
||||||
|
raise PluginError("Unknown plugin type '%s'" % ptype_name)
|
||||||
|
return cls._all_ptypes[ptype_name]
|
||||||
|
|
||||||
##@brief Handle plugins
|
##@brief Handle plugins
|
||||||
#
|
#
|
||||||
|
|
@ -212,6 +211,11 @@ class Plugin(object, metaclass=MetaPlugType):
|
||||||
#where plugin list is stored
|
#where plugin list is stored
|
||||||
_plist_confspecs = None
|
_plist_confspecs = None
|
||||||
|
|
||||||
|
##@brief The name of the plugin type in the confguration
|
||||||
|
#
|
||||||
|
#None in abstract classes and implemented by child classes
|
||||||
|
_type_conf_name = None
|
||||||
|
|
||||||
##@brief Plugin class constructor
|
##@brief Plugin class constructor
|
||||||
#
|
#
|
||||||
# Called by setting in early stage of lodel2 boot sequence using classmethod
|
# Called by setting in early stage of lodel2 boot sequence using classmethod
|
||||||
|
|
@ -290,7 +294,8 @@ class Plugin(object, metaclass=MetaPlugType):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
self.__type = DEFAULT_PLUGIN_TYPE
|
self.__type = DEFAULT_PLUGIN_TYPE
|
||||||
self.__type = str(self.__type).lower()
|
self.__type = str(self.__type).lower()
|
||||||
if self.__type not in PLUGINS_TYPES:
|
if self.__type not in MetaPlugType.all_ptype_names():
|
||||||
|
print("FUCK : ", MetaPlugType.all_ptype_names())
|
||||||
raise PluginError("Unknown plugin type '%s'" % self.__type)
|
raise PluginError("Unknown plugin type '%s'" % self.__type)
|
||||||
# Load plugin name from init file (just for checking)
|
# Load plugin name from init file (just for checking)
|
||||||
try:
|
try:
|
||||||
|
|
@ -427,6 +432,9 @@ name differ from the one found in plugin's init file"
|
||||||
logger.debug("Plugin '%s' loaded" % self.name)
|
logger.debug("Plugin '%s' loaded" % self.name)
|
||||||
self.loaded = True
|
self.loaded = True
|
||||||
|
|
||||||
|
##@brief Returns the loader module
|
||||||
|
#
|
||||||
|
#Accessor for the __loader__ python module
|
||||||
def loader_module(self):
|
def loader_module(self):
|
||||||
if not self.loaded:
|
if not self.loaded:
|
||||||
raise RuntimeError("Plugin %s not loaded yet."%self.name)
|
raise RuntimeError("Plugin %s not loaded yet."%self.name)
|
||||||
|
|
@ -535,10 +543,10 @@ file : '%s'. Running discover again..." % DISCOVER_CACHE_FILENAME)
|
||||||
raise PluginError("No plugin named %s found" % plugin_name)
|
raise PluginError("No plugin named %s found" % plugin_name)
|
||||||
pinfos = pdcache['plugins'][plugin_name]
|
pinfos = pdcache['plugins'][plugin_name]
|
||||||
ptype = pinfos['type']
|
ptype = pinfos['type']
|
||||||
if ptype == 'datasource':
|
if ptype not in MetaPlugType.all_ptype_names():
|
||||||
pcls = DatasourcePlugin
|
raise PluginError("Unknown plugin type '%s'" % ptype)
|
||||||
else:
|
pcls = MetaPlugType.type_from_name(ptype)
|
||||||
pcls = cls
|
print("\n\n\nINSTANCIATING : ", pcls, " from name : ", ptype)
|
||||||
plugin = pcls(plugin_name)
|
plugin = pcls(plugin_name)
|
||||||
cls._plugin_instances[plugin_name] = plugin
|
cls._plugin_instances[plugin_name] = plugin
|
||||||
logger.debug("Plugin %s available." % plugin)
|
logger.debug("Plugin %s available." % plugin)
|
||||||
|
|
@ -655,7 +663,7 @@ file : '%s'. Running discover again..." % DISCOVER_CACHE_FILENAME)
|
||||||
##@brief Return a list of child Class Plugin
|
##@brief Return a list of child Class Plugin
|
||||||
@classmethod
|
@classmethod
|
||||||
def plugin_types(cls):
|
def plugin_types(cls):
|
||||||
return all_types()
|
return MetaPlugType.all_types()
|
||||||
|
|
||||||
##@brief Attempt to open and load plugin discover cache
|
##@brief Attempt to open and load plugin discover cache
|
||||||
#@return discover cache
|
#@return discover cache
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,19 @@ class SessionPluginWrapper(MetaPlugType):
|
||||||
|
|
||||||
def __init__(self, name, bases, attrs):
|
def __init__(self, name, bases, attrs):
|
||||||
super().__init__(name, bases, attrs)
|
super().__init__(name, bases, attrs)
|
||||||
|
self._instance = None
|
||||||
|
|
||||||
##@brief Handles wrapper between class method and plugin loader functions
|
##@brief Handles wrapper between class method and plugin loader functions
|
||||||
def __get_attribute__(self, name):
|
def __getattribute__(self, name):
|
||||||
if name in SessionPluginWrapper._Actions:
|
instance = super().__getattribute__('_instance')
|
||||||
|
if name in SessionPluginWrapper._ACTIONS:
|
||||||
|
if instance is None:
|
||||||
|
raise PluginError("Trying to access to SessionHandler \
|
||||||
|
functions, but no session handler initialized")
|
||||||
return getattr(
|
return getattr(
|
||||||
self._instance.loader_module(),
|
instance.loader_module(),
|
||||||
SessionPluginWrapper._Actions[name])
|
SessionPluginWrapper._ACTIONS[name])
|
||||||
return super().__get_attribute__(name)
|
return super().__getattribute__(name)
|
||||||
|
|
||||||
|
|
||||||
##@page lodel2_plugins Lodel2 plugins system
|
##@page lodel2_plugins Lodel2 plugins system
|
||||||
|
|
@ -45,10 +50,12 @@ class SessionHandlerPlugin(Plugin, metaclass=SessionPluginWrapper):
|
||||||
'key': 'session_handler',
|
'key': 'session_handler',
|
||||||
'default': None,
|
'default': None,
|
||||||
'validator': SettingValidator('string', none_is_valid=False)}
|
'validator': SettingValidator('string', none_is_valid=False)}
|
||||||
|
|
||||||
|
_type_conf_name = 'session_handler'
|
||||||
|
|
||||||
def __init__(self, plugin_name):
|
def __init__(self, plugin_name):
|
||||||
if self._instance is None:
|
if self._instance is None:
|
||||||
super(Plugin, self).__init__(plugin_name)
|
super().__init__(plugin_name)
|
||||||
self._instance = self
|
self.__class__._instance = self
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("A SessionHandler Plugin is already plug")
|
raise RuntimeError("A SessionHandler Plugin is already plug")
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ class Settings(object, metaclass=MetaSettings):
|
||||||
lodel2_specs = LODEL2_CONF_SPECS
|
lodel2_specs = LODEL2_CONF_SPECS
|
||||||
loader = SettingsLoader(self.__conf_dir)
|
loader = SettingsLoader(self.__conf_dir)
|
||||||
plugin_list = []
|
plugin_list = []
|
||||||
for ptype in Plugin.plugin_types():
|
for ptype_name,ptype in Plugin.plugin_types().items():
|
||||||
pls = ptype.plist_confspecs()
|
pls = ptype.plist_confspecs()
|
||||||
lodel2_specs = confspec_append(lodel2_specs, **pls)
|
lodel2_specs = confspec_append(lodel2_specs, **pls)
|
||||||
cur_list = loader.getoption(
|
cur_list = loader.getoption(
|
||||||
|
|
@ -161,7 +161,6 @@ class Settings(object, metaclass=MetaSettings):
|
||||||
|
|
||||||
# Starting the Plugins class
|
# Starting the Plugins class
|
||||||
logger.debug("Starting lodel.plugin.Plugin class")
|
logger.debug("Starting lodel.plugin.Plugin class")
|
||||||
print("DEBUG : plugin list : ", plugin_list)
|
|
||||||
Plugin.start(plugin_list)
|
Plugin.start(plugin_list)
|
||||||
# Fetching conf specs from plugins
|
# Fetching conf specs from plugins
|
||||||
specs = [lodel2_specs]
|
specs = [lodel2_specs]
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ from lodel.settings.validator import SettingValidator
|
||||||
|
|
||||||
__plugin_name__ = 'ram_session'
|
__plugin_name__ = 'ram_session'
|
||||||
__version__ = [0,0,1]
|
__version__ = [0,0,1]
|
||||||
__type__ = 'session_handler'
|
__plugin_type__ = 'session_handler'
|
||||||
__loader__ = 'main.py'
|
__loader__ = 'main.py'
|
||||||
__author__ = "Lodel2 dev team"
|
__author__ = "Lodel2 dev team"
|
||||||
__fullname__ = "RAM Session Store Plugin"
|
__fullname__ = "RAM Session Store Plugin"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
__plugin_name__ = 'webui'
|
__plugin_name__ = 'webui'
|
||||||
__version__ = '0.0.1'
|
__version__ = '0.0.1'
|
||||||
__type__ = 'ui'
|
__plugin_type__ = 'ui'
|
||||||
__loader__ = 'main.py'
|
__loader__ = 'main.py'
|
||||||
__confspec__ = 'confspec.py'
|
__confspec__ = 'confspec.py'
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ from lodel.auth.client import Client
|
||||||
|
|
||||||
class WebUiClient(Client):
|
class WebUiClient(Client):
|
||||||
|
|
||||||
def __init__(self, ip, user_agent):
|
def __init__(self, ip, user_agent, session_token = None):
|
||||||
self.__ip = ip
|
self.__ip = ip
|
||||||
self.__user_agent = user_agent
|
self.__user_agent = user_agent
|
||||||
super().__init__()
|
super().__init__(session_token = session_token)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s (%s)" % (self.__ip, self.__user_agent)
|
return "%s (%s)" % (self.__ip, self.__user_agent)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue