1
0
Fork 0
mirror of https://github.com/yweber/lodel2.git synced 2026-03-14 23:32: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:
Yann 2016-08-24 15:07:38 +02:00
commit 1453cf49f9
10 changed files with 71 additions and 50 deletions

View file

@ -29,14 +29,14 @@ class LodelSession(object):
#@warning Cause maybe a performance issue !
def __token_checker(self):
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 \
exists !")
exists ! (exactly %d)" % refcount)
##@brief Property. Equals True if a session is started else False
@property
def started(self):
res = self.__token is None
res = self.__token is not None
if res:
self.__token_checker()
return res
@ -74,7 +74,8 @@ a session is allready started !!!")
def destroy(self):
if not self.started:
logger.debug("Destroying a session that is not started")
SessionHandler.destroy(self.__token)
else:
SessionHandler.destroy(self.__token)
self.__token = None
self.__datas = dict()
@ -173,10 +174,8 @@ class Client(object, metaclass = ClientMetaclass):
##@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
def __init__(self,ui_instance, client_infos, session_token = None):
def __init__(self,session_token = None):
if self.__class__ == Client:
raise NotImplementedError("Abstract class")
logger.debug("New instance of Client child class %s" %
@ -189,14 +188,12 @@ class Client(object, metaclass = ClientMetaclass):
else:
#first instanciation, fetching settings
self.fetch_settings()
##@brief Stores instance of UI
self.__ui_instance = ui_instance
##@brief Stores infos for authenticated users (None == anonymous)
self.__user = None
##@brief Stores the session handler
Client._instance = self
##@brief Stores LodelSession instance
self.__session = LodelSession(token)
self.__session = LodelSession(session_token)
logger.debug("New client : %s" % self)
##@brief Attempt to restore a session given a session token
@ -249,6 +246,11 @@ class Client(object, metaclass = ClientMetaclass):
if self.is_anon():
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
#@return True if client is anonymous
@classmethod

View file

@ -17,6 +17,7 @@ class DatasourcePlugin(Plugin):
'key': 'datasource_connectors',
'default': None,
'validator': SettingValidator('strip', none_is_valid = False) }
_type_conf_name = 'datasource'
def __init__(self, name):
super().__init__(name)

View file

@ -10,3 +10,5 @@ class Extension(Plugin):
'default': [],
'validator': SettingValidator('list', none_is_valid = False)}
_type_conf_name = 'extension'

View file

@ -12,6 +12,8 @@ class InterfacePlugin(Plugin):
'key': 'interface',
'default': None,
'validator': SettingValidator('strip', none_is_valid = True)}
_type_conf_name = 'ui'
def __init__(self, name):
if InterfacePlugin._instance is not None:

View file

@ -43,9 +43,7 @@ DEFAULT_PLUGINS_PATH_LIST = ['./plugins']
MANDATORY_VARNAMES = [PLUGIN_NAME_VARNAME, LOADER_FILENAME_VARNAME,
PLUGIN_VERSION_VARNAME]
DEFAULT_PLUGIN_TYPE = 'extension'
PLUGINS_TYPES = [DEFAULT_PLUGIN_TYPE, 'datasource', 'session_handler', 'ui']
DEFAULT_PLUGIN_TYPE = 'extension' #Value found in lodel/plugin/extensions.py::Extensions._type_conf_name
##@brief Describe and handle version numbers
class PluginVersion(object):
@ -149,37 +147,38 @@ to generic PluginVersion comparison function : '%s'" % cmp_fun_name)
return {'major': self.major, 'minor': self.minor,
'revision': self.revision}
##@brief Stores plugin class registered
__all_ptypes = list()
##@brief Plugin metaclass that allows to "catch" child class
#declaration
#
#Automatic script registration on child class declaration
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):
#Here we can store all child classes of Plugin
super().__init__(name, bases, attrs)
if len(bases) == 1 and bases[0] == object:
return
self.__register_types()
#list_name= [cls.__name__ for cls in __all_ptypes]
#if self.name in list_name:
# return
#else:
# plug_type_register(self)
#Regitering a new plugin type
MetaPlugType._all_ptypes[self._type_conf_name] = self
def __register_types(self):
plug_type_register(self)
@classmethod
def all_types(cls):
return copy.copy(cls._all_ptypes)
def plug_type_register(cls):
__all_ptypes.append(cls)
logger.info("New child class registered : %s" % cls.__name__)
def all_types():
return copy.copy(__all_ptypes)
@classmethod
def all_ptype_names(cls):
return list(cls._all_ptypes.keys())
@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
#
@ -212,6 +211,11 @@ class Plugin(object, metaclass=MetaPlugType):
#where plugin list is stored
_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
#
# Called by setting in early stage of lodel2 boot sequence using classmethod
@ -290,7 +294,8 @@ class Plugin(object, metaclass=MetaPlugType):
except AttributeError:
self.__type = DEFAULT_PLUGIN_TYPE
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)
# Load plugin name from init file (just for checking)
try:
@ -427,6 +432,9 @@ name differ from the one found in plugin's init file"
logger.debug("Plugin '%s' loaded" % self.name)
self.loaded = True
##@brief Returns the loader module
#
#Accessor for the __loader__ python module
def loader_module(self):
if not self.loaded:
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)
pinfos = pdcache['plugins'][plugin_name]
ptype = pinfos['type']
if ptype == 'datasource':
pcls = DatasourcePlugin
else:
pcls = cls
if ptype not in MetaPlugType.all_ptype_names():
raise PluginError("Unknown plugin type '%s'" % ptype)
pcls = MetaPlugType.type_from_name(ptype)
print("\n\n\nINSTANCIATING : ", pcls, " from name : ", ptype)
plugin = pcls(plugin_name)
cls._plugin_instances[plugin_name] = 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
@classmethod
def plugin_types(cls):
return all_types()
return MetaPlugType.all_types()
##@brief Attempt to open and load plugin discover cache
#@return discover cache

