Mercurial > libervia-backend
view src/plugins/plugin_xep_0280.py @ 2105:c96fe007ca41
core(constants): added a constant for profile extension (PLUGIN_EXT):
this constant may be modified if needed, which is the case on Android (it's modified by Cagou service's main.py), so platform detection is not needed anymore in sat_main.py.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 25 Dec 2016 16:43:56 +0100 |
parents | ad88808591ef |
children | 7de291c3cd0c |
line wrap: on
line source
#!/usr/bin/env python2 # -*- coding: utf-8 -*- # SAT plugin for managing xep-0280 # Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org) # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from sat.core.i18n import _, D_ from sat.core.log import getLogger log = getLogger(__name__) from sat.core import exceptions from sat.core.constants import Const as C from sat.core.xmpp import SatMessageProtocol from twisted.words.protocols.jabber.error import StanzaError from twisted.internet import defer from wokkel import disco, iwokkel from zope.interface import implements try: from twisted.words.protocols.xmlstream import XMPPHandler except ImportError: from wokkel.subprotocols import XMPPHandler PARAM_CATEGORY = "Misc" PARAM_NAME = "carbon" PARAM_LABEL = D_(u"Message carbons") NS_CARBONS = 'urn:xmpp:carbons:2' PLUGIN_INFO = { "name": "XEP-0280 Plugin", "import_name": "XEP-0280", "type": "XEP", "protocols": ["XEP-0280"], "dependencies": [], "main": "XEP_0280", "handler": "yes", "description": _("""Implementation of Message Carbons""") } class XEP_0280(object): # TODO: param is only checked at profile connection # activate carbons on param change even after profile connection # TODO: chat state notifications are not handled yet (and potentially other XEPs?) params = """ <params> <individual> <category name="{category_name}" label="{category_label}"> <param name="{param_name}" label="{param_label}" value="true" type="bool" security="0" /> </category> </individual> </params> """.format( category_name = PARAM_CATEGORY, category_label = D_(PARAM_CATEGORY), param_name = PARAM_NAME, param_label = PARAM_LABEL, ) def __init__(self, host): log.info(_("Plugin XEP_0280 initialization")) self.host = host host.memory.updateParams(self.params) host.trigger.add("MessageReceived", self.messageReceivedTrigger, priority=1000) def getHandler(self, profile): return XEP_0280_handler() @defer.inlineCallbacks def profileConnected(self, profile): """activate message carbons on connection if possible and activated in config""" client = self.host.getClient(profile) activate = self.host.memory.getParamA(PARAM_NAME, PARAM_CATEGORY, profile_key=profile) if not activate: log.info(_(u"Not activating message carbons as requested in params")) return try: yield self.host.checkFeatures((NS_CARBONS,), profile=profile) except exceptions.FeatureNotFound: log.warning(_(u"server doesn't handle message carbons")) else: log.info(_(u"message carbons available, enabling it")) iq_elt = client.IQ() iq_elt.addElement((NS_CARBONS, 'enable')) try: yield iq_elt.send() except StanzaError as e: log.warning(u"Can't activate message carbons: {}".format(e)) else: log.info(_(u"message carbons activated")) def messageReceivedTrigger(self, client, message_elt, post_treat): """get message and handle it if carbons namespace is present""" carbons_elt = None for e in message_elt.elements(): if e.uri == NS_CARBONS: carbons_elt = e break if carbons_elt is None: # this is not a message carbons, # we continue normal behaviour return True if message_elt['from'] != client.jid.userhost(): log.warning(u"The message carbon received is not from our server, hack attempt?\n{xml}".format( xml = message_elt.toXml(), )) return forwarded_elt = next(carbons_elt.elements(C.NS_FORWARD, 'forwarded')) cc_message_elt = next(forwarded_elt.elements(C.NS_CLIENT, 'message')) if carbons_elt.name == 'received': # on receive we replace the wrapping message with the CCed one # and continue the normal behaviour message_elt['from'] = cc_message_elt['from'] del message_elt.children[:] for c in cc_message_elt.children: message_elt.addChild(c) return True elif carbons_elt.name == 'sent': # on send we parse the message and just add it to history # and send it to frontends (without normal sending treatments) mess_data = SatMessageProtocol.parseMessage(cc_message_elt, client) if not mess_data['message'] and not mess_data['subject']: return False self.host.messageAddToHistory(mess_data, client) self.host.messageSendToBridge(mess_data, client) else: log.warning(u"invalid message carbons received:\n{xml}".format( xml = message_elt.toXml())) return False class XEP_0280_handler(XMPPHandler): implements(iwokkel.IDisco) def getDiscoInfo(self, requestor, target, nodeIdentifier=''): return [disco.DiscoFeature(NS_CARBONS)] def getDiscoItems(self, requestor, target, nodeIdentifier=''): return []