2005-04-12 23:09:06 +02:00
|
|
|
## common/connection.py
|
2005-04-12 13:46:20 +02:00
|
|
|
##
|
|
|
|
## Gajim Team:
|
|
|
|
## - Yann Le Boulanger <asterix@lagaule.org>
|
|
|
|
## - Vincent Hanquez <tab@snarc.org>
|
|
|
|
## - Nikos Kouremenos <nkour@jabber.org>
|
2005-07-30 12:59:15 +02:00
|
|
|
## - Dimitur Kirov <dkirov@gmail.com>
|
2005-04-12 13:46:20 +02:00
|
|
|
##
|
|
|
|
## Copyright (C) 2003-2005 Gajim Team
|
|
|
|
##
|
|
|
|
## This program 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 2 only.
|
|
|
|
##
|
|
|
|
## 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 General Public License for more details.
|
|
|
|
##
|
|
|
|
|
|
|
|
import sys
|
2005-08-07 23:42:32 +02:00
|
|
|
import sha
|
2005-04-12 13:46:20 +02:00
|
|
|
import os
|
|
|
|
import time
|
2005-05-18 18:42:28 +02:00
|
|
|
import sre
|
2005-05-20 19:30:29 +02:00
|
|
|
import traceback
|
2005-06-28 21:03:00 +02:00
|
|
|
import threading
|
2005-07-30 12:19:52 +02:00
|
|
|
import select
|
2005-08-12 16:59:28 +02:00
|
|
|
import socket
|
2005-07-30 12:59:15 +02:00
|
|
|
|
2005-04-27 20:26:31 +02:00
|
|
|
from calendar import timegm
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-04-26 20:45:54 +02:00
|
|
|
import common.xmpp
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-05-27 07:56:17 +02:00
|
|
|
from common import helpers
|
2005-04-14 09:42:26 +02:00
|
|
|
from common import gajim
|
|
|
|
from common import GnuPG
|
2005-08-02 00:58:14 +02:00
|
|
|
import socks5
|
2005-04-13 11:41:44 +02:00
|
|
|
USE_GPG = GnuPG.USE_GPG
|
2005-04-12 13:46:20 +02:00
|
|
|
|
|
|
|
from common import i18n
|
|
|
|
_ = i18n._
|
|
|
|
|
|
|
|
|
2005-04-30 10:48:50 +02:00
|
|
|
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
|
2005-04-12 13:46:20 +02:00
|
|
|
'invisible']
|
|
|
|
|
|
|
|
distro_info = {
|
2005-04-19 15:14:41 +02:00
|
|
|
'Arch Linux': '/etc/arch-release',
|
|
|
|
'Aurox Linux': '/etc/aurox-release',
|
|
|
|
'Conectiva Linux': '/etc/conectiva-release',
|
|
|
|
'Debian GNU/Linux': '/etc/debian_release',
|
|
|
|
'Debian GNU/Linux': '/etc/debian_version',
|
|
|
|
'Fedora Linux': '/etc/fedora-release',
|
|
|
|
'Gentoo Linux': '/etc/gentoo-release',
|
|
|
|
'Linux from Scratch': '/etc/lfs-release',
|
|
|
|
'Mandrake Linux': '/etc/mandrake-release',
|
|
|
|
'Slackware Linux': '/etc/slackware-release',
|
|
|
|
'Slackware Linux': '/etc/slackware-version',
|
|
|
|
'Solaris/Sparc': '/etc/release',
|
2005-06-04 22:54:21 +02:00
|
|
|
'Source Mage': '/etc/sourcemage_version',
|
2005-05-18 19:02:46 +02:00
|
|
|
'SUSE Linux': '/etc/SuSE-release',
|
2005-04-19 15:14:41 +02:00
|
|
|
'Sun JDS': '/etc/sun-release',
|
|
|
|
'PLD Linux': '/etc/pld-release',
|
|
|
|
'Yellow Dog Linux': '/etc/yellowdog-release',
|
2005-04-12 13:46:20 +02:00
|
|
|
# many distros use the /etc/redhat-release for compatibility
|
|
|
|
# so Redhat is the last
|
2005-04-19 15:14:41 +02:00
|
|
|
'Redhat Linux': '/etc/redhat-release'
|
2005-04-12 13:46:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
def get_os_info():
|
2005-04-17 01:15:03 +02:00
|
|
|
if os.name == 'nt':
|
2005-04-19 15:14:41 +02:00
|
|
|
win_version = {
|
|
|
|
(1, 4, 0): '95',
|
|
|
|
(1, 4, 10): '98',
|
|
|
|
(1, 4, 90): 'ME',
|
|
|
|
(2, 4, 0): 'NT',
|
|
|
|
(2, 5, 0): '2000',
|
2005-04-17 01:15:03 +02:00
|
|
|
(2, 5, 1): 'XP'
|
2005-04-19 15:14:41 +02:00
|
|
|
}[ os.sys.getwindowsversion()[3],
|
|
|
|
os.sys.getwindowsversion()[0],
|
2005-04-17 01:15:03 +02:00
|
|
|
os.sys.getwindowsversion()[1] ]
|
|
|
|
return 'Windows' + ' ' + win_version
|
2005-04-26 20:45:54 +02:00
|
|
|
elif os.name == 'posix':
|
2005-04-12 13:46:20 +02:00
|
|
|
executable = 'lsb_release'
|
|
|
|
params = ' --id --codename --release --short'
|
2005-08-09 13:34:16 +02:00
|
|
|
full_path_to_executable = helpers.is_in_path(executable, return_abs_path = True)
|
|
|
|
if full_path_to_executable:
|
|
|
|
command = executable + params
|
|
|
|
child_stdin, child_stdout = os.popen2(command)
|
|
|
|
output = child_stdout.readline().strip()
|
|
|
|
child_stdout.close()
|
|
|
|
child_stdin.close()
|
|
|
|
# some distros put n/a in places so remove them
|
|
|
|
pattern = sre.compile(r' n/a', sre.IGNORECASE)
|
|
|
|
output = sre.sub(pattern, '', output)
|
|
|
|
return output
|
|
|
|
|
2005-04-12 13:46:20 +02:00
|
|
|
# lsb_release executable not available, so parse files
|
2005-04-19 15:14:41 +02:00
|
|
|
for distro_name in distro_info:
|
|
|
|
path_to_file = distro_info[distro_name]
|
2005-04-12 13:46:20 +02:00
|
|
|
if os.path.exists(path_to_file):
|
|
|
|
fd = open(path_to_file)
|
2005-06-04 23:52:49 +02:00
|
|
|
text = fd.readline().strip() #get only first line
|
2005-04-12 13:46:20 +02:00
|
|
|
fd.close()
|
|
|
|
if path_to_file.endswith('version'):
|
2005-06-04 22:54:21 +02:00
|
|
|
# sourcemage_version has all the info we need
|
2005-06-06 02:11:48 +02:00
|
|
|
if not os.path.basename(path_to_file).startswith('sourcemage'):
|
2005-06-04 22:54:21 +02:00
|
|
|
text = distro_name + ' ' + text
|
2005-06-29 10:28:12 +02:00
|
|
|
elif path_to_file.endswith('aurox-release'):
|
|
|
|
# file doesn't have version
|
2005-04-19 15:14:41 +02:00
|
|
|
text = distro_name
|
|
|
|
elif path_to_file.endswith('lfs-release'): # file just has version
|
|
|
|
text = distro_name + ' ' + text
|
2005-04-12 13:46:20 +02:00
|
|
|
return text
|
2005-05-11 13:09:53 +02:00
|
|
|
return 'N/A'
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-04-19 15:14:41 +02:00
|
|
|
class Connection:
|
|
|
|
"""Connection class"""
|
2005-04-14 11:38:08 +02:00
|
|
|
def __init__(self, name):
|
2005-04-12 13:46:20 +02:00
|
|
|
self.name = name
|
|
|
|
self.connected = 0 # offline
|
2005-04-26 20:45:54 +02:00
|
|
|
self.connection = None # xmpppy instance
|
2005-04-12 13:46:20 +02:00
|
|
|
self.gpg = None
|
2005-08-07 23:42:32 +02:00
|
|
|
self.vcard_sha = None
|
2005-05-13 20:54:44 +02:00
|
|
|
self.status = ''
|
2005-07-07 22:45:24 +02:00
|
|
|
self.new_account_info = None
|
2005-06-07 20:21:36 +02:00
|
|
|
self.bookmarks = []
|
2005-05-27 14:07:20 +02:00
|
|
|
self.on_purpose = False
|
2005-08-27 02:07:43 +02:00
|
|
|
self.last_io = time.time()
|
2005-06-29 10:28:12 +02:00
|
|
|
self.to_be_sent = []
|
|
|
|
self.last_sent = []
|
2005-08-03 16:04:54 +02:00
|
|
|
self.files_props = {}
|
2005-04-14 13:06:58 +02:00
|
|
|
self.password = gajim.config.get_per('accounts', name, 'password')
|
2005-07-22 18:36:20 +02:00
|
|
|
self.privacy_rules_supported = False
|
2005-04-14 11:38:08 +02:00
|
|
|
if USE_GPG:
|
|
|
|
self.gpg = GnuPG.GnuPG()
|
|
|
|
gajim.config.set('usegpg', True)
|
|
|
|
else:
|
|
|
|
gajim.config.set('usegpg', False)
|
2005-04-12 13:46:20 +02:00
|
|
|
# END __init__
|
|
|
|
|
2005-08-09 20:45:16 +02:00
|
|
|
def put_event(self, ev):
|
2005-08-24 17:59:51 +02:00
|
|
|
if gajim.events_for_ui.has_key(self.name):
|
|
|
|
gajim.events_for_ui[self.name].append(ev)
|
2005-08-09 20:45:16 +02:00
|
|
|
|
2005-06-07 09:40:15 +02:00
|
|
|
def dispatch(self, event, data):
|
2005-06-29 14:57:46 +02:00
|
|
|
'''always passes account name as first param'''
|
2005-08-09 20:45:16 +02:00
|
|
|
gajim.mutex_events_for_ui.lock(self.put_event, [event, data])
|
|
|
|
gajim.mutex_events_for_ui.unlock()
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-08-07 23:42:32 +02:00
|
|
|
def add_sha(self, p):
|
|
|
|
c = p.setTag('x', namespace = common.xmpp.NS_VCARD_UPDATE)
|
|
|
|
if self.vcard_sha is not None:
|
|
|
|
c.setTagData('photo', self.vcard_sha)
|
|
|
|
return p
|
|
|
|
|
2005-05-31 15:53:22 +02:00
|
|
|
# this is in features.py but it is blocking
|
|
|
|
def _discover(self, ns, jid, node = None):
|
2005-05-23 12:46:22 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-04-26 20:45:54 +02:00
|
|
|
iq = common.xmpp.Iq(typ = 'get', to = jid, queryNS = ns)
|
|
|
|
if node:
|
|
|
|
iq.setQuerynode(node)
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq)
|
2005-04-26 20:45:54 +02:00
|
|
|
|
|
|
|
def discoverItems(self, jid, node = None):
|
|
|
|
'''According to JEP-0030: jid is mandatory,
|
|
|
|
name, node, action is optional.'''
|
|
|
|
self._discover(common.xmpp.NS_DISCO_ITEMS, jid, node)
|
|
|
|
|
|
|
|
def discoverInfo(self, jid, node = None):
|
|
|
|
'''According to JEP-0030:
|
|
|
|
For identity: category, name is mandatory, type is optional.
|
|
|
|
For feature: var is mandatory'''
|
|
|
|
self._discover(common.xmpp.NS_DISCO_INFO, jid, node)
|
|
|
|
|
2005-04-12 13:46:20 +02:00
|
|
|
def _vCardCB(self, con, vc):
|
2005-06-07 03:10:24 +02:00
|
|
|
"""Called when we receive a vCard
|
2005-04-12 13:46:20 +02:00
|
|
|
Parse the vCard and send it to plugins"""
|
2005-06-26 21:40:57 +02:00
|
|
|
frm_iq = vc.getFrom()
|
2005-08-08 15:34:48 +02:00
|
|
|
name = gajim.config.get_per('accounts', self.name, 'name')
|
|
|
|
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
|
|
|
|
our_jid = name + '@' + hostname
|
2005-06-26 21:40:57 +02:00
|
|
|
resource = ''
|
|
|
|
if frm_iq:
|
|
|
|
frm = frm_iq.getStripped()
|
|
|
|
resource = frm_iq.getResource()
|
2005-05-24 21:18:32 +02:00
|
|
|
else:
|
2005-08-08 15:34:48 +02:00
|
|
|
frm = our_jid
|
2005-06-26 21:40:57 +02:00
|
|
|
vcard = {'jid': frm, 'resource': resource}
|
2005-06-20 22:58:57 +02:00
|
|
|
if not vc.getTag('vCard'):
|
|
|
|
return
|
2005-04-26 20:45:54 +02:00
|
|
|
if vc.getTag('vCard').getNamespace() == common.xmpp.NS_VCARD:
|
2005-04-12 13:46:20 +02:00
|
|
|
card = vc.getChildren()[0]
|
|
|
|
for info in card.getChildren():
|
2005-06-07 10:50:47 +02:00
|
|
|
name = info.getName()
|
|
|
|
if name in ['ADR', 'TEL', 'EMAIL']: # we can have several
|
|
|
|
if not vcard.has_key(name):
|
|
|
|
vcard[name] = []
|
|
|
|
entry = {}
|
|
|
|
for c in info.getChildren():
|
|
|
|
entry[c.getName()] = c.getData()
|
|
|
|
vcard[name].append(entry)
|
|
|
|
elif info.getChildren() == []:
|
|
|
|
vcard[name] = info.getData()
|
2005-04-12 13:46:20 +02:00
|
|
|
else:
|
2005-06-07 10:50:47 +02:00
|
|
|
vcard[name] = {}
|
2005-04-12 13:46:20 +02:00
|
|
|
for c in info.getChildren():
|
2005-06-07 10:50:47 +02:00
|
|
|
vcard[name][c.getName()] = c.getData()
|
2005-08-08 15:34:48 +02:00
|
|
|
if frm == our_jid:
|
2005-08-07 23:42:32 +02:00
|
|
|
if vcard.has_key('PHOTO') and type(vcard['PHOTO']) == type({}) and \
|
|
|
|
vcard['PHOTO'].has_key('BINVAL'):
|
|
|
|
photo = vcard['PHOTO']['BINVAL']
|
|
|
|
self.vcard_sha = sha.sha(photo).hexdigest()
|
|
|
|
else:
|
|
|
|
self.vcard_sha = ''
|
2005-04-12 13:46:20 +02:00
|
|
|
self.dispatch('MYVCARD', vcard)
|
2005-08-07 23:42:32 +02:00
|
|
|
#we re-send our presence with sha
|
2005-08-18 10:33:51 +02:00
|
|
|
sshow = STATUS_LIST[self.connected]
|
2005-08-26 02:52:44 +02:00
|
|
|
prio = unicode(gajim.config.get_per('accounts', self.name,
|
|
|
|
'priority'))
|
2005-08-18 10:33:51 +02:00
|
|
|
p = common.xmpp.Presence(typ = None, priority = prio, show = sshow,
|
2005-08-08 14:23:51 +02:00
|
|
|
status = self.status)
|
2005-08-07 23:42:32 +02:00
|
|
|
p = self.add_sha(p)
|
|
|
|
self.to_be_sent.append(p)
|
2005-04-12 13:46:20 +02:00
|
|
|
else:
|
|
|
|
self.dispatch('VCARD', vcard)
|
|
|
|
|
2005-04-26 20:45:54 +02:00
|
|
|
|
2005-04-12 13:46:20 +02:00
|
|
|
def _messageCB(self, con, msg):
|
2005-06-07 03:10:24 +02:00
|
|
|
"""Called when we receive a message"""
|
2005-05-20 13:23:08 +02:00
|
|
|
msgtxt = msg.getBody()
|
2005-04-12 14:23:08 +02:00
|
|
|
mtype = msg.getType()
|
2005-07-05 23:44:01 +02:00
|
|
|
subject = msg.getSubject() # if not there, it's None
|
2005-04-12 13:46:20 +02:00
|
|
|
tim = msg.getTimestamp()
|
|
|
|
tim = time.strptime(tim, '%Y%m%dT%H:%M:%S')
|
2005-04-27 20:26:31 +02:00
|
|
|
tim = time.localtime(timegm(tim))
|
2005-05-30 12:41:55 +02:00
|
|
|
encrypted = False
|
2005-07-21 16:56:39 +02:00
|
|
|
chatstate = None
|
2005-04-26 20:45:54 +02:00
|
|
|
xtags = msg.getTags('x')
|
2005-04-12 13:46:20 +02:00
|
|
|
encTag = None
|
|
|
|
decmsg = ''
|
|
|
|
for xtag in xtags:
|
2005-04-26 20:45:54 +02:00
|
|
|
if xtag.getNamespace() == common.xmpp.NS_ENCRYPTED:
|
2005-04-12 13:46:20 +02:00
|
|
|
encTag = xtag
|
|
|
|
break
|
2005-07-19 16:38:58 +02:00
|
|
|
|
|
|
|
# chatstates - look for chatstate tags in a message
|
|
|
|
children = msg.getChildren()
|
|
|
|
for child in children:
|
|
|
|
if child.getNamespace() == 'http://jabber.org/protocol/chatstates':
|
2005-07-21 16:56:39 +02:00
|
|
|
chatstate = child.getName()
|
2005-07-19 16:38:58 +02:00
|
|
|
break
|
|
|
|
|
2005-04-12 13:46:20 +02:00
|
|
|
if encTag and USE_GPG:
|
|
|
|
#decrypt
|
|
|
|
encmsg = encTag.getData()
|
|
|
|
|
|
|
|
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
|
|
|
if keyID:
|
|
|
|
decmsg = self.gpg.decrypt(encmsg, keyID)
|
|
|
|
if decmsg:
|
|
|
|
msgtxt = decmsg
|
2005-05-30 12:41:55 +02:00
|
|
|
encrypted = True
|
2005-04-12 14:23:08 +02:00
|
|
|
if mtype == 'error':
|
2005-08-26 02:52:44 +02:00
|
|
|
self.dispatch('MSGERROR', (unicode(msg.getFrom()),
|
2005-04-12 13:46:20 +02:00
|
|
|
msg.getErrorCode(), msg.getError(), msgtxt, tim))
|
2005-04-12 14:23:08 +02:00
|
|
|
elif mtype == 'groupchat':
|
2005-04-12 13:46:20 +02:00
|
|
|
if subject:
|
2005-08-26 02:52:44 +02:00
|
|
|
self.dispatch('GC_SUBJECT', (unicode(msg.getFrom()), subject))
|
2005-04-12 13:46:20 +02:00
|
|
|
else:
|
2005-06-07 13:05:58 +02:00
|
|
|
if not msg.getTag('body'): #no <body>
|
|
|
|
return
|
2005-08-26 02:52:44 +02:00
|
|
|
self.dispatch('GC_MSG', (unicode(msg.getFrom()), msgtxt, tim))
|
|
|
|
gajim.logger.write('gc', msgtxt, unicode(msg.getFrom()),
|
|
|
|
tim = tim)
|
2005-07-05 23:35:37 +02:00
|
|
|
elif mtype == 'normal': # it's single message
|
|
|
|
log_msgtxt = msgtxt
|
|
|
|
if subject:
|
|
|
|
log_msgtxt = _('Subject: %s\n%s') % (subject, msgtxt)
|
2005-08-26 02:52:44 +02:00
|
|
|
gajim.logger.write('incoming', log_msgtxt, unicode(msg.getFrom()),
|
2005-07-05 23:35:37 +02:00
|
|
|
tim = tim)
|
2005-08-26 02:52:44 +02:00
|
|
|
self.dispatch('MSG', (unicode(msg.getFrom()), msgtxt, tim,
|
|
|
|
encrypted, mtype, subject, None))
|
2005-07-05 23:35:37 +02:00
|
|
|
else: # it's type 'chat'
|
2005-07-21 16:56:39 +02:00
|
|
|
if not msg.getTag('body') and chatstate is None: #no <body>
|
2005-06-07 13:05:58 +02:00
|
|
|
return
|
2005-07-05 23:35:37 +02:00
|
|
|
log_msgtxt = msgtxt
|
|
|
|
if subject:
|
|
|
|
log_msgtxt = _('Subject: %s\n%s') % (subject, msgtxt)
|
2005-07-22 22:27:24 +02:00
|
|
|
if msg.getTag('body'):
|
2005-08-26 02:52:44 +02:00
|
|
|
gajim.logger.write('incoming', log_msgtxt,
|
|
|
|
unicode(msg.getFrom()), tim = tim)
|
|
|
|
self.dispatch('MSG', (unicode(msg.getFrom()), msgtxt, tim,
|
|
|
|
encrypted, mtype, subject, chatstate))
|
2005-04-12 13:46:20 +02:00
|
|
|
# END messageCB
|
|
|
|
|
|
|
|
def _presenceCB(self, con, prs):
|
2005-06-07 03:10:24 +02:00
|
|
|
"""Called when we receive a presence"""
|
2005-08-26 02:52:44 +02:00
|
|
|
who = unicode(prs.getFrom())
|
2005-04-12 13:46:20 +02:00
|
|
|
prio = prs.getPriority()
|
|
|
|
if not prio:
|
|
|
|
prio = 0
|
2005-04-12 14:23:08 +02:00
|
|
|
ptype = prs.getType()
|
2005-06-04 00:49:07 +02:00
|
|
|
if ptype == 'available': ptype = None
|
2005-07-07 19:20:43 +02:00
|
|
|
gajim.log.debug('PresenceCB: %s' % ptype)
|
2005-04-26 20:45:54 +02:00
|
|
|
xtags = prs.getTags('x')
|
2005-04-12 13:46:20 +02:00
|
|
|
sigTag = None
|
|
|
|
keyID = ''
|
|
|
|
status = prs.getStatus()
|
|
|
|
for xtag in xtags:
|
2005-04-26 20:45:54 +02:00
|
|
|
if xtag.getNamespace() == common.xmpp.NS_SIGNED:
|
2005-04-12 13:46:20 +02:00
|
|
|
sigTag = xtag
|
|
|
|
break
|
|
|
|
if sigTag and USE_GPG:
|
|
|
|
#verify
|
|
|
|
sigmsg = sigTag.getData()
|
|
|
|
keyID = self.gpg.verify(status, sigmsg)
|
2005-06-23 20:27:14 +02:00
|
|
|
show = prs.getShow()
|
|
|
|
if not show in STATUS_LIST:
|
|
|
|
show = '' # We ignore unknown show
|
|
|
|
if not ptype and not show:
|
|
|
|
show = 'online'
|
2005-04-12 14:23:08 +02:00
|
|
|
elif ptype == 'unavailable':
|
2005-04-16 11:36:18 +02:00
|
|
|
show = 'offline'
|
2005-04-12 14:23:08 +02:00
|
|
|
elif ptype == 'subscribe':
|
2005-04-12 13:46:20 +02:00
|
|
|
gajim.log.debug('subscribe request from %s' % who)
|
|
|
|
if gajim.config.get('alwaysauth') or who.find("@") <= 0:
|
|
|
|
if self.connection:
|
2005-08-07 23:42:32 +02:00
|
|
|
p = common.xmpp.Presence(who, 'subscribed')
|
|
|
|
p = self.add_sha(p)
|
|
|
|
self.to_be_sent.append(p)
|
2005-04-12 13:46:20 +02:00
|
|
|
if who.find("@") <= 0:
|
2005-06-29 10:28:12 +02:00
|
|
|
self.dispatch('NOTIFY',
|
2005-08-26 02:52:44 +02:00
|
|
|
(prs.getFrom().getStripped(), 'offline', 'offline',
|
|
|
|
prs.getFrom().getResource(), prio, keyID, None, None,
|
|
|
|
None, None, None, None))
|
2005-04-12 13:46:20 +02:00
|
|
|
else:
|
|
|
|
if not status:
|
|
|
|
status = _('I would like to add you to my roster.')
|
|
|
|
self.dispatch('SUBSCRIBE', (who, status))
|
2005-04-12 14:23:08 +02:00
|
|
|
elif ptype == 'subscribed':
|
2005-04-12 13:46:20 +02:00
|
|
|
jid = prs.getFrom()
|
2005-08-26 02:52:44 +02:00
|
|
|
self.dispatch('SUBSCRIBED', (jid.getStripped(), jid.getResource()))
|
2005-08-25 12:06:33 +02:00
|
|
|
# BE CAREFUL: no con.updateRosterItem() in a callback
|
2005-08-02 00:58:14 +02:00
|
|
|
gajim.log.debug(_('we are now subscribed to %s') % who)
|
2005-04-12 14:23:08 +02:00
|
|
|
elif ptype == 'unsubscribe':
|
2005-07-24 22:00:38 +02:00
|
|
|
gajim.log.debug(_('unsubscribe request from %s') % who)
|
2005-04-12 14:23:08 +02:00
|
|
|
elif ptype == 'unsubscribed':
|
2005-08-02 00:58:14 +02:00
|
|
|
gajim.log.debug(_('we are now unsubscribed from %s') % who)
|
2005-04-12 13:46:20 +02:00
|
|
|
self.dispatch('UNSUBSCRIBED', prs.getFrom().getStripped())
|
2005-04-12 14:23:08 +02:00
|
|
|
elif ptype == 'error':
|
2005-04-12 13:46:20 +02:00
|
|
|
errmsg = prs.getError()
|
|
|
|
errcode = prs.getErrorCode()
|
2005-08-25 12:06:33 +02:00
|
|
|
if errcode == '409': #conflict: Nick Conflict
|
2005-08-25 16:07:17 +02:00
|
|
|
self.dispatch('ERROR', (_('Unable to join room'),
|
|
|
|
_('Server response:') + '\n' + errmsg))
|
2005-05-24 23:32:52 +02:00
|
|
|
elif errcode == '502': # Internal Timeout:
|
2005-08-26 02:52:44 +02:00
|
|
|
self.dispatch('NOTIFY', (prs.getFrom().getStripped(),
|
|
|
|
'error', errmsg, prs.getFrom().getResource(),
|
2005-06-20 09:50:50 +02:00
|
|
|
prio, keyID, prs.getRole(), prs.getAffiliation(), prs.getJid(),
|
|
|
|
prs.getReason(), prs.getActor(), prs.getStatusCode(),
|
|
|
|
prs.getNewNick()))
|
2005-04-12 13:46:20 +02:00
|
|
|
else:
|
2005-08-09 17:28:32 +02:00
|
|
|
self.dispatch('ERROR_ANSWER', ('', prs.getFrom().getStripped(),
|
|
|
|
errmsg, errcode))
|
2005-06-04 00:49:07 +02:00
|
|
|
if not ptype or ptype == 'unavailable':
|
2005-08-26 02:52:44 +02:00
|
|
|
jid = unicode(prs.getFrom())
|
|
|
|
gajim.logger.write('status', status, jid, show)
|
|
|
|
account = prs.getFrom().getStripped()
|
|
|
|
resource = prs.getFrom().getResource()
|
2005-06-04 02:37:49 +02:00
|
|
|
self.dispatch('NOTIFY', ( account, show, status,
|
|
|
|
resource, prio, keyID, prs.getRole(),
|
2005-05-24 23:32:52 +02:00
|
|
|
prs.getAffiliation(), prs.getJid(), prs.getReason(),
|
2005-06-19 00:09:31 +02:00
|
|
|
prs.getActor(), prs.getStatusCode(), prs.getNewNick()))
|
2005-04-12 13:46:20 +02:00
|
|
|
# END presenceCB
|
|
|
|
|
2005-04-26 20:45:54 +02:00
|
|
|
def _disconnectedCB(self):
|
2005-04-12 13:46:20 +02:00
|
|
|
"""Called when we are disconnected"""
|
|
|
|
gajim.log.debug('disconnectedCB')
|
2005-05-27 14:07:20 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
self.connected = 0
|
|
|
|
self.dispatch('STATUS', 'offline')
|
|
|
|
self.connection = None
|
|
|
|
if not self.on_purpose:
|
2005-06-07 03:17:38 +02:00
|
|
|
self.dispatch('ERROR',
|
2005-06-07 09:40:15 +02:00
|
|
|
(_('Connection with account "%s" has been lost') % self.name,
|
|
|
|
_('To continue sending and receiving messages, you will need to reconnect.')))
|
2005-05-27 14:07:20 +02:00
|
|
|
self.on_purpose = False
|
2005-08-06 18:31:41 +02:00
|
|
|
|
2005-04-12 13:46:20 +02:00
|
|
|
# END disconenctedCB
|
2005-08-06 18:31:41 +02:00
|
|
|
def _bytestreamErrorCB(self, con, iq_obj):
|
|
|
|
gajim.log.debug('_bytestreamErrorCB')
|
2005-08-26 02:52:44 +02:00
|
|
|
frm = unicode(iq_obj.getFrom())
|
|
|
|
id = unicode(iq_obj.getAttr('id'))
|
2005-08-06 18:31:41 +02:00
|
|
|
query = iq_obj.getTag('query')
|
|
|
|
streamhost = query.getTag('streamhost')
|
2005-08-26 02:52:44 +02:00
|
|
|
jid = iq_obj.getFrom().getStripped()
|
2005-08-06 18:31:41 +02:00
|
|
|
id = id[3:]
|
|
|
|
if not self.files_props.has_key(id):
|
|
|
|
return
|
|
|
|
file_props = self.files_props[id]
|
2005-08-11 22:26:17 +02:00
|
|
|
file_props['error'] = -4
|
2005-08-06 18:31:41 +02:00
|
|
|
self.dispatch('FILE_REQUEST_ERROR', (jid, file_props))
|
|
|
|
raise common.xmpp.NodeProcessed
|
2005-07-30 12:19:52 +02:00
|
|
|
|
|
|
|
def _bytestreamSetCB(self, con, iq_obj):
|
|
|
|
gajim.log.debug('_bytestreamSetCB')
|
2005-08-26 02:52:44 +02:00
|
|
|
target = unicode(iq_obj.getAttr('to'))
|
|
|
|
id = unicode(iq_obj.getAttr('id'))
|
2005-07-30 12:19:52 +02:00
|
|
|
query = iq_obj.getTag('query')
|
2005-08-26 02:52:44 +02:00
|
|
|
sid = unicode(query.getAttr('sid'))
|
2005-08-02 00:45:29 +02:00
|
|
|
file_props = gajim.socks5queue.get_file_props(
|
|
|
|
self.name, sid)
|
2005-07-30 12:19:52 +02:00
|
|
|
streamhosts=[]
|
|
|
|
for item in query.getChildren():
|
|
|
|
if item.getName() == 'streamhost':
|
2005-08-06 18:31:41 +02:00
|
|
|
host_dict={
|
2005-08-06 22:18:44 +02:00
|
|
|
'state': 0,
|
|
|
|
'target': target,
|
|
|
|
'id': id,
|
2005-08-07 15:24:21 +02:00
|
|
|
'sid': sid,
|
2005-08-26 02:52:44 +02:00
|
|
|
'initiator': unicode(iq_obj.getFrom())
|
2005-08-06 18:31:41 +02:00
|
|
|
}
|
2005-07-30 12:19:52 +02:00
|
|
|
for attr in item.getAttrs():
|
2005-08-26 02:52:44 +02:00
|
|
|
host_dict[attr] = item.getAttr(attr)
|
2005-07-30 12:19:52 +02:00
|
|
|
streamhosts.append(host_dict)
|
2005-08-06 18:31:41 +02:00
|
|
|
if file_props is None:
|
|
|
|
if self.files_props.has_key(sid):
|
|
|
|
file_props = self.files_props[sid]
|
|
|
|
file_props['fast'] = streamhosts
|
2005-08-07 14:05:36 +02:00
|
|
|
if file_props['type'] == 's':
|
|
|
|
# only psi do this
|
|
|
|
|
|
|
|
if file_props.has_key('streamhosts'):
|
|
|
|
file_props['streamhosts'].extend(streamhosts)
|
|
|
|
else:
|
|
|
|
file_props['streamhosts'] = streamhosts
|
|
|
|
if not gajim.socks5queue.get_file_props(self.name, sid):
|
|
|
|
gajim.socks5queue.add_file_props(self.name, file_props)
|
|
|
|
gajim.socks5queue.connect_to_hosts(self.name, sid,
|
|
|
|
self.send_success_connect_reply, None)
|
2005-08-06 18:31:41 +02:00
|
|
|
raise common.xmpp.NodeProcessed
|
|
|
|
fast = None
|
|
|
|
try:
|
|
|
|
fast = query.getTag('fast')
|
|
|
|
except Exception, e:
|
|
|
|
pass
|
|
|
|
file_props['streamhosts'] = streamhosts
|
|
|
|
conn_err = False
|
|
|
|
if file_props['type'] == 'r':
|
|
|
|
gajim.socks5queue.connect_to_hosts(self.name, sid,
|
|
|
|
self.send_success_connect_reply, self._connect_error)
|
|
|
|
raise common.xmpp.NodeProcessed
|
|
|
|
|
|
|
|
def send_success_connect_reply(self, streamhost):
|
|
|
|
''' send reply to the initiator of FT that we
|
|
|
|
made a connection
|
|
|
|
'''
|
|
|
|
if streamhost is None:
|
|
|
|
return None
|
2005-08-06 22:18:44 +02:00
|
|
|
iq = common.xmpp.Iq(to = streamhost['initiator'], typ = 'result',
|
2005-08-06 18:31:41 +02:00
|
|
|
frm = streamhost['target'])
|
|
|
|
iq.setAttr('id', streamhost['id'])
|
|
|
|
query = iq.setTag('query')
|
|
|
|
query.setNamespace(common.xmpp.NS_BYTESTREAM)
|
|
|
|
stream_tag = query.setTag('streamhost-used')
|
|
|
|
stream_tag.setAttr('jid', streamhost['jid'])
|
|
|
|
self.to_be_sent.append(iq)
|
2005-08-07 20:43:53 +02:00
|
|
|
|
2005-08-15 00:29:16 +02:00
|
|
|
def _connect_error(self, to, _id, sid, code = 404):
|
2005-08-06 18:31:41 +02:00
|
|
|
msg_dict = {
|
2005-08-06 22:18:44 +02:00
|
|
|
404: 'Could not connect to given hosts',
|
|
|
|
405: 'Cancel',
|
|
|
|
406: 'Not acceptable',
|
2005-08-06 18:31:41 +02:00
|
|
|
}
|
|
|
|
msg = msg_dict[code]
|
|
|
|
iq = None
|
|
|
|
iq = common.xmpp.Protocol(name = 'iq', to = to,
|
|
|
|
typ = 'error')
|
2005-08-11 22:26:17 +02:00
|
|
|
iq.setAttr('id', _id)
|
2005-08-06 18:31:41 +02:00
|
|
|
err = iq.setTag('error')
|
2005-08-26 02:52:44 +02:00
|
|
|
err.setAttr('code', unicode(code))
|
2005-08-06 18:31:41 +02:00
|
|
|
err.setData(msg)
|
|
|
|
self.to_be_sent.append(iq)
|
2005-08-11 22:26:17 +02:00
|
|
|
if code == 404:
|
|
|
|
file_props = gajim.socks5queue.get_file_props(self.name, sid)
|
2005-08-15 00:29:16 +02:00
|
|
|
if file_props is not None:
|
|
|
|
self.disconnect_transfer(file_props)
|
|
|
|
file_props['error'] = -3
|
|
|
|
self.dispatch('FILE_REQUEST_ERROR', (to, file_props))
|
2005-08-03 16:04:54 +02:00
|
|
|
|
|
|
|
def _bytestreamResultCB(self, con, iq_obj):
|
|
|
|
gajim.log.debug('_bytestreamResultCB')
|
2005-08-26 02:52:44 +02:00
|
|
|
frm = unicode(iq_obj.getFrom())
|
|
|
|
real_id = unicode(iq_obj.getAttr('id'))
|
2005-08-03 16:04:54 +02:00
|
|
|
query = iq_obj.getTag('query')
|
2005-08-06 22:18:44 +02:00
|
|
|
streamhost = None
|
|
|
|
try:
|
|
|
|
streamhost = query.getTag('streamhost')
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
if streamhost is not None: # this is a result for proxy request
|
2005-08-06 23:40:01 +02:00
|
|
|
jid = None
|
|
|
|
try:
|
|
|
|
jid = streamhost.getAttr('jid')
|
|
|
|
except:
|
|
|
|
raise common.xmpp.NodeProcessed
|
2005-08-06 18:31:41 +02:00
|
|
|
proxyhosts = []
|
|
|
|
for item in query.getChildren():
|
|
|
|
if item.getName() == 'streamhost':
|
2005-08-06 22:18:44 +02:00
|
|
|
host = item.getAttr('host')
|
|
|
|
port = item.getAttr('port')
|
|
|
|
jid = item.getAttr('jid')
|
|
|
|
conf = gajim.config
|
2005-08-09 16:53:33 +02:00
|
|
|
conf.add_per('ft_proxies65_cache', jid)
|
2005-08-26 02:52:44 +02:00
|
|
|
conf.set_per('ft_proxies65_cache', jid,
|
|
|
|
'host', unicode(host))
|
|
|
|
conf.set_per('ft_proxies65_cache', jid,
|
|
|
|
'port', int(port))
|
|
|
|
conf.set_per('ft_proxies65_cache', jid,
|
|
|
|
'jid', unicode(jid))
|
2005-08-06 22:18:44 +02:00
|
|
|
raise common.xmpp.NodeProcessed
|
|
|
|
try:
|
|
|
|
streamhost = query.getTag('streamhost-used')
|
|
|
|
except: # this bytestream result is not what we need
|
2005-08-06 23:40:01 +02:00
|
|
|
pass
|
2005-08-06 22:18:44 +02:00
|
|
|
id = real_id[3:]
|
|
|
|
if self.files_props.has_key(id):
|
|
|
|
file_props = self.files_props[id]
|
|
|
|
else:
|
|
|
|
raise common.xmpp.NodeProcessed
|
2005-08-10 17:59:55 +02:00
|
|
|
if streamhost is None:
|
|
|
|
# proxy approves the activate query
|
|
|
|
if real_id[:3] == 'au_':
|
|
|
|
id = real_id[3:]
|
|
|
|
if not file_props.has_key('streamhost-used') or \
|
|
|
|
file_props['streamhost-used'] is False:
|
|
|
|
raise common.xmpp.NodeProcessed
|
|
|
|
if not file_props.has_key('proxyhosts'):
|
|
|
|
raise common.xmpp.NodeProcessed
|
|
|
|
for host in file_props['proxyhosts']:
|
|
|
|
if host['initiator'] == frm and \
|
2005-08-26 02:52:44 +02:00
|
|
|
unicode(query.getAttr('sid')) == file_props['sid']:
|
2005-08-10 17:59:55 +02:00
|
|
|
gajim.socks5queue.activate_proxy(host['idx'])
|
|
|
|
break
|
|
|
|
raise common.xmpp.NodeProcessed
|
|
|
|
jid = streamhost.getAttr('jid')
|
2005-08-09 13:38:11 +02:00
|
|
|
if file_props.has_key('streamhost-used') and \
|
|
|
|
file_props['streamhost-used'] is True:
|
|
|
|
raise common.xmpp.NodeProcessed
|
|
|
|
|
|
|
|
if real_id[:3] == 'au_':
|
|
|
|
gajim.socks5queue.send_file(file_props, self.name)
|
|
|
|
raise common.xmpp.NodeProcessed
|
|
|
|
|
2005-08-06 18:31:41 +02:00
|
|
|
proxy = None
|
|
|
|
if file_props.has_key('proxyhosts'):
|
|
|
|
for proxyhost in file_props['proxyhosts']:
|
|
|
|
if proxyhost['jid'] == jid:
|
|
|
|
proxy = proxyhost
|
2005-08-06 22:18:44 +02:00
|
|
|
|
2005-08-06 18:31:41 +02:00
|
|
|
if proxy != None:
|
2005-08-09 13:38:11 +02:00
|
|
|
file_props['streamhost-used'] = True
|
2005-08-06 18:31:41 +02:00
|
|
|
if not file_props.has_key('streamhosts'):
|
2005-08-09 13:38:11 +02:00
|
|
|
file_props['streamhosts'] = []
|
2005-08-06 18:31:41 +02:00
|
|
|
file_props['streamhosts'].append(proxy)
|
|
|
|
file_props['is_a_proxy'] = True
|
|
|
|
receiver = socks5.Socks5Receiver(proxy, file_props['sid'], file_props)
|
|
|
|
gajim.socks5queue.add_receiver(self.name, receiver)
|
|
|
|
proxy['idx'] = receiver.queue_idx
|
|
|
|
gajim.socks5queue.on_success = self.proxy_auth_ok
|
|
|
|
raise common.xmpp.NodeProcessed
|
2005-08-09 13:38:11 +02:00
|
|
|
|
|
|
|
else:
|
2005-08-06 18:31:41 +02:00
|
|
|
gajim.socks5queue.send_file(file_props, self.name)
|
|
|
|
if file_props.has_key('fast'):
|
|
|
|
fasts = file_props['fast']
|
|
|
|
if len(fasts) > 0:
|
2005-08-26 02:52:44 +02:00
|
|
|
self._connect_error(unicode(iq_obj.getFrom()),
|
|
|
|
fasts[0]['id'], file_props['sid'], code = 406)
|
2005-08-09 13:38:11 +02:00
|
|
|
|
2005-08-03 16:04:54 +02:00
|
|
|
raise common.xmpp.NodeProcessed
|
2005-08-06 18:31:41 +02:00
|
|
|
|
2005-08-10 17:59:55 +02:00
|
|
|
def remove_all_transfers(self):
|
|
|
|
''' stops and removes all active connections from the socks5 pool '''
|
|
|
|
for file_props in self.files_props.values():
|
|
|
|
self.remove_transfer(file_props, remove_from_list = False)
|
|
|
|
del(self.files_props)
|
|
|
|
self.files_props = {}
|
|
|
|
|
|
|
|
def remove_transfer(self, file_props, remove_from_list = True):
|
2005-08-12 21:09:20 +02:00
|
|
|
if file_props is None:
|
|
|
|
return
|
2005-08-10 17:59:55 +02:00
|
|
|
if file_props.has_key('hash'):
|
|
|
|
gajim.socks5queue.remove_sender(file_props['hash'])
|
|
|
|
|
|
|
|
if file_props.has_key('streamhosts'):
|
|
|
|
for host in file_props['streamhosts']:
|
2005-08-15 00:29:16 +02:00
|
|
|
if host.has_key('idx') and host['idx'] > 0:
|
2005-08-10 17:59:55 +02:00
|
|
|
gajim.socks5queue.remove_receiver(host['idx'])
|
|
|
|
gajim.socks5queue.remove_sender(host['idx'])
|
|
|
|
sid = file_props['sid']
|
|
|
|
gajim.socks5queue.remove_file_props(self.name, sid)
|
|
|
|
|
|
|
|
if remove_from_list:
|
|
|
|
if self.files_props.has_key('sid'):
|
|
|
|
del(self.files_props['sid'])
|
|
|
|
|
|
|
|
def disconnect_transfer(self, file_props):
|
2005-08-12 21:09:20 +02:00
|
|
|
if file_props is None:
|
|
|
|
return
|
2005-08-10 17:59:55 +02:00
|
|
|
if file_props.has_key('hash'):
|
|
|
|
gajim.socks5queue.remove_sender(file_props['hash'])
|
|
|
|
|
|
|
|
if file_props.has_key('streamhosts'):
|
|
|
|
for host in file_props['streamhosts']:
|
2005-08-15 00:29:16 +02:00
|
|
|
if host.has_key('idx') and host['idx'] > 0:
|
2005-08-10 17:59:55 +02:00
|
|
|
gajim.socks5queue.remove_receiver(host['idx'])
|
|
|
|
gajim.socks5queue.remove_sender(host['idx'])
|
|
|
|
|
2005-08-06 18:31:41 +02:00
|
|
|
def proxy_auth_ok(self, proxy):
|
2005-08-07 15:24:21 +02:00
|
|
|
'''cb, called after authentication to proxy server '''
|
|
|
|
file_props = self.files_props[proxy['sid']]
|
2005-08-06 18:31:41 +02:00
|
|
|
iq = common.xmpp.Protocol(name = 'iq', to = proxy['initiator'],
|
|
|
|
typ = 'set')
|
2005-08-07 15:26:03 +02:00
|
|
|
auth_id = "au_" + proxy['sid']
|
2005-08-06 18:31:41 +02:00
|
|
|
iq.setID(auth_id)
|
|
|
|
query = iq.setTag('query')
|
|
|
|
query.setNamespace(common.xmpp.NS_BYTESTREAM)
|
2005-08-07 15:26:03 +02:00
|
|
|
query.setAttr('sid', proxy['sid'])
|
2005-08-06 18:31:41 +02:00
|
|
|
activate = query.setTag('activate')
|
|
|
|
activate.setData(file_props['proxy_receiver'])
|
|
|
|
iq.setID(auth_id)
|
|
|
|
self.to_be_sent.append(iq)
|
2005-08-03 16:04:54 +02:00
|
|
|
|
2005-07-30 17:06:35 +02:00
|
|
|
def _discoGetCB(self, con, iq_obj):
|
|
|
|
''' get disco info '''
|
2005-08-26 02:52:44 +02:00
|
|
|
frm = unicode(iq_obj.getFrom())
|
|
|
|
to = unicode(iq_obj.getAttr('to'))
|
|
|
|
id = unicode(iq_obj.getAttr('id'))
|
2005-07-30 17:06:35 +02:00
|
|
|
iq = common.xmpp.Iq(to = frm, typ = 'result', queryNS =\
|
|
|
|
common.xmpp.NS_DISCO, frm = to)
|
|
|
|
iq.setAttr('id', id)
|
2005-08-01 17:00:27 +02:00
|
|
|
query = iq.setTag('query')
|
2005-07-30 17:06:35 +02:00
|
|
|
# bytestream transfers
|
|
|
|
feature = common.xmpp.Node('feature')
|
2005-08-01 17:00:27 +02:00
|
|
|
feature.setAttr('var', common.xmpp.NS_BYTESTREAM)
|
|
|
|
query.addChild(node=feature)
|
|
|
|
# si methods
|
|
|
|
feature = common.xmpp.Node('feature')
|
|
|
|
feature.setAttr('var', common.xmpp.NS_SI)
|
|
|
|
query.addChild(node=feature)
|
2005-07-30 17:06:35 +02:00
|
|
|
# filetransfers transfers
|
2005-08-01 17:00:27 +02:00
|
|
|
feature = common.xmpp.Node('feature')
|
|
|
|
feature.setAttr('var', common.xmpp.NS_FILE)
|
|
|
|
query.addChild(node=feature)
|
|
|
|
|
2005-07-30 17:06:35 +02:00
|
|
|
self.to_be_sent.append(iq)
|
|
|
|
raise common.xmpp.NodeProcessed
|
2005-08-03 16:04:54 +02:00
|
|
|
|
|
|
|
def _siResultCB(self, con, iq_obj):
|
|
|
|
gajim.log.debug('_siResultCB')
|
|
|
|
id = iq_obj.getAttr('id')
|
|
|
|
if not self.files_props.has_key(id):
|
2005-08-04 13:18:26 +02:00
|
|
|
# no such jid
|
2005-08-03 16:04:54 +02:00
|
|
|
return
|
|
|
|
file_props = self.files_props[id]
|
|
|
|
if file_props is None:
|
2005-08-04 13:18:26 +02:00
|
|
|
# file properties for jid is none
|
2005-08-03 16:04:54 +02:00
|
|
|
return
|
2005-08-26 02:52:44 +02:00
|
|
|
file_props['receiver'] = unicode(iq_obj.getFrom())
|
|
|
|
jid = iq_obj.getFrom().getStripped()
|
2005-08-03 16:04:54 +02:00
|
|
|
si = iq_obj.getTag('si')
|
|
|
|
feature = si.setTag('feature')
|
|
|
|
if feature.getNamespace() != common.xmpp.NS_FEATURE:
|
|
|
|
return
|
|
|
|
form_tag = feature.getTag('x')
|
|
|
|
form = common.xmpp.DataForm(node=form_tag)
|
|
|
|
field = form.getField('stream-method')
|
|
|
|
if field.getValue() != common.xmpp.NS_BYTESTREAM:
|
|
|
|
return
|
2005-08-06 18:31:41 +02:00
|
|
|
self.send_socks5_info(file_props, fast = True)
|
2005-08-03 16:04:54 +02:00
|
|
|
raise common.xmpp.NodeProcessed
|
|
|
|
|
|
|
|
def _get_sha(self, sid, initiator, target):
|
|
|
|
import sha
|
|
|
|
return sha.new("%s%s%s" % (sid, initiator, target)).hexdigest()
|
2005-07-30 12:19:52 +02:00
|
|
|
|
2005-08-03 16:04:54 +02:00
|
|
|
def result_socks5_sid(self, sid, hash_id):
|
2005-08-06 18:31:41 +02:00
|
|
|
''' store the result of sha message from auth '''
|
2005-08-03 16:04:54 +02:00
|
|
|
if not self.files_props.has_key(sid):
|
|
|
|
return
|
|
|
|
file_props = self.files_props[sid]
|
|
|
|
file_props['hash'] = hash_id
|
|
|
|
return
|
|
|
|
|
2005-08-06 22:18:44 +02:00
|
|
|
|
|
|
|
def get_cached_proxies(self, proxy):
|
|
|
|
''' get cached entries for proxy and request the cache again '''
|
2005-08-09 16:53:33 +02:00
|
|
|
host = gajim.config.get_per('ft_proxies65_cache', proxy, 'host')
|
|
|
|
port = gajim.config.get_per('ft_proxies65_cache', proxy, 'port')
|
|
|
|
jid = gajim.config.get_per('ft_proxies65_cache', proxy, 'jid')
|
2005-08-06 22:18:44 +02:00
|
|
|
|
|
|
|
iq = common.xmpp.Protocol(name = 'iq', to = proxy, typ = 'get')
|
|
|
|
query = iq.setTag('query')
|
|
|
|
query.setNamespace(common.xmpp.NS_BYTESTREAM)
|
2005-08-07 14:05:36 +02:00
|
|
|
# FIXME bad logic - this should be somewhere else!
|
|
|
|
# this line should be put somewhere else
|
|
|
|
# self.to_be_sent.append(iq)
|
2005-08-06 22:18:44 +02:00
|
|
|
# ensure that we don;t return empty vars
|
|
|
|
if None not in (host, port, jid) or '' not in (host, port, jid):
|
|
|
|
return (host, port, jid)
|
|
|
|
return (None, None, None)
|
|
|
|
|
2005-08-06 18:31:41 +02:00
|
|
|
def send_socks5_info(self, file_props, fast = True, receiver = None,
|
|
|
|
sender = None):
|
2005-08-06 22:18:44 +02:00
|
|
|
''' send iq for the present streamhosts and proxies '''
|
2005-08-03 16:04:54 +02:00
|
|
|
if type(self.peerhost) != tuple:
|
|
|
|
return
|
2005-08-03 23:10:59 +02:00
|
|
|
port = gajim.config.get('file_transfers_port')
|
2005-08-12 15:40:42 +02:00
|
|
|
ft_override_host_to_send = gajim.config.get('ft_override_host_to_send')
|
2005-08-11 22:26:17 +02:00
|
|
|
cfg_proxies = gajim.config.get_per('accounts', self.name, 'file_transfer_proxies')
|
2005-08-06 18:31:41 +02:00
|
|
|
if receiver is None:
|
|
|
|
receiver = file_props['receiver']
|
|
|
|
if sender is None:
|
|
|
|
sender = file_props['sender']
|
2005-08-06 22:18:44 +02:00
|
|
|
proxyhosts = []
|
2005-08-11 22:26:17 +02:00
|
|
|
if fast and cfg_proxies:
|
|
|
|
proxies = map(lambda e:e.strip(), cfg_proxies.split(','))
|
2005-08-06 22:18:44 +02:00
|
|
|
for proxy in proxies:
|
|
|
|
(host, _port, jid) = self.get_cached_proxies(proxy)
|
|
|
|
if host is None:
|
|
|
|
continue
|
|
|
|
host_dict={
|
|
|
|
'state': 0,
|
2005-08-26 02:52:44 +02:00
|
|
|
'target': unicode(receiver),
|
2005-08-06 22:50:47 +02:00
|
|
|
'id': file_props['sid'],
|
2005-08-07 15:24:21 +02:00
|
|
|
'sid': file_props['sid'],
|
2005-08-06 22:18:44 +02:00
|
|
|
'initiator': proxy,
|
|
|
|
'host': host,
|
2005-08-26 02:52:44 +02:00
|
|
|
'port': unicode(_port),
|
2005-08-06 22:18:44 +02:00
|
|
|
'jid': jid
|
|
|
|
}
|
|
|
|
proxyhosts.append(host_dict)
|
2005-08-06 18:31:41 +02:00
|
|
|
sha_str = self._get_sha(file_props['sid'], sender,
|
|
|
|
receiver)
|
2005-08-03 16:04:54 +02:00
|
|
|
file_props['sha_str'] = sha_str
|
2005-08-12 15:40:42 +02:00
|
|
|
if not ft_override_host_to_send:
|
|
|
|
ft_override_host_to_send = self.peerhost[0]
|
2005-08-12 16:59:28 +02:00
|
|
|
ft_override_host_to_send = socket.gethostbyname(ft_override_host_to_send)
|
2005-08-03 16:04:54 +02:00
|
|
|
listener = gajim.socks5queue.start_listener(self.peerhost[0], port,
|
|
|
|
sha_str, self.result_socks5_sid, file_props['sid'])
|
|
|
|
if listener == None:
|
2005-08-12 21:09:20 +02:00
|
|
|
file_props['error'] = -5
|
2005-08-26 02:52:44 +02:00
|
|
|
self.dispatch('FILE_REQUEST_ERROR', (unicode(receiver), file_props))
|
|
|
|
self._connect_error(unicode(receiver), file_props['sid'],
|
2005-08-15 00:29:16 +02:00
|
|
|
file_props['sid'], code = 406)
|
2005-08-03 16:04:54 +02:00
|
|
|
return
|
2005-08-06 18:31:41 +02:00
|
|
|
|
2005-08-26 02:52:44 +02:00
|
|
|
iq = common.xmpp.Protocol(name = 'iq', to = unicode(receiver),
|
2005-08-03 16:04:54 +02:00
|
|
|
typ = 'set')
|
|
|
|
file_props['request-id'] = 'id_' + file_props['sid']
|
|
|
|
iq.setID(file_props['request-id'])
|
|
|
|
query = iq.setTag('query')
|
|
|
|
query.setNamespace(common.xmpp.NS_BYTESTREAM)
|
|
|
|
query.setAttr('mode', 'tcp')
|
|
|
|
query.setAttr('sid', file_props['sid'])
|
|
|
|
streamhost = query.setTag('streamhost')
|
2005-08-26 02:52:44 +02:00
|
|
|
streamhost.setAttr('port', unicode(port))
|
2005-08-12 15:40:42 +02:00
|
|
|
streamhost.setAttr('host', ft_override_host_to_send)
|
2005-08-06 18:31:41 +02:00
|
|
|
streamhost.setAttr('jid', sender)
|
2005-08-06 23:43:04 +02:00
|
|
|
if fast and proxyhosts != []:
|
2005-08-26 02:52:44 +02:00
|
|
|
file_props['proxy_receiver'] = unicode(receiver)
|
|
|
|
file_props['proxy_sender'] = unicode(sender)
|
2005-08-06 22:18:44 +02:00
|
|
|
file_props['proxyhosts'] = proxyhosts
|
|
|
|
for proxyhost in proxyhosts:
|
|
|
|
streamhost = common.xmpp.Node(tag = 'streamhost')
|
|
|
|
query.addChild(node=streamhost)
|
|
|
|
streamhost.setAttr('port', proxyhost['port'])
|
|
|
|
streamhost.setAttr('host', proxyhost['host'])
|
|
|
|
streamhost.setAttr('jid', proxyhost['jid'])
|
2005-08-17 17:48:14 +02:00
|
|
|
|
|
|
|
# don't add the proxy child tag for streamhosts, which are proxies
|
|
|
|
# proxy = streamhost.setTag('proxy')
|
|
|
|
# proxy.setNamespace(common.xmpp.NS_STREAM)
|
2005-08-03 16:04:54 +02:00
|
|
|
self.to_be_sent.append(iq)
|
|
|
|
|
2005-07-30 12:19:52 +02:00
|
|
|
def _siSetCB(self, con, iq_obj):
|
|
|
|
gajim.log.debug('_siSetCB')
|
2005-08-26 02:52:44 +02:00
|
|
|
jid = iq_obj.getFrom().getStripped()
|
2005-07-30 12:19:52 +02:00
|
|
|
si = iq_obj.getTag('si')
|
|
|
|
profile = si.getAttr('profile')
|
|
|
|
mime_type = si.getAttr('mime-type')
|
2005-07-30 17:30:38 +02:00
|
|
|
if profile != common.xmpp.NS_FILE:
|
2005-07-30 12:19:52 +02:00
|
|
|
return
|
|
|
|
feature = si.getTag('feature')
|
|
|
|
file_tag = si.getTag('file')
|
2005-08-06 22:18:44 +02:00
|
|
|
file_props = {'type': 'r'}
|
2005-07-30 12:19:52 +02:00
|
|
|
for attribute in file_tag.getAttrs():
|
|
|
|
if attribute in ['name', 'size', 'hash', 'date']:
|
|
|
|
val = file_tag.getAttr(attribute)
|
|
|
|
if val is None:
|
|
|
|
continue
|
|
|
|
file_props[attribute] = val
|
|
|
|
file_desc_tag = file_tag.getTag('desc')
|
|
|
|
if file_desc_tag is not None:
|
|
|
|
file_props['desc'] = file_desc_tag.getData()
|
|
|
|
|
|
|
|
if mime_type is not None:
|
|
|
|
file_props['mime-type'] = mime_type
|
2005-08-06 18:31:41 +02:00
|
|
|
name = gajim.config.get_per('accounts', self.name, 'name')
|
|
|
|
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
|
|
|
|
resource = gajim.config.get_per('accounts', self.name, 'resource')
|
|
|
|
file_props['receiver'] = name + '@' + hostname + '/' + resource
|
2005-07-30 12:19:52 +02:00
|
|
|
file_props['sender'] = iq_obj.getFrom()
|
2005-08-26 02:52:44 +02:00
|
|
|
file_props['request-id'] = unicode(iq_obj.getAttr('id'))
|
|
|
|
file_props['sid'] = unicode(si.getAttr('id'))
|
2005-08-02 00:45:29 +02:00
|
|
|
gajim.socks5queue.add_file_props(self.name, file_props)
|
2005-07-30 12:19:52 +02:00
|
|
|
self.dispatch('FILE_REQUEST', (jid, file_props))
|
|
|
|
raise common.xmpp.NodeProcessed
|
2005-07-30 16:13:45 +02:00
|
|
|
|
2005-08-23 23:52:56 +02:00
|
|
|
def _siErrorCB(self, con, iq_obj):
|
|
|
|
gajim.log.debug('_siErrorCB')
|
|
|
|
si = iq_obj.getTag('si')
|
|
|
|
profile = si.getAttr('profile')
|
|
|
|
if profile != common.xmpp.NS_FILE:
|
|
|
|
return
|
|
|
|
id = iq_obj.getAttr('id')
|
|
|
|
if not self.files_props.has_key(id):
|
|
|
|
# no such jid
|
|
|
|
return
|
|
|
|
file_props = self.files_props[id]
|
|
|
|
if file_props is None:
|
|
|
|
# file properties for jid is none
|
|
|
|
return
|
2005-08-26 02:52:44 +02:00
|
|
|
jid = iq_obj.getFrom().getStripped()
|
2005-08-23 23:52:56 +02:00
|
|
|
file_props['error'] = -3
|
|
|
|
self.dispatch('FILE_REQUEST_ERROR', (jid, file_props))
|
|
|
|
raise common.xmpp.NodeProcessed
|
|
|
|
|
2005-07-30 16:13:45 +02:00
|
|
|
def send_file_rejection(self, file_props):
|
|
|
|
''' informs sender that we refuse to download the file '''
|
2005-08-26 02:52:44 +02:00
|
|
|
iq = common.xmpp.Protocol(name = 'iq',
|
|
|
|
to = unicode(file_props['sender']), typ = 'error')
|
2005-07-30 16:13:45 +02:00
|
|
|
iq.setAttr('id', file_props['request-id'])
|
|
|
|
err = common.xmpp.ErrorNode(code = '406', typ = 'auth', name = 'not-acceptable')
|
|
|
|
iq.addChild(node=err)
|
|
|
|
self.to_be_sent.append(iq)
|
|
|
|
|
2005-07-30 12:19:52 +02:00
|
|
|
def send_file_approval(self, file_props):
|
2005-07-30 16:13:45 +02:00
|
|
|
''' comfirm that we want to download the file '''
|
2005-08-26 02:52:44 +02:00
|
|
|
iq = common.xmpp.Protocol(name = 'iq',
|
|
|
|
to = unicode(file_props['sender']), typ = 'result')
|
2005-07-30 12:19:52 +02:00
|
|
|
iq.setAttr('id', file_props['request-id'])
|
|
|
|
si = iq.setTag('si')
|
|
|
|
si.setNamespace(common.xmpp.NS_SI)
|
|
|
|
file_tag = si.setTag('file')
|
|
|
|
file_tag.setNamespace(common.xmpp.NS_FILE)
|
|
|
|
feature = si.setTag('feature')
|
|
|
|
feature.setNamespace(common.xmpp.NS_FEATURE)
|
|
|
|
_feature = common.xmpp.DataForm(typ='submit')
|
|
|
|
feature.addChild(node=_feature)
|
|
|
|
field = _feature.setField('stream-method')
|
|
|
|
field.delAttr('type')
|
|
|
|
field.setValue('http://jabber.org/protocol/bytestreams')
|
|
|
|
self.to_be_sent.append(iq)
|
|
|
|
|
2005-08-03 16:04:54 +02:00
|
|
|
def send_file_request(self, file_props):
|
|
|
|
name = gajim.config.get_per('accounts', self.name, 'name')
|
|
|
|
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
|
|
|
|
resource = gajim.config.get_per('accounts', self.name, 'resource')
|
|
|
|
frm = name + '@' + hostname + '/' + resource
|
|
|
|
file_props['sender'] = frm
|
|
|
|
fjid = file_props['receiver'].jid + '/' + file_props['receiver'].resource
|
|
|
|
iq = common.xmpp.Protocol(name = 'iq', to = fjid,
|
|
|
|
typ = 'set')
|
|
|
|
iq.setID(file_props['sid'])
|
|
|
|
self.files_props[file_props['sid']] = file_props
|
|
|
|
si = iq.setTag('si')
|
|
|
|
si.setNamespace(common.xmpp.NS_SI)
|
|
|
|
si.setAttr('profile', common.xmpp.NS_FILE)
|
|
|
|
si.setAttr('id', file_props['sid'])
|
|
|
|
file_tag = si.setTag('file')
|
|
|
|
file_tag.setNamespace(common.xmpp.NS_FILE)
|
|
|
|
file_tag.setAttr('name', file_props['name'])
|
|
|
|
file_tag.setAttr('size', file_props['size'])
|
|
|
|
desc = file_tag.setTag('desc')
|
|
|
|
if file_props.has_key('desc'):
|
|
|
|
desc.setData(file_props['desc'])
|
|
|
|
file_tag.setTag('range')
|
|
|
|
feature = si.setTag('feature')
|
|
|
|
feature.setNamespace(common.xmpp.NS_FEATURE)
|
|
|
|
_feature = common.xmpp.DataForm(typ='form')
|
|
|
|
feature.addChild(node=_feature)
|
|
|
|
field = _feature.setField('stream-method')
|
|
|
|
field.setAttr('type', 'list-single')
|
|
|
|
field.addOption('http://jabber.org/protocol/bytestreams')
|
|
|
|
self.to_be_sent.append(iq)
|
|
|
|
|
2005-04-12 13:46:20 +02:00
|
|
|
def _rosterSetCB(self, con, iq_obj):
|
2005-04-20 12:21:33 +02:00
|
|
|
gajim.log.debug('rosterSetCB')
|
2005-04-26 20:45:54 +02:00
|
|
|
for item in iq_obj.getTag('query').getChildren():
|
2005-08-26 02:52:44 +02:00
|
|
|
jid = item.getAttr('jid')
|
2005-04-12 13:46:20 +02:00
|
|
|
name = item.getAttr('name')
|
2005-08-26 02:52:44 +02:00
|
|
|
sub = item.getAttr('subscription')
|
2005-04-12 13:46:20 +02:00
|
|
|
ask = item.getAttr('ask')
|
|
|
|
groups = []
|
|
|
|
for group in item.getTags('group'):
|
2005-08-26 02:52:44 +02:00
|
|
|
groups.append(group.getData())
|
2005-04-12 13:46:20 +02:00
|
|
|
self.dispatch('ROSTER_INFO', (jid, name, sub, ask, groups))
|
2005-05-11 09:55:17 +02:00
|
|
|
raise common.xmpp.NodeProcessed
|
2005-04-12 13:46:20 +02:00
|
|
|
|
|
|
|
def _BrowseResultCB(self, con, iq_obj):
|
2005-04-20 12:21:33 +02:00
|
|
|
gajim.log.debug('BrowseResultCB')
|
2005-04-12 13:46:20 +02:00
|
|
|
identities, features, items = [], [], []
|
2005-05-07 14:24:19 +02:00
|
|
|
for q in iq_obj.getChildren():
|
|
|
|
if q.getNamespace() != common.xmpp.NS_BROWSE:
|
|
|
|
continue
|
|
|
|
attr = {}
|
|
|
|
for key in q.getAttrs().keys():
|
2005-08-26 02:52:44 +02:00
|
|
|
attr[key] = q.getAttr(key)
|
2005-05-07 14:24:19 +02:00
|
|
|
identities = [attr]
|
|
|
|
for node in q.getChildren():
|
|
|
|
if node.getName() == 'ns':
|
|
|
|
features.append(node.getData())
|
|
|
|
else:
|
|
|
|
infos = {}
|
|
|
|
for key in node.getAttrs().keys():
|
2005-08-26 02:52:44 +02:00
|
|
|
infos[key] = node.getAttr(key)
|
2005-05-07 14:24:19 +02:00
|
|
|
infos['category'] = node.getName()
|
|
|
|
items.append(infos)
|
2005-08-26 02:52:44 +02:00
|
|
|
jid = unicode(iq_obj.getFrom())
|
2005-05-07 14:24:19 +02:00
|
|
|
self.dispatch('AGENT_INFO', (jid, identities, features, items))
|
2005-04-12 13:46:20 +02:00
|
|
|
|
|
|
|
def _DiscoverItemsCB(self, con, iq_obj):
|
2005-04-20 12:21:33 +02:00
|
|
|
gajim.log.debug('DiscoverItemsCB')
|
2005-04-26 20:45:54 +02:00
|
|
|
q = iq_obj.getTag('query')
|
2005-04-23 23:54:12 +02:00
|
|
|
node = q.getAttr('node')
|
|
|
|
if not node:
|
|
|
|
node = ''
|
2005-04-12 13:46:20 +02:00
|
|
|
qp = iq_obj.getQueryPayload()
|
|
|
|
items = []
|
|
|
|
if not qp:
|
|
|
|
qp = []
|
|
|
|
for i in qp:
|
|
|
|
attr = {}
|
2005-04-26 20:45:54 +02:00
|
|
|
for key in i.getAttrs():
|
2005-08-26 02:52:44 +02:00
|
|
|
attr[key] = i.getAttrs()[key]
|
2005-04-12 13:46:20 +02:00
|
|
|
items.append(attr)
|
2005-08-26 02:52:44 +02:00
|
|
|
jid = unicode(iq_obj.getFrom())
|
2005-04-23 23:54:12 +02:00
|
|
|
self.dispatch('AGENT_INFO_ITEMS', (jid, node, items))
|
2005-04-12 13:46:20 +02:00
|
|
|
|
|
|
|
def _DiscoverInfoErrorCB(self, con, iq_obj):
|
2005-04-20 12:21:33 +02:00
|
|
|
gajim.log.debug('DiscoverInfoErrorCB')
|
2005-04-26 20:45:54 +02:00
|
|
|
iq = common.xmpp.Iq(to = iq_obj.getFrom(), typ = 'get', queryNS =\
|
|
|
|
common.xmpp.NS_AGENTS)
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
|
|
|
def _DiscoverInfoCB(self, con, iq_obj):
|
2005-04-20 12:21:33 +02:00
|
|
|
gajim.log.debug('DiscoverInfoCB')
|
2005-04-12 13:46:20 +02:00
|
|
|
# According to JEP-0030:
|
|
|
|
# For identity: category, name is mandatory, type is optional.
|
|
|
|
# For feature: var is mandatory
|
|
|
|
identities, features = [], []
|
2005-04-26 20:45:54 +02:00
|
|
|
q = iq_obj.getTag('query')
|
2005-04-23 23:54:12 +02:00
|
|
|
node = q.getAttr('node')
|
|
|
|
if not node:
|
|
|
|
node = ''
|
2005-04-26 20:45:54 +02:00
|
|
|
qc = iq_obj.getQueryChildren()
|
|
|
|
if not qc:
|
|
|
|
qc = []
|
|
|
|
for i in qc:
|
2005-04-12 13:46:20 +02:00
|
|
|
if i.getName() == 'identity':
|
|
|
|
attr = {}
|
2005-04-26 20:45:54 +02:00
|
|
|
for key in i.getAttrs().keys():
|
2005-08-26 02:52:44 +02:00
|
|
|
attr[key] = i.getAttr(key)
|
2005-04-12 13:46:20 +02:00
|
|
|
identities.append(attr)
|
|
|
|
elif i.getName() == 'feature':
|
|
|
|
features.append(i.getAttr('var'))
|
2005-08-26 02:52:44 +02:00
|
|
|
jid = unicode(iq_obj.getFrom())
|
2005-04-12 13:46:20 +02:00
|
|
|
if not identities:
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(common.xmpp.Iq(typ = 'get', queryNS = \
|
2005-05-07 12:57:40 +02:00
|
|
|
common.xmpp.NS_AGENTS))
|
2005-04-12 13:46:20 +02:00
|
|
|
else:
|
2005-04-24 17:47:08 +02:00
|
|
|
self.dispatch('AGENT_INFO_INFO', (jid, node, identities, features))
|
2005-04-26 20:45:54 +02:00
|
|
|
self.discoverItems(jid, node)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
|
|
|
def _VersionCB(self, con, iq_obj):
|
2005-04-20 12:21:33 +02:00
|
|
|
gajim.log.debug('VersionCB')
|
2005-05-07 12:57:40 +02:00
|
|
|
iq_obj = iq_obj.buildReply('result')
|
2005-04-12 13:46:20 +02:00
|
|
|
qp = iq_obj.getTag('query')
|
2005-04-26 23:33:01 +02:00
|
|
|
qp.setTagData('name', 'Gajim')
|
|
|
|
qp.setTagData('version', gajim.version)
|
2005-04-24 02:31:48 +02:00
|
|
|
send_os = gajim.config.get('send_os_info')
|
|
|
|
if send_os:
|
2005-04-26 23:33:01 +02:00
|
|
|
qp.setTagData('os', get_os_info())
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq_obj)
|
2005-05-13 19:20:13 +02:00
|
|
|
raise common.xmpp.NodeProcessed
|
2005-04-12 13:46:20 +02:00
|
|
|
|
|
|
|
def _VersionResultCB(self, con, iq_obj):
|
2005-04-20 12:21:33 +02:00
|
|
|
gajim.log.debug('VersionResultCB')
|
2005-04-12 13:46:20 +02:00
|
|
|
client_info = ''
|
|
|
|
os_info = ''
|
|
|
|
qp = iq_obj.getTag('query')
|
|
|
|
if qp.getTag('name'):
|
|
|
|
client_info += qp.getTag('name').getData()
|
|
|
|
if qp.getTag('version'):
|
|
|
|
client_info += ' ' + qp.getTag('version').getData()
|
|
|
|
if qp.getTag('os'):
|
|
|
|
os_info += qp.getTag('os').getData()
|
|
|
|
jid = iq_obj.getFrom().getStripped()
|
2005-04-25 00:58:41 +02:00
|
|
|
resource = iq_obj.getFrom().getResource()
|
|
|
|
self.dispatch('OS_INFO', (jid, resource, client_info, os_info))
|
2005-04-20 12:21:33 +02:00
|
|
|
|
|
|
|
def _MucOwnerCB(self, con, iq_obj):
|
|
|
|
gajim.log.debug('MucOwnerCB')
|
|
|
|
qp = iq_obj.getQueryPayload()
|
|
|
|
node = None
|
|
|
|
for q in qp:
|
2005-04-26 20:45:54 +02:00
|
|
|
if q.getNamespace() == common.xmpp.NS_DATA:
|
2005-04-20 12:21:33 +02:00
|
|
|
node = q
|
|
|
|
if not node:
|
|
|
|
return
|
|
|
|
# Parse the form
|
|
|
|
dic = {}
|
|
|
|
tag = node.getTag('title')
|
|
|
|
if tag:
|
|
|
|
dic['title'] = tag.getData()
|
|
|
|
tag = node.getTag('instructions')
|
|
|
|
if tag:
|
|
|
|
dic['instructions'] = tag.getData()
|
|
|
|
i = 0
|
|
|
|
for child in node.getChildren():
|
|
|
|
if child.getName() != 'field':
|
|
|
|
continue
|
|
|
|
var = child.getAttr('var')
|
|
|
|
ctype = child.getAttr('type')
|
|
|
|
label = child.getAttr('label')
|
|
|
|
if not var and ctype != 'fixed': # We must have var if type != fixed
|
|
|
|
continue
|
|
|
|
dic[i] = {}
|
|
|
|
if var:
|
|
|
|
dic[i]['var'] = var
|
|
|
|
if ctype:
|
|
|
|
dic[i]['type'] = ctype
|
|
|
|
if label:
|
|
|
|
dic[i]['label'] = label
|
|
|
|
tags = child.getTags('value')
|
|
|
|
if len(tags):
|
|
|
|
dic[i]['values'] = []
|
|
|
|
for tag in tags:
|
|
|
|
data = tag.getData()
|
|
|
|
if ctype == 'boolean':
|
2005-04-24 18:14:50 +02:00
|
|
|
if data in ['yes', 'true', 'assent', '1']:
|
2005-04-20 12:21:33 +02:00
|
|
|
data = True
|
|
|
|
else:
|
|
|
|
data = False
|
|
|
|
dic[i]['values'].append(data)
|
|
|
|
tag = child.getTag('desc')
|
|
|
|
if tag:
|
|
|
|
dic[i]['desc'] = tag.getData()
|
|
|
|
option_tags = child.getTags('option')
|
|
|
|
if len(option_tags):
|
|
|
|
dic[i]['options'] = {}
|
|
|
|
j = 0
|
|
|
|
for option_tag in option_tags:
|
|
|
|
dic[i]['options'][j] = {}
|
|
|
|
label = option_tag.getAttr('label')
|
|
|
|
if label:
|
|
|
|
dic[i]['options'][j]['label'] = label
|
|
|
|
tags = option_tag.getTags('value')
|
|
|
|
dic[i]['options'][j]['values'] = []
|
|
|
|
for tag in tags:
|
|
|
|
dic[i]['options'][j]['values'].append(tag.getData())
|
|
|
|
j += 1
|
|
|
|
i += 1
|
2005-08-26 02:52:44 +02:00
|
|
|
self.dispatch('GC_CONFIG', (unicode(iq_obj.getFrom()), dic))
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-04-26 00:22:23 +02:00
|
|
|
def _MucErrorCB(self, con, iq_obj):
|
|
|
|
gajim.log.debug('MucErrorCB')
|
2005-08-26 02:52:44 +02:00
|
|
|
jid = unicode(iq_obj.getFrom())
|
2005-04-26 00:22:23 +02:00
|
|
|
errmsg = iq_obj.getError()
|
|
|
|
errcode = iq_obj.getErrorCode()
|
|
|
|
self.dispatch('MSGERROR', (jid, errcode, errmsg))
|
|
|
|
|
2005-05-08 19:00:41 +02:00
|
|
|
def _getRosterCB(self, con, iq_obj):
|
2005-06-10 13:26:37 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-05-08 19:00:41 +02:00
|
|
|
roster = self.connection.getRoster().getRaw()
|
2005-07-07 19:20:43 +02:00
|
|
|
if not roster:
|
2005-05-08 19:00:41 +02:00
|
|
|
roster = {}
|
2005-06-04 02:37:49 +02:00
|
|
|
|
2005-05-08 19:00:41 +02:00
|
|
|
name = gajim.config.get_per('accounts', self.name, 'name')
|
|
|
|
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
|
|
|
|
if roster.has_key(name + '@' + hostname):
|
|
|
|
del roster[name + '@' + hostname]
|
|
|
|
self.dispatch('ROSTER', roster)
|
|
|
|
|
2005-06-07 20:21:36 +02:00
|
|
|
def _PrivateCB(self, con, iq_obj):
|
2005-06-11 19:21:30 +02:00
|
|
|
'''
|
2005-06-07 20:21:36 +02:00
|
|
|
Private Data (JEP 048 and 049)
|
2005-06-11 19:21:30 +02:00
|
|
|
'''
|
|
|
|
gajim.log.debug('PrivateCB')
|
|
|
|
storage = iq_obj.getTag('query').getTag('storage')
|
2005-06-07 20:21:36 +02:00
|
|
|
try:
|
|
|
|
ns = storage.getNamespace()
|
|
|
|
except AttributeError:
|
|
|
|
#Its a result for a 'set' Iq, so we don't do anything here
|
2005-06-11 19:21:30 +02:00
|
|
|
return
|
2005-06-07 20:21:36 +02:00
|
|
|
|
2005-06-11 19:21:30 +02:00
|
|
|
if ns == 'storage:bookmarks':
|
2005-06-07 20:21:36 +02:00
|
|
|
#Bookmarked URLs and Conferences
|
|
|
|
#http://www.jabber.org/jeps/jep-0048.html
|
2005-06-11 19:21:30 +02:00
|
|
|
confs = storage.getTags('conference')
|
|
|
|
urls = storage.getTags('url')
|
2005-06-07 20:21:36 +02:00
|
|
|
for conf in confs:
|
2005-08-18 21:06:24 +02:00
|
|
|
autojoin_val = conf.getAttr('autojoin')
|
|
|
|
if autojoin_val is None: # not there (it's optional)
|
|
|
|
autojoin_val == False
|
2005-06-11 19:21:30 +02:00
|
|
|
bm = { 'name': conf.getAttr('name'),
|
|
|
|
'jid': conf.getAttr('jid'),
|
2005-08-18 21:06:24 +02:00
|
|
|
'autojoin': autojoin_val,
|
2005-06-11 19:21:30 +02:00
|
|
|
'password': conf.getTagData('password'),
|
|
|
|
'nick': conf.getTagData('nick') }
|
2005-06-07 20:21:36 +02:00
|
|
|
|
2005-06-09 22:35:44 +02:00
|
|
|
self.bookmarks.append(bm)
|
2005-06-11 19:21:30 +02:00
|
|
|
self.dispatch('BOOKMARKS', self.bookmarks)
|
|
|
|
|
|
|
|
elif ns == 'gajim:prefs':
|
2005-06-07 20:21:36 +02:00
|
|
|
#Preferences data
|
|
|
|
#http://www.jabber.org/jeps/jep-0049.html
|
|
|
|
#TODO: implement this
|
2005-08-05 15:29:39 +02:00
|
|
|
pass
|
|
|
|
|
|
|
|
def build_http_auth_answer(self, iq_obj, answer):
|
|
|
|
if answer == 'yes':
|
|
|
|
iq = iq_obj.buildReply('result')
|
|
|
|
elif answer == 'no':
|
|
|
|
iq = iq_obj.buildReply('error')
|
|
|
|
iq.setError('not-authorized', 401)
|
|
|
|
self.to_be_sent.append(iq)
|
|
|
|
|
|
|
|
def _HttpAuthCB(self, con, iq_obj):
|
2005-08-06 12:11:02 +02:00
|
|
|
gajim.log.debug('HttpAuthCB')
|
2005-08-05 15:29:39 +02:00
|
|
|
opt = gajim.config.get_per('accounts', self.name, 'http_auth')
|
|
|
|
if opt in ['yes', 'no']:
|
|
|
|
self.build_http_auth_answer(iq_obj, opt)
|
|
|
|
else:
|
|
|
|
method = iq_obj.getTagAttr('confirm', 'method')
|
|
|
|
url = iq_obj.getTagAttr('confirm', 'url')
|
|
|
|
self.dispatch('HTTP_AUTH', (method, url, iq_obj));
|
|
|
|
raise common.xmpp.NodeProcessed
|
2005-06-07 20:21:36 +02:00
|
|
|
|
2005-05-10 18:53:28 +02:00
|
|
|
def _ErrorCB(self, con, iq_obj):
|
|
|
|
errmsg = iq_obj.getError()
|
|
|
|
errcode = iq_obj.getErrorCode()
|
2005-08-26 02:52:44 +02:00
|
|
|
jid_from = unicode(iq_obj.getFrom())
|
|
|
|
id = unicode(iq_obj.getID())
|
2005-08-03 18:21:23 +02:00
|
|
|
self.dispatch('ERROR_ANSWER', (id, jid_from, errmsg, errcode))
|
2005-06-22 16:54:02 +02:00
|
|
|
|
|
|
|
def _StanzaArrivedCB(self, con, obj):
|
2005-08-27 02:07:43 +02:00
|
|
|
self.last_io = time.time()
|
2005-05-10 18:53:28 +02:00
|
|
|
|
2005-08-16 18:10:36 +02:00
|
|
|
def _event_dispatcher(self, realm, event, data):
|
2005-06-14 12:29:36 +02:00
|
|
|
if realm == common.xmpp.NS_REGISTER:
|
|
|
|
if event == common.xmpp.features.REGISTER_DATA_RECEIVED:
|
|
|
|
# data is (agent, DataFrom)
|
2005-07-20 22:00:57 +02:00
|
|
|
if self.new_account_info and\
|
|
|
|
self.new_account_info['hostname'] == data[0]:
|
2005-07-07 22:45:24 +02:00
|
|
|
#it's a new account
|
|
|
|
req = data[1].asDict()
|
|
|
|
req['username'] = self.new_account_info['name']
|
|
|
|
req['password'] = self.new_account_info['password']
|
2005-07-20 22:00:57 +02:00
|
|
|
if not common.xmpp.features.register(self.connection, data[0],
|
|
|
|
req):
|
2005-07-07 22:45:24 +02:00
|
|
|
self.dispatch('ERROR', (_('Error:'), self.connection.lastErr))
|
|
|
|
return
|
|
|
|
self.connected = 0
|
|
|
|
self.password = self.new_account_info['password']
|
|
|
|
if USE_GPG:
|
|
|
|
self.gpg = GnuPG.GnuPG()
|
|
|
|
gajim.config.set('usegpg', True)
|
|
|
|
else:
|
|
|
|
gajim.config.set('usegpg', False)
|
|
|
|
gajim.connections[self.name] = self
|
2005-07-18 23:16:31 +02:00
|
|
|
self.dispatch('ACC_OK', (self.name, self.new_account_info))
|
2005-07-07 22:45:24 +02:00
|
|
|
self.new_account_info = None
|
|
|
|
return
|
2005-06-14 12:29:36 +02:00
|
|
|
self.dispatch('REGISTER_AGENT_INFO', (data[0], data[1].asDict()))
|
2005-08-06 01:43:28 +02:00
|
|
|
elif realm == '':
|
|
|
|
if event == common.xmpp.transports.DATA_RECEIVED:
|
2005-08-26 02:52:44 +02:00
|
|
|
self.dispatch('STANZA_ARRIVED', unicode(data))
|
2005-08-06 01:43:28 +02:00
|
|
|
elif event == common.xmpp.transports.DATA_SENT:
|
2005-08-26 02:52:44 +02:00
|
|
|
self.dispatch('STANZA_SENT', unicode(data))
|
2005-06-14 12:29:36 +02:00
|
|
|
|
2005-04-12 13:46:20 +02:00
|
|
|
def connect(self):
|
2005-06-29 14:57:46 +02:00
|
|
|
"""Connect and authenticate to the Jabber server
|
|
|
|
Returns connection, and connection type ('tls', 'ssl', 'tcp', '')"""
|
2005-04-14 13:06:58 +02:00
|
|
|
name = gajim.config.get_per('accounts', self.name, 'name')
|
2005-04-12 13:46:20 +02:00
|
|
|
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
|
|
|
|
resource = gajim.config.get_per('accounts', self.name, 'resource')
|
2005-05-30 13:01:08 +02:00
|
|
|
usessl = gajim.config.get_per('accounts', self.name, 'usessl')
|
2005-06-26 01:25:17 +02:00
|
|
|
try_connecting_for_foo_secs = gajim.config.get_per('accounts', self.name,
|
|
|
|
'try_connecting_for_foo_secs')
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-05-26 15:35:58 +02:00
|
|
|
#create connection if it doesn't already exist
|
2005-04-14 13:06:58 +02:00
|
|
|
if self.connection:
|
|
|
|
return self.connection
|
2005-04-18 11:18:50 +02:00
|
|
|
self.connected = 1
|
2005-06-08 17:48:53 +02:00
|
|
|
p = gajim.config.get_per('accounts', self.name, 'proxy')
|
2005-07-04 09:28:42 +02:00
|
|
|
if p and p in gajim.config.get_per('proxies'):
|
2005-06-08 17:48:53 +02:00
|
|
|
proxy = {'host': gajim.config.get_per('proxies', p, 'host')}
|
|
|
|
proxy['port'] = gajim.config.get_per('proxies', p, 'port')
|
|
|
|
proxy['user'] = gajim.config.get_per('proxies', p, 'user')
|
|
|
|
proxy['password'] = gajim.config.get_per('proxies', p, 'pass')
|
2005-04-14 13:06:58 +02:00
|
|
|
else:
|
|
|
|
proxy = None
|
2005-05-28 20:20:27 +02:00
|
|
|
if gajim.verbose:
|
2005-05-08 19:00:41 +02:00
|
|
|
con = common.xmpp.Client(hostname)
|
2005-04-14 13:06:58 +02:00
|
|
|
else:
|
2005-05-03 10:06:59 +02:00
|
|
|
con = common.xmpp.Client(hostname, debug = [])
|
2005-06-26 01:25:17 +02:00
|
|
|
common.xmpp.dispatcher.DefaultTimeout = try_connecting_for_foo_secs
|
2005-05-20 12:49:46 +02:00
|
|
|
con.UnregisterDisconnectHandler(con.DisconnectHandler)
|
2005-04-26 20:45:54 +02:00
|
|
|
con.RegisterDisconnectHandler(self._disconnectedCB)
|
2005-06-13 23:16:41 +02:00
|
|
|
|
2005-06-14 12:26:01 +02:00
|
|
|
h = hostname
|
|
|
|
p = 5222
|
2005-08-05 01:29:41 +02:00
|
|
|
# autodetect [for SSL in 5223/443 and for TLS if broadcasted]
|
|
|
|
secur = None
|
2005-06-14 12:26:01 +02:00
|
|
|
if usessl:
|
|
|
|
p = 5223
|
2005-06-18 13:37:29 +02:00
|
|
|
secur=1 #1 means force SSL no matter what the port will be
|
2005-06-14 12:26:01 +02:00
|
|
|
if gajim.config.get_per('accounts', self.name, 'use_custom_host'):
|
|
|
|
h = gajim.config.get_per('accounts', self.name, 'custom_host')
|
|
|
|
p = gajim.config.get_per('accounts', self.name, 'custom_port')
|
2005-06-18 13:37:29 +02:00
|
|
|
|
|
|
|
con_type = con.connect((h, p), proxy = proxy, secure=secur) #FIXME: blocking
|
2005-08-02 00:45:29 +02:00
|
|
|
self.peerhost = con.get_peerhost()
|
2005-05-26 15:35:58 +02:00
|
|
|
if not con_type:
|
2005-05-30 16:08:48 +02:00
|
|
|
gajim.log.debug("Couldn't connect to %s" % self.name)
|
2005-05-18 16:05:54 +02:00
|
|
|
self.connected = 0
|
2005-04-12 13:46:20 +02:00
|
|
|
self.dispatch('STATUS', 'offline')
|
2005-06-07 09:40:15 +02:00
|
|
|
self.dispatch('ERROR', (_('Could not connect to "%s"') % self.name,
|
2005-06-13 14:35:53 +02:00
|
|
|
_('Check your connection or try again later')))
|
2005-06-29 17:09:10 +02:00
|
|
|
return None
|
2005-06-29 17:06:05 +02:00
|
|
|
|
2005-07-25 09:52:04 +02:00
|
|
|
gajim.log.debug(_('Connected to server with %s'), con_type)
|
2005-06-29 17:06:05 +02:00
|
|
|
|
2005-08-09 19:21:35 +02:00
|
|
|
# notify the gui about con_type
|
|
|
|
self.dispatch('CON_TYPE', con_type)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-04-26 20:45:54 +02:00
|
|
|
con.RegisterHandler('message', self._messageCB)
|
|
|
|
con.RegisterHandler('presence', self._presenceCB)
|
2005-05-27 18:43:38 +02:00
|
|
|
con.RegisterHandler('iq', self._vCardCB, 'result',
|
2005-04-26 20:45:54 +02:00
|
|
|
common.xmpp.NS_VCARD)
|
2005-05-27 18:43:38 +02:00
|
|
|
con.RegisterHandler('iq', self._rosterSetCB, 'set',
|
2005-04-26 20:45:54 +02:00
|
|
|
common.xmpp.NS_ROSTER)
|
2005-07-30 12:19:52 +02:00
|
|
|
con.RegisterHandler('iq', self._siSetCB, 'set',
|
|
|
|
common.xmpp.NS_SI)
|
2005-08-23 23:52:56 +02:00
|
|
|
con.RegisterHandler('iq', self._siErrorCB, 'error',
|
|
|
|
common.xmpp.NS_SI)
|
2005-08-03 16:04:54 +02:00
|
|
|
con.RegisterHandler('iq', self._siResultCB, 'result',
|
|
|
|
common.xmpp.NS_SI)
|
2005-07-30 17:06:35 +02:00
|
|
|
con.RegisterHandler('iq', self._discoGetCB, 'get',
|
|
|
|
common.xmpp.NS_DISCO)
|
2005-07-30 12:19:52 +02:00
|
|
|
con.RegisterHandler('iq', self._bytestreamSetCB, 'set',
|
|
|
|
common.xmpp.NS_BYTESTREAM)
|
2005-08-03 16:04:54 +02:00
|
|
|
con.RegisterHandler('iq', self._bytestreamResultCB, 'result',
|
|
|
|
common.xmpp.NS_BYTESTREAM)
|
2005-08-06 18:31:41 +02:00
|
|
|
con.RegisterHandler('iq', self._bytestreamErrorCB, 'error',
|
|
|
|
common.xmpp.NS_BYTESTREAM)
|
2005-05-27 18:43:38 +02:00
|
|
|
con.RegisterHandler('iq', self._BrowseResultCB, 'result',
|
2005-04-26 20:45:54 +02:00
|
|
|
common.xmpp.NS_BROWSE)
|
2005-05-27 18:43:38 +02:00
|
|
|
con.RegisterHandler('iq', self._DiscoverItemsCB, 'result',
|
2005-04-26 20:45:54 +02:00
|
|
|
common.xmpp.NS_DISCO_ITEMS)
|
2005-05-27 18:43:38 +02:00
|
|
|
con.RegisterHandler('iq', self._DiscoverInfoCB, 'result',
|
2005-04-26 20:45:54 +02:00
|
|
|
common.xmpp.NS_DISCO_INFO)
|
2005-05-27 18:43:38 +02:00
|
|
|
con.RegisterHandler('iq', self._DiscoverInfoErrorCB, 'error',
|
2005-04-26 20:45:54 +02:00
|
|
|
common.xmpp.NS_DISCO_INFO)
|
2005-05-27 18:43:38 +02:00
|
|
|
con.RegisterHandler('iq', self._VersionCB, 'get',
|
2005-04-26 20:45:54 +02:00
|
|
|
common.xmpp.NS_VERSION)
|
2005-05-27 18:43:38 +02:00
|
|
|
con.RegisterHandler('iq', self._VersionResultCB, 'result',
|
2005-04-26 20:45:54 +02:00
|
|
|
common.xmpp.NS_VERSION)
|
2005-05-27 18:43:38 +02:00
|
|
|
con.RegisterHandler('iq', self._MucOwnerCB, 'result',
|
2005-04-26 20:45:54 +02:00
|
|
|
common.xmpp.NS_MUC_OWNER)
|
2005-05-27 18:43:38 +02:00
|
|
|
con.RegisterHandler('iq', self._getRosterCB, 'result',
|
2005-05-08 19:00:41 +02:00
|
|
|
common.xmpp.NS_ROSTER)
|
2005-06-07 20:21:36 +02:00
|
|
|
con.RegisterHandler('iq', self._PrivateCB, 'result',
|
|
|
|
common.xmpp.NS_PRIVATE)
|
2005-08-05 15:29:39 +02:00
|
|
|
con.RegisterHandler('iq', self._HttpAuthCB, 'get',
|
|
|
|
common.xmpp.NS_HTTP_AUTH)
|
2005-05-10 18:53:28 +02:00
|
|
|
con.RegisterHandler('iq', self._ErrorCB, 'error')
|
2005-06-22 16:54:02 +02:00
|
|
|
con.RegisterHandler('iq', self._StanzaArrivedCB)
|
|
|
|
con.RegisterHandler('presence', self._StanzaArrivedCB)
|
|
|
|
con.RegisterHandler('message', self._StanzaArrivedCB)
|
2005-06-14 12:29:36 +02:00
|
|
|
con.RegisterEventHandler(self._event_dispatcher)
|
2005-04-26 20:45:54 +02:00
|
|
|
|
2005-05-11 18:37:01 +02:00
|
|
|
try:
|
2005-05-31 15:53:22 +02:00
|
|
|
#FIXME: blocking
|
2005-06-01 14:33:29 +02:00
|
|
|
auth = con.auth(name, self.password, resource, 1)
|
2005-05-11 18:37:01 +02:00
|
|
|
except IOError: #probably a timeout
|
2005-05-18 16:05:54 +02:00
|
|
|
self.connected = 0
|
2005-05-11 18:37:01 +02:00
|
|
|
self.dispatch('STATUS', 'offline')
|
2005-06-07 09:40:15 +02:00
|
|
|
self.dispatch('ERROR', (_('Could not connect to "%s"') % self.name,
|
2005-06-13 14:35:53 +02:00
|
|
|
_('Check your connection or try again later')))
|
2005-08-16 18:10:36 +02:00
|
|
|
return None
|
|
|
|
con.RegisterEventHandler(self._event_dispatcher)
|
2005-05-11 18:37:01 +02:00
|
|
|
if auth:
|
2005-05-08 19:00:41 +02:00
|
|
|
con.initRoster()
|
2005-08-27 02:07:43 +02:00
|
|
|
self.last_io = time.time()
|
2005-04-12 13:46:20 +02:00
|
|
|
self.connected = 2
|
2005-06-29 17:09:10 +02:00
|
|
|
return con # return connection
|
2005-04-12 13:46:20 +02:00
|
|
|
else:
|
2005-05-30 16:08:48 +02:00
|
|
|
gajim.log.debug("Couldn't authenticate to %s" % self.name)
|
2005-05-18 16:05:54 +02:00
|
|
|
self.connected = 0
|
2005-04-12 13:46:20 +02:00
|
|
|
self.dispatch('STATUS', 'offline')
|
2005-08-09 17:28:32 +02:00
|
|
|
self.dispatch('ERROR', (_('Authentication failed with "%s"') % self.name,
|
2005-06-10 01:08:28 +02:00
|
|
|
_('Please check your login and password for correctness.')))
|
2005-06-29 17:09:10 +02:00
|
|
|
return None
|
2005-05-31 15:53:22 +02:00
|
|
|
# END connect
|
2005-04-12 13:46:20 +02:00
|
|
|
|
|
|
|
def quit(self, kill_core):
|
|
|
|
if kill_core:
|
|
|
|
if self.connected > 1:
|
|
|
|
self.connected = 0
|
2005-07-03 14:36:13 +02:00
|
|
|
self.connection.disconnect()
|
2005-04-12 13:46:20 +02:00
|
|
|
return
|
|
|
|
|
|
|
|
def ask_roster(self):
|
|
|
|
roster = {}
|
|
|
|
if self.connection:
|
|
|
|
roster = self.connection.getRoster().getRaw()
|
|
|
|
return roster
|
2005-07-22 18:36:20 +02:00
|
|
|
|
|
|
|
def build_privacy_rule(self, name, action):
|
|
|
|
'''Build a Privacy rule stanza for invisibility'''
|
|
|
|
iq = common.xmpp.Iq('set', common.xmpp.NS_PRIVACY, xmlns = '')
|
|
|
|
l = iq.getTag('query').setTag('list', {'name': name})
|
|
|
|
i = l.setTag('item', {'action': action, 'order': '1'})
|
|
|
|
i.setTag('presence-out')
|
|
|
|
return iq
|
|
|
|
|
|
|
|
def activate_privacy_rule(self, name):
|
|
|
|
'''activate a privacy rule'''
|
|
|
|
iq = common.xmpp.Iq('set', common.xmpp.NS_PRIVACY, xmlns = '')
|
|
|
|
iq.getTag('query').setTag('active', {'name': name})
|
|
|
|
self.connection.send(iq)
|
|
|
|
|
|
|
|
def send_invisible_presence(self, msg, signed, initial = False):
|
|
|
|
# try to set the privacy rule
|
|
|
|
iq = self.build_privacy_rule('invisible', 'deny')
|
|
|
|
self.connection.SendAndCallForResponse(iq, self._continue_invisible,
|
|
|
|
{'msg': msg, 'signed': signed, 'initial': initial})
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-07-22 18:36:20 +02:00
|
|
|
def _continue_invisible(self, con, iq_obj, msg, signed, initial):
|
|
|
|
ptype = ''
|
|
|
|
show = ''
|
|
|
|
# FIXME: JEP 126 need some modifications (see http://lists.jabber.ru/pipermail/ejabberd/2005-July/001252.html). So I disable it for the moment
|
|
|
|
if 1 or iq_obj.getType() == 'error': #server doesn't support privacy lists
|
|
|
|
# We use the old way which is not xmpp complient
|
|
|
|
ptype = 'invisible'
|
|
|
|
show = 'invisible'
|
|
|
|
else:
|
|
|
|
# active the privacy rule
|
|
|
|
self.privacy_rules_supported = True
|
|
|
|
self.activate_privacy_rule('invisible')
|
2005-08-26 02:52:44 +02:00
|
|
|
prio = unicode(gajim.config.get_per('accounts', self.name, 'priority'))
|
2005-07-22 18:36:20 +02:00
|
|
|
p = common.xmpp.Presence(typ = ptype, priority = prio, show = show)
|
2005-08-07 23:42:32 +02:00
|
|
|
p = self.add_sha(p)
|
2005-07-22 18:36:20 +02:00
|
|
|
if msg:
|
|
|
|
p.setStatus(msg)
|
|
|
|
if signed:
|
|
|
|
p.setTag(common.xmpp.NS_SIGNED + ' x').setData(signed)
|
|
|
|
self.connection.send(p)
|
2005-08-09 19:21:35 +02:00
|
|
|
self.dispatch('STATUS', 'invisible')
|
2005-07-22 18:36:20 +02:00
|
|
|
if initial:
|
|
|
|
#ask our VCard
|
2005-08-08 15:34:48 +02:00
|
|
|
self.request_vcard(None)
|
2005-07-22 18:36:20 +02:00
|
|
|
|
|
|
|
#Get bookmarks from private namespace
|
|
|
|
self.get_bookmarks()
|
2005-07-30 12:19:52 +02:00
|
|
|
|
2005-06-28 21:03:00 +02:00
|
|
|
def change_status(self, show, msg, sync = False):
|
|
|
|
if sync:
|
|
|
|
self.change_status2(show, msg)
|
|
|
|
else:
|
|
|
|
t = threading.Thread(target=self.change_status2, args = (show, msg))
|
|
|
|
t.start()
|
|
|
|
|
|
|
|
def change_status2(self, show, msg):
|
2005-05-13 20:54:44 +02:00
|
|
|
if not show in STATUS_LIST:
|
2005-04-12 13:46:20 +02:00
|
|
|
return -1
|
2005-06-04 16:27:09 +02:00
|
|
|
sshow = show # show to be send
|
|
|
|
if show == 'online':
|
|
|
|
sshow = None
|
2005-04-12 13:46:20 +02:00
|
|
|
signed = ''
|
2005-08-01 20:19:36 +02:00
|
|
|
if not msg:
|
|
|
|
lowered_uf_status_msg = helpers.get_uf_show(show).lower()
|
2005-08-14 16:32:10 +02:00
|
|
|
if lowered_uf_status_msg == _('invisible'): # do not show I'm invisible!
|
|
|
|
lowered_uf_status_msg = _('offline')
|
2005-08-01 20:19:36 +02:00
|
|
|
msg = _("I'm %s") % lowered_uf_status_msg
|
2005-04-12 13:46:20 +02:00
|
|
|
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
|
|
|
if keyID and USE_GPG:
|
2005-07-23 13:44:54 +02:00
|
|
|
if self.connected < 2 and self.gpg.passphrase is None:
|
2005-06-29 10:28:12 +02:00
|
|
|
# We didn't set a passphrase
|
2005-08-13 17:06:04 +02:00
|
|
|
self.dispatch('ERROR', (_('OpenPGP passphrase was not given'),
|
|
|
|
#%s is the account name here
|
2005-08-09 19:21:35 +02:00
|
|
|
_('You will be connected to %s without OpenPGP.') % self.name))
|
2005-08-01 20:19:36 +02:00
|
|
|
else:
|
2005-06-18 18:57:57 +02:00
|
|
|
signed = self.gpg.sign(msg, keyID)
|
|
|
|
if signed == 'BAD_PASSPHRASE':
|
|
|
|
signed = ''
|
|
|
|
if self.connected < 2:
|
2005-08-09 19:21:35 +02:00
|
|
|
self.dispatch('BAD_PASSPHRASE', ())
|
2005-05-20 17:32:05 +02:00
|
|
|
self.status = msg
|
2005-05-19 19:50:19 +02:00
|
|
|
if show != 'offline' and not self.connected:
|
2005-06-29 17:09:10 +02:00
|
|
|
self.connection = self.connect()
|
2005-04-12 13:46:20 +02:00
|
|
|
if self.connected == 2:
|
2005-05-13 20:54:44 +02:00
|
|
|
self.connected = STATUS_LIST.index(show)
|
2005-04-12 13:46:20 +02:00
|
|
|
#send our presence
|
2005-05-13 20:54:44 +02:00
|
|
|
if show == 'invisible':
|
2005-07-22 18:36:20 +02:00
|
|
|
self.send_invisible_presence(msg, signed, True)
|
|
|
|
return
|
2005-08-26 02:52:44 +02:00
|
|
|
prio = unicode(gajim.config.get_per('accounts', self.name,
|
|
|
|
'priority'))
|
2005-08-07 23:42:32 +02:00
|
|
|
p = common.xmpp.Presence(typ = None, priority = prio, show = sshow)
|
|
|
|
p = self.add_sha(p)
|
2005-05-20 17:32:05 +02:00
|
|
|
if msg:
|
|
|
|
p.setStatus(msg)
|
2005-04-26 20:45:54 +02:00
|
|
|
if signed:
|
2005-04-26 23:33:01 +02:00
|
|
|
p.setTag(common.xmpp.NS_SIGNED + ' x').setData(signed)
|
2005-04-26 20:45:54 +02:00
|
|
|
|
2005-07-15 22:04:02 +02:00
|
|
|
if self.connection:
|
|
|
|
self.connection.send(p)
|
2005-08-09 19:21:35 +02:00
|
|
|
self.dispatch('STATUS', show)
|
2005-04-12 13:46:20 +02:00
|
|
|
#ask our VCard
|
2005-08-08 15:34:48 +02:00
|
|
|
self.request_vcard(None)
|
2005-06-07 20:21:36 +02:00
|
|
|
|
|
|
|
#Get bookmarks from private namespace
|
|
|
|
self.get_bookmarks()
|
|
|
|
|
2005-05-19 19:50:19 +02:00
|
|
|
elif show == 'offline' and self.connected:
|
2005-04-12 13:46:20 +02:00
|
|
|
self.connected = 0
|
2005-05-04 21:20:02 +02:00
|
|
|
if self.connection:
|
2005-05-27 14:07:20 +02:00
|
|
|
self.on_purpose = True
|
2005-05-20 17:32:05 +02:00
|
|
|
p = common.xmpp.Presence(typ = 'unavailable')
|
2005-08-07 23:42:32 +02:00
|
|
|
p = self.add_sha(p)
|
2005-05-20 17:32:05 +02:00
|
|
|
if msg:
|
|
|
|
p.setStatus(msg)
|
2005-08-10 17:59:55 +02:00
|
|
|
self.remove_all_transfers()
|
2005-07-15 22:04:02 +02:00
|
|
|
if self.connection:
|
|
|
|
self.connection.send(p)
|
2005-05-31 18:47:05 +02:00
|
|
|
try:
|
|
|
|
self.connection.disconnect()
|
|
|
|
except:
|
|
|
|
pass
|
2005-08-09 19:21:35 +02:00
|
|
|
self.dispatch('STATUS', 'offline')
|
2005-04-18 11:18:50 +02:00
|
|
|
self.connection = None
|
2005-05-13 20:54:44 +02:00
|
|
|
elif show != 'offline' and self.connected:
|
2005-07-22 18:36:20 +02:00
|
|
|
was_invisible = self.connected == STATUS_LIST.index('invisible')
|
2005-05-13 20:54:44 +02:00
|
|
|
self.connected = STATUS_LIST.index(show)
|
|
|
|
if show == 'invisible':
|
2005-07-22 18:36:20 +02:00
|
|
|
self.send_invisible_presence(msg, signed)
|
|
|
|
return
|
|
|
|
if was_invisible and self.privacy_rules_supported:
|
|
|
|
iq = self.build_privacy_rule('visible', 'allow')
|
|
|
|
self.connection.send(iq)
|
|
|
|
self.activate_privacy_rule('visible')
|
2005-08-26 02:52:44 +02:00
|
|
|
prio = unicode(gajim.config.get_per('accounts', self.name,
|
|
|
|
'priority'))
|
2005-08-07 23:42:32 +02:00
|
|
|
p = common.xmpp.Presence(typ = None, priority = prio, show = sshow)
|
|
|
|
p = self.add_sha(p)
|
2005-05-20 17:32:05 +02:00
|
|
|
if msg:
|
|
|
|
p.setStatus(msg)
|
|
|
|
if signed:
|
|
|
|
p.setTag(common.xmpp.NS_SIGNED + ' x').setData(signed)
|
2005-07-16 19:12:11 +02:00
|
|
|
if self.connection:
|
2005-07-15 22:04:02 +02:00
|
|
|
self.connection.send(p)
|
2005-08-09 19:21:35 +02:00
|
|
|
self.dispatch('STATUS', show)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-08-06 14:33:20 +02:00
|
|
|
def send_motd(self, jid, subject = '', msg = ''):
|
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
msg_iq = common.xmpp.Message(to = jid, body = msg, subject = subject)
|
|
|
|
self.to_be_sent.append(msg_iq)
|
|
|
|
|
2005-07-19 16:38:58 +02:00
|
|
|
def send_message(self, jid, msg, keyID, type = 'chat', subject='', chatstate = None):
|
2005-04-14 09:42:26 +02:00
|
|
|
if not self.connection:
|
2005-04-12 13:46:20 +02:00
|
|
|
return
|
2005-07-19 16:38:58 +02:00
|
|
|
if not msg and chatstate is None:
|
2005-06-21 22:04:23 +02:00
|
|
|
return
|
2005-04-12 13:46:20 +02:00
|
|
|
msgtxt = msg
|
|
|
|
msgenc = ''
|
|
|
|
if keyID and USE_GPG:
|
|
|
|
#encrypt
|
2005-05-27 16:16:34 +02:00
|
|
|
msgenc = self.gpg.encrypt(msg, [keyID])
|
2005-07-04 18:27:26 +02:00
|
|
|
if msgenc:
|
2005-07-06 14:13:54 +02:00
|
|
|
msgtxt = '[This message is encrypted]'
|
|
|
|
lang = os.getenv('LANG')
|
|
|
|
if lang is not None or lang != 'en': # we're not english
|
|
|
|
msgtxt = _('[This message is encrypted]') +\
|
|
|
|
' ([This message is encrypted])' # one in locale and one en
|
2005-07-02 17:49:25 +02:00
|
|
|
if type == 'chat':
|
|
|
|
msg_iq = common.xmpp.Message(to = jid, body = msgtxt, typ = type)
|
|
|
|
else:
|
|
|
|
if subject:
|
|
|
|
msg_iq = common.xmpp.Message(to = jid, body = msgtxt,
|
|
|
|
typ = 'normal', subject = subject)
|
|
|
|
else:
|
|
|
|
msg_iq = common.xmpp.Message(to = jid, body = msgtxt,
|
|
|
|
typ = 'normal')
|
2005-04-12 13:46:20 +02:00
|
|
|
if msgenc:
|
2005-04-26 20:45:54 +02:00
|
|
|
msg_iq.setTag(common.xmpp.NS_ENCRYPTED + ' x').setData(msgenc)
|
2005-07-19 16:38:58 +02:00
|
|
|
|
|
|
|
# chatstates - if peer supports jep85, send chatstates
|
|
|
|
# please note that the only valid tag inside a message containing a <body> tag is the active event
|
2005-07-21 17:23:18 +02:00
|
|
|
if chatstate is not None:
|
2005-07-22 02:34:08 +02:00
|
|
|
msg_iq.setTag(chatstate, {},
|
|
|
|
namespace = 'http://jabber.org/protocol/chatstates')
|
2005-07-19 16:38:58 +02:00
|
|
|
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(msg_iq)
|
2005-07-23 13:54:01 +02:00
|
|
|
if msg:
|
|
|
|
gajim.logger.write('outgoing', msg, jid)
|
2005-04-12 13:46:20 +02:00
|
|
|
self.dispatch('MSGSENT', (jid, msg, keyID))
|
|
|
|
|
2005-07-04 23:30:00 +02:00
|
|
|
def send_stanza(self, stanza):
|
|
|
|
''' send a stanza untouched '''
|
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
self.to_be_sent.append(stanza)
|
|
|
|
|
2005-04-14 09:42:26 +02:00
|
|
|
def request_subscription(self, jid, msg):
|
2005-04-12 13:46:20 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
gajim.log.debug('subscription request for %s' % jid)
|
2005-08-07 23:42:32 +02:00
|
|
|
p = common.xmpp.Presence(jid, 'subscribe')
|
|
|
|
p = self.add_sha(p)
|
2005-04-12 13:46:20 +02:00
|
|
|
if not msg:
|
|
|
|
msg = _('I would like to add you to my roster.')
|
2005-08-07 23:42:32 +02:00
|
|
|
p.setStatus(msg)
|
|
|
|
self.to_be_sent.append(p)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-04-14 09:42:26 +02:00
|
|
|
def send_authorization(self, jid):
|
2005-04-12 13:46:20 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-08-07 23:42:32 +02:00
|
|
|
p = common.xmpp.Presence(jid, 'subscribed')
|
|
|
|
p = self.add_sha(p)
|
|
|
|
self.to_be_sent.append(p)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-04-14 09:42:26 +02:00
|
|
|
def refuse_authorization(self, jid):
|
2005-04-12 13:46:20 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-08-07 23:42:32 +02:00
|
|
|
p = common.xmpp.Presence(jid, 'unsubscribed')
|
|
|
|
p = self.add_sha(p)
|
|
|
|
self.to_be_sent.append(p)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
|
|
|
def unsubscribe(self, jid):
|
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
delauth = gajim.config.get('delauth')
|
|
|
|
delroster = gajim.config.get('delroster')
|
|
|
|
if delauth:
|
2005-04-26 20:45:54 +02:00
|
|
|
self.connection.getRoster().Unsubscribe(jid)
|
2005-04-12 13:46:20 +02:00
|
|
|
if delroster:
|
2005-04-26 20:45:54 +02:00
|
|
|
self.connection.getRoster().delItem(jid)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-05-11 11:08:06 +02:00
|
|
|
def _continue_unsubscribe(self, con, iq_obj, agent):
|
|
|
|
self.connection.getRoster().delItem(agent)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-05-08 19:33:08 +02:00
|
|
|
def unsubscribe_agent(self, agent):
|
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-05-11 11:08:06 +02:00
|
|
|
iq = common.xmpp.Iq('set', common.xmpp.NS_REGISTER, to = agent)
|
|
|
|
iq.getTag('query').setTag('remove')
|
|
|
|
self.connection.SendAndCallForResponse(iq, self._continue_unsubscribe,
|
2005-05-08 19:33:08 +02:00
|
|
|
{'agent': agent})
|
|
|
|
return
|
|
|
|
|
2005-07-19 16:38:58 +02:00
|
|
|
def update_contact(self, jid, name, groups):
|
2005-04-12 13:46:20 +02:00
|
|
|
if self.connection:
|
2005-04-30 10:48:50 +02:00
|
|
|
self.connection.getRoster().setItem(jid = jid, name = name,
|
2005-04-26 20:45:54 +02:00
|
|
|
groups = groups)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-04-23 23:54:12 +02:00
|
|
|
def request_agents(self, jid, node):
|
2005-04-12 13:46:20 +02:00
|
|
|
if self.connection:
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(common.xmpp.Iq(to = jid, typ = 'get',
|
2005-05-07 12:57:40 +02:00
|
|
|
queryNS = common.xmpp.NS_BROWSE))
|
2005-04-26 20:45:54 +02:00
|
|
|
self.discoverInfo(jid, node)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-05-08 22:56:11 +02:00
|
|
|
def request_register_agent_info(self, agent):
|
2005-04-12 13:46:20 +02:00
|
|
|
if not self.connection:
|
|
|
|
return None
|
2005-07-07 22:45:24 +02:00
|
|
|
common.xmpp.features.getRegInfo(self.connection, agent, sync = False)
|
2005-04-26 20:45:54 +02:00
|
|
|
|
|
|
|
def register_agent(self, agent, info):
|
2005-04-12 13:46:20 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-05-31 15:53:22 +02:00
|
|
|
# FIXME: Blocking
|
|
|
|
common.xmpp.features.register(self.connection, agent, info)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-07-07 22:45:24 +02:00
|
|
|
def new_account(self, name, config, sync = False):
|
|
|
|
if sync:
|
|
|
|
self.new_account2(name, config)
|
|
|
|
else:
|
|
|
|
t = threading.Thread(target=self.new_account2, args = (name, config))
|
|
|
|
t.start()
|
|
|
|
|
|
|
|
def new_account2(self, name, config):
|
2005-04-12 13:46:20 +02:00
|
|
|
# If a connection already exist we cannot create a new account
|
|
|
|
if self.connection:
|
|
|
|
return
|
2005-06-08 17:48:53 +02:00
|
|
|
p = config['proxy']
|
2005-07-04 09:28:42 +02:00
|
|
|
if p and p in gajim.config.get_per('proxies'):
|
2005-06-08 17:48:53 +02:00
|
|
|
proxy = {'host': gajim.config.get_per('proxies', p, 'host')}
|
|
|
|
proxy['port'] = gajim.config.get_per('proxies', p, 'port')
|
|
|
|
proxy['user'] = gajim.config.get_per('proxies', p, 'user')
|
|
|
|
proxy['password'] = gajim.config.get_per('proxies', p, 'pass')
|
2005-04-12 13:46:20 +02:00
|
|
|
else:
|
|
|
|
proxy = None
|
2005-05-31 15:53:22 +02:00
|
|
|
if gajim.verbose:
|
|
|
|
c = common.xmpp.Client(server = config['hostname'])
|
|
|
|
else:
|
|
|
|
c = common.xmpp.Client(server = config['hostname'], debug = [])
|
|
|
|
common.xmpp.dispatcher.DefaultTimeout = 45
|
|
|
|
c.UnregisterDisconnectHandler(c.DisconnectHandler)
|
|
|
|
c.RegisterDisconnectHandler(self._disconnectedCB)
|
2005-06-21 16:24:15 +02:00
|
|
|
h = config['hostname']
|
2005-06-14 12:26:01 +02:00
|
|
|
p = 5222
|
2005-06-18 13:37:29 +02:00
|
|
|
usessl = None
|
|
|
|
if usessl: #FIXME: we cannot create an account if we want ssl connection to create it
|
2005-06-14 12:26:01 +02:00
|
|
|
p = 5223
|
|
|
|
if config['use_custom_host']:
|
|
|
|
h = config['custom_host']
|
|
|
|
p = config['custom_port']
|
2005-06-18 13:37:29 +02:00
|
|
|
secur = None # autodetect [for SSL in 5223/443 and for TLS if broadcasted]
|
|
|
|
if usessl:
|
|
|
|
secur=1 #1 means force SSL no matter what the port is
|
|
|
|
con_type = c.connect((h, p), proxy = proxy, secure=secur)#FIXME: blocking
|
2005-05-26 15:35:58 +02:00
|
|
|
if not con_type:
|
2005-05-30 16:08:48 +02:00
|
|
|
gajim.log.debug("Couldn't connect to %s" % name)
|
2005-06-07 09:40:15 +02:00
|
|
|
self.dispatch('ERROR', (_('Could not connect to "%s"') % name,
|
2005-06-14 12:26:01 +02:00
|
|
|
_('Check your connection or try again later.')))
|
2005-05-26 15:35:58 +02:00
|
|
|
return False
|
2005-07-24 22:00:38 +02:00
|
|
|
gajim.log.debug(_('Connected to server with %s'), con_type)
|
2005-06-29 14:57:46 +02:00
|
|
|
|
2005-07-07 22:45:24 +02:00
|
|
|
c.RegisterEventHandler(self._event_dispatcher)
|
|
|
|
self.new_account_info = config
|
|
|
|
self.connection = c
|
2005-05-31 15:53:22 +02:00
|
|
|
self.name = name
|
2005-07-07 22:45:24 +02:00
|
|
|
common.xmpp.features.getRegInfo(c, config['hostname'])
|
2005-04-12 13:46:20 +02:00
|
|
|
|
|
|
|
def account_changed(self, new_name):
|
|
|
|
self.name = new_name
|
|
|
|
|
|
|
|
def request_os_info(self, jid, resource):
|
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-07-03 01:07:26 +02:00
|
|
|
to_whom_jid = jid
|
2005-07-03 01:03:11 +02:00
|
|
|
if resource:
|
2005-07-03 01:07:26 +02:00
|
|
|
to_whom_jid += '/' + resource
|
2005-07-03 01:03:11 +02:00
|
|
|
iq = common.xmpp.Iq(to=to_whom_jid, typ = 'get', queryNS =\
|
2005-04-26 20:45:54 +02:00
|
|
|
common.xmpp.NS_VERSION)
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-05-24 21:18:32 +02:00
|
|
|
def request_vcard(self, jid = None):
|
|
|
|
'''request the VCARD and return the iq'''
|
2005-04-12 13:46:20 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-05-24 21:18:32 +02:00
|
|
|
iq = common.xmpp.Iq(typ = 'get')
|
|
|
|
if jid:
|
|
|
|
iq.setTo(jid)
|
2005-04-26 20:45:54 +02:00
|
|
|
iq.setTag(common.xmpp.NS_VCARD + ' vCard')
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq)
|
2005-04-12 13:46:20 +02:00
|
|
|
#('VCARD', {entry1: data, entry2: {entry21: data, ...}, ...})
|
|
|
|
|
|
|
|
def send_vcard(self, vcard):
|
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-04-26 20:45:54 +02:00
|
|
|
iq = common.xmpp.Iq(typ = 'set')
|
|
|
|
iq2 = iq.setTag(common.xmpp.NS_VCARD + ' vCard')
|
2005-06-07 10:50:47 +02:00
|
|
|
for i in vcard:
|
2005-06-06 17:29:27 +02:00
|
|
|
if i == 'jid':
|
|
|
|
continue
|
|
|
|
if type(vcard[i]) == type({}):
|
2005-06-07 10:50:47 +02:00
|
|
|
iq3 = iq2.addChild(i)
|
|
|
|
for j in vcard[i]:
|
|
|
|
iq3.addChild(j).setData(vcard[i][j])
|
|
|
|
elif type(vcard[i]) == type([]):
|
|
|
|
for j in vcard[i]:
|
|
|
|
iq3 = iq2.addChild(i)
|
|
|
|
for k in j:
|
|
|
|
iq3.addChild(k).setData(j[k])
|
2005-06-06 17:29:27 +02:00
|
|
|
else:
|
|
|
|
iq2.addChild(i).setData(vcard[i])
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-06-07 20:21:36 +02:00
|
|
|
def get_settings(self):
|
|
|
|
''' Get Gajim settings as described in JEP 0049 '''
|
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
iq = common.xmpp.Iq(typ='get')
|
|
|
|
iq2 = iq.addChild(name='query', namespace='jabber:iq:private')
|
|
|
|
iq3 = iq2.addChild(name='gajim', namespace='gajim:prefs')
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq)
|
2005-06-07 20:21:36 +02:00
|
|
|
|
|
|
|
def get_bookmarks(self):
|
|
|
|
''' Get Bookmarks from storage as described in JEP 0048 '''
|
2005-06-11 16:14:50 +02:00
|
|
|
self.bookmarks = [] #avoid multiple bookmarks when re-connecting
|
2005-06-07 20:21:36 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
iq = common.xmpp.Iq(typ='get')
|
|
|
|
iq2 = iq.addChild(name="query", namespace="jabber:iq:private")
|
|
|
|
iq3 = iq2.addChild(name="storage", namespace="storage:bookmarks")
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq)
|
2005-06-07 20:21:36 +02:00
|
|
|
|
|
|
|
def store_bookmarks(self):
|
|
|
|
''' Send bookmarks to the storage namespace '''
|
2005-06-10 17:45:09 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-06-07 20:21:36 +02:00
|
|
|
iq = common.xmpp.Iq(typ='set')
|
2005-07-04 23:30:00 +02:00
|
|
|
iq2 = iq.addChild(name='query', namespace='jabber:iq:private')
|
|
|
|
iq3 = iq2.addChild(name='storage', namespace='storage:bookmarks')
|
2005-06-07 20:21:36 +02:00
|
|
|
for bm in self.bookmarks:
|
2005-07-04 23:30:00 +02:00
|
|
|
iq4 = iq3.addChild(name = "conference")
|
|
|
|
iq4.setAttr('jid', bm['jid'])
|
|
|
|
iq4.setAttr('autojoin', bm['autojoin'])
|
|
|
|
iq4.setAttr('name', bm['name'])
|
|
|
|
iq5 = iq4.setTagData('nick', bm['nick'])
|
|
|
|
iq5 = iq4.setTagData('password', bm['password'])
|
|
|
|
self.to_be_sent.append(iq)
|
2005-06-07 20:21:36 +02:00
|
|
|
|
2005-04-12 14:23:08 +02:00
|
|
|
def send_agent_status(self, agent, ptype):
|
2005-04-12 13:46:20 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-04-26 20:45:54 +02:00
|
|
|
p = common.xmpp.Presence(to = agent, typ = ptype)
|
2005-08-07 23:42:32 +02:00
|
|
|
p = self.add_sha(p)
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(p)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-04-18 14:17:43 +02:00
|
|
|
def join_gc(self, nick, room, server, password):
|
2005-04-12 13:46:20 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-06-04 16:27:09 +02:00
|
|
|
show = STATUS_LIST[self.connected]
|
|
|
|
ptype = None
|
|
|
|
if show == 'online':
|
|
|
|
show = None
|
2005-05-13 20:54:44 +02:00
|
|
|
p = common.xmpp.Presence(to = '%s@%s/%s' % (room, server, nick),
|
2005-06-04 16:27:09 +02:00
|
|
|
show = show, status = self.status)
|
2005-08-07 23:42:32 +02:00
|
|
|
p = self.add_sha(p)
|
2005-05-18 11:18:29 +02:00
|
|
|
t = p.setTag(common.xmpp.NS_MUC + ' x')
|
|
|
|
if password:
|
|
|
|
t.setTagData('password', password)
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(p)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
|
|
|
def send_gc_message(self, jid, msg):
|
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-04-26 20:45:54 +02:00
|
|
|
msg_iq = common.xmpp.Message(jid, msg, typ = 'groupchat')
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(msg_iq)
|
2005-04-12 13:46:20 +02:00
|
|
|
self.dispatch('MSGSENT', (jid, msg))
|
|
|
|
|
|
|
|
def send_gc_subject(self, jid, subject):
|
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-04-26 20:45:54 +02:00
|
|
|
msg_iq = common.xmpp.Message(jid,typ = 'groupchat', subject = subject)
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(msg_iq)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-04-20 12:21:33 +02:00
|
|
|
def request_gc_config(self, room_jid):
|
2005-05-27 18:43:38 +02:00
|
|
|
iq = common.xmpp.Iq(typ = 'get', queryNS = common.xmpp.NS_MUC_OWNER,
|
2005-04-26 20:45:54 +02:00
|
|
|
to = room_jid)
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq)
|
2005-06-29 10:28:12 +02:00
|
|
|
|
2005-06-19 01:44:33 +02:00
|
|
|
def change_gc_nick(self, room_jid, nick):
|
2005-06-19 00:09:31 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-08-07 23:42:32 +02:00
|
|
|
p = common.xmpp.Presence(to = '%s/%s' % (room_jid, nick))
|
|
|
|
p = self.add_sha(p)
|
|
|
|
self.to_be_sent.append(p)
|
2005-04-20 12:21:33 +02:00
|
|
|
|
2005-04-12 13:46:20 +02:00
|
|
|
def send_gc_status(self, nick, jid, show, status):
|
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-06-04 00:49:07 +02:00
|
|
|
ptype = None
|
2005-04-12 13:46:20 +02:00
|
|
|
if show == 'offline':
|
2005-04-12 14:23:08 +02:00
|
|
|
ptype = 'unavailable'
|
2005-04-12 13:46:20 +02:00
|
|
|
show = None
|
2005-06-04 16:27:09 +02:00
|
|
|
if show == 'online':
|
|
|
|
show = None
|
2005-08-07 23:42:32 +02:00
|
|
|
p = common.xmpp.Presence(to = '%s/%s' % (jid, nick), typ = ptype,
|
|
|
|
show = show, status = status)
|
|
|
|
p = self.add_sha(p)
|
|
|
|
self.to_be_sent.append(p)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-07-02 20:33:51 +02:00
|
|
|
def gc_set_role(self, room_jid, nick, role, reason = ''):
|
2005-07-19 16:38:58 +02:00
|
|
|
'''role is for all the life of the room so it's based on nick'''
|
2005-04-12 13:46:20 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-04-26 20:45:54 +02:00
|
|
|
iq = common.xmpp.Iq(typ = 'set', to = room_jid, queryNS =\
|
|
|
|
common.xmpp.NS_MUC_ADMIN)
|
|
|
|
item = iq.getTag('query').setTag('item')
|
|
|
|
item.setAttr('nick', nick)
|
|
|
|
item.setAttr('role', role)
|
2005-07-02 20:33:51 +02:00
|
|
|
if reason:
|
|
|
|
item.addChild(name = 'reason', payload = reason)
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-07-02 20:33:51 +02:00
|
|
|
def gc_set_affiliation(self, room_jid, jid, affiliation, reason = ''):
|
2005-07-19 16:38:58 +02:00
|
|
|
'''affiliation is for all the life of the room so it's based on jid'''
|
2005-04-12 13:46:20 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-04-26 20:45:54 +02:00
|
|
|
iq = common.xmpp.Iq(typ = 'set', to = room_jid, queryNS =\
|
|
|
|
common.xmpp.NS_MUC_ADMIN)
|
|
|
|
item = iq.getTag('query').setTag('item')
|
|
|
|
item.setAttr('jid', jid)
|
|
|
|
item.setAttr('affiliation', affiliation)
|
2005-07-02 20:33:51 +02:00
|
|
|
if reason:
|
|
|
|
item.addChild(name = 'reason', payload = reason)
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-04-20 12:21:33 +02:00
|
|
|
def send_gc_config(self, room_jid, config):
|
2005-04-26 20:45:54 +02:00
|
|
|
iq = common.xmpp.Iq(typ = 'set', to = room_jid, queryNS =\
|
|
|
|
common.xmpp.NS_MUC_OWNER)
|
|
|
|
query = iq.getTag('query')
|
2005-05-31 15:53:22 +02:00
|
|
|
# FIXME: should really use XData class
|
|
|
|
x = query.setTag(common.xmpp.NS_DATA + ' x', attrs = {'type': 'submit'})
|
2005-04-20 12:21:33 +02:00
|
|
|
i = 0
|
|
|
|
while config.has_key(i):
|
2005-04-25 11:30:24 +02:00
|
|
|
if not config[i].has_key('type'):
|
|
|
|
i += 1
|
|
|
|
continue
|
|
|
|
if config[i]['type'] == 'fixed':
|
|
|
|
i += 1
|
|
|
|
continue
|
2005-04-28 00:14:28 +02:00
|
|
|
tag = x.addChild('field')
|
2005-04-20 12:21:33 +02:00
|
|
|
if config[i].has_key('var'):
|
2005-04-26 20:45:54 +02:00
|
|
|
tag.setAttr('var', config[i]['var'])
|
2005-04-20 12:21:33 +02:00
|
|
|
if config[i].has_key('values'):
|
|
|
|
for val in config[i]['values']:
|
|
|
|
if val == False:
|
2005-04-25 11:30:24 +02:00
|
|
|
val = '0'
|
2005-04-20 12:21:33 +02:00
|
|
|
elif val == True:
|
2005-04-25 11:30:24 +02:00
|
|
|
val = '1'
|
2005-04-26 20:45:54 +02:00
|
|
|
tag.setTagData('value', val)
|
2005-04-20 12:21:33 +02:00
|
|
|
i += 1
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq)
|
2005-04-20 12:21:33 +02:00
|
|
|
|
2005-04-12 13:46:20 +02:00
|
|
|
def gpg_passphrase(self, passphrase):
|
|
|
|
if USE_GPG:
|
|
|
|
self.gpg.passphrase = passphrase
|
|
|
|
|
2005-05-29 23:34:01 +02:00
|
|
|
def ask_gpg_keys(self):
|
|
|
|
if USE_GPG:
|
|
|
|
keys = self.gpg.get_keys()
|
|
|
|
return keys
|
|
|
|
return None
|
|
|
|
|
2005-04-12 13:46:20 +02:00
|
|
|
def ask_gpg_secrete_keys(self):
|
|
|
|
if USE_GPG:
|
|
|
|
keys = self.gpg.get_secret_keys()
|
|
|
|
return keys
|
|
|
|
return None
|
|
|
|
|
|
|
|
def change_password(self, password, username):
|
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
|
2005-04-26 20:45:54 +02:00
|
|
|
iq = common.xmpp.Iq(typ = 'set', to = hostname)
|
|
|
|
q = iq.setTag(common.xmpp.NS_REGISTER + ' query')
|
|
|
|
q.setTagData('username',username)
|
|
|
|
q.setTagData('password',password)
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq)
|
2005-04-12 13:46:20 +02:00
|
|
|
|
2005-04-20 14:23:41 +02:00
|
|
|
def unregister_account(self):
|
|
|
|
if self.connected == 0:
|
|
|
|
self.connection = self.connect()
|
|
|
|
if self.connected > 1:
|
|
|
|
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
|
2005-04-26 20:45:54 +02:00
|
|
|
iq = common.xmpp.Iq(typ = 'set', to = hostname)
|
|
|
|
q = iq.setTag(common.xmpp.NS_REGISTER + ' query').setTag('remove')
|
2005-07-04 23:30:00 +02:00
|
|
|
self.to_be_sent.append(iq)
|
2005-04-20 00:29:38 +02:00
|
|
|
|
2005-06-26 01:25:17 +02:00
|
|
|
def send_keepalive(self):
|
2005-08-27 02:07:43 +02:00
|
|
|
# nothing received for the last foo seconds (60 secs by default)
|
|
|
|
self.to_be_sent.append(' ')
|
2005-06-26 01:25:17 +02:00
|
|
|
|
2005-04-18 11:18:50 +02:00
|
|
|
def process(self, timeout):
|
2005-04-12 13:46:20 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
if self.connected:
|
2005-06-29 10:28:12 +02:00
|
|
|
now = time.time()
|
|
|
|
l = []
|
|
|
|
for t in self.last_sent:
|
|
|
|
if (now - t) < 1:
|
|
|
|
l.append(t)
|
|
|
|
self.last_sent = l
|
|
|
|
t_limit = time.time() + timeout
|
|
|
|
while time.time() < t_limit and len(self.to_be_sent) and \
|
|
|
|
len(self.last_sent) < gajim.config.get_per('accounts',
|
|
|
|
self.name, 'max_stanza_per_sec'):
|
2005-07-30 12:19:52 +02:00
|
|
|
tosend = self.to_be_sent.pop(0)
|
|
|
|
|
|
|
|
self.connection.send(tosend)
|
2005-08-27 02:07:43 +02:00
|
|
|
t = time.time()
|
|
|
|
self.last_io = t
|
|
|
|
self.last_sent.append(t)
|
2005-05-18 15:42:12 +02:00
|
|
|
try:
|
2005-08-27 02:07:43 +02:00
|
|
|
# do we want keepalives?
|
|
|
|
if gajim.config.get_per('accounts', self.name, 'keep_alives_enabled'):
|
|
|
|
t = gajim.config.get_per('accounts', self.name,
|
|
|
|
'keep_alive_every_foo_secs')
|
|
|
|
# should we send keepalive?
|
|
|
|
if time.time() > (self.last_io + t):
|
2005-06-26 01:25:17 +02:00
|
|
|
self.send_keepalive()
|
2005-06-29 10:28:12 +02:00
|
|
|
|
2005-07-03 14:42:53 +02:00
|
|
|
if self.connection:
|
|
|
|
self.connection.Process(timeout)
|
2005-05-18 20:57:54 +02:00
|
|
|
except:
|
2005-07-24 22:00:38 +02:00
|
|
|
gajim.log.debug(_('error appeared while processing xmpp:'))
|
2005-05-20 19:30:29 +02:00
|
|
|
traceback.print_exc()
|
2005-05-18 15:42:12 +02:00
|
|
|
self.connected = 0
|
|
|
|
self.dispatch('STATUS', 'offline')
|
2005-05-23 12:46:22 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2005-05-18 15:42:12 +02:00
|
|
|
try:
|
|
|
|
self.connection.disconnect()
|
|
|
|
except:
|
2005-07-24 22:00:38 +02:00
|
|
|
gajim.log.debug(_('error appeared while processing xmpp:'))
|
2005-05-20 19:30:29 +02:00
|
|
|
traceback.print_exc()
|
2005-05-18 15:42:12 +02:00
|
|
|
self.connection = None
|
2005-05-31 15:53:22 +02:00
|
|
|
# END Connection
|