1274
+ − 1 #!/usr/bin/python
+ − 2 # -*- coding: utf-8 -*-
+ − 3
+ − 4 # SAT plugin for Stanza Forwarding (XEP-0297)
1396
+ − 5 # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Jérôme Poisson (goffi@goffi.org)
+ − 6 # Copyright (C) 2013, 2014, 2015 Adrien Cossa (souliane@mailoo.org)
1274
+ − 7
+ − 8 # This program is free software: you can redistribute it and/or modify
+ − 9 # it under the terms of the GNU Affero General Public License as published by
+ − 10 # the Free Software Foundation, either version 3 of the License, or
+ − 11 # (at your option) any later version.
+ − 12
+ − 13 # This program is distributed in the hope that it will be useful,
+ − 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ − 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ − 16 # GNU Affero General Public License for more details.
+ − 17
+ − 18 # You should have received a copy of the GNU Affero General Public License
+ − 19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
+ − 20
+ − 21 from sat.core.constants import Const as C
+ − 22 from sat.core.i18n import _
+ − 23 from sat.core.log import getLogger
+ − 24 log = getLogger ( __name__ )
+ − 25
+ − 26 from wokkel import disco , iwokkel
+ − 27 try :
+ − 28 from twisted.words.protocols.xmlstream import XMPPHandler
+ − 29 except ImportError :
+ − 30 from wokkel.subprotocols import XMPPHandler
+ − 31 from zope.interface import implements
+ − 32
+ − 33 from twisted.words.xish import domish
+ − 34
+ − 35 NS_SF = 'urn:xmpp:forward:0'
+ − 36
+ − 37 PLUGIN_INFO = {
+ − 38 "name" : "Stanza Forwarding" ,
+ − 39 "import_name" : "XEP-0297" ,
+ − 40 "type" : "XEP" ,
+ − 41 "protocols" : [ "XEP-0297" ],
+ − 42 "main" : "XEP_0297" ,
+ − 43 "handler" : "yes" ,
+ − 44 "description" : _ ( """Implementation of Stanza Forwarding""" )
+ − 45 }
+ − 46
+ − 47
+ − 48 class XEP_0297 ( object ):
+ − 49
+ − 50 def __init__ ( self , host ):
+ − 51 log . info ( _ ( "Stanza Forwarding plugin initialization" ))
+ − 52 self . host = host
+ − 53
+ − 54 def getHandler ( self , profile ):
+ − 55 return XEP_0297_handler ( self , profile )
+ − 56
+ − 57 @classmethod
+ − 58 def updateUri ( cls , element , uri ):
+ − 59 """Update recursively the element URI.
+ − 60
+ − 61 @param element (domish.Element): element to update
+ − 62 @param uri (unicode): new URI
+ − 63 """
+ − 64 # XXX: we need this because changing the URI of an existing element
+ − 65 # containing children doesn't update the children's blank URI.
+ − 66 element . uri = uri
+ − 67 element . defaultUri = uri
+ − 68 for child in element . children :
+ − 69 if isinstance ( child , domish . Element ) and not child . uri :
+ − 70 XEP_0297 . updateUri ( child , uri )
+ − 71
+ − 72 def forward ( self , stanza , to_jid , stamp , body = '' , profile_key = C . PROF_KEY_NONE ):
+ − 73 """Forward a message to the given JID.
+ − 74
+ − 75 @param stanza (domish.Element): original stanza to be forwarded.
+ − 76 @param to_jid (JID): recipient JID.
+ − 77 @param stamp (datetime): offset-aware timestamp of the original reception.
+ − 78 @param body (unicode): optional description.
+ − 79 @param profile_key (unicode): %(doc_profile_key)s
+ − 80 @return: a Deferred when the message has been sent
+ − 81 """
+ − 82 msg = domish . Element (( None , 'message' ))
+ − 83 msg [ 'to' ] = to_jid . full ()
+ − 84 msg [ 'type' ] = stanza [ 'type' ]
+ − 85
+ − 86 body_elt = domish . Element (( None , 'body' ))
+ − 87 if body :
+ − 88 body_elt . addContent ( body )
+ − 89
+ − 90 forwarded_elt = domish . Element (( NS_SF , 'forwarded' ))
+ − 91 delay_elt = self . host . plugins [ 'XEP-0203' ] . delay ( stamp )
+ − 92 forwarded_elt . addChild ( delay_elt )
+ − 93 if not stanza . uri : # None or ''
+ − 94 XEP_0297 . updateUri ( stanza , 'jabber:client' )
+ − 95 forwarded_elt . addChild ( stanza )
+ − 96
+ − 97 msg . addChild ( body_elt )
+ − 98 msg . addChild ( forwarded_elt )
+ − 99
+ − 100 client = self . host . getClient ( profile_key )
+ − 101 return client . xmlstream . send ( msg . toXml ())
+ − 102
+ − 103
+ − 104 class XEP_0297_handler ( XMPPHandler ):
+ − 105 implements ( iwokkel . IDisco )
+ − 106
+ − 107 def __init__ ( self , plugin_parent , profile ):
+ − 108 self . plugin_parent = plugin_parent
+ − 109 self . host = plugin_parent . host
+ − 110 self . profile = profile
+ − 111
+ − 112 def getDiscoInfo ( self , requestor , target , nodeIdentifier = '' ):
+ − 113 return [ disco . DiscoFeature ( NS_SF )]
+ − 114
+ − 115 def getDiscoItems ( self , requestor , target , nodeIdentifier = '' ):
+ − 116 return []