plugin groupblog: subscriptions/notifications

This commit is contained in:
Goffi 2012-06-25 00:08:16 +02:00
commit 357374bcd2
6 changed files with 101 additions and 6 deletions

View file

@ -252,6 +252,12 @@ class DBusBridgeFrontend(BridgeFrontend):
def getMassiveLastGroupBlogs(self, publishers_type, publishers, max_items=10, profile_key='@DEFAULT@', callback=None, errback=None):
return self.db_plugin_iface.getMassiveLastGroupBlogs(publishers_type, publishers, max_items, profile_key, reply_handler=callback, error_handler=errback)
def subscribeGroupBlog(self, jid, profile_key='@DEFAULT@', callback=None, errback=None):
return self.db_plugin_iface.subscribeGroupBlog(jid, profile_key, reply_handler=callback, error_handler=errback)
def massiveSubscribeGroupBlogs(self, publishers_type, publishers, profile_key='@DEFAULT@', callback=None, errback=None):
return self.db_plugin_iface.massiveSubscribeGroupBlogs(publishers_type, publishers, profile_key, reply_handler=callback, error_handler=errback)
def sendPersonalEvent(self, event_type, data, profile_key):
return self.db_plugin_iface.sendPersonalEvent(event_type, data, profile_key)

View file

@ -34,6 +34,9 @@ const_OBJ_PATH = '/org/goffi/SAT/bridge'
const_CORE_SUFFIX = ".core"
const_PLUGIN_SUFFIX = ".plugin"
class ParseError(Exception):
pass
class MethodNotRegistered(dbus.DBusException):
_dbus_error_name = const_ERROR_PREFIX + ".MethodNotRegistered"
@ -50,7 +53,7 @@ class GenericException(dbus.DBusException):
def __init__(self, twisted_error):
super(GenericException,self).__init__()
mess = twisted_error.getErrorMessage()
self._dbus_error_name = const_ERROR_PREFIX+"."+ (mess or str(err.__class__))
self._dbus_error_name = const_ERROR_PREFIX+"."+ (mess or str(twisted_error.__class__))
class DbusObject(dbus.service.Object):

View file

@ -34,6 +34,9 @@ const_OBJ_PATH = '/org/goffi/SAT/bridge'
const_CORE_SUFFIX = ".core"
const_PLUGIN_SUFFIX = ".plugin"
class ParseError(Exception):
pass
class MethodNotRegistered(dbus.DBusException):
_dbus_error_name = const_ERROR_PREFIX + ".MethodNotRegistered"
@ -50,7 +53,7 @@ class GenericException(dbus.DBusException):
def __init__(self, twisted_error):
super(GenericException,self).__init__()
mess = twisted_error.getErrorMessage()
self._dbus_error_name = const_ERROR_PREFIX+"."+ (mess or str(err.__class__))
self._dbus_error_name = const_ERROR_PREFIX+"."+ (mess or str(twisted_error.__class__))
class DbusObject(dbus.service.Object):

View file

@ -145,6 +145,12 @@ class DBusBridgeFrontend(BridgeFrontend):
def getMassiveLastGroupBlogs(self, publishers_type, publishers, max_items=10, profile_key='@DEFAULT@', callback=None, errback=None):
return self.db_plugin_iface.getMassiveLastGroupBlogs(publishers_type, publishers, max_items, profile_key, reply_handler=callback, error_handler=errback)
def subscribeGroupBlog(self, jid, profile_key='@DEFAULT@', callback=None, errback=None):
return self.db_plugin_iface.subscribeGroupBlog(jid, profile_key, reply_handler=callback, error_handler=errback)
def massiveSubscribeGroupBlogs(self, publishers_type, publishers, profile_key='@DEFAULT@', callback=None, errback=None):
return self.db_plugin_iface.massiveSubscribeGroupBlogs(publishers_type, publishers, profile_key, reply_handler=callback, error_handler=errback)
def sendPersonalEvent(self, event_type, data, profile_key):
return self.db_plugin_iface.sendPersonalEvent(event_type, data, profile_key)

View file

