Show
Ignore:
Timestamp:
05/17/08 04:23:46 (5 months ago)
Author:
bct
Message:

fixed link-local messaging (broken by session-centric) and removed a ton of duplicated/unused code

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/common/zeroconf/connection_handlers_zeroconf.py

    r9625 r9648  
    3636from common import gajim 
    3737from common.zeroconf import zeroconf 
     38 
    3839STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd', 
    3940        'invisible'] 
     
    4950        HAS_IDLE = False 
    5051 
    51 from common.stanza_session import EncryptedStanzaSession  
    52  
    53 class ConnectionVcard: 
    54         def __init__(self):  
    55                 self.vcard_sha = None  
    56                 self.vcard_shas = {} # sha of contacts  
    57                 self.room_jids = [] # list of gc jids so that vcard are saved in a folder 
    58  
    59         def add_sha(self, p, send_caps = True):  
    60                 pass  
    61          
     52from common import connection_handlers 
     53from session import ChatControlSession 
     54 
     55class ConnectionVcard(connection_handlers.ConnectionVcard): 
     56        def add_sha(self, p, send_caps = True): 
     57                pass 
     58 
    6259        def add_caps(self, p): 
    6360                pass 
    6461 
    65         def node_to_dict(self, node): 
    66                 dict = {} 
    67                  
    68                 for info in node.getChildren(): 
    69                         name = info.getName() 
    70                         if name in ('ADR', 'TEL', 'EMAIL'): # we can have several 
    71                                 if not dict.has_key(name): 
    72                                         dict[name] = [] 
    73                                 entry = {} 
    74                                 for c in info.getChildren(): 
    75                                          entry[c.getName()] = c.getData() 
    76                                 dict[name].append(entry) 
    77                         elif info.getChildren() == []: 
    78                                 dict[name] = info.getData() 
    79                         else: 
    80                                 dict[name] = {} 
    81                                 for c in info.getChildren(): 
    82                                          dict[name][c.getName()] = c.getData() 
    83                  
    84                 return dict 
    85  
    86         def save_vcard_to_hd(self, full_jid, card): 
    87                 jid, nick = gajim.get_room_and_nick_from_fjid(full_jid) 
    88                 puny_jid = helpers.sanitize_filename(jid) 
    89                 path = os.path.join(gajim.VCARD_PATH, puny_jid) 
    90                 if jid in self.room_jids or os.path.isdir(path): 
    91                         # remove room_jid file if needed 
    92                         if os.path.isfile(path): 
    93                                 os.remove(path) 
    94                         # create folder if needed 
    95                         if not os.path.isdir(path): 
    96                                 os.mkdir(path, 0700) 
    97                         puny_nick = helpers.sanitize_filename(nick) 
    98                         path_to_file = os.path.join(gajim.VCARD_PATH, puny_jid, puny_nick) 
    99                 else: 
    100                         path_to_file = path 
    101                 fil = open(path_to_file, 'w') 
    102                 fil.write(str(card)) 
    103                 fil.close() 
    104          
    105         def get_cached_vcard(self, fjid, is_fake_jid = False): 
    106                 '''return the vcard as a dict 
    107                 return {} if vcard was too old 
    108                 return None if we don't have cached vcard''' 
    109                 jid, nick = gajim.get_room_and_nick_from_fjid(fjid) 
    110                 puny_jid = helpers.sanitize_filename(jid) 
    111                 if is_fake_jid: 
    112                         puny_nick = helpers.sanitize_filename(nick) 
    113                         path_to_file = os.path.join(gajim.VCARD_PATH, puny_jid, puny_nick) 
    114                 else: 
    115                         path_to_file = os.path.join(gajim.VCARD_PATH, puny_jid) 
    116                 if not os.path.isfile(path_to_file): 
    117                         return None 
    118                 # We have the vcard cached 
    119                 f = open(path_to_file) 
    120                 c = f.read() 
    121                 f.close() 
    122                 card = common.xmpp.Node(node = c) 
    123                 vcard = self.node_to_dict(card) 
    124                 if vcard.has_key('PHOTO'): 
    125                         if not isinstance(vcard['PHOTO'], dict): 
    126                                 del vcard['PHOTO'] 
    127                         elif vcard['PHOTO'].has_key('SHA'): 
    128                                 cached_sha = vcard['PHOTO']['SHA'] 
    129                                 if self.vcard_shas.has_key(jid) and self.vcard_shas[jid] != \ 
    130                                         cached_sha: 
    131                                         # user change his vcard so don't use the cached one 
    132                                         return {} 
    133                 vcard['jid'] = jid 
    134                 vcard['resource'] = gajim.get_resource_from_jid(fjid) 
    135                 return vcard 
    136  
    13762        def request_vcard(self, jid = None, is_fake_jid = False): 
    13863                pass 
    139                  
     64 
    14065        def send_vcard(self, vcard): 
    14166                pass 
    14267 
    143 class ConnectionBytestream: 
    144         def __init__(self): 
    145                 self.files_props = {} 
    146          
    147         def is_transfer_stopped(self, file_props): 
    148                 if file_props.has_key('error') and file_props['error'] != 0: 
    149                         return True 
    150                 if file_props.has_key('completed') and file_props['completed']: 
    151                         return True 
    152                 if file_props.has_key('connected') and file_props['connected'] == False: 
    153                         return True 
    154                 if not file_props.has_key('stopped') or not file_props['stopped']: 
    155                         return False 
    156                 return True 
    157          
    158         def send_success_connect_reply(self, streamhost): 
    159                 ''' send reply to the initiator of FT that we 
    160                 made a connection 
    161                 ''' 
    162                 if streamhost is None: 
    163                         return None 
    164                 iq = common.xmpp.Iq(to = streamhost['initiator'], typ = 'result', 
    165                         frm = streamhost['target']) 
    166                 iq.setAttr('id', streamhost['id']) 
    167                 query = iq.setTag('query') 
    168                 query.setNamespace(common.xmpp.NS_BYTESTREAM) 
    169                 stream_tag = query.setTag('streamhost-used') 
    170                 stream_tag.setAttr('jid', streamhost['jid']) 
    171                 self.connection.send(iq) 
    172          
    173         def remove_transfers_for_contact(self, contact): 
    174                 ''' stop all active transfer for contact ''' 
    175                 for file_props in self.files_props.values(): 
    176                         if self.is_transfer_stopped(file_props): 
    177                                 continue 
    178                         receiver_jid = unicode(file_props['receiver']).split('/')[0] 
    179                         if contact.jid == receiver_jid: 
    180                                 file_props['error'] = -5 
    181                                 self.remove_transfer(file_props) 
    182                                 self.dispatch('FILE_REQUEST_ERROR', (contact.jid, file_props, '')) 
    183                         sender_jid = unicode(file_props['sender']) 
    184                         if contact.jid == sender_jid: 
    185                                 file_props['error'] = -3 
    186                                 self.remove_transfer(file_props) 
    187          
    188         def remove_all_transfers(self): 
    189                 ''' stops and removes all active connections from the socks5 pool ''' 
    190                 for file_props in self.files_props.values(): 
    191                         self.remove_transfer(file_props, remove_from_list = False) 
    192                 del(self.files_props) 
    193                 self.files_props = {} 
    194          
    195         def remove_transfer(self, file_props, remove_from_list = True): 
    196                 if file_props is None: 
    197                         return 
    198                 self.disconnect_transfer(file_props) 
    199                 sid = file_props['sid'] 
    200                 gajim.socks5queue.remove_file_props(self.name, sid) 
    201  
    202                 if remove_from_list: 
    203                         if self.files_props.has_key('sid'): 
    204                                 del(self.files_props['sid']) 
    205          
    206         def disconnect_transfer(self, file_props): 
    207                 if file_props is None: 
    208                         return 
    209                 if file_props.has_key('hash'): 
    210                         gajim.socks5queue.remove_sender(file_props['hash']) 
    211  
    212                 if file_props.has_key('streamhosts'): 
    213                         for host in file_props['streamhosts']: 
    214                                 if host.has_key('idx') and host['idx'] > 0: 
    215                                         gajim.socks5queue.remove_receiver(host['idx']) 
    216                                         gajim.socks5queue.remove_sender(host['idx']) 
    217          
     68class ConnectionBytestream(connection_handlers.ConnectionBytestream): 
    21869        def send_socks5_info(self, file_props, fast = True, receiver = None, 
    21970                sender = None): 
     
    275126                self.connection.send(iq) 
    276127 
    277         def send_file_rejection(self, file_props): 
    278                 ''' informs sender that we refuse to download the file ''' 
    279                 # user response to ConfirmationDialog may come after we've disconneted 
    280                 if not self.connection or self.connected < 2: 
    281                         return 
    282                 iq = common.xmpp.Protocol(name = 'iq', 
    283                         to = unicode(file_props['sender']), typ = 'error') 
    284                 iq.setAttr('id', file_props['request-id']) 
    285                 err = common.xmpp.ErrorNode(code = '403', typ = 'cancel', name = 
    286                         'forbidden', text = 'Offer Declined') 
    287                 iq.addChild(node=err) 
    288                 self.connection.send(iq) 
    289  
    290         def send_file_approval(self, file_props): 
    291                 ''' send iq, confirming that we want to download the file ''' 
    292                 # user response to ConfirmationDialog may come after we've disconneted 
    293                 if not self.connection or self.connected < 2: 
    294                         return 
    295                 iq = common.xmpp.Protocol(name = 'iq', 
    296                         to = unicode(file_props['sender']), typ = 'result') 
    297                 iq.setAttr('id', file_props['request-id']) 
    298                 si = iq.setTag('si') 
    299                 si.setNamespace(common.xmpp.NS_SI) 
    300                 if file_props.has_key('offset') and file_props['offset']: 
    301                         file_tag = si.setTag('file') 
    302                         file_tag.setNamespace(common.xmpp.NS_FILE) 
    303                         range_tag = file_tag.setTag('range') 
    304                         range_tag.setAttr('offset', file_props['offset']) 
    305                 feature = si.setTag('feature') 
    306                 feature.setNamespace(common.xmpp.NS_FEATURE) 
    307                 _feature = common.xmpp.DataForm(typ='submit') 
    308                 feature.addChild(node=_feature) 
    309                 field = _feature.setField('stream-method') 
    310                 field.delAttr('type') 
    311                 field.setValue(common.xmpp.NS_BYTESTREAM) 
    312                 self.connection.send(iq) 
    313  
    314128        def send_file_request(self, file_props): 
    315129                ''' send iq for new FT request ''' 
     
    319133                frm = our_jid 
    320134                file_props['sender'] = frm 
    321                 fjid = file_props['receiver'].jid  
     135                fjid = file_props['receiver'].jid 
    322136                iq = common.xmpp.Protocol(name = 'iq', to = fjid, 
    323137                        typ = 'set') 
     
    344158                field.addOption(common.xmpp.NS_BYTESTREAM) 
    345159                self.connection.send(iq) 
    346          
    347         def _result_socks5_sid(self, sid, hash_id): 
    348                 ''' store the result of sha message from auth. ''' 
    349                 if not self.files_props.has_key(sid): 
    350                         return 
    351                 file_props = self.files_props[sid] 
    352                 file_props['hash'] = hash_id 
    353                 return 
    354          
    355         def _connect_error(self, to, _id, sid, code = 404): 
    356                 ''' cb, when there is an error establishing BS connection, or  
    357                 when connection is rejected''' 
    358                 msg_dict = { 
    359                         404: 'Could not connect to given hosts', 
    360                         405: 'Cancel', 
    361                         406: 'Not acceptable', 
    362                 } 
    363                 msg = msg_dict[code] 
    364                 iq = None 
    365                 iq = common.xmpp.Protocol(name = 'iq', to = to, 
    366                         typ = 'error') 
    367                 iq.setAttr('id', _id) 
    368                 err = iq.setTag('error') 
    369                 err.setAttr('code', unicode(code)) 
    370                 err.setData(msg) 
    371                 self.connection.send(iq) 
    372                 if code == 404: 
    373                         file_props = gajim.socks5queue.get_file_props(self.name, sid) 
    374                         if file_props is not None: 
    375                                 self.disconnect_transfer(file_props) 
    376                                 file_props['error'] = -3 
    377                                 self.dispatch('FILE_REQUEST_ERROR', (to, file_props, msg)) 
    378  
    379         def _proxy_auth_ok(self, proxy): 
    380                 '''cb, called after authentication to proxy server ''' 
    381                 file_props = self.files_props[proxy['sid']] 
    382                 iq = common.xmpp.Protocol(name = 'iq', to = proxy['initiator'], 
    383                 typ = 'set') 
    384                 auth_id = "au_" + proxy['sid'] 
    385                 iq.setID(auth_id) 
    386                 query = iq.setTag('query') 
    387                 query.setNamespace(common.xmpp.NS_BYTESTREAM) 
    388                 query.setAttr('sid',  proxy['sid']) 
    389                 activate = query.setTag('activate') 
    390                 activate.setData(file_props['proxy_receiver']) 
    391                 iq.setID(auth_id) 
    392                 self.connection.send(iq) 
    393          
    394         # register xmpppy handlers for bytestream and FT stanzas 
    395         def _bytestreamErrorCB(self, con, iq_obj): 
    396                 gajim.log.debug('_bytestreamErrorCB') 
    397                 id = unicode(iq_obj.getAttr('id')) 
    398                 frm = unicode(iq_obj.getFrom()) 
    399                 query = iq_obj.getTag('query') 
    400                 gajim.proxy65_manager.error_cb(frm, query) 
    401                 jid = unicode(iq_obj.getFrom()) 
    402                 id = id[3:] 
    403                 if not self.files_props.has_key(id): 
    404                         return 
    405                 file_props = self.files_props[id] 
    406                 file_props['error'] = -4 
    407                 self.dispatch('FILE_REQUEST_ERROR', (jid, file_props, '')) 
    408                 raise common.xmpp.NodeProcessed 
    409          
     160 
    410161        def _bytestreamSetCB(self, con, iq_obj): 
    411162                gajim.log.debug('_bytestreamSetCB') 
     
    433184                                file_props = self.files_props[sid] 
    434185                                file_props['fast'] = streamhosts 
    435                                 if file_props['type'] == 's':  
     186                                if file_props['type'] == 's': 
    436187                                        if file_props.has_key('streamhosts'): 
    437188                                                file_props['streamhosts'].extend(streamhosts) 
     
    466217                                                gajim.socks5queue.activate_proxy(host['idx']) 
    467218                                                raise common.xmpp.NodeProcessed 
    468          
     219 
    469220        def _bytestreamResultCB(self, con, iq_obj): 
    470221                gajim.log.debug('_bytestreamResultCB') 
     
    473224                query = iq_obj.getTag('query') 
    474225                gajim.proxy65_manager.resolve_result(frm, query) 
    475                  
     226 
    476227                try: 
    477228                        streamhost =  query.getTag('streamhost-used') 
     
    532283                                        self._connect_error(frm, fasts[0]['id'], file_props['sid'], 
    533284                                                code = 406) 
    534                  
     285 
    535286                raise common.xmpp.NodeProcessed 
    536          
     287 
    537288        def _siResultCB(self, con, iq_obj): 
    538289                gajim.log.debug('_siResultCB') 
     
    572323                self.send_socks5_info(file_props, fast = True) 
    573324                raise common.xmpp.NodeProcessed 
    574          
     325 
    575326        def _siSetCB(self, con, iq_obj): 
    576327                gajim.log.debug('_siSetCB') 
     
    596347                        file_props['mime-type'] = mime_type 
    597348                our_jid = gajim.get_jid_from_account(self.name) 
    598                 file_props['receiver'] = our_jid  
     349                file_props['receiver'] = our_jid 
    599350                file_props['sender'] = unicode(iq_obj.getFrom()) 
    600351                file_props['request-id'] = unicode(iq_obj.getAttr('id')) 
     
    624375                raise common.xmpp.NodeProcessed 
    625376 
    626 class ConnectionHandlersZeroconf(ConnectionVcard, ConnectionBytestream): 
     377class ConnectionHandlersZeroconf(ConnectionVcard, ConnectionBytestream, connection_handlers.ConnectionHandlersBase): 
    627378        def __init__(self): 
    628379                ConnectionVcard.__init__(self) 
    629380                ConnectionBytestream.__init__(self) 
    630                 # List of IDs we are waiting answers for {id: (type_of_request, data), } 
    631                 self.awaiting_answers = {} 
    632                 # List of IDs that will produce a timeout is answer doesn't arrive 
    633                 # {time_of_the_timeout: (id, message to send to gui), } 
    634                 self.awaiting_timeouts = {} 
    635                 # keep the jids we auto added (transports contacts) to not send the 
    636                 # SUBSCRIBED event to gui 
    637                 self.automatically_added = [] 
    638                 # keep track of sessions this connection has with other JIDs 
    639                 self.sessions = {} 
     381                connection_handlers.ConnectionHandlersBase.__init__(self) 
     382 
    640383                try: 
    641384                        idle.init() 
    642385                except: 
    643386                        HAS_IDLE = False 
    644                          
     387 
    645388        def _messageCB(self, ip, con, msg): 
    646389                '''Called when we receive a message''' 
     390 
     391                gajim.log.debug('Zeroconf MessageCB') 
     392 
     393                frm = msg.getFrom() 
    647394                mtype = msg.getType() 
    648395                thread_id = msg.getThread() 
    649                 tim = msg.getTimestamp() 
    650                 tim = helpers.datetime_tuple(tim) 
    651                 tim = time.localtime(timegm(tim)) 
    652                 frm = msg.getFrom() 
     396 
     397                if not mtype: 
     398                        mtype = 'normal' 
    653399 
    654400                if frm == None: 
     
    656402                                if ip == self.connection.zeroconf.contacts[key][zeroconf.C_ADDRESS]: 
    657403                                        frm = key 
     404 
    658405                frm = unicode(frm) 
    659                 jid  = frm 
    660  
    661                 session = self.get_or_create_session(frm, thread_id, mtype) 
     406 
     407                session = self.get_or_create_session(frm, thread_id) 
    662408 
    663409                if thread_id and not session.received_thread_id: 
    664410                        session.received_thread_id = True 
    665                  
     411 
    666412                if msg.getTag('feature') and msg.getTag('feature').namespace == \ 
    667413                common.xmpp.NS_FEATURE: 
     
    669415                                self._FeatureNegCB(con, msg, session) 
    670416                        return 
     417 
    671418                if msg.getTag('init') and msg.getTag('init').namespace == \ 
    672419                common.xmpp.NS_ESESSION_INIT: 
    673420                        self._InitE2ECB(con, msg, session) 
    674421 
    675                 no_log_for = gajim.config.get_per('accounts', self.name, 
    676                         'no_log_for').split() 
    677422                encrypted = False 
    678                 chatstate = None 
    679  
    680                 e2e_tag = msg.getTag('c', namespace = common.xmpp.NS_STANZA_CRYPTO) 
    681                 if e2e_tag: 
     423                tim = msg.getTimestamp() 
     424                tim = helpers.datetime_tuple(tim) 
     425                tim = time.localtime(timegm(tim)) 
     426 
     427                if msg.getTag('c', namespace = common.xmpp.NS_STANZA_CRYPTO): 
    682428                        encrypted = True 
    683429 
     
    686432                        except: 
    687433                                self.dispatch('FAILED_DECRYPT', (frm, tim)) 
    688                  
     434 
    689435                msgtxt = msg.getBody() 
    690                 msghtml = msg.getXHTML() 
    691436                subject = msg.getSubject() # if not there, it's None 
    692437 
    693                 encTag = msg.getTag('x', namespace = common.xmpp.NS_ENCRYPTED) 
    694                 decmsg = '' 
    695                 form_node = msg.getTag('x', namespace = common.xmpp.NS_DATA) 
    696438                # invitations 
    697439                invite = None 
     440                encTag = msg.getTag('x', namespace = common.xmpp.NS_ENCRYPTED) 
     441 
    698442                if not encTag: 
    699443                        invite = msg.getTag('x', namespace = common.xmpp.NS_MUC_USER) 
    700444                        if invite and not invite.getTag('invite'): 
    701445                                invite = None 
    702                 delayed = msg.getTag('x', namespace = common.xmpp.NS_DELAY) != None 
    703                 msg_id = None 
    704                 composing_xep = None 
    705                 xtags = msg.getTags('x') 
    706                 # chatstates - look for chatstate tags in a message if not delayed 
    707                 if not delayed: 
    708                         composing_xep = False 
    709                         children = msg.getChildren() 
    710                         for child in children: 
    711                                 if child.getNamespace() == 'http://jabber.org/protocol/chatstates': 
    712                                         chatstate = child.getName() 
    713                                         composing_xep = 'XEP-0085' 
    714                                         break 
    715                         # No JEP-0085 support, fallback to JEP-0022 
    716                         if not chatstate: 
    717                                 chatstate_child = msg.getTag('x', namespace = common.xmpp.NS_EVENT) 
    718                                 if chatstate_child: 
    719                                         chatstate = 'active' 
    720                                         composing_xep = 'XEP-0022' 
    721                                         if not msgtxt and chatstate_child.getTag('composing'): 
    722                                                 chatstate = 'composing' 
    723                 # JEP-0172 User Nickname 
    724                 user_nick = msg.getTagData('nick') 
    725                 if not user_nick: 
    726                         user_nick = '' 
    727446 
    728447                if encTag and self.USE_GPG: 
    729448                        #decrypt 
    730449                        encmsg = encTag.getData() 
    731                          
     450 
    732451                        keyID = gajim.config.get_per('accounts', self.name, 'keyid') 
    733452                        if keyID: 
    734453                                decmsg = self.gpg.decrypt(encmsg, keyID) 
    735454                                # \x00 chars are not allowed in C (so in GTK) 
    736                                 decmsg = decmsg.replace('\x00', '') 
    737                 if decmsg: 
    738                         msgtxt = decmsg 
    739                         encrypted = True 
     455                                msgtxt = decmsg.replace('\x00', '') 
     456                                encrypted = True 
     457 
    740458                if mtype == 'error': 
    741                         error_msg = msg.getError() 
    742                         if not error_msg: 
    743                                 error_msg = msgtxt 
    744                                 msgtxt = None 
    745                         if self.name not in no_log_for: 
    746                                 gajim.logger.write('error', frm, error_msg, tim = tim, 
    747                                         subject = subject) 
    748                         self.dispatch('MSGERROR', (frm, msg.getErrorCode(), error_msg, msgtxt, 
    749                                 tim)) 
    750                 elif mtype == 'chat': # it's type 'chat' 
    751                         if not msg.getTag('body') and chatstate is None: #no <body> 
    752                                 return 
    753                         if msg.getTag('body') and self.name not in no_log_for and jid not in\ 
    754                                 no_log_for and msgtxt: 
    755                                 msg_id = gajim.logger.write('chat_msg_recv', frm, msgtxt, tim = tim, 
    756                                         subject = subject) 
    757                         self.dispatch('MSG', (frm, msgtxt, tim, encrypted, mtype, subject, 
    758                                 chatstate, msg_id, composing_xep, user_nick, msghtml, session, 
    759                                 form_node)) 
    760                 elif mtype == 'normal': # it's single message 
    761                         if self.name not in no_log_for and jid not in no_log_for and msgtxt: 
    762                                 gajim.logger.write('single_msg_recv', frm, msgtxt, tim = tim, 
    763                                         subject = subject) 
    764                         if invite: 
    765                                 self.dispatch('MSG', (frm, msgtxt, tim, encrypted, 'normal', 
    766                                         subject, chatstate, msg_id, composing_xep, user_nick, msghtml, 
    767                                         session, form_node)) 
     459                        self.dispatch_error_msg(msg, msgtxt, session, frm, tim, subject) 
     460                else: 
     461                        # XXX this shouldn't be hardcoded 
     462                        if isinstance(session, ChatControlSession): 
     463                                session.received(frm, msgtxt, tim, encrypted, subject, msg) 
     464                        else: 
     465                                session.received(msg) 
    768466        # END messageCB 
    769          
    770         def _FeatureNegCB(self, con, stanza, session): 
    771                 gajim.log.debug('FeatureNegCB') 
    772                 feature = stanza.getTag(name='feature', namespace=common.xmpp.NS_FEATURE) 
    773                 form = common.xmpp.DataForm(node=feature.getTag('x')) 
    774  
    775                 if form['FORM_TYPE'] == 'urn:xmpp:ssn': 
    776                         self.dispatch('SESSION_NEG', (stanza.getFrom(), session, form)) 
    777                 else: 
    778                         reply = stanza.buildReply() 
    779                         reply.setType('error') 
    780  
    781                         reply.addChild(feature) 
    782                         reply.addChild(node=xmpp.ErrorNode('service-unavailable', typ='cancel')) 
    783  
    784                         con.send(reply) 
    785                  
    786                 raise common.xmpp.NodeProcessed 
    787  
    788         def _InitE2ECB(self, con, stanza, session): 
    789                 gajim.log.debug('InitE2ECB') 
    790                 init = stanza.getTag(name='init', namespace=common.xmpp.NS_ESESSION_INIT) 
    791                 form = common.xmpp.DataForm(node=init.getTag('x')) 
    792  
    793                 self.dispatch('SESSION_NEG', (stanza.getFrom