View file

@ -17,14 +17,19 @@ class SessionPluginWrapper(MetaPlugType):
def __init__(self, name, bases, attrs):
super().__init__(name, bases, attrs)
self._instance = None
##@brief Handles wrapper between class method and plugin loader functions
def __get_attribute__(self, name):
if name in SessionPluginWrapper._Actions:
def __getattribute__(self, name):
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(
self._instance.loader_module(),
SessionPluginWrapper._Actions[name])
return super().__get_attribute__(name)
instance.loader_module(),
SessionPluginWrapper._ACTIONS[name])
return super().__getattribute__(name)
##@page lodel2_plugins Lodel2 plugins system
@ -45,10 +50,12 @@ class SessionHandlerPlugin(Plugin, metaclass=SessionPluginWrapper):
'key': 'session_handler',
'default': None,
'validator': SettingValidator('string', none_is_valid=False)}
_type_conf_name = 'session_handler'
def __init__(self, plugin_name):
if self._instance is None:
super(Plugin, self).__init__(plugin_name)
self._instance = self
super().__init__(plugin_name)
self.__class__._instance = self
else:
raise RuntimeError("A SessionHandler Plugin is already plug")

View file

@ -135,7 +135,7 @@ class Settings(object, metaclass=MetaSettings):
lodel2_specs = LODEL2_CONF_SPECS
loader = SettingsLoader(self.__conf_dir)
plugin_list = []
for ptype in Plugin.plugin_types():
for ptype_name,ptype in Plugin.plugin_types().items():
pls = ptype.plist_confspecs()
lodel2_specs = confspec_append(lodel2_specs, **pls)
cur_list = loader.getoption(
@ -161,7 +161,6 @@ class Settings(object, metaclass=MetaSettings):
# Starting the Plugins class
logger.debug("Starting lodel.plugin.Plugin class")
print("DEBUG : plugin list : ", plugin_list)
Plugin.start(plugin_list)
# Fetching conf specs from plugins
specs = [lodel2_specs]

View file

@ -2,7 +2,7 @@ from lodel.settings.validator import SettingValidator
__plugin_name__ = 'ram_session'
__version__ = [0,0,1]
__type__ = 'session_handler'
__plugin_type__ = 'session_handler'
__loader__ = 'main.py'
__author__ = "Lodel2 dev team"
__fullname__ = "RAM Session Store Plugin"

View file

@ -1,5 +1,5 @@
__plugin_name__ = 'webui'
__version__ = '0.0.1'
__type__ = 'ui'
__plugin_type__ = 'ui'
__loader__ = 'main.py'
__confspec__ = 'confspec.py'

View file

@ -2,10 +2,10 @@ from lodel.auth.client import Client
class WebUiClient(Client):
def __init__(self, ip, user_agent):
def __init__(self, ip, user_agent, session_token = None):
self.__ip = ip
self.__user_agent = user_agent
super().__init__()
super().__init__(session_token = session_token)
def __str__(self):
return "%s (%s)" % (self.__ip, self.__user_agent)