terom@62: from twisted.internet import protocol terom@62: from twisted.application import service, internet terom@62: from twisted.python import log terom@62: terom@62: import datetime terom@62: terom@62: class ModuleInfo (object) : terom@62: """ terom@62: Nexus-side handle on a Module terom@62: """ terom@62: terom@62: # module's name terom@62: name = None terom@62: terom@62: def __str__ (self) : terom@64: return "%s" % (self.name) terom@62: terom@62: def __repr__ (self) : terom@62: return "" % (self.name, ) terom@62: terom@62: terom@62: class Event (object) : terom@62: """ terom@62: An Event, sent by a Module to the Nexus, to be distributed further terom@62: """ terom@62: terom@62: # the ModuleInfo object terom@62: module = None terom@62: terom@62: # the event type as a string terom@62: type = None terom@62: terom@62: # event message as a string (up to 64k, although that won't fit onto IRC..) terom@62: msg = None terom@62: terom@62: # timestamp as a datetime.datetime terom@62: when = None terom@62: terom@62: def __init__ (self, module, type, msg) : terom@62: self.module = module terom@62: self.type = type terom@62: self.msg = msg terom@62: terom@62: self.when = datetime.datetime.now() terom@62: terom@62: def __str__ (self) : terom@62: return "[%s] %s" % (self.type, self.msg) terom@62: terom@62: def __repr__ (self) : terom@62: return "%s @ %s" % (self.type, self.when) terom@62: terom@62: terom@62: class Module (ModuleInfo, protocol.ClientFactory) : terom@62: """ terom@62: Module core, handles the API connection state and processes all messages terom@62: """ terom@62: terom@62: # our API connection to the Nexus terom@62: connection = None terom@62: terom@62: def __init__ (self, config, protocol) : terom@62: """ terom@62: config - configuration for connecting to nexus terom@62: protocol - API client protocol to use for this factory terom@62: """ terom@62: terom@62: self.protocol = protocol terom@62: terom@62: self.connection = None terom@62: terom@62: # XXX: legacy: self.secret = config['api-secret'] terom@62: terom@64: terom@62: def _onRegistered (self, connection) : terom@62: """ terom@62: Connected to nexus and registered terom@62: """ terom@62: terom@62: log.msg("Connected and registered") terom@62: terom@62: self.connection = connection terom@64: terom@64: # XXX: abort on errors? terom@62: self.handleConnect() terom@62: terom@64: terom@64: # XXX: unused, bad interface terom@62: def disconnect (self) : terom@62: """ terom@62: Disconnect from Nexus terom@62: """ terom@62: terom@62: self.connection.transport.loseConnection() terom@64: terom@64: terom@62: def sendEvent (self, type, msg) : terom@62: """ terom@62: Send event to nexus terom@62: """ terom@62: terom@62: self.connection.sendEvent(Event(self, type, msg)) terom@62: terom@64: terom@62: def handleConnect (self) : terom@62: """ terom@62: Do something once we are connected to nexus and registered terom@62: """ terom@62: terom@62: pass terom@62: terom@64: def abort (self, err) : terom@64: """ terom@64: Abort this module, disconnecting with the given error terom@64: """ terom@64: terom@64: self.connection.abort(str(err)) terom@64: terom@62: def makeService (module_class, config, protocol) : terom@62: s = service.MultiService() terom@62: terom@62: # build factory terom@62: factory = module_class(config, protocol) terom@62: terom@62: # the API client terom@62: log.msg("Connecting to API server on [%s:%d]" % (config['api-server'], config['api-port'])) terom@62: api_client = internet.TCPClient(config['api-server'], config['api-port'], factory) terom@62: terom@62: api_client.setServiceParent(s) terom@62: terom@62: return s terom@62: