Add IQ and Gateway module
This commit is contained in:
		
							parent
							
								
									d93fe8b1ea
								
							
						
					
					
						commit
						9ae6654dd3
					
				
					 10 changed files with 204 additions and 159 deletions
				
			
		| 
						 | 
					@ -367,12 +367,6 @@ class CommonConnection:
 | 
				
			||||||
                                    additional_data=obj.additional_data,
 | 
					                                    additional_data=obj.additional_data,
 | 
				
			||||||
                                    stanza_id=obj.stanza_id)
 | 
					                                    stanza_id=obj.stanza_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def unsubscribe_agent(self, agent):
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        To be implemented by derived classes
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        raise NotImplementedError
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def update_contact(self, jid, name, groups):
 | 
					    def update_contact(self, jid, name, groups):
 | 
				
			||||||
        if self.connection:
 | 
					        if self.connection:
 | 
				
			||||||
            self.getRoster().set_item(jid=jid, name=name, groups=groups)
 | 
					            self.getRoster().set_item(jid=jid, name=name, groups=groups)
 | 
				
			||||||
| 
						 | 
					@ -1602,17 +1596,6 @@ class Connection(CommonConnection, ConnectionHandlers):
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        self.connection.send(stanza)
 | 
					        self.connection.send(stanza)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def unsubscribe_agent(self, agent):
 | 
					 | 
				
			||||||
        if not app.account_is_connected(self.name):
 | 
					 | 
				
			||||||
            return
 | 
					 | 
				
			||||||
        iq = nbxmpp.Iq('set', nbxmpp.NS_REGISTER, to=agent)
 | 
					 | 
				
			||||||
        iq.setQuery().setTag('remove')
 | 
					 | 
				
			||||||
        id_ = self.connection.getAnID()
 | 
					 | 
				
			||||||
        iq.setID(id_)
 | 
					 | 
				
			||||||
        self.awaiting_answers[id_] = (AGENT_REMOVED, agent)
 | 
					 | 
				
			||||||
        self.connection.send(iq)
 | 
					 | 
				
			||||||
        self.getRoster().del_item(agent)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def send_new_account_infos(self, form, is_form):
 | 
					    def send_new_account_infos(self, form, is_form):
 | 
				
			||||||
        if is_form:
 | 
					        if is_form:
 | 
				
			||||||
            # Get username and password and put them in new_account_info
 | 
					            # Get username and password and put them in new_account_info
 | 
				
			||||||
