scripts/gestion/trigger/services/service.py
2014-07-14 04:01:17 +02:00

92 lines
3.1 KiB
Python

#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
"""
This module provides a basic service class to other services. It should *NOT*
be referenced in configuration of trigger.
"""
import collections
import cranslib.clogger as clogger
import gestion.config.trigger as trigger_config
from gestion.trigger.host import TriggerFactory
logger = clogger.CLogger("trigger", "service", "debug", trigger_config.debug)
class MetaService(type):
"""Metaclass designed to handle all services.
"""
def __new__(mcs, cname, cpar, cattrs):
"""Method producing the new class itself
At first, I wanted to put the changes_trigger modification in __new__,
using direct modification of cattrs['changes_trigger'] by pointing the
required methods (classmethods). The problem was that these methods were
bound at the return of type.__new__, for a reason I could not exactly
explain.
I found a workaround using __init__, so the point would be to remove
__new__, and directly use type.__new__, but this comment seems useful,
so __new__ will survive.
"""
return super(MetaService, mcs).__new__(mcs, cname, cpar, cattrs)
def __init__(cls, cname, cpar, cattrs):
"""Used to register the generated classes in TriggerFactory, and modify the behavior of
changes_trigger by pointing functions instead of their names. This allows to cancel any
positional requirement in class definition.
Do NEVER return something in __init__ function.
"""
if not cname == "BasicService":
TriggerFactory.register(cname.lower(), cls)
changes_trigger = collections.defaultdict(list)
# I love getattr
text_changes_trigger = getattr(cls, "changes_trigger", {})
for (ldap_attr_name, funcs_name) in text_changes_trigger.items():
for func_name in funcs_name:
# I really love getattr.
get = getattr(cls, func_name, None)
if get is None:
logger.critical("Fatal, bad function (%s) reference in %s.", func_name, cname)
continue
changes_trigger[ldap_attr_name].append(get)
setattr(cls, "changes_trigger", changes_trigger)
super(MetaService, cls).__init__(cname, cpar, cattrs)
class BasicService(object):
"""Basic service handler. Other services should inherit fron this one.
"""
__metaclass__ = MetaService
changes_trigger = {}
@classmethod
def get_changes(cls, body, diff):
"""Looks for changes and creates messages to send back
"""
# list of all messages to send.
msg_list = []
# lists all functions to call
func_list = set()
for (attrib, functions) in cls.changes_trigger.iteritems():
if attrib in diff:
func_list.update(functions)
for function in func_list:
msg_list.append(function(body, diff))
return msg_list
@classmethod
def regen(cls, body):
"""This method is referenced to avoid uncaught exceptions
"""
pass