comparison src/plugins/plugin_misc_groupblog.py @ 993:301b342c697a

core: use of the new core.log module: /!\ this is a massive refactoring and was largely automated, it probably did bring some bugs /!\
author Goffi <goffi@goffi.org>
date Sat, 19 Apr 2014 19:19:19 +0200
parents e1842ebcb2f3
children 4be53c14845e
comparison
equal deleted inserted replaced
992:f51a1895275c 993:301b342c697a
17 # You should have received a copy of the GNU Affero General Public License 17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20 from sat.core.i18n import _ 20 from sat.core.i18n import _
21 from sat.core.constants import Const as C 21 from sat.core.constants import Const as C
22 from logging import debug, info, warning, error 22 from sat.core.log import getLogger
23 log = getLogger(__name__)
23 from twisted.internet import defer 24 from twisted.internet import defer
24 from twisted.words.protocols.jabber import jid 25 from twisted.words.protocols.jabber import jid
25 from twisted.words.xish.domish import Element, generateElementsNamed 26 from twisted.words.xish.domish import Element, generateElementsNamed
26 from sat.core import exceptions 27 from sat.core import exceptions
27 from wokkel import disco, data_form, iwokkel 28 from wokkel import disco, data_form, iwokkel
81 82
82 class GroupBlog(object): 83 class GroupBlog(object):
83 """This class use a SàT PubSub Service to manage access on microblog""" 84 """This class use a SàT PubSub Service to manage access on microblog"""
84 85
85 def __init__(self, host): 86 def __init__(self, host):
86 info(_("Group blog plugin initialization")) 87 log.info(_("Group blog plugin initialization"))
87 self.host = host 88 self.host = host
88 89
89 host.bridge.addMethod("sendGroupBlog", ".plugin", in_sign='sassa{ss}s', out_sign='', 90 host.bridge.addMethod("sendGroupBlog", ".plugin", in_sign='sassa{ss}s', out_sign='',
90 method=self.sendGroupBlog, 91 method=self.sendGroupBlog,
91 async=True) 92 async=True)
155 156
156 client = self.host.getClient(profile) 157 client = self.host.getClient(profile)
157 158
158 #we first check that we have a item-access pubsub server 159 #we first check that we have a item-access pubsub server
159 if not hasattr(client, "item_access_pubsub"): 160 if not hasattr(client, "item_access_pubsub"):
160 debug(_('Looking for item-access powered pubsub server')) 161 log.debug(_('Looking for item-access powered pubsub server'))
161 #we don't have any pubsub server featuring item access yet 162 #we don't have any pubsub server featuring item access yet
162 item_access_pubsubs = yield self.host.findFeaturesSet((NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK), "pubsub", "service", profile_key=profile) 163 item_access_pubsubs = yield self.host.findFeaturesSet((NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK), "pubsub", "service", profile_key=profile)
163 # item_access_pubsubs = yield self.host.findFeaturesSet((NS_PUBSUB_ITEM_ACCESS, NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK), "pubsub", "service", profile_key=profile) 164 # item_access_pubsubs = yield self.host.findFeaturesSet((NS_PUBSUB_ITEM_ACCESS, NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK), "pubsub", "service", profile_key=profile)
164 try: 165 try:
165 client.item_access_pubsub = item_access_pubsubs.pop() 166 client.item_access_pubsub = item_access_pubsubs.pop()
166 info(_("item-access powered pubsub service found: [%s]") % client.item_access_pubsub.full()) 167 log.info(_("item-access powered pubsub service found: [%s]") % client.item_access_pubsub.full())
167 except KeyError: 168 except KeyError:
168 client.item_access_pubsub = None 169 client.item_access_pubsub = None
169 170
170 if not client.item_access_pubsub: 171 if not client.item_access_pubsub:
171 error(_("No item-access powered pubsub server found, can't use group blog")) 172 log.error(_("No item-access powered pubsub server found, can't use group blog"))
172 raise NoCompatiblePubSubServerFound 173 raise NoCompatiblePubSubServerFound
173 174
174 defer.returnValue((profile, client)) 175 defer.returnValue((profile, client))
175 176
176 def pubSubItemsReceivedTrigger(self, event, profile): 177 def pubSubItemsReceivedTrigger(self, event, profile):
184 #FIXME: basic origin check, must be improved 185 #FIXME: basic origin check, must be improved
185 #TODO: automatic security test 186 #TODO: automatic security test
186 if (not (origin_host) 187 if (not (origin_host)
187 or len(event_host) < len(origin_host) 188 or len(event_host) < len(origin_host)
188 or event_host[-len(origin_host):] != origin_host): 189 or event_host[-len(origin_host):] != origin_host):
189 warning("Host incoherence between %s and %s (hack attempt ?)" % (unicode(event.sender), 190 log.warning("Host incoherence between %s and %s (hack attempt ?)" % (unicode(event.sender),
190 unicode(publisher))) 191 unicode(publisher)))
191 return False 192 return False
192 193
193 client = self.host.getClient(profile) 194 client = self.host.getClient(profile)
194 195
241 access_model = form.get(P.OPT_ACCESS_MODEL, 'open') 242 access_model = form.get(P.OPT_ACCESS_MODEL, 'open')
242 if access_model == "roster": 243 if access_model == "roster":
243 try: 244 try:
244 microblog_data["groups"] = '\n'.join(form.fields[P.OPT_ROSTER_GROUPS_ALLOWED].values) 245 microblog_data["groups"] = '\n'.join(form.fields[P.OPT_ROSTER_GROUPS_ALLOWED].values)
245 except KeyError: 246 except KeyError:
246 warning("No group found for roster access-model") 247 log.warning("No group found for roster access-model")
247 microblog_data["groups"] = '' 248 microblog_data["groups"] = ''
248 249
249 break 250 break
250 251
251 @defer.inlineCallbacks 252 @defer.inlineCallbacks
315 form.addField(allowed) 316 form.addField(allowed)
316 mblog_item.addChild(form.toElement()) 317 mblog_item.addChild(form.toElement())
317 elif access_type == "JID": 318 elif access_type == "JID":
318 raise NotImplementedError 319 raise NotImplementedError
319 else: 320 else:
320 error(_("Unknown access_type")) 321 log.error(_("Unknown access_type"))
321 raise BadAccessTypeError 322 raise BadAccessTypeError
322 323
323 defer_blog = self.host.plugins["XEP-0060"].publish(service, node_name, items=[mblog_item], profile_key=client.profile) 324 defer_blog = self.host.plugins["XEP-0060"].publish(service, node_name, items=[mblog_item], profile_key=client.profile)
324 defer_blog.addErrback(self._mblogPublicationFailed) 325 defer_blog.addErrback(self._mblogPublicationFailed)
325 return defer_blog 326 return defer_blog
371 raise BadAccessListError("No valid group") 372 raise BadAccessListError("No valid group")
372 return self._publishMblog(client.item_access_pubsub, client, "GROUP", _groups, message, extra) 373 return self._publishMblog(client.item_access_pubsub, client, "GROUP", _groups, message, extra)
373 elif access_type == "JID": 374 elif access_type == "JID":
374 raise NotImplementedError 375 raise NotImplementedError
375 else: 376 else:
376 error(_("Unknown access type")) 377 log.error(_("Unknown access type"))
377 raise BadAccessTypeError 378 raise BadAccessTypeError
378 379
379 return self._initialise(profile_key).addCallback(initialised) 380 return self._initialise(profile_key).addCallback(initialised)
380 381
381 def deleteGroupBlog(self, pub_data, comments, profile_key=C.PROF_KEY_NONE): 382 def deleteGroupBlog(self, pub_data, comments, profile_key=C.PROF_KEY_NONE):
393 node = self.getNodeName(client.jid) 394 node = self.getNodeName(client.jid)
394 if comments: 395 if comments:
395 # remove the associated comments node 396 # remove the associated comments node
396 comments_service, comments_node = self.host.plugins["XEP-0277"].parseCommentUrl(comments) 397 comments_service, comments_node = self.host.plugins["XEP-0277"].parseCommentUrl(comments)
397 d = self.host.plugins["XEP-0060"].deleteNode(comments_service, comments_node, profile_key=profile) 398 d = self.host.plugins["XEP-0060"].deleteNode(comments_service, comments_node, profile_key=profile)
398 d.addErrback(lambda failure: error("Deletion of node %s failed: %s" % (comments_node, failure.getErrorMessage()))) 399 d.addErrback(lambda failure: log.error("Deletion of node %s failed: %s" % (comments_node, failure.getErrorMessage())))
399 # remove the item itself 400 # remove the item itself
400 d = self.host.plugins["XEP-0060"].retractItems(service_jid, node, [item_id], profile_key=profile) 401 d = self.host.plugins["XEP-0060"].retractItems(service_jid, node, [item_id], profile_key=profile)
401 d.addErrback(lambda failure: error("Deletion of item %s from %s failed: %s" % (item_id, node, failure.getErrorMessage()))) 402 d.addErrback(lambda failure: log.error("Deletion of item %s from %s failed: %s" % (item_id, node, failure.getErrorMessage())))
402 return d 403 return d
403 404
404 def notify(d): 405 def notify(d):
405 # TODO: this works only on the same host, and notifications for item deletion should be 406 # TODO: this works only on the same host, and notifications for item deletion should be
406 # implemented according to http://xmpp.org/extensions/xep-0060.html#publisher-delete-success-notify 407 # implemented according to http://xmpp.org/extensions/xep-0060.html#publisher-delete-success-notify
445 # XXX: use the item identifier? http://bugs.goffi.org/show_bug.cgi?id=63 446 # XXX: use the item identifier? http://bugs.goffi.org/show_bug.cgi?id=63
446 entry_id = comments_node.split('_')[1].split('__')[0] 447 entry_id = comments_node.split('_')[1].split('__')[0]
447 self.__fillCommentsElement(mblog_data, entry_id, node, service_jid) 448 self.__fillCommentsElement(mblog_data, entry_id, node, service_jid)
448 entry_d = self.host.plugins["XEP-0277"].data2entry(mblog_data, profile) 449 entry_d = self.host.plugins["XEP-0277"].data2entry(mblog_data, profile)
449 entry_d.addCallback(lambda mblog_item: self.host.plugins["XEP-0060"].publish(service_jid, node, items=[mblog_item], profile_key=profile)) 450 entry_d.addCallback(lambda mblog_item: self.host.plugins["XEP-0060"].publish(service_jid, node, items=[mblog_item], profile_key=profile))
450 entry_d.addErrback(lambda failure: error("Modification of %s failed: %s" % (pub_data, failure.getErrorMessage()))) 451 entry_d.addErrback(lambda failure: log.error("Modification of %s failed: %s" % (pub_data, failure.getErrorMessage())))
451 return entry_d 452 return entry_d
452 453
453 return self._initialise(profile_key).addCallback(initialised) 454 return self._initialise(profile_key).addCallback(initialised)
454 455
455 def sendGroupBlogComment(self, node_url, message, extra, profile_key=C.PROF_KEY_NONE): 456 def sendGroupBlogComment(self, node_url, message, extra, profile_key=C.PROF_KEY_NONE):
499 # every comments node must be subscribed, except if we are the publisher (we are already subscribed in this case) 500 # every comments node must be subscribed, except if we are the publisher (we are already subscribed in this case)
500 if pub_jid.userhostJID() != client.jid.userhostJID(): 501 if pub_jid.userhostJID() != client.jid.userhostJID():
501 self.host.plugins["XEP-0060"].subscribe(jid.JID(gbdata["comments_service"]), gbdata["comments_node"], 502 self.host.plugins["XEP-0060"].subscribe(jid.JID(gbdata["comments_service"]), gbdata["comments_node"],
502 profile_key=client.profile) 503 profile_key=client.profile)
503 except KeyError: 504 except KeyError:
504 warning("Missing key for comments") 505 log.warning("Missing key for comments")
505 defer.returnValue(ret) 506 defer.returnValue(ret)
506 507
507 def __getGroupBlogs(self, pub_jid_s, max_items=10, item_ids=None, profile_key=C.PROF_KEY_NONE): 508 def __getGroupBlogs(self, pub_jid_s, max_items=10, item_ids=None, profile_key=C.PROF_KEY_NONE):
508 """Retrieve previously published items from a publish subscribe node. 509 """Retrieve previously published items from a publish subscribe node.
509 @param pub_jid_s: jid of the publisher 510 @param pub_jid_s: jid of the publisher
773 service = client.item_access_pubsub 774 service = client.item_access_pubsub
774 jid_ = client.jid 775 jid_ = client.jid
775 776
776 main_node = self.getNodeName(jid_) 777 main_node = self.getNodeName(jid_)
777 d = self.host.plugins["XEP-0060"].deleteNode(service, main_node, profile_key=profile) 778 d = self.host.plugins["XEP-0060"].deleteNode(service, main_node, profile_key=profile)
778 d.addCallback(lambda dummy: info(_("All microblog's main items from %s have been deleted!") % jid_.userhost())) 779 d.addCallback(lambda dummy: log.info(_("All microblog's main items from %s have been deleted!") % jid_.userhost()))
779 d.addErrback(lambda failure: error(_("Deletion of node %(node)s failed: %(message)s") % 780 d.addErrback(lambda failure: log.error(_("Deletion of node %(node)s failed: %(message)s") %
780 {'node': main_node, 'message': failure.getErrorMessage()})) 781 {'node': main_node, 'message': failure.getErrorMessage()}))
781 return d 782 return d
782 783
783 return self._initialise(profile_key).addCallback(initialised) 784 return self._initialise(profile_key).addCallback(initialised)
784 785
797 blogs = [] 798 blogs = []
798 for jid_ in jids: 799 for jid_ in jids:
799 main_node = self.getNodeName(jid_) 800 main_node = self.getNodeName(jid_)
800 d = self.host.plugins["XEP-0060"].getItems(service, main_node, profile_key=profile) 801 d = self.host.plugins["XEP-0060"].getItems(service, main_node, profile_key=profile)
801 d.addCallback(getComments, client) 802 d.addCallback(getComments, client)
802 d.addErrback(lambda failure, main_node: error(_("Retrieval of items for node %(node)s failed: %(message)s") % 803 d.addErrback(lambda failure, main_node: log.error(_("Retrieval of items for node %(node)s failed: %(message)s") %
803 {'node': main_node, 'message': failure.getErrorMessage()}), main_node) 804 {'node': main_node, 'message': failure.getErrorMessage()}), main_node)
804 blogs.append(d) 805 blogs.append(d)
805 806
806 return defer.DeferredList(blogs) 807 return defer.DeferredList(blogs)
807 808
820 continue 821 continue
821 href = link.getAttribute('href') 822 href = link.getAttribute('href')
822 service, node = self.host.plugins['XEP-0277'].parseCommentUrl(href) 823 service, node = self.host.plugins['XEP-0277'].parseCommentUrl(href)
823 d = self.host.plugins["XEP-0060"].getItems(service, node, profile_key=profile_key) 824 d = self.host.plugins["XEP-0060"].getItems(service, node, profile_key=profile_key)
824 d.addCallback(lambda items, service, node: (service, node, items), service, node) 825 d.addCallback(lambda items, service, node: (service, node, items), service, node)
825 d.addErrback(lambda failure, node: error(_("Retrieval of comments for node %(node)s failed: %(message)s") % 826 d.addErrback(lambda failure, node: log.error(_("Retrieval of comments for node %(node)s failed: %(message)s") %
826 {'node': node, 'message': failure.getErrorMessage()}), node) 827 {'node': node, 'message': failure.getErrorMessage()}), node)
827 comments.append(d) 828 comments.append(d)
828 dlist = defer.DeferredList(comments) 829 dlist = defer.DeferredList(comments)
829 dlist.addCallback(deleteComments, client) 830 dlist.addCallback(deleteComments, client)
830 return dlist 831 return dlist
852 if name.children[0] == user_jid_s: 853 if name.children[0] == user_jid_s:
853 item_ids.append(comment_item.getAttribute('id')) 854 item_ids.append(comment_item.getAttribute('id'))
854 deletions = [] 855 deletions = []
855 if item_ids: # remove the comments of the user on the given post 856 if item_ids: # remove the comments of the user on the given post
856 d = self.host.plugins['XEP-0060'].retractItems(service, node_id, item_ids, profile_key=profile_key) 857 d = self.host.plugins['XEP-0060'].retractItems(service, node_id, item_ids, profile_key=profile_key)
857 d.addCallback(lambda dummy, node_id: debug(_('Comments of user %(user)s in node %(node)s have been retracted') % 858 d.addCallback(lambda dummy, node_id: log.debug(_('Comments of user %(user)s in node %(node)s have been retracted') %
858 {'user': user_jid_s, 'node': node_id}), node_id) 859 {'user': user_jid_s, 'node': node_id}), node_id)
859 d.addErrback(lambda failure, node_id: error(_("Retraction of comments from %(user)s in node %(node)s failed: %(message)s") % 860 d.addErrback(lambda failure, node_id: log.error(_("Retraction of comments from %(user)s in node %(node)s failed: %(message)s") %
860 {'user': user_jid_s, 'node': node_id, 'message': failure.getErrorMessage()}), node_id) 861 {'user': user_jid_s, 'node': node_id, 'message': failure.getErrorMessage()}), node_id)
861 deletions.append(d) 862 deletions.append(d)
862 return defer.DeferredList(deletions) 863 return defer.DeferredList(deletions)
863 864
864 return self._initialise(profile_key).addCallback(initialised) 865 return self._initialise(profile_key).addCallback(initialised)