| 
						 | 
					@ -1656,20 +1639,6 @@ class Connection(CommonConnection, ConnectionHandlers):
 | 
				
			||||||
        self.connection = con
 | 
					        self.connection = con
 | 
				
			||||||
        nbxmpp.features_nb.getRegInfo(con, self._hostname)
 | 
					        nbxmpp.features_nb.getRegInfo(con, self._hostname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def request_gateway_prompt(self, jid, prompt=None):
 | 
					 | 
				
			||||||
        def _on_prompt_result(resp):
 | 
					 | 
				
			||||||
            app.nec.push_incoming_event(GatewayPromptReceivedEvent(None,
 | 
					 | 
				
			||||||
                conn=self, stanza=resp))
 | 
					 | 
				
			||||||
        if prompt:
 | 
					 | 
				
			||||||
            typ_ = 'set'
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            typ_ = 'get'
 | 
					 | 
				
			||||||
        iq = nbxmpp.Iq(typ=typ_, to=jid)
 | 
					 | 
				
			||||||
        query = iq.addChild(name='query', namespace=nbxmpp.NS_GATEWAY)
 | 
					 | 
				
			||||||
        if prompt:
 | 
					 | 
				
			||||||
            query.setTagData('prompt', prompt)
 | 
					 | 
				
			||||||
        self.connection.SendAndCallForResponse(iq, _on_prompt_result)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def getRoster(self):
 | 
					    def getRoster(self):
 | 
				
			||||||
        return self.get_module('Roster')
 | 
					        return self.get_module('Roster')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,25 +38,15 @@ from gajim.common.caps_cache import muc_caps_cache
 | 
				
			||||||
from gajim.common.connection_handlers_events import *
 | 
					from gajim.common.connection_handlers_events import *
 | 
				
			||||||
from gajim.common.const import KindConstant
 | 
					from gajim.common.const import KindConstant
 | 
				
			||||||
from gajim.common.jingle import ConnectionJingle
 | 
					from gajim.common.jingle import ConnectionJingle
 | 
				
			||||||
from gajim.common.nec import NetworkEvent
 | 
					 | 
				
			||||||
from gajim.common.protocol.bytestream import ConnectionSocks5Bytestream
 | 
					from gajim.common.protocol.bytestream import ConnectionSocks5Bytestream
 | 
				
			||||||
from gajim.common.protocol.bytestream import ConnectionIBBytestream
 | 
					from gajim.common.protocol.bytestream import ConnectionIBBytestream
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log = logging.getLogger('gajim.c.connection_handlers')
 | 
					log = logging.getLogger('gajim.c.connection_handlers')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# kind of events we can wait for an answer
 | 
					 | 
				
			||||||
AGENT_REMOVED = 'agent_removed'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# basic connection handlers used here and in zeroconf
 | 
					# basic connection handlers used here and in zeroconf
 | 
				
			||||||
class ConnectionHandlersBase:
 | 
					class ConnectionHandlersBase:
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        # List of IDs we are waiting answers for {id: (type_of_request, data), }
 | 
					 | 
				
			||||||
        self.awaiting_answers = {}
 | 
					 | 
				
			||||||
        # List of IDs that will produce a timeout is answer doesn't arrive
 | 
					 | 
				
			||||||
        # {time_of_the_timeout: (id, message to send to gui), }
 | 
					 | 
				
			||||||
        self.awaiting_timeouts = {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # keep track of sessions this connection has with other JIDs
 | 
					        # keep track of sessions this connection has with other JIDs
 | 
				
			||||||
        self.sessions = {}
 | 
					        self.sessions = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -291,35 +281,6 @@ class ConnectionHandlers(ConnectionSocks5Bytestream,
 | 
				
			||||||
        app.ged.remove_event_handler('agent-removed', ged.CORE,
 | 
					        app.ged.remove_event_handler('agent-removed', ged.CORE,
 | 
				
			||||||
            self._nec_agent_removed)
 | 
					            self._nec_agent_removed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _ErrorCB(self, con, iq_obj):
 | 
					 | 
				
			||||||
        log.debug('ErrorCB')
 | 
					 | 
				
			||||||
        app.nec.push_incoming_event(IqErrorReceivedEvent(None, conn=self,
 | 
					 | 
				
			||||||
            stanza=iq_obj))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _IqCB(self, con, iq_obj, properties):
 | 
					 | 
				
			||||||
        id_ = iq_obj.getID()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        app.nec.push_incoming_event(NetworkEvent('raw-iq-received',
 | 
					 | 
				
			||||||
            conn=self, stanza=iq_obj))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Check if we were waiting a timeout for this id
 | 
					 | 
				
			||||||
        found_tim = None
 | 
					 | 
				
			||||||
        for tim in self.awaiting_timeouts:
 | 
					 | 
				
			||||||
            if id_ == self.awaiting_timeouts[tim][0]:
 | 
					 | 
				
			||||||
                found_tim = tim
 | 
					 | 
				
			||||||
                break
 | 
					 | 
				
			||||||
        if found_tim:
 | 
					 | 
				
			||||||
            del self.awaiting_timeouts[found_tim]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if id_ not in self.awaiting_answers:
 | 
					 | 
				
			||||||
            return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.awaiting_answers[id_][0] == AGENT_REMOVED:
 | 
					 | 
				
			||||||
            jid = self.awaiting_answers[id_][1]
 | 
					 | 
				
			||||||
            app.nec.push_incoming_event(AgentRemovedEvent(None, conn=self,
 | 
					 | 
				
			||||||
                agent=jid))
 | 
					 | 
				
			||||||
            del self.awaiting_answers[id_]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _nec_agent_removed(self, obj):
 | 
					    def _nec_agent_removed(self, obj):
 | 
				
			||||||
        if obj.conn.name != self.name:
 | 
					        if obj.conn.name != self.name:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
| 
						 | 
					@ -445,8 +406,6 @@ class ConnectionHandlers(ConnectionSocks5Bytestream,
 | 
				
			||||||
        con.RegisterHandler('iq', self._JingleCB, 'result')
 | 
					        con.RegisterHandler('iq', self._JingleCB, 'result')
 | 
				
			||||||
        con.RegisterHandler('iq', self._JingleCB, 'error')
 | 
					        con.RegisterHandler('iq', self._JingleCB, 'error')
 | 
				
			||||||
        con.RegisterHandler('iq', self._JingleCB, 'set', nbxmpp.NS_JINGLE)
 | 
					        con.RegisterHandler('iq', self._JingleCB, 'set', nbxmpp.NS_JINGLE)
 | 
				
			||||||
        con.RegisterHandler('iq', self._ErrorCB, 'error')
 | 
					 | 
				
			||||||
        con.RegisterHandler('iq', self._IqCB)
 | 
					 | 
				
			||||||
        con.RegisterHandler('iq', self._ResultCB, 'result')
 | 
					        con.RegisterHandler('iq', self._ResultCB, 'result')
 | 
				
			||||||
        con.RegisterHandler('unknown', self._StreamCB,
 | 
					        con.RegisterHandler('unknown', self._StreamCB,
 | 
				
			||||||
            nbxmpp.NS_XMPP_STREAMS, xmlns=nbxmpp.NS_STREAMS)
 | 
					            nbxmpp.NS_XMPP_STREAMS, xmlns=nbxmpp.NS_STREAMS)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,16 +119,6 @@ class HelperEvent:
 | 
				
			||||||
            self.muc_pm = muc_user.getChildren() == []
 | 
					            self.muc_pm = muc_user.getChildren() == []
 | 
				
			||||||
        return self.muc_pm
 | 
					        return self.muc_pm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IqErrorReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
 | 
					 | 
				
			||||||
    name = 'iq-error-received'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def generate(self):
 | 
					 | 
				
			||||||
        self.get_id()
 | 
					 | 
				
			||||||
        self.get_jid_resource(check_fake_jid=True)
 | 
					 | 
				
			||||||
        self.errmsg = self.stanza.getErrorMsg()
 | 
					 | 
				
			||||||
        self.errcode = self.stanza.getErrorCode()
 | 
					 | 
				
			||||||
        return True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class StreamReceivedEvent(nec.NetworkIncomingEvent):
 | 
					class StreamReceivedEvent(nec.NetworkIncomingEvent):
 | 
				
			||||||
    name = 'stream-received'
 | 
					    name = 'stream-received'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -266,16 +256,6 @@ class StanzaReceivedEvent(nec.NetworkIncomingEvent):
 | 
				
			||||||
class StanzaSentEvent(nec.NetworkIncomingEvent):
 | 
					class StanzaSentEvent(nec.NetworkIncomingEvent):
 | 
				
			||||||
    name = 'stanza-sent'
 | 
					    name = 'stanza-sent'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AgentRemovedEvent(nec.NetworkIncomingEvent):
 | 
					 | 
				
			||||||
    name = 'agent-removed'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def generate(self):
 | 
					 | 
				
			||||||
        self.jid_list = []
 | 
					 | 
				
			||||||
        for jid in app.contacts.get_jid_list(self.conn.name):
 | 
					 | 
				
			||||||
            if jid.endswith('@' + self.agent):
 | 
					 | 
				
			||||||
                self.jid_list.append(jid)
 | 
					 | 
				
			||||||
        return True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class BadGPGPassphraseEvent(nec.NetworkIncomingEvent):
 | 
					class BadGPGPassphraseEvent(nec.NetworkIncomingEvent):
 | 
				
			||||||
    name = 'bad-gpg-passphrase'
 | 
					    name = 'bad-gpg-passphrase'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -479,22 +459,6 @@ class FileTransferCompletedEvent(nec.NetworkIncomingEvent):
 | 
				
			||||||
        self.jid = app.get_jid_without_resource(jid)
 | 
					        self.jid = app.get_jid_without_resource(jid)
 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GatewayPromptReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
 | 
					 | 
				
			||||||
    name = 'gateway-prompt-received'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def generate(self):
 | 
					 | 
				
			||||||
        self.get_jid_resource()
 | 
					 | 
				
			||||||
        query = self.stanza.getTag('query')
 | 
					 | 
				
			||||||
        if query:
 | 
					 | 
				
			||||||
            self.desc = query.getTagData('desc')
 | 
					 | 
				
			||||||
            self.prompt = query.getTagData('prompt')
 | 
					 | 
				
			||||||
            self.prompt_jid = query.getTagData('jid')
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            self.desc = None
 | 
					 | 
				
			||||||
            self.prompt = None
 | 
					 | 
				
			||||||
            self.prompt_jid = None
 | 
					 | 
				
			||||||
        return True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class NotificationEvent(nec.NetworkIncomingEvent):
 | 
					class NotificationEvent(nec.NetworkIncomingEvent):
 | 
				
			||||||
    name = 'notification'
 | 
					    name = 'notification'
 | 
				
			||||||
    base_network_events = ['decrypted-message-received',
 | 
					    base_network_events = ['decrypted-message-received',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,8 @@ from gajim.common.types import ConnectionT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log = logging.getLogger('gajim.c.m')
 | 
					log = logging.getLogger('gajim.c.m')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ZEROCONF_MODULES = ['adhoc_commands',
 | 
					ZEROCONF_MODULES = ['iq',
 | 
				
			||||||
 | 
					                    'adhoc_commands',
 | 
				
			||||||
                    'receipts',
 | 
					                    'receipts',
 | 
				
			||||||
                    'discovery',
 | 
					                    'discovery',
 | 
				
			||||||
                    'chatstates']
 | 
					                    'chatstates']
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										95
									
								
								gajim/common/modules/gateway.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								gajim/common/modules/gateway.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,95 @@
 | 
				
			||||||
 | 
					# This file is part of Gajim.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Gajim is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published
 | 
				
			||||||
 | 
					# by the Free Software Foundation; version 3 only.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Gajim 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 General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with Gajim.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# XEP-0100: Gateway Interaction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import nbxmpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from gajim.common import app
 | 
				
			||||||
 | 
					from gajim.common.nec import NetworkEvent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					log = logging.getLogger('gajim.c.m.gateway')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Gateway:
 | 
				
			||||||
 | 
					    def __init__(self, con):
 | 
				
			||||||
 | 
					        self._con = con
 | 
				
			||||||
 | 
					        self._account = con.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.handlers = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def unsubscribe(self, agent):
 | 
				
			||||||
 | 
					        if not app.account_is_connected(self._account):
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        iq = nbxmpp.Iq('set', nbxmpp.NS_REGISTER, to=agent)
 | 
				
			||||||
 | 
					        iq.setQuery().setTag('remove')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._con.connection.SendAndCallForResponse(
 | 
				
			||||||
 | 
					            iq, self._on_unsubscribe_result)
 | 
				
			||||||
 | 
					        self._con.getRoster().del_item(agent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _on_unsubscribe_result(self, stanza):
 | 
				
			||||||
 | 
					        if not nbxmpp.isResultNode(stanza):
 | 
				
			||||||
 | 
					            log.info('Error: %s', stanza.getError())
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        agent = stanza.getFrom().getBare()
 | 
				
			||||||
 | 
					        jid_list = []
 | 
				
			||||||
 | 
					        for jid in app.contacts.get_jid_list(self._account):
 | 
				
			||||||
 | 
					            if jid.endswith('@' + agent):
 | 
				
			||||||
 | 
					                jid_list.append(jid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        app.nec.push_incoming_event(
 | 
				
			||||||
 | 
					            NetworkEvent('agent-removed',
 | 
				
			||||||
 | 
					                         conn=self._con,
 | 
				
			||||||
 | 
					                         agent=agent,
 | 
				
			||||||
 | 
					                         jid_list=jid_list))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def request_gateway_prompt(self, jid, prompt=None):
 | 
				
			||||||
 | 
					        typ_ = 'get'
 | 
				
			||||||
 | 
					        if prompt:
 | 
				
			||||||
 | 
					            typ_ = 'set'
 | 
				
			||||||
 | 
					        iq = nbxmpp.Iq(typ=typ_, to=jid)
 | 
				
			||||||
 | 
					        query = iq.addChild(name='query', namespace=nbxmpp.NS_GATEWAY)
 | 
				
			||||||
 | 
					        if prompt:
 | 
				
			||||||
 | 
					            query.setTagData('prompt', prompt)
 | 
				
			||||||
 | 
					        self._con.connection.SendAndCallForResponse(iq, self._on_prompt_result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _on_prompt_result(self, stanza):
 | 
				
			||||||
 | 
					        jid = str(stanza.getFrom())
 | 
				
			||||||
 | 
					        fjid = stanza.getFrom().getBare()
 | 
				
			||||||
 | 
					        resource = stanza.getFrom().getResource()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        query = stanza.getTag('query')
 | 
				
			||||||
 | 
					        if query is not None:
 | 
				
			||||||
 | 
					            desc = query.getTagData('desc')
 | 
				
			||||||
 | 
					            prompt = query.getTagData('prompt')
 | 
				
			||||||
 | 
					            prompt_jid = query.getTagData('jid')
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            desc = None
 | 
				
			||||||
 | 
					            prompt = None
 | 
				
			||||||
 | 
					            prompt_jid = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        app.nec.push_incoming_event(
 | 
				
			||||||
 | 
					            NetworkEvent('gateway-prompt-received',
 | 
				
			||||||
 | 
					                         conn=self._con,
 | 
				
			||||||
 | 
					                         fjid=fjid,
 | 
				
			||||||
 | 
					                         jid=jid,
 | 
				
			||||||
 | 
					                         resource=resource,
 | 
				
			||||||
 | 
					                         desc=desc,
 | 
				
			||||||
 | 
					                         prompt=prompt,
 | 
				
			||||||
 | 
					                         prompt_jid=prompt_jid,
 | 
				
			||||||
 | 
					                         stanza=stanza))
 | 
				
			||||||
							
								
								
									
										87
									
								
								gajim/common/modules/iq.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								gajim/common/modules/iq.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,87 @@
 | 
				
			||||||
 | 
					# This file is part of Gajim.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Gajim is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published
 | 
				
			||||||
 | 
					# by the Free Software Foundation; version 3 only.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Gajim 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 General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Iq handler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import nbxmpp
 | 
				
			||||||
 | 
					from nbxmpp.const import Error
 | 
				
			||||||
 | 
					from nbxmpp.structs import StanzaHandler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from gajim.common import app
 | 
				
			||||||
 | 
					from gajim.common.nec import NetworkEvent
 | 
				
			||||||
 | 
					from gajim.common.file_props import FilesProp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					log = logging.getLogger('gajim.c.m.iq')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Iq:
 | 
				
			||||||
 | 
					    def __init__(self, con):
 | 
				
			||||||
 | 
					        self._con = con
 | 
				
			||||||
 | 
					        self._account = con.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.handlers = [
 | 
				
			||||||
 | 
					            StanzaHandler(name='iq',
 | 
				
			||||||
 | 
					                          callback=self._iq_error_received,
 | 
				
			||||||
 | 
					                          typ='error',
 | 
				
			||||||
 | 
					                          priority=51),
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _iq_error_received(self, _con, _stanza, properties):
 | 
				
			||||||
 | 
					        log.info('Error: %s', properties.error)
 | 
				
			||||||
 | 
					        if properties.error.type in (Error.JID_MALFORMED,
 | 
				
			||||||
 | 
					                                     Error.FORBIDDEN,
 | 
				
			||||||
 | 
					                                     Error.NOT_ACCEPTABLE):
 | 
				
			||||||
 | 
					            sid = self._get_sid(properties.id)
 | 
				
			||||||
 | 
					            file_props = FilesProp.getFileProp(self._account, sid)
 | 
				
			||||||
 | 
					            if file_props:
 | 
				
			||||||
 | 
					                if properties.error.type == Error.JID_MALFORMED:
 | 
				
			||||||
 | 
					                    file_props.error = -3
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    file_props.error = -4
 | 
				
			||||||
 | 
					                app.nec.push_incoming_event(
 | 
				
			||||||
 | 
					                    NetworkEvent('file-request-error',
 | 
				
			||||||
 | 
					                                 conn=self._con,
 | 
				
			||||||
 | 
					                                 jid=properties.jid.getBare(),
 | 
				
			||||||
 | 
					                                 file_props=file_props,
 | 
				
			||||||
 | 
					                                 error_msg=properties.error.message))
 | 
				
			||||||
 | 
					                self._con.disconnect_transfer(file_props)
 | 
				
			||||||
 | 
					                raise nbxmpp.NodeProcessed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if properties.error.type == Error.ITEM_NOT_FOUND:
 | 
				
			||||||
 | 
					            sid = self._get_sid(properties.id)
 | 
				
			||||||
 | 
					            file_props = FilesProp.getFileProp(self._account, sid)
 | 
				
			||||||
 | 
					            if file_props:
 | 
				
			||||||
 | 
					                app.nec.push_incoming_event(
 | 
				
			||||||
 | 
					                    NetworkEvent('file-send-error',
 | 
				
			||||||
 | 
					                                 account=self._account,
 | 
				
			||||||
 | 
					                                 jid=str(properties.jid),
 | 
				
			||||||
 | 
					                                 file_props=file_props))
 | 
				
			||||||
 | 
					                self._con.disconnect_transfer(file_props)
 | 
				
			||||||
 | 
					                raise nbxmpp.NodeProcessed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        app.nec.push_incoming_event(
 | 
				
			||||||
 | 
					            NetworkEvent('iq-error-received',
 | 
				
			||||||
 | 
					                         account=self._account,
 | 
				
			||||||
 | 
					                         properties=properties))
 | 
				
			||||||
 | 
					        raise nbxmpp.NodeProcessed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @staticmethod
 | 
				
			||||||
 | 
					    def _get_sid(id_):
 | 
				
			||||||
 | 
					        sid = id_
 | 
				
			||||||
 | 
					        if len(id_) > 3 and id_[2] == '_':
 | 
				
			||||||
 | 
					            sid = id_[3:]
 | 
				
			||||||
 | 
					        return sid
 | 
				
			||||||
| 
						 | 
					@ -44,8 +44,6 @@ log = logging.getLogger('gajim.c.z.connection_handlers_zeroconf')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
 | 
					STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
 | 
				
			||||||
               'invisible']
 | 
					               'invisible']
 | 
				
			||||||
# kind of events we can wait for an answer
 | 
					 | 
				
			||||||
AGENT_REMOVED = 'agent_removed'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ZeroconfMessageReceivedEvent(NetworkIncomingEvent):
 | 
					class ZeroconfMessageReceivedEvent(NetworkIncomingEvent):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -115,7 +115,8 @@ class AddNewContactWindow(Gtk.ApplicationWindow):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if account:
 | 
					            if account:
 | 
				
			||||||
                for service in self.agents[type_]:
 | 
					                for service in self.agents[type_]:
 | 
				
			||||||
                    app.connections[account].request_gateway_prompt(service)
 | 
					                    con = app.connections[account]
 | 
				
			||||||
 | 
					                    con.get_module('Gateway').request_gateway_prompt(service)
 | 
				
			||||||
        self.protocol_combobox.set_active(0)
 | 
					        self.protocol_combobox.set_active(0)
 | 
				
			||||||
        self.auto_authorize_checkbutton.show()
 | 
					        self.auto_authorize_checkbutton.show()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -246,8 +247,8 @@ class AddNewContactWindow(Gtk.ApplicationWindow):
 | 
				
			||||||
            transport = model[row][0]
 | 
					            transport = model[row][0]
 | 
				
			||||||
            if self.account and not self.jid_escaped:
 | 
					            if self.account and not self.jid_escaped:
 | 
				
			||||||
                self.adding_jid = (jid, transport, type_)
 | 
					                self.adding_jid = (jid, transport, type_)
 | 
				
			||||||
                app.connections[self.account].request_gateway_prompt(
 | 
					                con = app.connections[self.account]
 | 
				
			||||||
                    transport, jid)
 | 
					                con.get_module('Gateway').request_gateway_prompt(transport, jid)
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                jid = jid.replace('@', '%') + '@' + transport
 | 
					                jid = jid.replace('@', '%') + '@' + transport
 | 
				
			||||||
                self._add_jid(jid, type_)
 | 
					                self._add_jid(jid, type_)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@ from gajim.common import passwords
 | 
				
			||||||
from gajim.common import logging_helpers
 | 
					from gajim.common import logging_helpers
 | 
				
			||||||
from gajim.common.i18n import _
 | 
					from gajim.common.i18n import _
 | 
				
			||||||
from gajim.common.connection_handlers_events import (
 | 
					from gajim.common.connection_handlers_events import (
 | 
				
			||||||
    OurShowEvent, FileRequestErrorEvent, FileTransferCompletedEvent,
 | 
					    OurShowEvent, FileTransferCompletedEvent,
 | 
				
			||||||
    UpdateRosterAvatarEvent, UpdateGCAvatarEvent, UpdateRoomAvatarEvent)
 | 
					    UpdateRosterAvatarEvent, UpdateGCAvatarEvent, UpdateRoomAvatarEvent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from gajim.common.modules.httpupload import HTTPUploadProgressEvent
 | 
					from gajim.common.modules.httpupload import HTTPUploadProgressEvent
 | 
				
			||||||
| 
						 | 
					@ -199,38 +199,11 @@ class Interface:
 | 
				
			||||||
            'id': obj.iq_id}, sec_msg, on_response_yes=(on_yes, obj),
 | 
					            'id': obj.iq_id}, sec_msg, on_response_yes=(on_yes, obj),
 | 
				
			||||||
            on_response_no=(response, obj, 'no'))
 | 
					            on_response_no=(response, obj, 'no'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_event_iq_error(self, obj):
 | 
					    def handle_event_iq_error(self, event):
 | 
				
			||||||
        #('ERROR_ANSWER', account, (id_, fjid, errmsg, errcode))
 | 
					        ctrl = self.msg_win_mgr.get_control(event.properties.jid.getBare(),
 | 
				
			||||||
        if str(obj.errcode) in ('400', '403', '406') and obj.id_:
 | 
					                                            event.account)
 | 
				
			||||||
            # show the error dialog
 | 
					 | 
				
			||||||
            sid = obj.id_
 | 
					 | 
				
			||||||
            if len(obj.id_) > 3 and obj.id_[2] == '_':
 | 
					 | 
				
			||||||
                sid = obj.id_[3:]
 | 
					 | 
				
			||||||
            file_props = FilesProp.getFileProp(obj.conn.name, sid)
 | 
					 | 
				
			||||||
            if file_props:
 | 
					 | 
				
			||||||
                if str(obj.errcode) == '400':
 | 
					 | 
				
			||||||
                    file_props.error = -3
 | 
					 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    file_props.error = -4
 | 
					 | 
				
			||||||
                app.nec.push_incoming_event(FileRequestErrorEvent(None,
 | 
					 | 
				
			||||||
                    conn=obj.conn, jid=obj.jid, file_props=file_props,
 | 
					 | 
				
			||||||
                    error_msg=obj.errmsg))
 | 
					 | 
				
			||||||
                obj.conn.disconnect_transfer(file_props)
 | 
					 | 
				
			||||||
                return
 | 
					 | 
				
			||||||
        elif str(obj.errcode) == '404':
 | 
					 | 
				
			||||||
            sid = obj.id_
 | 
					 | 
				
			||||||
            if len(obj.id_) > 3 and obj.id_[2] == '_':
 | 
					 | 
				
			||||||
                sid = obj.id_[3:]
 | 
					 | 
				
			||||||
            file_props = FilesProp.getFileProp(obj.conn.name, sid)
 | 
					 | 
				
			||||||
            if file_props:
 | 
					 | 
				
			||||||
                self.handle_event_file_send_error(obj.conn.name, (obj.fjid,
 | 
					 | 
				
			||||||
                    file_props))
 | 
					 | 
				
			||||||
                obj.conn.disconnect_transfer(file_props)
 | 
					 | 
				
			||||||
                return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ctrl = self.msg_win_mgr.get_control(obj.fjid, obj.conn.name)
 | 
					 | 
				
			||||||
        if ctrl and ctrl.type_id == message_control.TYPE_GC:
 | 
					        if ctrl and ctrl.type_id == message_control.TYPE_GC:
 | 
				
			||||||
            ctrl.print_conversation('Error %s: %s' % (obj.errcode, obj.errmsg))
 | 
					            ctrl.print_conversation('Error: %s' % event.properties.error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					    @staticmethod
 | 
				
			||||||
    def handle_event_connection_lost(obj):
 | 
					    def handle_event_connection_lost(obj):
 | 
				
			||||||
| 
						 | 
					@ -739,25 +712,23 @@ class Interface:
 | 
				
			||||||
    def handle_event_bookmarks(self, obj):
 | 
					    def handle_event_bookmarks(self, obj):
 | 
				
			||||||
        gui_menu_builder.build_bookmark_menu(obj.account)
 | 
					        gui_menu_builder.build_bookmark_menu(obj.account)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_event_file_send_error(self, account, array):
 | 
					    def handle_event_file_send_error(self, event):
 | 
				
			||||||
        jid = array[0]
 | 
					 | 
				
			||||||
        file_props = array[1]
 | 
					 | 
				
			||||||
        ft = self.instances['file_transfers']
 | 
					        ft = self.instances['file_transfers']
 | 
				
			||||||
        ft.set_status(file_props, 'stop')
 | 
					        ft.set_status(event.file_props, 'stop')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if helpers.allow_popup_window(account):
 | 
					        if helpers.allow_popup_window(event.account):
 | 
				
			||||||
            ft.show_send_error(file_props)
 | 
					            ft.show_send_error(event.file_props)
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        event = events.FileSendErrorEvent(file_props)
 | 
					        event = events.FileSendErrorEvent(event.file_props)
 | 
				
			||||||
        self.add_event(account, jid, event)
 | 
					        self.add_event(event.account, event.jid, event)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if helpers.allow_showing_notification(account):
 | 
					        if helpers.allow_showing_notification(event.account):
 | 
				
			||||||
            event_type = _('File Transfer Error')
 | 
					            event_type = _('File Transfer Error')
 | 
				
			||||||
            app.notification.popup(
 | 
					            app.notification.popup(
 | 
				
			||||||
                event_type, jid, account,
 | 
					                event_type, event.jid, event.account,
 | 
				
			||||||
                'file-send-error', 'gajim-ft_error',
 | 
					                'file-send-error', 'gajim-ft_error',
 | 
				
			||||||
                event_type, file_props.name)
 | 
					                event_type, event.file_props.name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_event_file_request_error(self, obj):
 | 
					    def handle_event_file_request_error(self, obj):
 | 
				
			||||||
        # ('FILE_REQUEST_ERROR', account, (jid, file_props, error_msg))
 | 
					        # ('FILE_REQUEST_ERROR', account, (jid, file_props, error_msg))
 | 
				
			||||||
| 
						 | 
					@ -1383,7 +1354,7 @@ class Interface:
 | 
				
			||||||
    def create_core_handlers_list(self):
 | 
					    def create_core_handlers_list(self):
 | 
				
			||||||
        self.handlers = {
 | 
					        self.handlers = {
 | 
				
			||||||
            'DB_ERROR': [self.handle_event_db_error],
 | 
					            'DB_ERROR': [self.handle_event_db_error],
 | 
				
			||||||
            'FILE_SEND_ERROR': [self.handle_event_file_send_error],
 | 
					            'file-send-error': [self.handle_event_file_send_error],
 | 
				
			||||||
            'pep-received': [self.handle_atom_entry],
 | 
					            'pep-received': [self.handle_atom_entry],
 | 
				
			||||||
            'bad-gpg-passphrase': [self.handle_event_bad_gpg_passphrase],
 | 
					            'bad-gpg-passphrase': [self.handle_event_bad_gpg_passphrase],
 | 
				
			||||||
            'bookmarks-received': [self.handle_event_bookmarks],
 | 
					            'bookmarks-received': [self.handle_event_bookmarks],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2774,7 +2774,7 @@ class RosterWindow:
 | 
				
			||||||
        def remove(list_):
 | 
					        def remove(list_):
 | 
				
			||||||
            for (contact, account) in list_:
 | 
					            for (contact, account) in list_:
 | 
				
			||||||
                full_jid = contact.get_full_jid()
 | 
					                full_jid = contact.get_full_jid()
 | 
				
			||||||
                app.connections[account].unsubscribe_agent(full_jid)
 | 
					                app.connections[account].get_module('Gateway').unsubscribe(full_jid)
 | 
				
			||||||
                # remove transport from treeview
 | 
					                # remove transport from treeview
 | 
				
			||||||
                self.remove_contact(contact.jid, account, backend=True)
 | 
					                self.remove_contact(contact.jid, account, backend=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue