# HG changeset patch # User Goffi # Date 1300997726 -3600 # Node ID 2b52a5da09788821afee9fecd0465010f08df3e7 # Parent 9f3a6cf916685b7f99da77864da5909c46045f2b plugin XEP_0277: microblog access model can now be changed plugin XEP_0060: added some method to manage pubsub nodes diff -r 9f3a6cf91668 -r 2b52a5da0978 frontends/src/bridge/DBus.py --- a/frontends/src/bridge/DBus.py Mon Feb 21 01:38:16 2011 +0100 +++ b/frontends/src/bridge/DBus.py Thu Mar 24 21:15:26 2011 +0100 @@ -215,3 +215,5 @@ data = [('', '')] #XXX: we have to do this awful hack because python dbus need to guess the signature return self.db_req_iface.gatewayRegister(action, target, data, profile_key) + def getLastMicroblogs(self, jid, max_items, profile_key='@DEFAULT@', callback=None, errback=None): + return self.db_comm_iface.getLastMicroblogs(jid, max_items, profile_key, reply_handler=callback, error_handler=errback) diff -r 9f3a6cf91668 -r 2b52a5da0978 src/bridge/bridge_constructor/dbus_frontend_template.py --- a/src/bridge/bridge_constructor/dbus_frontend_template.py Mon Feb 21 01:38:16 2011 +0100 +++ b/src/bridge/bridge_constructor/dbus_frontend_template.py Thu Mar 24 21:15:26 2011 +0100 @@ -96,4 +96,6 @@ data = [('', '')] #XXX: we have to do this awful hack because python dbus need to guess the signature return self.db_req_iface.gatewayRegister(action, target, data, profile_key) + def getLastMicroblogs(self, jid, max_items, profile_key='@DEFAULT@', callback=None, errback=None): + return self.db_comm_iface.getLastMicroblogs(jid, max_items, profile_key, reply_handler=callback, error_handler=errback) diff -r 9f3a6cf91668 -r 2b52a5da0978 src/plugins/plugin_xep_0060.py --- a/src/plugins/plugin_xep_0060.py Mon Feb 21 01:38:16 2011 +0100 +++ b/src/plugins/plugin_xep_0060.py Thu Mar 24 21:15:26 2011 +0100 @@ -70,10 +70,16 @@ @param profile: profile which manage this handler""" self.managedNodes.append((node_name, callback)) - def publish(self, service, nodeIdentifier, items=None, profile_key='@DEFAULT@'): + def __getClientNProfile(self, profile_key, action='do pusbsub'): + """Return a tuple of (client, profile) + raise error when the profile doesn't exists + @param profile_key: as usual :) + @param action: text of action to show in case of error""" profile = self.host.memory.getProfileName(profile_key) if not profile: - err_mess = _('Trying to publish items with an unknown profile key [%s]') % profile_key + err_mess = _('Trying to %(action)s with an unknown profile key [%(profile_key)s]') % { + 'action':action, + 'profile_key':profile_key} error(err_mess) raise Exception(err_mess) try: @@ -82,21 +88,32 @@ err_mess = _('INTERNAL ERROR: no handler for required profile') error(err_mess) raise Exception(err_mess) - client.publish(service, nodeIdentifier, items, client.parent.jid) + return profile, client + + def publish(self, service, nodeIdentifier, items=None, profile_key='@DEFAULT@'): + profile,client = self.__getClientNProfile(profile_key, 'publish item') + return client.publish(service, nodeIdentifier, items, client.parent.jid) def getItems(self, service, node, max_items=None, sub_id=None, profile_key='@DEFAULT@'): - profile = self.host.memory.getProfileName(profile_key) - if not profile: - err_mess = _('Trying to get items with an unknown profile key [%s]') % profile_key - error(err_mess) - raise Exception(err_mess) - try: - client = self.clients[profile] - except KeyError: - err_mess = _('INTERNAL ERROR: no handler for required profile') - error(err_mess) - raise Exception(err_mess) + profile,client = self.__getClientNProfile(profile_key, 'get items') return client.items(service, node, max_items, sub_id, client.parent.jid) + + def getOptions(self, service, nodeIdentifier, subscriber, subscriptionIdentifier=None, profile_key='@DEFAULT@'): + profile,client = self.__getClientNProfile(profile_key, 'get options') + return client.getOptions(service, nodeIdentifier, subscriber, subscriptionIdentifier) + + def setOptions(self, service, nodeIdentifier, subscriber, options, subscriptionIdentifier=None, profile_key='@DEFAULT@'): + profile,client = self.__getClientNProfile(profile_key, 'set options') + return client.setOptions(service, nodeIdentifier, subscriber, options, subscriptionIdentifier) + + def createNode(self, service, nodeIdentifier, options, profile_key='@DEFAULT@'): + profile,client = self.__getClientNProfile(profile_key, 'create node') + return client.createNode(service, nodeIdentifier, options) + + def deleteNode(self, service, nodeIdentifier, profile_key='@DEFAULT@'): + profile,client = self.__getClientNProfile(profile_key, 'delete node') + return client.deleteNode(service, nodeIdentifier) + class SatPubSubClient(pubsub.PubSubClient): implements(disco.IDisco) @@ -115,8 +132,8 @@ return node[1](event, self.parent.profile) def deleteReceived(self, event): - import pdb - pdb.set_trace() + #TODO: manage delete event + debug(_("Publish node deleted")) def purgeReceived(self, event): import pdb diff -r 9f3a6cf91668 -r 2b52a5da0978 src/plugins/plugin_xep_0277.py --- a/src/plugins/plugin_xep_0277.py Mon Feb 21 01:38:16 2011 +0100 +++ b/src/plugins/plugin_xep_0277.py Thu Mar 24 21:15:26 2011 +0100 @@ -33,6 +33,9 @@ from time import time NS_MICROBLOG = 'urn:xmpp:microblog:0' +NS_ACCESS_MODEL = 'pubsub#access_model' +NS_PERSIST_ITEMS = 'pubsub#persist_items' +NS_MAX_ITEMS = 'pubsub#max_items' PLUGIN_INFO = { "name": "Microblogging over XMPP Plugin", @@ -61,6 +64,10 @@ 'param_2':'%(doc_profile)s', 'return':'list of microblog data (dict)' }) + host.bridge.addMethod("setMicroblogAccess", ".communication", in_sign='ss', out_sign='', + method=self.setMicroblogAccess, + doc = { + }) def _item2mbdata(self, item): """Convert an XML Item to microblog data used in bridge API @@ -124,10 +131,47 @@ self.host.plugins["XEP-0060"].publish(None, NS_MICROBLOG, [item], profile_key = profile) return 0 - def getLastMicroblogs(self, pub_jid, max_items=1, profile_key='@DEFAULT@', callback=None, errback=None): + def getLastMicroblogs(self, pub_jid, max_items=10, profile_key='@DEFAULT@', callback=None, errback=None): + """Get the last published microblogs + @param pub_jid: jid of the publisher + @param max_items: how many microblogs we wants to get + @param profile_key: profile key + @param callback: used for the async answer + @param errback: used for the async answer + """ assert(callback) d = self.host.plugins["XEP-0060"].getItems(jid.JID(pub_jid), NS_MICROBLOG, max_items=max_items, profile_key=profile_key) d.addCallbacks(lambda items: callback(map(self._item2mbdata, items)), errback) + def setMicroblogAccess(self, access="presence", profile_key='@DEFAULT@'): + """Create a microblog node on PEP with given access + If the node already exists, it is deleted and recreated + @param access: Node access model, according to xep-0060 #4.5 + @param profile_key: profile key""" + + jid, xmlstream = self.host.getJidNStream(profile_key) + def cb(result): + #Node is created with right permission + debug(_("Microblog node created")) + + def fatal_err(s_error): + #Something went wrong + error(_("Can't set microblog access")) + + def err_cb(s_error): + #If the node already exists, the condition is "conflict", + #else we have an unmanaged error + if s_error.value.condition=='conflict': + d = self.host.plugins["XEP-0060"].deleteNode(jid.userhostJID(), NS_MICROBLOG, profile_key=profile_key) + d.addCallback(lambda x: create_node().addCallback(cb).addErrback(fatal_err)) + d.addErrback(fatal_err) + else: + fatal_err(s_error) + + def create_node(): + return self.host.plugins["XEP-0060"].createNode(jid.userhostJID(), NS_MICROBLOG, {NS_ACCESS_MODEL:access, NS_PERSIST_ITEMS:1, NS_MAX_ITEMS:-1}, profile_key=profile_key) + + create_node().addCallback(cb).addErrback(err_cb) +