comparison src/plugins/plugin_misc_groupblog.py @ 476:b9fd32b46306

plugin groupblog: added disco info + misc fixes
author Goffi <goffi@goffi.org>
date Thu, 31 May 2012 00:26:39 +0200
parents 6cd04adddaea
children 031b0e0aaab8
comparison
equal deleted inserted replaced
475:6bb9305e0b9c 476:b9fd32b46306
18 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 """ 20 """
21 21
22 from logging import debug, info, error 22 from logging import debug, info, error
23 from twisted.internet import protocol, defer 23 from twisted.internet import defer
24 from twisted.words.protocols.jabber import jid 24 from twisted.words.protocols.jabber import jid
25 from twisted.words.protocols.jabber import error as jab_error 25
26 import twisted.internet.error 26 from wokkel import disco, data_form, iwokkel
27 from twisted.words.xish import domish 27
28 from sat.tools.xml_tools import ElementParser 28 from zope.interface import implements
29 29
30 from wokkel import disco, pubsub, data_form 30 try:
31 from feed.atom import Entry, Author 31 from twisted.words.protocols.xmlstream import XMPPHandler
32 import uuid 32 except ImportError:
33 from time import time 33 from wokkel.subprotocols import XMPPHandler
34 34
35 NS_PUBSUB = 'http://jabber.org/protocol/pubsub' 35 NS_PUBSUB = 'http://jabber.org/protocol/pubsub'
36 NS_GROUPBLOG = 'http://goffi.org/protocol/groupblog'
36 #NS_PUBSUB_EXP = 'http://goffi.org/protocol/pubsub' #for non official features 37 #NS_PUBSUB_EXP = 'http://goffi.org/protocol/pubsub' #for non official features
37 NS_PUBSUB_EXP = NS_PUBSUB #XXX: we can't use custom namespace as Wokkel's PubSubService use official NS 38 NS_PUBSUB_EXP = NS_PUBSUB #XXX: we can't use custom namespace as Wokkel's PubSubService use official NS
38 NS_PUBSUB_ITEM_ACCESS = NS_PUBSUB_EXP + "#item-access" 39 NS_PUBSUB_ITEM_ACCESS = NS_PUBSUB_EXP + "#item-access"
39 NS_PUBSUB_CREATOR_JID_CHECK = NS_PUBSUB_EXP + "#creator-jid-check" 40 NS_PUBSUB_CREATOR_JID_CHECK = NS_PUBSUB_EXP + "#creator-jid-check"
40 NS_PUBSUB_ITEM_CONFIG = NS_PUBSUB_EXP + "#item-config" 41 NS_PUBSUB_ITEM_CONFIG = NS_PUBSUB_EXP + "#item-config"
53 "import_name": "groupblog", 54 "import_name": "groupblog",
54 "type": "MISC", 55 "type": "MISC",
55 "protocols": [], 56 "protocols": [],
56 "dependencies": ["XEP-0277"], 57 "dependencies": ["XEP-0277"],
57 "main": "GroupBlog", 58 "main": "GroupBlog",
58 "handler": "no", 59 "handler": "yes",
59 "description": _("""Implementation of microblogging with roster access""") 60 "description": _("""Implementation of microblogging with roster access""")
60 } 61 }
61 62
62 class NoCompatiblePubSubServerFound(Exception): 63 class NoCompatiblePubSubServerFound(Exception):
63 pass 64 pass
85 86
86 host.bridge.addMethod("getMassiveLastGroupBlogs", ".plugin", 87 host.bridge.addMethod("getMassiveLastGroupBlogs", ".plugin",
87 in_sign='sasis', out_sign='a{saa{ss}}', 88 in_sign='sasis', out_sign='a{saa{ss}}',
88 method=self.getMassiveLastGroupBlogs, 89 method=self.getMassiveLastGroupBlogs,
89 async = True) 90 async = True)
90 91
92 def getHandler(self, profile):
93 return GroupBlog_handler()
91 94
92 @defer.inlineCallbacks 95 @defer.inlineCallbacks
93 def initialise(self, profile_key): 96 def initialise(self, profile_key):
94 """Check that this data for this profile are initialised, and do it else 97 """Check that this data for this profile are initialised, and do it else
95 @param client: client of the profile 98 @param client: client of the profile
107 110
108 #we first check that we have a item-access pubsub server 111 #we first check that we have a item-access pubsub server
109 if not hasattr(client,"item_access_pubsub"): 112 if not hasattr(client,"item_access_pubsub"):
110 debug(_('Looking for item-access power pubsub server')) 113 debug(_('Looking for item-access power pubsub server'))
111 #we don't have any pubsub server featuring item access yet 114 #we don't have any pubsub server featuring item access yet
112 test = self.host.memory.getServerServiceEntities("pubsub", "service", profile)
113 client.item_access_pubsub = None 115 client.item_access_pubsub = None
114 for entity in self.host.memory.getServerServiceEntities("pubsub", "service", profile): 116 for entity in self.host.memory.getServerServiceEntities("pubsub", "service", profile):
115 disco = yield client.disco.requestInfo(entity) 117 _disco = yield client.disco.requestInfo(entity)
116 if set([NS_PUBSUB_ITEM_ACCESS, NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK]).issubset(disco.features): 118 if set([NS_PUBSUB_ITEM_ACCESS, NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK]).issubset(_disco.features):
117 info(_("item-access powered pubsub service found: [%s]") % entity.full()) 119 info(_("item-access powered pubsub service found: [%s]") % entity.full())
118 client.item_access_pubsub = entity 120 client.item_access_pubsub = entity
119 121
120 if not client.item_access_pubsub: 122 if not client.item_access_pubsub:
121 error(_("No item-access powered pubsub server found, can't use group blog")) 123 error(_("No item-access powered pubsub server found, can't use group blog"))
135 mblog_item = self.host.plugins["XEP-0277"].data2entry({'content':message}, client.profile) 137 mblog_item = self.host.plugins["XEP-0277"].data2entry({'content':message}, client.profile)
136 form = data_form.Form('submit', formNamespace=NS_PUBSUB_ITEM_CONFIG) 138 form = data_form.Form('submit', formNamespace=NS_PUBSUB_ITEM_CONFIG)
137 if access_type == "PUBLIC": 139 if access_type == "PUBLIC":
138 if access_list: 140 if access_list:
139 raise BadAccessListError("access_list must be empty for PUBLIC access") 141 raise BadAccessListError("access_list must be empty for PUBLIC access")
142 access = data_form.Field(None, OPT_ACCESS_MODEL, value="open")
143 form.addField(access)
140 elif access_type == "GROUP": 144 elif access_type == "GROUP":
141 field = data_form.Field('list-multi', OPT_ROSTER_GROUPS_ALLOWED, values=access_list) 145 access = data_form.Field(None, OPT_ACCESS_MODEL, value="roster")
142 form.addField(field) 146 allowed = data_form.Field(None, OPT_ROSTER_GROUPS_ALLOWED, values=access_list)
147 form.addField(access)
148 form.addField(allowed)
143 mblog_item.addChild(form.toElement()) 149 mblog_item.addChild(form.toElement())
144 elif access_type == "JID": 150 elif access_type == "JID":
145 raise NotImplementedError 151 raise NotImplementedError
146 else: 152 else:
147 error(_("Unknown access_type")) 153 error(_("Unknown access_type"))
194 def initialised(result): 200 def initialised(result):
195 profile, client = result 201 profile, client = result
196 d = self.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, jid.JID(pub_jid).userhost(), 202 d = self.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, jid.JID(pub_jid).userhost(),
197 max_items=max_items, profile_key=profile_key) 203 max_items=max_items, profile_key=profile_key)
198 d.addCallback(lambda items: map(self.host.plugins["XEP-0277"].item2mbdata, items)) 204 d.addCallback(lambda items: map(self.host.plugins["XEP-0277"].item2mbdata, items))
199 205 d.addErrback(lambda ignore: {}) #TODO: more complete error management (log !)
200 self.initialise(profile_key).addCallback(initialised) 206 return d
207
201 #TODO: we need to use the server corresponding the the host of the jid 208 #TODO: we need to use the server corresponding the the host of the jid
209 return self.initialise(profile_key).addCallback(initialised)
202 210
203 def getMassiveLastGroupBlogs(self, publishers_type, publishers, max_items=10, profile_key='@DEFAULT@'): 211 def getMassiveLastGroupBlogs(self, publishers_type, publishers, max_items=10, profile_key='@DEFAULT@'):
204 """Get the last published microblogs for a list of groups or jids 212 """Get the last published microblogs for a list of groups or jids
205 @param publishers_type: type of the list of publishers (one of "GROUP" or "JID" or "ALL") 213 @param publishers_type: type of the list of publishers (one of "GROUP" or "JID" or "ALL")
206 @param publishers: list of publishers, according to "publishers_type" (list of groups or list of jids) 214 @param publishers: list of publishers, according to "publishers_type" (list of groups or list of jids)
244 if publishers_type=="ALL" and publishers: 252 if publishers_type=="ALL" and publishers:
245 raise Exception("Publishers list must be empty when getting microblogs for all contacts") 253 raise Exception("Publishers list must be empty when getting microblogs for all contacts")
246 return self.initialise(profile_key).addCallback(initialised) 254 return self.initialise(profile_key).addCallback(initialised)
247 #TODO: we need to use the server corresponding the the host of the jid 255 #TODO: we need to use the server corresponding the the host of the jid
248 256
257 class GroupBlog_handler(XMPPHandler):
258 implements(iwokkel.IDisco)
259
260 def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
261 return [disco.DiscoFeature(NS_GROUPBLOG)]
262
263 def getDiscoItems(self, requestor, target, nodeIdentifier=''):
264 return []
265