@ -34,6 +34,7 @@ except ImportError:
NS_PUBSUB = 'http://jabber.org/protocol/pubsub'
NS_GROUPBLOG = 'http://goffi.org/protocol/groupblog'
NS_NODE_PREFIX = 'urn:xmpp:groupblog:'
#NS_PUBSUB_EXP = 'http://goffi.org/protocol/pubsub' #for non official features
NS_PUBSUB_EXP = NS_PUBSUB #XXX: we can't use custom namespace as Wokkel's PubSubService use official NS
NS_PUBSUB_ITEM_ACCESS = NS_PUBSUB_EXP + "#item-access"
@ -88,6 +89,17 @@ class GroupBlog():
in_sign='sasis', out_sign='a{saa{ss}}',
method=self.getMassiveLastGroupBlogs,
async = True)
host.bridge.addMethod("subscribeGroupBlog", ".plugin", in_sign='ss', out_sign='',
method=self.subscribeGroupBlog,
async = True)
host.bridge.addMethod("massiveSubscribeGroupBlogs", ".plugin", in_sign='sass', out_sign='',
method=self.massiveSubscribeGroupBlogs,
async = True)
host.trigger.add("PubSubItemsReceived", self.pubSubItemsReceivedTrigger)
def getHandler(self, profile):
return GroupBlog_handler()
@ -115,7 +127,8 @@ class GroupBlog():
client.item_access_pubsub = None
for entity in self.host.memory.getServerServiceEntities("pubsub", "service", profile):
_disco = yield client.disco.requestInfo(entity)
if set([NS_PUBSUB_ITEM_ACCESS, NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK]).issubset(_disco.features):
#if set([NS_PUBSUB_ITEM_ACCESS, NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK]).issubset(_disco.features):
if set([NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK]).issubset(_disco.features):
info(_("item-access powered pubsub service found: [%s]") % entity.full())
client.item_access_pubsub = entity
@ -125,6 +138,24 @@ class GroupBlog():
defer.returnValue((profile, client))
def pubSubItemsReceivedTrigger(self, event, profile):
""""Trigger which catch groupblogs events"""
if event.nodeIdentifier.startswith(NS_NODE_PREFIX):
for item in event.items:
microblog_data = self.host.plugins["XEP-0277"].item2mbdata(item)
self.host.bridge.personalEvent(event.sender.full(), "MICROBLOG", microblog_data, profile)
return False
return True
def getNodeName(self, publisher):
"""Retrieve the name of publisher's node
@param publisher: publisher's jid
@return: node's name (string)"""
return NS_NODE_PREFIX + publisher.userhost()
def _publishMblog(self, service, client, access_type, access_list, message):
"""Actually publish the message on the group blog
@ -152,7 +183,7 @@ class GroupBlog():
else:
error(_("Unknown access_type"))
raise BadAccessTypeError
defer_blog = self.host.plugins["XEP-0060"].publish(service, client.jid.userhost(), items=[mblog_item], profile_key=client.profile)
defer_blog = self.host.plugins["XEP-0060"].publish(service, self.getNodeName(client.jid), items=[mblog_item], profile_key=client.profile)
defer_blog.addErrback(self._mblogPublicationFailed)
def _mblogPublicationFailed(self, failure):
@ -199,7 +230,7 @@ class GroupBlog():
def initialised(result):
profile, client = result
d = self.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, jid.JID(pub_jid).userhost(),
d = self.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, self.getNodeName(jid.JID(pub_jid)),
max_items=max_items, profile_key=profile_key)
d.addCallback(lambda items: map(self.host.plugins["XEP-0277"].item2mbdata, items))
d.addErrback(lambda ignore: {}) #TODO: more complete error management (log !)
@ -235,7 +266,7 @@ class GroupBlog():
jids = [contact.jid.userhost() for contact in contacts]
mblogs = []
for _jid in jids:
d = self.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, jid.JID(_jid).userhost(),
d = self.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, self.getNodeName(jid.JID(_jid)),
max_items=max_items, profile_key=profile_key)
d.addCallback(lambda items, source_jid: (source_jid, map(self.host.plugins["XEP-0277"].item2mbdata, items)), _jid)
mblogs.append(d)
@ -254,6 +285,50 @@ class GroupBlog():
return self.initialise(profile_key).addCallback(initialised)
#TODO: we need to use the server corresponding the the host of the jid
def subscribeGroupBlog(self, pub_jid, profile_key='@DEFAULT'):
def initialised(result):
profile, client = result
d = self.host.plugins["XEP-0060"].subscribe(client.item_access_pubsub, self.getNodeName(jid.JID(pub_jid)),
profile_key=profile_key)
return d
#TODO: we need to use the server corresponding the the host of the jid
return self.initialise(profile_key).addCallback(initialised)
def massiveSubscribeGroupBlogs(self, publishers_type, publishers, profile_key='@DEFAULT@'):
"""Subscribe microblogs for a list of groups or jids
@param publishers_type: type of the list of publishers (one of "GROUP" or "JID" or "ALL")
@param publishers: list of publishers, according to "publishers_type" (list of groups or list of jids)
@param profile_key: profile key
"""
def initialised(result):
profile, client = result
if publishers_type == "ALL":
contacts = client.roster.getItems()
jids = [contact.jid.userhost() for contact in contacts]
mblogs = []
for _jid in jids:
d = self.host.plugins["XEP-0060"].subscribe(client.item_access_pubsub, self.getNodeName(jid.JID(_jid)),
profile_key=profile_key)
mblogs.append(d)
dlist = defer.DeferredList(mblogs)
return dlist
return defer.fail("Unknown type")
#TODO: custom exception
if publishers_type not in ["GROUP", "JID", "ALL"]:
raise Exception("Bad call, unknown publishers_type")
if publishers_type=="ALL" and publishers:
raise Exception("Publishers list must be empty when getting microblogs for all contacts")
return self.initialise(profile_key).addCallback(initialised)
#TODO: we need to use the server corresponding the the host of the jid
class GroupBlog_handler(XMPPHandler):
implements(iwokkel.IDisco)

View file

@ -131,6 +131,8 @@ class SatPubSubClient(pubsub.PubSubClient):
pubsub.PubSubClient.connectionInitialized(self)
def itemsReceived(self, event):
if not self.host.trigger.point("PubSubItemsReceived", event, self.parent.profile):
return
for node in self.parent_plugin.managedNodes:
if event.nodeIdentifier == node[0]:
return node[1](event, self.parent.profile)