plugins xep-0060, xep-0163, xep-0277, groupblog: bloging improvments (huge patch, sorry):

/!\ not everything is working yet, and specially groupblogs are broken /!\
    - renamed bridge api to use prefixed methods (e.g. psSubscribeToMany instead of subscribeToMany in PubSub)
    - (xep-0060): try to find a default PubSub service, and put it in client.pubsub_service
    - (xep-0060): extra dictionary can be used in bridge method for RSM and other options
    - (xep-0060): XEP_0060.addManagedNode and XEP_0060.removeManagedNode allow to easily catch notifications for a specific node
    - (xep-0060): retractItem manage "notify" attribute
    - (xep-0060): new signal psEvent will be used to transmit notifications to frontends
    - (xep-0060, constants): added a bunch of useful constants
    - (xep-0163): removed personalEvent in favor of psEvent
    - (xep-0163): addPEPEvent now filter non PEP events for in_callback
    - (xep-0277): use of new XEP-0060 plugin's addManagedNode
    - (xep-0277): fixed author handling for incoming blogs: author is the human readable name, author_jid it jid, and author_jid_verified is set to True is the jid is checked
    - (xep-0277): reworked data2entry with Twisted instead of feed, item_id can now be specified, <content/> is changed to  <title/> if there is only content
    - (xep-0277): comments are now managed here (core removed from groupblog)
    - (xep-0277): (comments) node is created if needed, default pubsub service is used if available, else PEP
    - (xep-0277): retract is managed
This commit is contained in:
Goffi 2015-08-16 00:39:44 +02:00
commit b7409e0488

View file

@ -29,8 +29,7 @@ from wokkel import disco, data_form, iwokkel
from wokkel import rsm
from zope.interface import implements
from feed import date
import uuid
import urllib
# import uuid
try:
from twisted.words.protocols.xmlstream import XMPPHandler
@ -40,7 +39,6 @@ except ImportError:
NS_PUBSUB = 'http://jabber.org/protocol/pubsub'
NS_GROUPBLOG = 'http://goffi.org/protocol/groupblog'
NS_NODE_PREFIX = 'urn:xmpp:groupblog:'
NS_COMMENT_PREFIX = 'urn:xmpp:comments:'
#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"
@ -137,7 +135,7 @@ class GroupBlog(object):
# method=self.subscribeGroupBlog,
# async=True)
host.trigger.add("PubSubItemsReceived", self.pubSubItemsReceivedTrigger)
# host.trigger.add("PubSubItemsReceived", self.pubSubItemsReceivedTrigger)
## plugin management methods ##
@ -172,43 +170,43 @@ class GroupBlog(object):
defer.returnValue((profile, client))
def pubSubItemsReceivedTrigger(self, event, profile):
""""Trigger which catch groupblogs events"""
# def pubSubItemsReceivedTrigger(self, event, profile):
# """"Trigger which catch groupblogs events"""
if event.nodeIdentifier.startswith(NS_NODE_PREFIX):
# Microblog
publisher = jid.JID(event.nodeIdentifier[len(NS_NODE_PREFIX):])
origin_host = publisher.host.split('.')
event_host = event.sender.host.split('.')
#FIXME: basic origin check, must be improved
#TODO: automatic security test
if (not (origin_host)
or len(event_host) < len(origin_host)
or event_host[-len(origin_host):] != origin_host):
log.warning(u"Host incoherence between %s and %s (hack attempt ?)" % (unicode(event.sender),
unicode(publisher)))
return False
# if event.nodeIdentifier.startswith(NS_NODE_PREFIX):
# # Microblog
# publisher = jid.JID(event.nodeIdentifier[len(NS_NODE_PREFIX):])
# origin_host = publisher.host.split('.')
# event_host = event.sender.host.split('.')
# #FIXME: basic origin check, must be improved
# #TODO: automatic security test
# if (not (origin_host)
# or len(event_host) < len(origin_host)
# or event_host[-len(origin_host):] != origin_host):
# log.warning(u"Host incoherence between %s and %s (hack attempt ?)" % (unicode(event.sender),
# unicode(publisher)))
# return False
client = self.host.getClient(profile)
# client = self.host.getClient(profile)
def gbdataManagementMicroblog(gbdata):
for gbdatum in gbdata:
self.host.bridge.personalEvent(publisher.full(), "MICROBLOG", gbdatum, profile)
# def gbdataManagementMicroblog(gbdata):
# for gbdatum in gbdata:
# self.host.bridge.personalEvent(publisher.full(), "MICROBLOG", gbdatum, profile)
d = self._itemsConstruction(event.items, publisher, client)
d.addCallback(gbdataManagementMicroblog)
return False
# d = self._itemsConstruction(event.items, publisher, client)
# d.addCallback(gbdataManagementMicroblog)
# return False
elif event.nodeIdentifier.startswith(NS_COMMENT_PREFIX):
# Comment
def gbdataManagementComments(gbdata):
for gbdatum in gbdata:
publisher = None # FIXME: see below (_handleCommentsItems)
self.host.bridge.personalEvent(publisher.full() if publisher else gbdatum["author"], "MICROBLOG", gbdatum, profile)
d = self._handleCommentsItems(event.items, event.sender, event.nodeIdentifier)
d.addCallback(gbdataManagementComments)
return False
return True
# elif event.nodeIdentifier.startswith(NS_COMMENT_PREFIX):
# # Comment
# def gbdataManagementComments(gbdata):
# for gbdatum in gbdata:
# publisher = None # FIXME: see below (_handleCommentsItems)
# self.host.bridge.personalEvent(publisher.full() if publisher else gbdatum["author"], "MICROBLOG", gbdatum, profile)
# d = self._handleCommentsItems(event.items, event.sender, event.nodeIdentifier)
# d.addCallback(gbdataManagementComments)
# return False
# return True
## internal helping methodes ##
@ -338,20 +336,20 @@ class GroupBlog(object):
entry_d.addCallback(itemCreated)
return entry_d
def _fillCommentsElement(self, mblog_data, entry_id, node_name, service_jid):
"""
@param mblog_data: dict containing the microblog data
@param entry_id: unique identifier of the entry
@param node_name: the pubsub node name
@param service_jid: the JID of the pubsub service
@return: the comments node string
"""
if entry_id is None:
entry_id = unicode(uuid.uuid4())
comments_node = "%s_%s__%s" % (NS_COMMENT_PREFIX, entry_id, node_name)
mblog_data['comments'] = "xmpp:%(service)s?%(query)s" % {'service': service_jid.userhost(),
'query': urllib.urlencode([('node', comments_node.encode('utf-8'))])}
return comments_node
# def _fillCommentsElement(self, mblog_data, entry_id, node_name, service_jid):
# """
# @param mblog_data: dict containing the microblog data
# @param entry_id: unique identifier of the entry
# @param node_name: the pubsub node name
# @param service_jid: the JID of the pubsub service
# @return: the comments node string
# """
# if entry_id is None:
# entry_id = unicode(uuid.uuid4())
# comments_node = "%s_%s__%s" % (NS_COMMENT_PREFIX, entry_id, node_name)
# mblog_data['comments'] = "xmpp:%(service)s?%(query)s" % {'service': service_jid.userhost(),
# 'query': urllib.urlencode([('node', comments_node.encode('utf-8'))])}
# return comments_node
def _mblogPublicationFailed(self, failure):
#TODO