# -*- coding: UTF-8 -*- import os, json, sys, uuid from lisa.server.libs import RulesEngine, Commands, Wit from twisted.internet.protocol import Factory, Protocol from twisted.protocols.basic import LineReceiver from twisted.internet import ssl from twisted.python import log from OpenSSL import SSL from lisa.server.libs.txscheduler.manager import ScheduledTaskManager from lisa.server.libs.txscheduler.service import ScheduledTaskService from lisa.server.plugins.PluginManager import PluginManager from lisa.server.service import configuration, dir_path from lisa.server.web.manageplugins.models import Intent, Rule # Create a task manager to pass it to other services taskman = ScheduledTaskManager(configuration) scheduler = ScheduledTaskService(taskman) class ServerTLSContext(ssl.DefaultOpenSSLContextFactory): def __init__(self, *args, **kw): kw['sslmethod'] = SSL.TLSv1_METHOD ssl.DefaultOpenSSLContextFactory.__init__(self, *args, **kw) class Lisa(LineReceiver): def __init__(self,factory, wit): self.factory = factory self.wit = wit def answerToClient(self, jsondata): if configuration['debug']['debug_output']: log.msg("OUTPUT: " + str(jsondata)) jsonreturned = json.loads(jsondata) if 'all' in jsonreturned['clients_zone']: for client in self.factory.clients: client['object'].sendLine(jsondata) else: for zone in jsonreturned['clients_zone']: if zone == 'sender': self.sendLine(jsondata) else: for client in self.factory.clients: if client['zone'] == zone: client['object'].sendLine(jsondata) def askToClient(self, jsondata): jsondata['type'] = 'question' self.answerToClient(jsondata=jsondata) def connectionMade(self): self.client_uuid = str(uuid.uuid1()) self.factory.clients.append({"object": self, "zone": "", "type": "", "uuid": self.client_uuid}) if configuration['enable_secure_mode']: ctx = ServerTLSContext( privateKeyFileName=os.path.normpath(dir_path + '/' + 'configuration/ssl/server.key'), certificateFileName= os.path.normpath(dir_path + '/' + 'configuration/ssl/server.crt') ) self.transport.startTLS(ctx, self.factory) pass def connectionLost(self, reason): log.err('Lost connection. Reason:', reason) for client in self.factory.clients: if client['object'] == self: self.factory.clients.remove(client) def lineReceived(self, data): if configuration['debug']['debug_input']: log.msg("INPUT: " + str(data)) try: jsonData = json.loads(data) except ValueError, e: self.sendLine("Error : Invalid JSON") else: for client in self.factory.clients: if client['object'] == self and (not client['type'] or not client['zone']): client['type'], client['zone'] = jsonData['type'], jsonData['zone'] if jsonData['type'] == "chat": RulesEngine(configuration).Rules(jsonData=jsonData, lisaprotocol=self) elif jsonData['type'] == "command": Commands(configuration, lisaprotocol=self).parse(jsonData=jsonData) class LisaFactory(Factory): def __init__(self): self.wit = Wit(configuration) self.clients = [] self.syspath = sys.path def buildProtocol(self, addr): self.Lisa = Lisa(self,self.wit) return self.Lisa def LisaReload(self): global enabled_plugins log.msg("Reloading L.I.S.A Engine") sys.path = self.syspath enabled_plugins = [] self.build_activeplugins() def SchedReload(self): global taskman log.msg("Reloading Task Scheduler") self.taskman = taskman return self.taskman.reload() # Create an instance LisaInstance = LisaFactory() LisaProtocolInstance = Lisa(LisaInstance, LisaInstance.wit) # Load the plugins pluginmanager = PluginManager() pluginmanager.loadPlugins() def Initialize(): # Create the default core_intents_list intent defaults_intent_list = {'name': "core_intents_list", 'function': "list", 'module': "core.intents.Intents", 'enabled': True } intent_list, created = Intent.objects.get_or_create(name='core_intents_list', defaults=defaults_intent_list) # Create the default rule of the rule engine defaults_rule = {'name': "DefaultAnwser", 'order': 999, 'before': None, 'after': """lisaprotocol.answerToClient(json.dumps( { 'plugin': jsonOutput['plugin'], 'method': jsonOutput['method'], 'body': jsonOutput['body'], 'clients_zone': ['sender'], 'from': jsonOutput['from'] }))""", 'end': True, 'enabled': True } default_rule, created = Rule.objects.get_or_create(name='DefaultAnwser', defaults=defaults_rule)