# HG changeset patch # User Ralph Meijer # Date 1088001109 0 # Node ID 4cc41776b7d748cde18b4e38c91f4972e377ae52 # Parent 1b68bdae21eb65ba4de1c6f1c8ac6e7324213923 Initial revision diff -r 1b68bdae21eb -r 4cc41776b7d7 idavoll/__init__.py diff -r 1b68bdae21eb -r 4cc41776b7d7 idavoll/backend.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/idavoll/backend.py Wed Jun 23 14:31:49 2004 +0000 @@ -0,0 +1,62 @@ +from twisted.application import service +from twisted.python import components, failure +from twisted.internet import defer, reactor + +class IBackendService(components.Interface): + """ Interface to a backend service of a pubsub service """ + +class BackendException(Exception): + def __init__(self, msg = ''): + self.msg = msg + + def __str__(self): + return self.msg + +class NodeNotFound(BackendException): + #def __init__(self, msg = 'Node not found'): + # BackendException.__init__(self, msg) + pass + +class NotAuthorized(BackendException): + pass + +class MemoryBackendService(service.Service): + + __implements__ = IBackendService, + + def __init__(self): + self.nodes = {"ralphm/test": 'test'} + self.subscribers = {"ralphm/test": ["ralphm@ik.nu", "intosi@ik.nu"] } + self.affiliations = {"ralphm/test": { "ralphm@ik.nu": "owner", "ralphm@se-135.se.wtb.tue.nl": 'publisher' } } + + def do_publish(self, node, publisher, item): + try: + try: + result = self.nodes[node] + except KeyError: + raise NodeNotFound + + try: + affiliation = self.affiliations[node][publisher] + if affiliation not in ['owner', 'publisher']: + raise NotAuthorized + except KeyError: + raise NotAuthorized() + print "publish by %s to %s" % (publisher, node) + return defer.succeed(result) + except: + f = failure.Failure() + return defer.fail(f) + + def get_subscribers(self, node): + d = defer.Deferred() + try: + result = self.subscribers[node] + except: + f = failure.Failure() + reactor.callLater(0, d.errback, f) + else: + reactor.callLater(0, d.callback, result) + + return d + diff -r 1b68bdae21eb -r 4cc41776b7d7 idavoll/idavoll.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/idavoll/idavoll.py Wed Jun 23 14:31:49 2004 +0000 @@ -0,0 +1,56 @@ +from twisted.protocols.jabber import component +from twisted.application import service +import backend +import pubsub +import xmpp_error + +import sys + +IQ_GET = '/iq[@type="get"]' +IQ_SET = '/iq[@type="set"]' +VERSION = IQ_GET + '/query[@xmlns="jabber:iq:version"]' + +class IdavollService(component.Service): + + def componentConnected(self, xmlstream): + self.xmlstream = xmlstream + xmlstream.addObserver(VERSION, self.onVersion, 1) + xmlstream.addObserver(IQ_GET, self.iqFallback, -1) + xmlstream.addObserver(IQ_SET, self.iqFallback, -1) + + def onVersion(self, iq): + print "version?" + iq.swapAttributeValues("to", "from") + iq["type"] = "result" + name = iq.addElement("name", None, 'Idavoll') + version = iq.addElement("version", None, '0.1') + self.send(iq) + iq.handled = True + + def iqFallback(self, iq): + if iq.handled == True: + return + + self.send(xmpp_error.error_from_iq(iq, 'feature-not-implemented')) + +def makeService(config): + serviceCollection = service.MultiService() + + pss = backend.MemoryBackendService() + + # set up Jabber Component + c = component.buildServiceManager(config["jid"], config["secret"], + ("tcp:%s:%s" % (config["rhost"], config["rport"]))) + + s = component.IService(pss) + s.jid = config["jid"] + s.setServiceParent(c) + + s = IdavollService() + s.setServiceParent(c) + + c.setServiceParent(serviceCollection) + + # other stuff + + return c diff -r 1b68bdae21eb -r 4cc41776b7d7 idavoll/plugins.tml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/idavoll/plugins.tml Wed Jun 23 14:31:49 2004 +0000 @@ -0,0 +1,3 @@ +register("Idavoll", "idavoll.tap", + description="Jabber Publish Subscribe Component", + type='tap', tapname='idavoll') diff -r 1b68bdae21eb -r 4cc41776b7d7 idavoll/pubsub.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/idavoll/pubsub.py Wed Jun 23 14:31:49 2004 +0000 @@ -0,0 +1,73 @@ +from twisted.protocols.jabber import component,jid +from twisted.xish import utility +from twisted.python import components +import backend +import xmpp_error + +IQ_GET = '/iq[@type="get"]' +IQ_SET = '/iq[@type="set"]' +PUBSUB_GET = IQ_GET + '/pubsub[@xmlns="http://jabber.org/protocol/pubsub"]' +PUBSUB_SET = IQ_SET + '/pubsub[@xmlns="http://jabber.org/protocol/pubsub"]' + +PUBSUB_CREATE = PUBSUB_SET + '/create' +PUBSUB_PUBLISH = PUBSUB_SET + '/publish' + +class ComponentServiceFromBackend(component.Service, utility.EventDispatcher): + + def __init__(self, backend): + utility.EventDispatcher.__init__(self) + self.backend = backend + self.addObserver(PUBSUB_PUBLISH, self.onPublish) + + def componentConnected(self, xmlstream): + xmlstream.addObserver(PUBSUB_SET, self.onPubSub) + xmlstream.addObserver(PUBSUB_GET, self.onPubSub) + + def error(self, failure, iq): + r = failure.trap(backend.NotAuthorized, backend.NodeNotFound) + + if r == backend.NotAuthorized: + xmpp_error.error_from_iq(iq, 'not-authorized', failure.value.msg) + + if r == backend.NodeNotFound: + xmpp_error.error_from_iq(iq, 'item-not-found', failure.value.msg) + + return iq + + def success(self, result, iq): + iq.swapAttributeValues("to", "from") + iq["type"] = 'result' + iq.children = [] + return iq + + def onPubSub(self, iq): + self.dispatch(iq) + iq.handled = True + + def onPublish(self, iq): + node = iq.pubsub.publish["node"] + + d = self.backend.do_publish(node, jid.JID(iq["from"]).userhost(), iq.pubsub.publish.item) + d.addCallback(self.success, iq) + d.addErrback(self.error, iq) + d.addCallback(self.send) + + +""" + def onCreateSet(self, iq): + node = iq.pubsub.create["node"] + owner = jid.JID(iq["from"]).userhost() + + try: + node = self.backend.create_node(node, owner) + + if iq.pubsub.create["node"] == None: + # also show node name + except: + pass + + iq.handled = True +""" + +components.registerAdapter(ComponentServiceFromBackend, backend.IBackendService, component.IService) + diff -r 1b68bdae21eb -r 4cc41776b7d7 idavoll/tap.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/idavoll/tap.py Wed Jun 23 14:31:49 2004 +0000 @@ -0,0 +1,15 @@ +from twisted.application import internet, service +from twisted.internet import interfaces +from twisted.python import usage +import idavoll + +class Options(usage.Options): + optParameters = [ + ('jid', None, 'pubsub'), + ('secret', None, None), + ('rhost', None, '127.0.0.1'), + ('rport', None, '6000') + ] + +def makeService(config): + return idavoll.makeService(config) diff -r 1b68bdae21eb -r 4cc41776b7d7 idavoll/xmpp_error.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/idavoll/xmpp_error.py Wed Jun 23 14:31:49 2004 +0000 @@ -0,0 +1,27 @@ +conditions = { + 'not-authorized': {'code': '401', 'type': 'cancel'}, + 'item-not-found': {'code': '404', 'type': 'cancel'}, + 'feature-not-implemented': {'code': '501', 'type': 'cancel'}, +} + +def error_from_iq(iq, condition, text = '', type = None): + iq.swapAttributeValues("to", "from") + iq["type"] = 'error' + e = iq.addElement("error") + + c = e.addElement(condition) + c["xmlns"] = "urn:ietf:params:xml:ns:xmpp-stanzas" + + if type == None: + type = conditions[condition]['type'] + + code = conditions[condition]['code'] + + e["code"] = code + e["type"] = type + + if text: + t = e.addElement("text", None, text) + t["xmlns"] = "urn:ietf:params:xml:ns:xmpp-stanzas" + + return iq