2005-04-12 21:09:06 +00:00
## common/connection.py
2005-04-12 11:46:20 +00:00
##
2005-12-09 17:15:30 +00:00
## Contributors for this file:
2005-04-12 11:46:20 +00:00
## - Yann Le Boulanger <asterix@lagaule.org>
## - Nikos Kouremenos <nkour@jabber.org>
2005-09-03 13:48:25 +00:00
## - Dimitur Kirov <dkirov@gmail.com>
2005-11-13 01:48:48 +00:00
## - Travis Shirk <travis@pobox.com>
2005-04-12 11:46:20 +00:00
##
2005-12-09 23:30:28 +00:00
## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Copyright (C) 2005 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Nikos Kouremenos <nkour@jabber.org>
## Dimitur Kirov <dkirov@gmail.com>
## Travis Shirk <travis@pobox.com>
## Norman Rasmussen <norman@rasmussen.co.za>
2005-04-12 11:46:20 +00:00
##
## 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.
##
2005-09-10 09:25:06 +00:00
# kind of events we can wait for an answer
VCARD_PUBLISHED = ' vcard_published '
2005-11-28 16:26:19 +00:00
VCARD_ARRIVED = ' vcard_arrived '
2005-09-10 09:25:06 +00:00
2005-04-12 11:46:20 +00:00
import sys
2005-08-07 21:42:32 +00:00
import sha
2005-04-12 11:46:20 +00:00
import os
import time
2005-05-18 16:42:28 +00:00
import sre
2005-05-20 17:30:29 +00:00
import traceback
2005-06-28 19:03:00 +00:00
import threading
2005-07-30 10:19:52 +00:00
import select
2005-08-12 14:59:28 +00:00
import socket
2005-11-04 08:19:15 +00:00
import random
random . seed ( )
2005-10-04 18:22:25 +00:00
import signal
2005-12-05 08:45:39 +00:00
import base64
2005-10-05 11:05:51 +00:00
if os . name != ' nt ' :
signal . signal ( signal . SIGPIPE , signal . SIG_DFL )
2005-07-30 10:59:15 +00:00
2005-04-27 18:26:31 +00:00
from calendar import timegm
2005-04-12 11:46:20 +00:00
2005-04-26 18:45:54 +00:00
import common . xmpp
2005-04-12 11:46:20 +00:00
2005-05-27 05:56:17 +00:00
from common import helpers
2005-04-14 07:42:26 +00:00
from common import gajim
from common import GnuPG
2005-08-01 22:58:14 +00:00
import socks5
2005-04-13 09:41:44 +00:00
USE_GPG = GnuPG . USE_GPG
2005-04-12 11:46:20 +00:00
from common import i18n
_ = i18n . _
2005-09-18 19:52:06 +00:00
# determine which DNS resolution library is available
2005-11-06 20:58:22 +00:00
HAS_DNSPYTHON = False
HAS_PYDNS = False
2005-09-18 19:52:06 +00:00
try :
import dns . resolver # http://dnspython.org/
2005-11-06 20:58:22 +00:00
HAS_DNSPYTHON = True
2005-09-18 19:52:06 +00:00
except ImportError :
try :
import DNS # http://pydns.sf.net/
2005-11-06 20:58:22 +00:00
HAS_PYDNS = True
2005-09-18 19:52:06 +00:00
except ImportError :
gajim . log . debug ( " Could not load one of the supported DNS libraries (dnspython or pydns). SRV records will not be queried and you may need to set custom hostname/port for some servers to be accessible. " )
2005-04-12 11:46:20 +00:00
2005-04-30 08:48:50 +00:00
STATUS_LIST = [ ' offline ' , ' connecting ' , ' online ' , ' chat ' , ' away ' , ' xa ' , ' dnd ' ,
2005-04-12 11:46:20 +00:00
' invisible ' ]
distro_info = {
2005-04-19 13:14:41 +00: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 20:54:21 +00:00
' Source Mage ' : ' /etc/sourcemage_version ' ,
2005-05-18 17:02:46 +00:00
' SUSE Linux ' : ' /etc/SuSE-release ' ,
2005-04-19 13:14:41 +00:00
' Sun JDS ' : ' /etc/sun-release ' ,
' PLD Linux ' : ' /etc/pld-release ' ,
' Yellow Dog Linux ' : ' /etc/yellowdog-release ' ,
2005-04-12 11:46:20 +00:00
# many distros use the /etc/redhat-release for compatibility
# so Redhat is the last
2005-04-19 13:14:41 +00:00
' Redhat Linux ' : ' /etc/redhat-release '
2005-04-12 11:46:20 +00:00
}
def get_os_info ( ) :
2005-04-16 23:15:03 +00:00
if os . name == ' nt ' :
2005-10-21 17:00:37 +00:00
ver = os . sys . getwindowsversion ( )
ver_format = ver [ 3 ] , ver [ 0 ] , ver [ 1 ]
2005-04-19 13:14:41 +00:00
win_version = {
( 1 , 4 , 0 ) : ' 95 ' ,
( 1 , 4 , 10 ) : ' 98 ' ,
( 1 , 4 , 90 ) : ' ME ' ,
( 2 , 4 , 0 ) : ' NT ' ,
( 2 , 5 , 0 ) : ' 2000 ' ,
2005-10-21 16:46:27 +00:00
( 2 , 5 , 1 ) : ' XP ' ,
( 2 , 5 , 2 ) : ' 2003 '
2005-10-21 17:00:37 +00:00
}
if win_version . has_key ( ver_format ) :
return ' Windows ' + ' ' + win_version [ ver_format ]
else :
return ' Windows '
2005-04-26 18:45:54 +00:00
elif os . name == ' posix ' :
2005-04-12 11:46:20 +00:00
executable = ' lsb_release '
params = ' --id --codename --release --short '
2005-08-09 11:34:16 +00: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 )
2005-09-28 15:00:01 +00:00
output = helpers . temp_failure_retry ( child_stdout . readline ) . strip ( )
2005-08-09 11:34:16 +00:00
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 11:46:20 +00:00
# lsb_release executable not available, so parse files
2005-04-19 13:14:41 +00:00
for distro_name in distro_info :
path_to_file = distro_info [ distro_name ]
2005-04-12 11:46:20 +00:00
if os . path . exists ( path_to_file ) :
fd = open ( path_to_file )
2005-06-04 21:52:49 +00:00
text = fd . readline ( ) . strip ( ) #get only first line
2005-04-12 11:46:20 +00:00
fd . close ( )
if path_to_file . endswith ( ' version ' ) :
2005-06-04 20:54:21 +00:00
# sourcemage_version has all the info we need
2005-06-06 00:11:48 +00:00
if not os . path . basename ( path_to_file ) . startswith ( ' sourcemage ' ) :
2005-06-04 20:54:21 +00:00
text = distro_name + ' ' + text
2005-06-29 08:28:12 +00:00
elif path_to_file . endswith ( ' aurox-release ' ) :
# file doesn't have version
2005-04-19 13:14:41 +00:00
text = distro_name
elif path_to_file . endswith ( ' lfs-release ' ) : # file just has version
text = distro_name + ' ' + text
2005-04-12 11:46:20 +00:00
return text
2005-12-06 22:08:10 +00:00
2005-10-25 08:39:41 +00:00
# our last chance, ask uname and strip it
uname_output = helpers . get_output_of_command ( ' uname -a | cut -d " " -f1,3 ' )
if uname_output is not None :
2005-10-31 20:54:05 +00:00
return uname_output [ 0 ] # only first line
2005-05-11 11:09:53 +00:00
return ' N/A '
2005-04-12 11:46:20 +00:00
2005-04-19 13:14:41 +00:00
class Connection :
""" Connection class """
2005-04-14 09:38:08 +00:00
def __init__ ( self , name ) :
2005-04-12 11:46:20 +00:00
self . name = name
self . connected = 0 # offline
2005-04-26 18:45:54 +00:00
self . connection = None # xmpppy instance
2005-04-12 11:46:20 +00:00
self . gpg = None
2005-08-07 21:42:32 +00:00
self . vcard_sha = None
2005-10-31 17:31:30 +00:00
self . vcard_shas = { } # sha of contacts
2005-05-13 18:54:44 +00:00
self . status = ' '
2005-09-05 13:28:09 +00:00
self . old_show = ' '
2005-12-06 17:37:54 +00:00
# holds the actual hostname to which we are connected
2005-11-20 13:27:37 +00:00
self . connected_hostname = None
2005-09-05 13:28:09 +00:00
self . time_to_reconnect = None
2005-07-07 20:45:24 +00:00
self . new_account_info = None
2005-06-07 18:21:36 +00:00
self . bookmarks = [ ]
2005-05-27 12:07:20 +00:00
self . on_purpose = False
2005-08-27 00:07:43 +00:00
self . last_io = time . time ( )
2005-06-29 08:28:12 +00:00
self . to_be_sent = [ ]
self . last_sent = [ ]
2005-08-03 14:04:54 +00:00
self . files_props = { }
2005-12-20 16:18:17 +00:00
self . last_history_line = { }
2005-04-14 11:06:58 +00:00
self . password = gajim . config . get_per ( ' accounts ' , name , ' password ' )
2005-09-07 15:32:31 +00:00
self . server_resource = gajim . config . get_per ( ' accounts ' , name , ' resource ' )
2005-09-08 08:33:35 +00:00
self . privacy_rules_supported = False
2005-11-19 19:33:11 +00:00
# Do we continue connection when we get roster (send presence,get vcard...)
2005-09-08 08:33:35 +00:00
self . continue_connect_info = None
2005-11-19 19:33:11 +00:00
# List of IDs we are waiting answers for {id: (type_of_request, data), }
2005-09-10 09:25:06 +00:00
self . awaiting_answers = { }
2005-11-19 19:33:11 +00:00
# List of IDs that will produce a timeout is answer doesn't arrive
# {time_of_the_timeout: (id, message to send to gui), }
self . awaiting_timeouts = { }
2005-04-14 09:38:08 +00:00
if USE_GPG :
self . gpg = GnuPG . GnuPG ( )
gajim . config . set ( ' usegpg ' , True )
else :
gajim . config . set ( ' usegpg ' , False )
2005-09-05 13:28:09 +00:00
self . retrycount = 0
2005-04-12 11:46:20 +00:00
# END __init__
2005-11-02 22:08:31 +00:00
def get_full_jid ( self , iq_obj ) :
''' return the full jid (with resource) from an iq as unicode '''
2005-11-03 14:46:56 +00:00
return helpers . parse_jid ( str ( iq_obj . getFrom ( ) ) )
2005-11-02 22:08:31 +00:00
def get_jid ( self , iq_obj ) :
''' return the jid (without resource) from an iq as unicode '''
2005-11-03 14:46:56 +00:00
jid = self . get_full_jid ( iq_obj )
return gajim . get_jid_without_resource ( jid )
2005-11-02 22:08:31 +00:00
2005-08-09 18:45:16 +00:00
def put_event ( self , ev ) :
2005-08-24 15:59:51 +00:00
if gajim . events_for_ui . has_key ( self . name ) :
gajim . events_for_ui [ self . name ] . append ( ev )
2005-08-09 18:45:16 +00:00
2005-06-07 07:40:15 +00:00
def dispatch ( self , event , data ) :
2005-06-29 12:57:46 +00:00
''' always passes account name as first param '''
2005-08-09 18:45:16 +00:00
gajim . mutex_events_for_ui . lock ( self . put_event , [ event , data ] )
gajim . mutex_events_for_ui . unlock ( )
2005-04-12 11:46:20 +00:00
2005-08-07 21:42:32 +00: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 13:53:22 +00:00
# this is in features.py but it is blocking
2005-12-06 22:08:10 +00:00
def _discover ( self , ns , jid , node = None ) :
2005-05-23 10:46:22 +00:00
if not self . connection :
return
2005-04-26 18:45:54 +00:00
iq = common . xmpp . Iq ( typ = ' get ' , to = jid , queryNS = ns )
if node :
iq . setQuerynode ( node )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( iq )
2005-04-26 18:45:54 +00:00
def discoverItems ( self , jid , node = None ) :
2005-12-06 22:08:10 +00:00
''' According to JEP-0030: jid is mandatory,
2005-09-03 13:48:25 +00:00
name , node , action is optional . '''
2005-04-26 18:45:54 +00:00
self . _discover ( common . xmpp . NS_DISCO_ITEMS , jid , node )
2005-12-06 22:08:10 +00:00
2005-04-26 18:45:54 +00:00
def discoverInfo ( self , jid , node = None ) :
''' According to JEP-0030:
2005-10-30 09:58:13 +00:00
For identity : category , type is mandatory , name is optional .
2005-04-26 18:45:54 +00:00
For feature : var is mandatory '''
self . _discover ( common . xmpp . NS_DISCO_INFO , jid , node )
2005-10-31 10:23:33 +00:00
def node_to_dict ( self , node ) :
dict = { }
for info in node . getChildren ( ) :
name = info . getName ( )
if name in ( ' ADR ' , ' TEL ' , ' EMAIL ' ) : # we can have several
if not dict . has_key ( name ) :
dict [ name ] = [ ]
entry = { }
for c in info . getChildren ( ) :
entry [ c . getName ( ) ] = c . getData ( )
dict [ name ] . append ( entry )
elif info . getChildren ( ) == [ ] :
dict [ name ] = info . getData ( )
else :
dict [ name ] = { }
for c in info . getChildren ( ) :
dict [ name ] [ c . getName ( ) ] = c . getData ( )
return dict
2005-04-12 11:46:20 +00:00
def _vCardCB ( self , con , vc ) :
2005-06-07 01:10:24 +00:00
""" Called when we receive a vCard
2005-04-12 11:46:20 +00:00
Parse the vCard and send it to plugins """
2005-10-31 10:23:33 +00:00
if not vc . getTag ( ' vCard ' ) :
return
2005-06-26 19:40:57 +00:00
frm_iq = vc . getFrom ( )
2005-09-09 21:15:41 +00:00
our_jid = gajim . get_jid_from_account ( self . name )
2005-06-26 19:40:57 +00:00
resource = ' '
if frm_iq :
2005-11-03 09:21:12 +00:00
who = self . get_full_jid ( vc )
frm , resource = gajim . get_room_and_nick_from_fjid ( who )
2005-05-24 19:18:32 +00:00
else :
2005-08-08 13:34:48 +00:00
frm = our_jid
2005-04-26 18:45:54 +00:00
if vc . getTag ( ' vCard ' ) . getNamespace ( ) == common . xmpp . NS_VCARD :
2005-04-12 11:46:20 +00:00
card = vc . getChildren ( ) [ 0 ]
2005-10-31 17:31:30 +00:00
vcard = self . node_to_dict ( card )
2005-11-01 14:43:00 +00:00
if vcard . has_key ( ' PHOTO ' ) and isinstance ( vcard [ ' PHOTO ' ] , dict ) and \
2005-10-31 17:31:30 +00:00
vcard [ ' PHOTO ' ] . has_key ( ' BINVAL ' ) :
photo = vcard [ ' PHOTO ' ] [ ' BINVAL ' ]
2005-12-05 08:45:39 +00:00
photo_decoded = base64 . decodestring ( photo )
avatar_sha = sha . sha ( photo_decoded ) . hexdigest ( )
2005-10-31 17:31:30 +00:00
else :
avatar_sha = ' '
if avatar_sha :
card . getTag ( ' PHOTO ' ) . setTagData ( ' SHA ' , avatar_sha )
if frm != our_jid :
if avatar_sha :
self . vcard_shas [ frm ] = avatar_sha
elif self . vcard_shas . has_key ( frm ) :
del self . vcard_shas [ frm ]
# Save it to file
2005-10-30 16:46:50 +00:00
path_to_file = os . path . join ( gajim . VCARDPATH , frm )
fil = open ( path_to_file , ' w ' )
fil . write ( str ( card ) )
fil . close ( )
2005-10-31 17:31:30 +00:00
2005-10-31 10:23:33 +00:00
vcard [ ' jid ' ] = frm
vcard [ ' resource ' ] = resource
2005-08-08 13:34:48 +00:00
if frm == our_jid :
2005-04-12 11:46:20 +00:00
self . dispatch ( ' MYVCARD ' , vcard )
2005-10-31 20:51:45 +00:00
# we re-send our presence with sha if has changed and if we are
# not invisible
if self . vcard_sha == avatar_sha :
return
self . vcard_sha = avatar_sha
2005-09-07 14:41:14 +00:00
if STATUS_LIST [ self . connected ] == ' invisible ' :
return
2005-09-05 13:28:09 +00:00
sshow = helpers . get_xmpp_show ( STATUS_LIST [ self . connected ] )
2005-08-26 00:52:44 +00:00
prio = unicode ( gajim . config . get_per ( ' accounts ' , self . name ,
' priority ' ) )
2005-08-18 08:33:51 +00:00
p = common . xmpp . Presence ( typ = None , priority = prio , show = sshow ,
2005-08-08 12:23:51 +00:00
status = self . status )
2005-08-07 21:42:32 +00:00
p = self . add_sha ( p )
self . to_be_sent . append ( p )
2005-04-12 11:46:20 +00:00
else :
self . dispatch ( ' VCARD ' , vcard )
Merged revisions 5017-5020,5022-5029 via svnmerge from
svn://svn.gajim.org/gajim/trunk
........
r5017 | asterix | 2006-01-06 01:55:51 -0700 (Fri, 06 Jan 2006) | 2 lines
use escape for pango markup
........
r5018 | asterix | 2006-01-06 02:21:39 -0700 (Fri, 06 Jan 2006) | 2 lines
missing new contacts function
........
r5019 | asterix | 2006-01-06 11:03:07 -0700 (Fri, 06 Jan 2006) | 2 lines
handle the click on toggle_gpg_encryption menuitem
........
r5020 | asterix | 2006-01-06 11:14:14 -0700 (Fri, 06 Jan 2006) | 2 lines
use the saved size even if a chat window is already opened
........
r5022 | asterix | 2006-01-07 03:43:47 -0700 (Sat, 07 Jan 2006) | 2 lines
we can now resume filetransfert
........
r5023 | asterix | 2006-01-07 03:56:31 -0700 (Sat, 07 Jan 2006) | 2 lines
[Knuckles] Google E-Mail Notification
........
r5024 | asterix | 2006-01-07 04:02:16 -0700 (Sat, 07 Jan 2006) | 2 lines
better string
........
r5025 | asterix | 2006-01-07 04:14:32 -0700 (Sat, 07 Jan 2006) | 2 lines
fix a TB
........
r5026 | asterix | 2006-01-07 05:36:55 -0700 (Sat, 07 Jan 2006) | 2 lines
we can now drag a file on a contact in the roster to send him a file
........
r5027 | asterix | 2006-01-07 06:26:28 -0700 (Sat, 07 Jan 2006) | 2 lines
contact.groups is always a list, even if emtpy
........
r5028 | asterix | 2006-01-07 06:54:30 -0700 (Sat, 07 Jan 2006) | 2 lines
make all buttons insensitive on a category row in disco
........
r5029 | asterix | 2006-01-07 07:19:25 -0700 (Sat, 07 Jan 2006) | 2 lines
auto open groupchat configuration window when we create a new room
........
2006-01-07 17:25:35 +00:00
def _gMailCB ( self , con , gm ) :
""" Called when we get notified of new mail messages in gmail account """
if not gm . getTag ( ' new-mail ' ) :
return
if gm . getTag ( ' new-mail ' ) . getNamespace ( ) == common . xmpp . NS_GMAILNOTIFY :
jid = gajim . get_jid_from_account ( self . name )
gajim . log . debug ( ( ' Notifying user of new gmail e-mail on %s . ' ) % ( jid ) )
self . dispatch ( ' GMAIL_NOTIFY ' , jid )
raise common . xmpp . NodeProcessed
2005-04-26 18:45:54 +00:00
2005-04-12 11:46:20 +00:00
def _messageCB ( self , con , msg ) :
2005-06-07 01:10:24 +00:00
""" Called when we receive a message """
2005-05-20 11:23:08 +00:00
msgtxt = msg . getBody ( )
2005-04-12 12:23:08 +00:00
mtype = msg . getType ( )
2005-07-05 21:44:01 +00:00
subject = msg . getSubject ( ) # if not there, it's None
2005-04-12 11:46:20 +00:00
tim = msg . getTimestamp ( )
tim = time . strptime ( tim , ' % Y % m %d T % H: % M: % S ' )
2005-04-27 18:26:31 +00:00
tim = time . localtime ( timegm ( tim ) )
2005-11-02 22:08:31 +00:00
frm = self . get_full_jid ( msg )
2005-12-04 22:23:41 +00:00
jid = self . get_jid ( msg )
2005-12-04 22:58:38 +00:00
no_log_for = gajim . config . get_per ( ' accounts ' , self . name , ' no_log_for ' )
2005-05-30 10:41:55 +00:00
encrypted = False
2005-07-21 14:56:39 +00:00
chatstate = None
2005-04-26 18:45:54 +00:00
xtags = msg . getTags ( ' x ' )
2005-04-12 11:46:20 +00:00
encTag = None
decmsg = ' '
2005-09-11 15:02:22 +00:00
invite = None
2005-04-12 11:46:20 +00:00
for xtag in xtags :
2005-04-26 18:45:54 +00:00
if xtag . getNamespace ( ) == common . xmpp . NS_ENCRYPTED :
2005-04-12 11:46:20 +00:00
encTag = xtag
break
2005-10-06 20:27:11 +00:00
#invitations
elif xtag . getNamespace ( ) == common . xmpp . NS_MUC_USER and \
2005-12-06 22:08:10 +00:00
xtag . getTag ( ' invite ' ) :
2005-09-11 15:02:22 +00:00
invite = xtag
2005-10-06 20:27:11 +00:00
# FIXME: Msn transport (CMSN1.2.1 and PyMSN0.10) do NOT RECOMMENDED
# invitation
2005-10-04 13:31:55 +00:00
# stanza (MUC JEP) remove in 2007, as we do not do NOT RECOMMENDED
2005-10-04 11:33:57 +00:00
elif xtag . getNamespace ( ) == common . xmpp . NS_CONFERENCE :
room_jid = xtag . getAttr ( ' jid ' )
self . dispatch ( ' GC_INVITATION ' , ( room_jid , frm , ' ' , None ) )
return
2005-07-19 14:38:58 +00: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 14:56:39 +00:00
chatstate = child . getName ( )
2005-07-19 14:38:58 +00:00
break
2005-12-06 22:08:10 +00:00
2005-04-12 11:46:20 +00:00
if encTag and USE_GPG :
#decrypt
encmsg = encTag . getData ( )
2005-12-06 22:08:10 +00:00
2005-04-12 11:46:20 +00:00
keyID = gajim . config . get_per ( ' accounts ' , self . name , ' keyid ' )
if keyID :
decmsg = self . gpg . decrypt ( encmsg , keyID )
if decmsg :
msgtxt = decmsg
2005-05-30 10:41:55 +00:00
encrypted = True
2005-04-12 12:23:08 +00:00
if mtype == ' error ' :
2005-10-04 10:49:58 +00:00
self . dispatch ( ' MSGERROR ' , ( frm , msg . getErrorCode ( ) , msg . getError ( ) ,
msgtxt , tim ) )
2005-04-12 12:23:08 +00:00
elif mtype == ' groupchat ' :
2005-04-12 11:46:20 +00:00
if subject :
2005-10-04 10:49:58 +00:00
self . dispatch ( ' GC_SUBJECT ' , ( frm , subject ) )
2005-04-12 11:46:20 +00:00
else :
2005-06-07 11:05:58 +00:00
if not msg . getTag ( ' body ' ) : #no <body>
return
2005-10-04 10:49:58 +00:00
self . dispatch ( ' GC_MSG ' , ( frm , msgtxt , tim ) )
2005-12-20 16:18:17 +00:00
if self . name not in no_log_for and not \
2005-12-24 22:00:28 +00:00
int ( float ( time . mktime ( tim ) ) ) < = self . last_history_line [ jid ] :
2005-12-04 22:23:41 +00:00
gajim . logger . write ( ' gc_msg ' , frm , msgtxt , tim = tim )
2005-11-27 15:45:54 +00:00
elif mtype == ' chat ' : # it's type 'chat'
if not msg . getTag ( ' body ' ) and chatstate is None : #no <body>
return
2005-12-04 22:23:41 +00:00
if msg . getTag ( ' body ' ) and self . name not in no_log_for and jid not in \
no_log_for :
2005-11-27 15:45:54 +00:00
gajim . logger . write ( ' chat_msg_recv ' , frm , msgtxt , tim = tim , subject = subject )
self . dispatch ( ' MSG ' , ( frm , msgtxt , tim , encrypted , mtype , subject ,
chatstate ) )
else : # it's single message
2005-12-04 22:23:41 +00:00
if self . name not in no_log_for and jid not in no_log_for :
gajim . logger . write ( ' single_msg_recv ' , frm , msgtxt , tim = tim , subject = subject )
2005-09-11 15:02:22 +00:00
if invite is not None :
2005-10-04 10:59:11 +00:00
item = invite . getTag ( ' invite ' )
jid_from = item . getAttr ( ' from ' )
reason = item . getTagData ( ' reason ' )
item = invite . getTag ( ' password ' )
password = invite . getTagData ( ' password ' )
self . dispatch ( ' GC_INVITATION ' , ( frm , jid_from , reason , password ) )
2005-09-11 15:02:22 +00:00
else :
2005-12-07 16:09:03 +00:00
self . dispatch ( ' MSG ' , ( frm , msgtxt , tim , encrypted , ' normal ' ,
subject , None ) )
2005-04-12 11:46:20 +00:00
# END messageCB
def _presenceCB ( self , con , prs ) :
2005-06-07 01:10:24 +00:00
""" Called when we receive a presence """
2005-04-12 12:23:08 +00:00
ptype = prs . getType ( )
2005-09-28 15:24:26 +00:00
if ptype == ' available ' :
ptype = None
2005-07-07 17:20:43 +00:00
gajim . log . debug ( ' PresenceCB: %s ' % ptype )
2005-09-19 16:13:45 +00:00
is_gc = False # is it a GC presence ?
2005-04-12 11:46:20 +00:00
sigTag = None
2005-10-31 17:31:30 +00:00
avatar_sha = None
2005-09-19 16:13:45 +00:00
xtags = prs . getTags ( ' x ' )
for x in xtags :
2005-09-28 15:24:26 +00:00
if x . getNamespace ( ) . startswith ( common . xmpp . NS_MUC ) :
2005-09-19 16:13:45 +00:00
is_gc = True
if x . getNamespace ( ) == common . xmpp . NS_SIGNED :
2005-09-19 16:27:10 +00:00
sigTag = x
2005-10-31 17:31:30 +00:00
if x . getNamespace ( ) == common . xmpp . NS_VCARD_UPDATE :
avatar_sha = x . getTagData ( ' photo ' )
2005-12-06 22:08:10 +00:00
2005-11-02 22:08:31 +00:00
who = self . get_full_jid ( prs )
2005-11-03 09:21:12 +00:00
jid_stripped , resource = gajim . get_room_and_nick_from_fjid ( who )
2005-12-04 22:58:38 +00:00
no_log_for = gajim . config . get_per ( ' accounts ' , self . name , ' no_log_for ' )
2005-09-19 16:13:45 +00:00
status = prs . getStatus ( )
2005-06-23 18:27:14 +00: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 12:23:08 +00:00
elif ptype == ' unavailable ' :
2005-04-16 09:36:18 +00:00
show = ' offline '
2005-09-19 16:13:45 +00:00
2005-09-27 11:14:39 +00:00
prio = prs . getPriority ( )
try :
prio = int ( prio )
except :
prio = 0
keyID = ' '
if sigTag and USE_GPG :
#verify
sigmsg = sigTag . getData ( )
keyID = self . gpg . verify ( status , sigmsg )
2005-09-19 16:13:45 +00:00
if is_gc :
if ptype == ' error ' :
errmsg = prs . getError ( )
errcode = prs . getErrorCode ( )
if errcode == ' 502 ' : # Internal Timeout:
self . dispatch ( ' NOTIFY ' , ( jid_stripped , ' error ' , errmsg , resource ,
prio , keyID ) )
elif errcode == ' 401 ' : # password required to join
2005-12-06 22:08:10 +00:00
self . dispatch ( ' ERROR ' , ( _ ( ' Unable to join room ' ) ,
2005-09-19 16:13:45 +00:00
_ ( ' A password is required to join this room. ' ) ) )
elif errcode == ' 403 ' : # we are banned
2005-12-06 22:08:10 +00:00
self . dispatch ( ' ERROR ' , ( _ ( ' Unable to join room ' ) ,
2005-09-19 16:13:45 +00:00
_ ( ' You are banned from this room. ' ) ) )
elif errcode == ' 404 ' : # room does not exist
2005-12-06 22:08:10 +00:00
self . dispatch ( ' ERROR ' , ( _ ( ' Unable to join room ' ) ,
2005-09-19 16:13:45 +00:00
_ ( ' Such room does not exist. ' ) ) )
elif errcode == ' 405 ' :
2005-12-06 22:08:10 +00:00
self . dispatch ( ' ERROR ' , ( _ ( ' Unable to join room ' ) ,
2005-09-19 16:13:45 +00:00
_ ( ' Room creation is restricted. ' ) ) )
elif errcode == ' 406 ' :
2005-12-06 22:08:10 +00:00
self . dispatch ( ' ERROR ' , ( _ ( ' Unable to join room ' ) ,
2005-09-19 16:13:45 +00:00
_ ( ' Your registered nickname must be used. ' ) ) )
elif errcode == ' 407 ' :
2005-12-06 22:08:10 +00:00
self . dispatch ( ' ERROR ' , ( _ ( ' Unable to join room ' ) ,
2005-09-19 16:13:45 +00:00
_ ( ' You are not in the members list. ' ) ) )
elif errcode == ' 409 ' : # nick conflict
2005-09-26 22:29:52 +00:00
# the jid_from in this case is FAKE JID: room_jid/nick
2005-10-03 18:19:31 +00:00
# resource holds the bad nick so propose a new one
2005-11-18 17:47:52 +00:00
proposed_nickname = resource + \
gajim . config . get ( ' gc_proposed_nick_char ' )
2005-09-28 15:24:26 +00:00
room_jid = gajim . get_room_from_fjid ( who )
2005-12-06 22:08:10 +00:00
self . dispatch ( ' ASK_NEW_NICK ' , ( room_jid , _ ( ' Unable to join room ' ) ,
2005-10-03 18:19:31 +00:00
_ ( ' Your desired nickname is in use or registered by another occupant. \n Please specify another nickname below: ' ) , proposed_nickname ) )
2005-09-19 16:13:45 +00:00
else : # print in the window the error
self . dispatch ( ' ERROR_ANSWER ' , ( ' ' , jid_stripped ,
errmsg , errcode ) )
if not ptype or ptype == ' unavailable ' :
2005-12-04 22:23:41 +00:00
if gajim . config . get ( ' log_contact_status_changes ' ) and self . name \
not in no_log_for and jid_stripped not in no_log_for :
2005-11-23 23:28:26 +00:00
gajim . logger . write ( ' gcstatus ' , who , status , show )
2005-09-19 16:13:45 +00:00
self . dispatch ( ' GC_NOTIFY ' , ( jid_stripped , show , status , resource ,
prs . getRole ( ) , prs . getAffiliation ( ) , prs . getJid ( ) ,
prs . getReason ( ) , prs . getActor ( ) , prs . getStatusCode ( ) ,
prs . getNewNick ( ) ) )
return
if ptype == ' subscribe ' :
2005-04-12 11:46:20 +00:00
gajim . log . debug ( ' subscribe request from %s ' % who )
if gajim . config . get ( ' alwaysauth ' ) or who . find ( " @ " ) < = 0 :
if self . connection :
2005-08-07 21:42:32 +00:00
p = common . xmpp . Presence ( who , ' subscribed ' )
p = self . add_sha ( p )
self . to_be_sent . append ( p )
2005-04-12 11:46:20 +00:00
if who . find ( " @ " ) < = 0 :
2005-06-29 08:28:12 +00:00
self . dispatch ( ' NOTIFY ' ,
2005-09-19 16:13:45 +00:00
( jid_stripped , ' offline ' , ' offline ' , resource , prio , keyID ) )
2005-04-12 11:46:20 +00:00
else :
if not status :
status = _ ( ' I would like to add you to my roster. ' )
self . dispatch ( ' SUBSCRIBE ' , ( who , status ) )
2005-04-12 12:23:08 +00:00
elif ptype == ' subscribed ' :
2005-09-19 16:13:45 +00:00
self . dispatch ( ' SUBSCRIBED ' , ( jid_stripped , resource ) )
2005-08-25 10:06:33 +00:00
# BE CAREFUL: no con.updateRosterItem() in a callback
2005-08-01 22:58:14 +00:00
gajim . log . debug ( _ ( ' we are now subscribed to %s ' ) % who )
2005-04-12 12:23:08 +00:00
elif ptype == ' unsubscribe ' :
2005-07-24 20:00:38 +00:00
gajim . log . debug ( _ ( ' unsubscribe request from %s ' ) % who )
2005-04-12 12:23:08 +00:00
elif ptype == ' unsubscribed ' :
2005-08-01 22:58:14 +00:00
gajim . log . debug ( _ ( ' we are now unsubscribed from %s ' ) % who )
2005-09-19 16:13:45 +00:00
self . dispatch ( ' UNSUBSCRIBED ' , jid_stripped )
2005-04-12 12:23:08 +00:00
elif ptype == ' error ' :
2005-04-12 11:46:20 +00:00
errmsg = prs . getError ( )
errcode = prs . getErrorCode ( )
2005-09-03 17:18:07 +00:00
if errcode == ' 502 ' : # Internal Timeout:
2005-09-19 16:13:45 +00:00
self . dispatch ( ' NOTIFY ' , ( jid_stripped , ' error ' , errmsg , resource ,
prio , keyID ) )
2005-09-06 19:29:25 +00:00
else : # print in the window the error
2005-09-19 16:13:45 +00:00
self . dispatch ( ' ERROR_ANSWER ' , ( ' ' , jid_stripped ,
2005-08-09 15:28:32 +00:00
errmsg , errcode ) )
2005-10-31 17:31:30 +00:00
if avatar_sha :
if self . vcard_shas . has_key ( jid_stripped ) :
if avatar_sha != self . vcard_shas [ jid_stripped ] :
# avatar has been updated
2005-11-03 20:52:04 +00:00
self . request_vcard ( jid_stripped )
2005-10-31 17:31:30 +00:00
else :
self . vcard_shas [ jid_stripped ] = avatar_sha
2005-06-03 22:49:07 +00:00
if not ptype or ptype == ' unavailable ' :
2005-12-04 22:23:41 +00:00
if gajim . config . get ( ' log_contact_status_changes ' ) and self . name \
not in no_log_for and jid_stripped not in no_log_for :
2005-11-23 23:28:26 +00:00
gajim . logger . write ( ' status ' , jid_stripped , status , show )
2005-09-19 16:13:45 +00:00
self . dispatch ( ' NOTIFY ' , ( jid_stripped , show , status , resource , prio ,
keyID ) )
2005-04-12 11:46:20 +00:00
# END presenceCB
2005-04-26 18:45:54 +00:00
def _disconnectedCB ( self ) :
2005-04-12 11:46:20 +00:00
""" Called when we are disconnected """
gajim . log . debug ( ' disconnectedCB ' )
2005-05-27 12:07:20 +00:00
if not self . connection :
return
self . connected = 0
self . dispatch ( ' STATUS ' , ' offline ' )
self . connection = None
if not self . on_purpose :
2005-12-06 22:08:10 +00:00
self . dispatch ( ' ERROR ' ,
2005-06-07 07:40:15 +00:00
( _ ( ' Connection with account " %s " has been lost ' ) % self . name ,
_ ( ' To continue sending and receiving messages, you will need to reconnect. ' ) ) )
2005-05-27 12:07:20 +00:00
self . on_purpose = False
2005-12-06 22:08:10 +00:00
2005-04-12 11:46:20 +00:00
# END disconenctedCB
2005-09-05 13:28:09 +00:00
def _reconnect ( self ) :
2005-09-10 12:05:48 +00:00
# Do not try to reco while we are already trying
self . time_to_reconnect = None
t = threading . Thread ( target = self . _reconnect2 )
t . start ( )
def _reconnect2 ( self ) :
2005-09-05 13:28:09 +00:00
gajim . log . debug ( ' reconnect ' )
2005-09-10 12:05:48 +00:00
self . retrycount + = 1
2005-09-05 13:28:09 +00:00
signed = self . get_signed_msg ( self . status )
self . connect_and_init ( self . old_show , self . status , signed )
if self . connected < 2 : #connection failed
if self . retrycount > 10 :
self . connected = 0
self . dispatch ( ' STATUS ' , ' offline ' )
2005-12-06 22:08:10 +00:00
self . dispatch ( ' ERROR ' ,
2005-09-05 13:28:09 +00:00
( _ ( ' Connection with account " %s " has been lost ' ) % self . name ,
_ ( ' To continue sending and receiving messages, you will need to reconnect. ' ) ) )
self . retrycount = 0
return
if self . retrycount > 5 :
self . time_to_reconnect = time . time ( ) + 20
else :
self . time_to_reconnect = time . time ( ) + 10
else :
#reconnect succeeded
self . time_to_reconnect = None
self . retrycount = 0
2005-12-06 22:08:10 +00:00
2005-09-05 13:28:09 +00:00
def _disconnectedReconnCB ( self ) :
""" Called when we are disconnected """
gajim . log . debug ( ' disconnectedReconnCB ' )
if not self . connection :
return
self . old_show = STATUS_LIST [ self . connected ]
self . connected = 0
self . dispatch ( ' STATUS ' , ' offline ' )
self . connection = None
if not self . on_purpose :
if gajim . config . get_per ( ' accounts ' , self . name , ' autoreconnect ' ) :
self . connected = 1
self . dispatch ( ' STATUS ' , ' connecting ' )
self . time_to_reconnect = time . time ( ) + 10
else :
2005-12-06 22:08:10 +00:00
self . dispatch ( ' ERROR ' ,
2005-09-05 13:28:09 +00:00
( _ ( ' Connection with account " %s " has been lost ' ) % self . name ,
_ ( ' To continue sending and receiving messages, you will need to reconnect. ' ) ) )
self . on_purpose = False
# END disconenctedReconnCB
2005-12-06 22:08:10 +00:00
2005-08-06 16:31:41 +00:00
def _bytestreamErrorCB ( self , con , iq_obj ) :
gajim . log . debug ( ' _bytestreamErrorCB ' )
2005-08-26 00:52:44 +00:00
id = unicode ( iq_obj . getAttr ( ' id ' ) )
2005-08-06 16:31:41 +00:00
query = iq_obj . getTag ( ' query ' )
2005-11-02 22:08:31 +00:00
jid = self . get_jid ( iq_obj )
2005-08-06 16:31:41 +00:00
id = id [ 3 : ]
if not self . files_props . has_key ( id ) :
return
file_props = self . files_props [ id ]
2005-08-11 20:26:17 +00:00
file_props [ ' error ' ] = - 4
2005-08-06 16:31:41 +00:00
self . dispatch ( ' FILE_REQUEST_ERROR ' , ( jid , file_props ) )
raise common . xmpp . NodeProcessed
2005-12-06 22:08:10 +00:00
2005-07-30 10:19:52 +00:00
def _bytestreamSetCB ( self , con , iq_obj ) :
gajim . log . debug ( ' _bytestreamSetCB ' )
2005-08-26 00:52:44 +00:00
target = unicode ( iq_obj . getAttr ( ' to ' ) )
id = unicode ( iq_obj . getAttr ( ' id ' ) )
2005-07-30 10:19:52 +00:00
query = iq_obj . getTag ( ' query ' )
2005-08-26 00:52:44 +00:00
sid = unicode ( query . getAttr ( ' sid ' ) )
2005-08-01 22:45:29 +00:00
file_props = gajim . socks5queue . get_file_props (
self . name , sid )
2005-07-30 10:19:52 +00:00
streamhosts = [ ]
for item in query . getChildren ( ) :
if item . getName ( ) == ' streamhost ' :
2005-08-06 16:31:41 +00:00
host_dict = {
2005-12-06 22:08:10 +00:00
' state ' : 0 ,
' target ' : target ,
' id ' : id ,
2005-08-07 13:24:21 +00:00
' sid ' : sid ,
2005-11-02 22:08:31 +00:00
' initiator ' : self . get_full_jid ( iq_obj )
2005-08-06 16:31:41 +00:00
}
2005-07-30 10:19:52 +00:00
for attr in item . getAttrs ( ) :
2005-08-26 00:52:44 +00:00
host_dict [ attr ] = item . getAttr ( attr )
2005-07-30 10:19:52 +00:00
streamhosts . append ( host_dict )
2005-08-06 16:31:41 +00:00
if file_props is None :
if self . files_props . has_key ( sid ) :
file_props = self . files_props [ sid ]
file_props [ ' fast ' ] = streamhosts
2005-11-06 20:29:08 +00:00
if file_props [ ' type ' ] == ' s ' : # FIXME: remove fast xmlns
2005-08-07 12:05:36 +00:00
# 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 )
2005-12-06 22:08:10 +00:00
gajim . socks5queue . connect_to_hosts ( self . name , sid ,
2005-08-07 12:05:36 +00:00
self . send_success_connect_reply , None )
2005-08-06 16:31:41 +00:00
raise common . xmpp . NodeProcessed
2005-12-25 14:44:37 +00:00
2005-08-06 16:31:41 +00:00
file_props [ ' streamhosts ' ] = streamhosts
if file_props [ ' type ' ] == ' r ' :
2005-12-06 22:08:10 +00:00
gajim . socks5queue . connect_to_hosts ( self . name , sid ,
2005-08-06 16:31:41 +00:00
self . send_success_connect_reply , self . _connect_error )
raise common . xmpp . NodeProcessed
2005-12-06 22:08:10 +00:00
2005-08-06 16:31:41 +00:00
def send_success_connect_reply ( self , streamhost ) :
2005-12-06 22:08:10 +00:00
''' send reply to the initiator of FT that we
2005-08-06 16:31:41 +00:00
made a connection
'''
if streamhost is None :
return None
2005-12-06 22:08:10 +00:00
iq = common . xmpp . Iq ( to = streamhost [ ' initiator ' ] , typ = ' result ' ,
2005-08-06 16:31:41 +00: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-12-06 22:08:10 +00:00
2005-08-14 22:29:16 +00:00
def _connect_error ( self , to , _id , sid , code = 404 ) :
2005-08-06 16:31:41 +00:00
msg_dict = {
2005-12-06 22:08:10 +00:00
404 : ' Could not connect to given hosts ' ,
405 : ' Cancel ' ,
406 : ' Not acceptable ' ,
2005-08-06 16:31:41 +00:00
}
msg = msg_dict [ code ]
iq = None
2005-12-06 22:08:10 +00:00
iq = common . xmpp . Protocol ( name = ' iq ' , to = to ,
2005-08-06 16:31:41 +00:00
typ = ' error ' )
2005-08-11 20:26:17 +00:00
iq . setAttr ( ' id ' , _id )
2005-08-06 16:31:41 +00:00
err = iq . setTag ( ' error ' )
2005-08-26 00:52:44 +00:00
err . setAttr ( ' code ' , unicode ( code ) )
2005-08-06 16:31:41 +00:00
err . setData ( msg )
self . to_be_sent . append ( iq )
2005-08-11 20:26:17 +00:00
if code == 404 :
file_props = gajim . socks5queue . get_file_props ( self . name , sid )
2005-08-14 22:29:16 +00: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-12-06 22:08:10 +00:00
2005-08-03 14:04:54 +00:00
def _bytestreamResultCB ( self , con , iq_obj ) :
gajim . log . debug ( ' _bytestreamResultCB ' )
2005-11-02 22:08:31 +00:00
frm = self . get_full_jid ( iq_obj )
2005-08-26 00:52:44 +00:00
real_id = unicode ( iq_obj . getAttr ( ' id ' ) )
2005-08-03 14:04:54 +00:00
query = iq_obj . getTag ( ' query ' )
2005-08-06 20:18:44 +00:00
streamhost = None
try :
streamhost = query . getTag ( ' streamhost ' )
2005-12-06 22:08:10 +00:00
except :
2005-08-06 20:18:44 +00:00
pass
if streamhost is not None : # this is a result for proxy request
2005-08-06 21:40:01 +00:00
jid = None
try :
jid = streamhost . getAttr ( ' jid ' )
except :
raise common . xmpp . NodeProcessed
2005-08-06 16:31:41 +00:00
proxyhosts = [ ]
for item in query . getChildren ( ) :
if item . getName ( ) == ' streamhost ' :
2005-08-06 20:18:44 +00:00
host = item . getAttr ( ' host ' )
port = item . getAttr ( ' port ' )
jid = item . getAttr ( ' jid ' )
conf = gajim . config
2005-08-09 14:53:33 +00:00
conf . add_per ( ' ft_proxies65_cache ' , jid )
2005-08-26 00:52:44 +00: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 20:18:44 +00:00
raise common . xmpp . NodeProcessed
try :
streamhost = query . getTag ( ' streamhost-used ' )
except : # this bytestream result is not what we need
2005-08-06 21:40:01 +00:00
pass
2005-08-06 20:18:44 +00:00
id = real_id [ 3 : ]
if self . files_props . has_key ( id ) :
file_props = self . files_props [ id ]
else :
raise common . xmpp . NodeProcessed
2005-12-06 22:08:10 +00:00
if streamhost is None :
2005-08-10 15:59:55 +00:00
# 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 00:52:44 +00:00
unicode ( query . getAttr ( ' sid ' ) ) == file_props [ ' sid ' ] :
2005-08-10 15:59:55 +00:00
gajim . socks5queue . activate_proxy ( host [ ' idx ' ] )
break
raise common . xmpp . NodeProcessed
jid = streamhost . getAttr ( ' jid ' )
2005-08-09 11:38:11 +00:00
if file_props . has_key ( ' streamhost-used ' ) and \
file_props [ ' streamhost-used ' ] is True :
raise common . xmpp . NodeProcessed
2005-12-06 22:08:10 +00:00
2005-08-09 11:38:11 +00:00
if real_id [ : 3 ] == ' au_ ' :
gajim . socks5queue . send_file ( file_props , self . name )
raise common . xmpp . NodeProcessed
2005-12-06 22:08:10 +00:00
2005-08-06 16:31:41 +00:00
proxy = None
if file_props . has_key ( ' proxyhosts ' ) :
for proxyhost in file_props [ ' proxyhosts ' ] :
if proxyhost [ ' jid ' ] == jid :
proxy = proxyhost
2005-12-06 22:08:10 +00:00
2005-08-06 16:31:41 +00:00
if proxy != None :
2005-08-09 11:38:11 +00:00
file_props [ ' streamhost-used ' ] = True
2005-08-06 16:31:41 +00:00
if not file_props . has_key ( ' streamhosts ' ) :
2005-08-09 11:38:11 +00:00
file_props [ ' streamhosts ' ] = [ ]
2005-08-06 16:31:41 +00: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-12-06 22:08:10 +00:00
2005-08-09 11:38:11 +00:00
else :
2005-08-06 16:31:41 +00:00
gajim . socks5queue . send_file ( file_props , self . name )
if file_props . has_key ( ' fast ' ) :
fasts = file_props [ ' fast ' ]
if len ( fasts ) > 0 :
2005-11-02 22:08:31 +00:00
self . _connect_error ( frm , fasts [ 0 ] [ ' id ' ] , file_props [ ' sid ' ] ,
code = 406 )
2005-12-06 22:08:10 +00:00
2005-08-03 14:04:54 +00:00
raise common . xmpp . NodeProcessed
2005-12-06 22:08:10 +00:00
2005-08-10 15:59:55 +00: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 = { }
2005-12-06 22:08:10 +00:00
2005-08-10 15:59:55 +00:00
def remove_transfer ( self , file_props , remove_from_list = True ) :
2005-08-12 19:09:20 +00:00
if file_props is None :
return
2005-10-07 11:57:04 +00:00
self . disconnect_transfer ( file_props )
2005-08-10 15:59:55 +00:00
sid = file_props [ ' sid ' ]
gajim . socks5queue . remove_file_props ( self . name , sid )
2005-12-06 22:08:10 +00:00
2005-08-10 15:59:55 +00:00
if remove_from_list :
if self . files_props . has_key ( ' sid ' ) :
del ( self . files_props [ ' sid ' ] )
2005-12-06 22:08:10 +00:00
2005-08-10 15:59:55 +00:00
def disconnect_transfer ( self , file_props ) :
2005-08-12 19:09:20 +00:00
if file_props is None :
return
2005-08-10 15:59:55 +00:00
if file_props . has_key ( ' hash ' ) :
gajim . socks5queue . remove_sender ( file_props [ ' hash ' ] )
2005-12-06 22:08:10 +00:00
2005-08-10 15:59:55 +00:00
if file_props . has_key ( ' streamhosts ' ) :
for host in file_props [ ' streamhosts ' ] :
2005-08-14 22:29:16 +00:00
if host . has_key ( ' idx ' ) and host [ ' idx ' ] > 0 :
2005-08-10 15:59:55 +00:00
gajim . socks5queue . remove_receiver ( host [ ' idx ' ] )
gajim . socks5queue . remove_sender ( host [ ' idx ' ] )
2005-12-06 22:08:10 +00:00
2005-08-06 16:31:41 +00:00
def proxy_auth_ok ( self , proxy ) :
2005-08-07 13:24:21 +00:00
''' cb, called after authentication to proxy server '''
file_props = self . files_props [ proxy [ ' sid ' ] ]
2005-12-06 22:08:10 +00:00
iq = common . xmpp . Protocol ( name = ' iq ' , to = proxy [ ' initiator ' ] ,
2005-08-06 16:31:41 +00:00
typ = ' set ' )
2005-08-07 13:26:03 +00:00
auth_id = " au_ " + proxy [ ' sid ' ]
2005-08-06 16:31:41 +00:00
iq . setID ( auth_id )
query = iq . setTag ( ' query ' )
query . setNamespace ( common . xmpp . NS_BYTESTREAM )
2005-08-07 13:26:03 +00:00
query . setAttr ( ' sid ' , proxy [ ' sid ' ] )
2005-08-06 16:31:41 +00:00
activate = query . setTag ( ' activate ' )
activate . setData ( file_props [ ' proxy_receiver ' ] )
iq . setID ( auth_id )
self . to_be_sent . append ( iq )
2005-12-06 22:08:10 +00:00
2005-07-30 15:06:35 +00:00
def _discoGetCB ( self , con , iq_obj ) :
''' get disco info '''
2005-11-02 22:08:31 +00:00
frm = self . get_full_jid ( iq_obj )
2005-08-26 00:52:44 +00:00
to = unicode ( iq_obj . getAttr ( ' to ' ) )
id = unicode ( iq_obj . getAttr ( ' id ' ) )
2005-07-30 15:06:35 +00:00
iq = common . xmpp . Iq ( to = frm , typ = ' result ' , queryNS = \
common . xmpp . NS_DISCO , frm = to )
iq . setAttr ( ' id ' , id )
2005-08-01 15:00:27 +00:00
query = iq . setTag ( ' query ' )
2005-07-30 15:06:35 +00:00
# bytestream transfers
feature = common . xmpp . Node ( ' feature ' )
2005-08-01 15:00:27 +00: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 15:06:35 +00:00
# filetransfers transfers
2005-08-01 15:00:27 +00:00
feature = common . xmpp . Node ( ' feature ' )
feature . setAttr ( ' var ' , common . xmpp . NS_FILE )
query . addChild ( node = feature )
2005-12-06 22:08:10 +00:00
2005-07-30 15:06:35 +00:00
self . to_be_sent . append ( iq )
raise common . xmpp . NodeProcessed
2005-12-06 22:08:10 +00:00
2005-08-03 14:04:54 +00: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 11:18:26 +00:00
# no such jid
2005-12-06 22:08:10 +00:00
return
2005-08-03 14:04:54 +00:00
file_props = self . files_props [ id ]
if file_props is None :
2005-08-04 11:18:26 +00:00
# file properties for jid is none
2005-08-03 14:04:54 +00:00
return
2005-11-02 22:08:31 +00:00
file_props [ ' receiver ' ] = self . get_full_jid ( iq_obj )
2005-08-03 14:04:54 +00:00
si = iq_obj . getTag ( ' si ' )
Merged revisions 5017-5020,5022-5029 via svnmerge from
svn://svn.gajim.org/gajim/trunk
........
r5017 | asterix | 2006-01-06 01:55:51 -0700 (Fri, 06 Jan 2006) | 2 lines
use escape for pango markup
........
r5018 | asterix | 2006-01-06 02:21:39 -0700 (Fri, 06 Jan 2006) | 2 lines
missing new contacts function
........
r5019 | asterix | 2006-01-06 11:03:07 -0700 (Fri, 06 Jan 2006) | 2 lines
handle the click on toggle_gpg_encryption menuitem
........
r5020 | asterix | 2006-01-06 11:14:14 -0700 (Fri, 06 Jan 2006) | 2 lines
use the saved size even if a chat window is already opened
........
r5022 | asterix | 2006-01-07 03:43:47 -0700 (Sat, 07 Jan 2006) | 2 lines
we can now resume filetransfert
........
r5023 | asterix | 2006-01-07 03:56:31 -0700 (Sat, 07 Jan 2006) | 2 lines
[Knuckles] Google E-Mail Notification
........
r5024 | asterix | 2006-01-07 04:02:16 -0700 (Sat, 07 Jan 2006) | 2 lines
better string
........
r5025 | asterix | 2006-01-07 04:14:32 -0700 (Sat, 07 Jan 2006) | 2 lines
fix a TB
........
r5026 | asterix | 2006-01-07 05:36:55 -0700 (Sat, 07 Jan 2006) | 2 lines
we can now drag a file on a contact in the roster to send him a file
........
r5027 | asterix | 2006-01-07 06:26:28 -0700 (Sat, 07 Jan 2006) | 2 lines
contact.groups is always a list, even if emtpy
........
r5028 | asterix | 2006-01-07 06:54:30 -0700 (Sat, 07 Jan 2006) | 2 lines
make all buttons insensitive on a category row in disco
........
r5029 | asterix | 2006-01-07 07:19:25 -0700 (Sat, 07 Jan 2006) | 2 lines
auto open groupchat configuration window when we create a new room
........
2006-01-07 17:25:35 +00:00
file_tag = si . getTag ( ' file ' )
range_tag = None
if file_tag :
range_tag = file_tag . getTag ( ' range ' )
if range_tag :
offset = range_tag . getAttr ( ' offset ' )
if offset :
file_props [ ' offset ' ] = int ( offset )
length = range_tag . getAttr ( ' length ' )
if length :
file_props [ ' length ' ] = int ( length )
2005-08-03 14:04:54 +00:00
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 16:31:41 +00:00
self . send_socks5_info ( file_props , fast = True )
2005-08-03 14:04:54 +00:00
raise common . xmpp . NodeProcessed
2005-12-06 22:08:10 +00:00
2005-08-03 14:04:54 +00:00
def _get_sha ( self , sid , initiator , target ) :
return sha . new ( " %s %s %s " % ( sid , initiator , target ) ) . hexdigest ( )
2005-12-06 22:08:10 +00:00
2005-08-03 14:04:54 +00:00
def result_socks5_sid ( self , sid , hash_id ) :
2005-08-06 16:31:41 +00:00
''' store the result of sha message from auth '''
2005-08-03 14:04:54 +00:00
if not self . files_props . has_key ( sid ) :
return
file_props = self . files_props [ sid ]
file_props [ ' hash ' ] = hash_id
return
2005-12-06 22:08:10 +00:00
2005-08-06 20:18:44 +00:00
def get_cached_proxies ( self , proxy ) :
''' get cached entries for proxy and request the cache again '''
2005-08-09 14:53:33 +00: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-12-06 22:08:10 +00:00
2005-08-06 20:18:44 +00:00
iq = common . xmpp . Protocol ( name = ' iq ' , to = proxy , typ = ' get ' )
query = iq . setTag ( ' query ' )
query . setNamespace ( common . xmpp . NS_BYTESTREAM )
2005-08-07 12:05:36 +00: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 20:18:44 +00: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-12-06 22:08:10 +00:00
def send_socks5_info ( self , file_props , fast = True , receiver = None ,
2005-08-06 16:31:41 +00:00
sender = None ) :
2005-08-06 20:18:44 +00:00
''' send iq for the present streamhosts and proxies '''
2005-08-03 14:04:54 +00:00
if type ( self . peerhost ) != tuple :
return
2005-08-03 21:10:59 +00:00
port = gajim . config . get ( ' file_transfers_port ' )
2005-08-12 13:40:42 +00:00
ft_override_host_to_send = gajim . config . get ( ' ft_override_host_to_send ' )
2005-11-01 14:43:00 +00:00
cfg_proxies = gajim . config . get_per ( ' accounts ' , self . name ,
' file_transfer_proxies ' )
2005-08-06 16:31:41 +00:00
if receiver is None :
receiver = file_props [ ' receiver ' ]
if sender is None :
sender = file_props [ ' sender ' ]
2005-08-06 20:18:44 +00:00
proxyhosts = [ ]
2005-08-11 20:26:17 +00:00
if fast and cfg_proxies :
proxies = map ( lambda e : e . strip ( ) , cfg_proxies . split ( ' , ' ) )
2005-08-06 20:18:44 +00:00
for proxy in proxies :
( host , _port , jid ) = self . get_cached_proxies ( proxy )
if host is None :
continue
host_dict = {
2005-12-06 22:08:10 +00:00
' state ' : 0 ,
' target ' : unicode ( receiver ) ,
' id ' : file_props [ ' sid ' ] ,
' sid ' : file_props [ ' sid ' ] ,
2005-08-06 20:18:44 +00:00
' initiator ' : proxy ,
' host ' : host ,
2005-08-26 00:52:44 +00:00
' port ' : unicode ( _port ) ,
2005-08-06 20:18:44 +00:00
' jid ' : jid
}
proxyhosts . append ( host_dict )
2005-12-06 22:08:10 +00:00
sha_str = self . _get_sha ( file_props [ ' sid ' ] , sender ,
2005-08-06 16:31:41 +00:00
receiver )
2005-08-03 14:04:54 +00:00
file_props [ ' sha_str ' ] = sha_str
2005-08-12 13:40:42 +00:00
if not ft_override_host_to_send :
ft_override_host_to_send = self . peerhost [ 0 ]
2005-08-12 14:59:28 +00:00
ft_override_host_to_send = socket . gethostbyname ( ft_override_host_to_send )
2005-12-06 22:08:10 +00:00
listener = gajim . socks5queue . start_listener ( self . peerhost [ 0 ] , port ,
2005-08-03 14:04:54 +00:00
sha_str , self . result_socks5_sid , file_props [ ' sid ' ] )
if listener == None :
2005-08-12 19:09:20 +00:00
file_props [ ' error ' ] = - 5
2005-08-26 00:52:44 +00:00
self . dispatch ( ' FILE_REQUEST_ERROR ' , ( unicode ( receiver ) , file_props ) )
2005-12-06 22:08:10 +00:00
self . _connect_error ( unicode ( receiver ) , file_props [ ' sid ' ] ,
2005-08-14 22:29:16 +00:00
file_props [ ' sid ' ] , code = 406 )
2005-08-03 14:04:54 +00:00
return
2005-12-06 22:08:10 +00:00
iq = common . xmpp . Protocol ( name = ' iq ' , to = unicode ( receiver ) ,
2005-08-03 14:04:54 +00: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 00:52:44 +00:00
streamhost . setAttr ( ' port ' , unicode ( port ) )
2005-08-12 13:40:42 +00:00
streamhost . setAttr ( ' host ' , ft_override_host_to_send )
2005-08-06 16:31:41 +00:00
streamhost . setAttr ( ' jid ' , sender )
2005-08-06 21:43:04 +00:00
if fast and proxyhosts != [ ] :
2005-08-26 00:52:44 +00:00
file_props [ ' proxy_receiver ' ] = unicode ( receiver )
file_props [ ' proxy_sender ' ] = unicode ( sender )
2005-08-06 20:18:44 +00: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-12-06 22:08:10 +00:00
2005-08-17 15:48:14 +00: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 14:04:54 +00:00
self . to_be_sent . append ( iq )
2005-12-06 22:08:10 +00:00
2005-07-30 10:19:52 +00:00
def _siSetCB ( self , con , iq_obj ) :
gajim . log . debug ( ' _siSetCB ' )
2005-11-02 22:08:31 +00:00
jid = self . get_jid ( iq_obj )
2005-07-30 10:19:52 +00:00
si = iq_obj . getTag ( ' si ' )
profile = si . getAttr ( ' profile ' )
mime_type = si . getAttr ( ' mime-type ' )
2005-07-30 15:30:38 +00:00
if profile != common . xmpp . NS_FILE :
2005-07-30 10:19:52 +00:00
return
file_tag = si . getTag ( ' file ' )
2005-08-06 20:18:44 +00:00
file_props = { ' type ' : ' r ' }
2005-07-30 10:19:52 +00:00
for attribute in file_tag . getAttrs ( ) :
2005-10-27 13:22:42 +00:00
if attribute in ( ' name ' , ' size ' , ' hash ' , ' date ' ) :
2005-07-30 10:19:52 +00:00
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 ( )
2005-12-06 22:08:10 +00:00
2005-07-30 10:19:52 +00:00
if mime_type is not None :
file_props [ ' mime-type ' ] = mime_type
2005-09-13 10:52:51 +00:00
our_jid = gajim . get_jid_from_account ( self . name )
2005-09-07 15:32:31 +00:00
resource = self . server_resource
2005-09-12 22:46:41 +00:00
file_props [ ' receiver ' ] = our_jid + ' / ' + resource
2005-11-02 22:08:31 +00:00
file_props [ ' sender ' ] = self . get_full_jid ( iq_obj )
2005-08-26 00:52:44 +00:00
file_props [ ' request-id ' ] = unicode ( iq_obj . getAttr ( ' id ' ) )
file_props [ ' sid ' ] = unicode ( si . getAttr ( ' id ' ) )
2005-08-01 22:45:29 +00:00
gajim . socks5queue . add_file_props ( self . name , file_props )
2005-07-30 10:19:52 +00:00
self . dispatch ( ' FILE_REQUEST ' , ( jid , file_props ) )
raise common . xmpp . NodeProcessed
2005-12-06 22:08:10 +00:00
2005-08-23 21:52:56 +00: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
2005-12-06 22:08:10 +00:00
return
2005-08-23 21:52:56 +00:00
file_props = self . files_props [ id ]
if file_props is None :
# file properties for jid is none
return
2005-11-02 22:08:31 +00:00
jid = self . get_jid ( iq_obj )
2005-08-23 21:52:56 +00:00
file_props [ ' error ' ] = - 3
self . dispatch ( ' FILE_REQUEST_ERROR ' , ( jid , file_props ) )
raise common . xmpp . NodeProcessed
2005-12-06 22:08:10 +00:00
2005-07-30 14:13:45 +00:00
def send_file_rejection ( self , file_props ) :
''' informs sender that we refuse to download the file '''
2005-08-26 00:52:44 +00:00
iq = common . xmpp . Protocol ( name = ' iq ' ,
to = unicode ( file_props [ ' sender ' ] ) , typ = ' error ' )
2005-07-30 14:13:45 +00:00
iq . setAttr ( ' id ' , file_props [ ' request-id ' ] )
2005-11-01 14:43:00 +00:00
err = common . xmpp . ErrorNode ( code = ' 406 ' , typ = ' auth ' , name =
' not-acceptable ' )
2005-07-30 14:13:45 +00:00
iq . addChild ( node = err )
self . to_be_sent . append ( iq )
2005-07-30 10:19:52 +00:00
def send_file_approval ( self , file_props ) :
2005-07-30 14:13:45 +00:00
''' comfirm that we want to download the file '''
2005-08-26 00:52:44 +00:00
iq = common . xmpp . Protocol ( name = ' iq ' ,
to = unicode ( file_props [ ' sender ' ] ) , typ = ' result ' )
2005-07-30 10:19:52 +00: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 )
Merged revisions 5017-5020,5022-5029 via svnmerge from
svn://svn.gajim.org/gajim/trunk
........
r5017 | asterix | 2006-01-06 01:55:51 -0700 (Fri, 06 Jan 2006) | 2 lines
use escape for pango markup
........
r5018 | asterix | 2006-01-06 02:21:39 -0700 (Fri, 06 Jan 2006) | 2 lines
missing new contacts function
........
r5019 | asterix | 2006-01-06 11:03:07 -0700 (Fri, 06 Jan 2006) | 2 lines
handle the click on toggle_gpg_encryption menuitem
........
r5020 | asterix | 2006-01-06 11:14:14 -0700 (Fri, 06 Jan 2006) | 2 lines
use the saved size even if a chat window is already opened
........
r5022 | asterix | 2006-01-07 03:43:47 -0700 (Sat, 07 Jan 2006) | 2 lines
we can now resume filetransfert
........
r5023 | asterix | 2006-01-07 03:56:31 -0700 (Sat, 07 Jan 2006) | 2 lines
[Knuckles] Google E-Mail Notification
........
r5024 | asterix | 2006-01-07 04:02:16 -0700 (Sat, 07 Jan 2006) | 2 lines
better string
........
r5025 | asterix | 2006-01-07 04:14:32 -0700 (Sat, 07 Jan 2006) | 2 lines
fix a TB
........
r5026 | asterix | 2006-01-07 05:36:55 -0700 (Sat, 07 Jan 2006) | 2 lines
we can now drag a file on a contact in the roster to send him a file
........
r5027 | asterix | 2006-01-07 06:26:28 -0700 (Sat, 07 Jan 2006) | 2 lines
contact.groups is always a list, even if emtpy
........
r5028 | asterix | 2006-01-07 06:54:30 -0700 (Sat, 07 Jan 2006) | 2 lines
make all buttons insensitive on a category row in disco
........
r5029 | asterix | 2006-01-07 07:19:25 -0700 (Sat, 07 Jan 2006) | 2 lines
auto open groupchat configuration window when we create a new room
........
2006-01-07 17:25:35 +00:00
if file_props . has_key ( ' offset ' ) and file_props [ ' offset ' ] :
range_tag = file_tag . setTag ( ' range ' )
range_tag . setAttr ( ' offset ' , file_props [ ' offset ' ] )
2005-07-30 10:19:52 +00:00
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-12-06 22:08:10 +00:00
2005-08-03 14:04:54 +00:00
def send_file_request ( self , file_props ) :
2005-09-13 10:52:51 +00:00
our_jid = gajim . get_jid_from_account ( self . name )
2005-09-07 15:32:31 +00:00
resource = self . server_resource
2005-09-12 22:46:41 +00:00
frm = our_jid + ' / ' + resource
2005-08-03 14:04:54 +00:00
file_props [ ' sender ' ] = frm
fjid = file_props [ ' receiver ' ] . jid + ' / ' + file_props [ ' receiver ' ] . resource
2005-12-06 22:08:10 +00:00
iq = common . xmpp . Protocol ( name = ' iq ' , to = fjid ,
2005-08-03 14:04:54 +00:00
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 ' )
2005-10-07 11:57:04 +00:00
field . addOption ( common . xmpp . NS_BYTESTREAM )
2005-08-03 14:04:54 +00:00
self . to_be_sent . append ( iq )
2005-12-06 22:08:10 +00:00
2005-04-12 11:46:20 +00:00
def _rosterSetCB ( self , con , iq_obj ) :
2005-04-20 10:21:33 +00:00
gajim . log . debug ( ' rosterSetCB ' )
2005-04-26 18:45:54 +00:00
for item in iq_obj . getTag ( ' query ' ) . getChildren ( ) :
2005-11-03 20:41:35 +00:00
jid = helpers . parse_jid ( item . getAttr ( ' jid ' ) )
2005-04-12 11:46:20 +00:00
name = item . getAttr ( ' name ' )
2005-08-26 00:52:44 +00:00
sub = item . getAttr ( ' subscription ' )
2005-04-12 11:46:20 +00:00
ask = item . getAttr ( ' ask ' )
groups = [ ]
for group in item . getTags ( ' group ' ) :
2005-08-26 00:52:44 +00:00
groups . append ( group . getData ( ) )
2005-04-12 11:46:20 +00:00
self . dispatch ( ' ROSTER_INFO ' , ( jid , name , sub , ask , groups ) )
2005-05-11 07:55:17 +00:00
raise common . xmpp . NodeProcessed
2005-04-12 11:46:20 +00:00
2005-10-30 09:58:13 +00:00
def _DiscoverItemsErrorCB ( self , con , iq_obj ) :
gajim . log . debug ( ' DiscoverItemsErrorCB ' )
2005-11-02 22:08:31 +00:00
jid = self . get_full_jid ( iq_obj )
2005-10-30 09:58:13 +00:00
self . dispatch ( ' AGENT_ERROR_ITEMS ' , ( jid ) )
2005-04-12 11:46:20 +00:00
def _DiscoverItemsCB ( self , con , iq_obj ) :
2005-04-20 10:21:33 +00:00
gajim . log . debug ( ' DiscoverItemsCB ' )
2005-04-26 18:45:54 +00:00
q = iq_obj . getTag ( ' query ' )
2005-04-23 21:54:12 +00:00
node = q . getAttr ( ' node ' )
if not node :
node = ' '
2005-04-12 11:46:20 +00:00
qp = iq_obj . getQueryPayload ( )
items = [ ]
if not qp :
qp = [ ]
for i in qp :
2005-11-22 20:09:47 +00:00
# CDATA payload is not processed, only nodes
if not isinstance ( i , common . xmpp . simplexml . Node ) :
continue
2005-04-12 11:46:20 +00:00
attr = { }
2005-04-26 18:45:54 +00:00
for key in i . getAttrs ( ) :
2005-08-26 00:52:44 +00:00
attr [ key ] = i . getAttrs ( ) [ key ]
2005-04-12 11:46:20 +00:00
items . append ( attr )
2005-11-02 22:08:31 +00:00
jid = self . get_full_jid ( iq_obj )
2005-04-23 21:54:12 +00:00
self . dispatch ( ' AGENT_INFO_ITEMS ' , ( jid , node , items ) )
2005-04-12 11:46:20 +00:00
2005-10-30 09:58:13 +00:00
def _DiscoverInfoErrorCB ( self , con , iq_obj ) :
gajim . log . debug ( ' DiscoverInfoErrorCB ' )
2005-11-02 22:08:31 +00:00
jid = self . get_full_jid ( iq_obj )
2005-10-30 09:58:13 +00:00
self . dispatch ( ' AGENT_ERROR_INFO ' , ( jid ) )
2005-04-12 11:46:20 +00:00
def _DiscoverInfoCB ( self , con , iq_obj ) :
2005-04-20 10:21:33 +00:00
gajim . log . debug ( ' DiscoverInfoCB ' )
2005-04-12 11:46:20 +00:00
# According to JEP-0030:
2005-10-30 09:58:13 +00:00
# For identity: category, type is mandatory, name is optional.
2005-04-12 11:46:20 +00:00
# For feature: var is mandatory
2005-10-30 09:58:13 +00:00
identities , features , data = [ ] , [ ] , [ ]
2005-04-26 18:45:54 +00:00
q = iq_obj . getTag ( ' query ' )
2005-04-23 21:54:12 +00:00
node = q . getAttr ( ' node ' )
if not node :
node = ' '
2005-04-26 18:45:54 +00:00
qc = iq_obj . getQueryChildren ( )
if not qc :
qc = [ ]
for i in qc :
2005-04-12 11:46:20 +00:00
if i . getName ( ) == ' identity ' :
attr = { }
2005-04-26 18:45:54 +00:00
for key in i . getAttrs ( ) . keys ( ) :
2005-08-26 00:52:44 +00:00
attr [ key ] = i . getAttr ( key )
2005-04-12 11:46:20 +00:00
identities . append ( attr )
elif i . getName ( ) == ' feature ' :
features . append ( i . getAttr ( ' var ' ) )
2005-11-03 20:50:52 +00:00
elif i . getName ( ) == ' x ' and i . getAttr ( ' xmlns ' ) == common . xmpp . NS_DATA :
2005-10-30 09:58:13 +00:00
data . append ( common . xmpp . DataForm ( node = i ) )
2005-11-02 22:08:31 +00:00
jid = self . get_full_jid ( iq_obj )
2005-09-06 11:54:23 +00:00
if identities : #if not: an error occured
2005-10-30 09:58:13 +00:00
self . dispatch ( ' AGENT_INFO_INFO ' , ( jid , node , identities ,
features , data ) )
2005-04-12 11:46:20 +00:00
def _VersionCB ( self , con , iq_obj ) :
2005-04-20 10:21:33 +00:00
gajim . log . debug ( ' VersionCB ' )
2005-05-07 10:57:40 +00:00
iq_obj = iq_obj . buildReply ( ' result ' )
2005-04-12 11:46:20 +00:00
qp = iq_obj . getTag ( ' query ' )
2005-04-26 21:33:01 +00:00
qp . setTagData ( ' name ' , ' Gajim ' )
qp . setTagData ( ' version ' , gajim . version )
2005-04-24 00:31:48 +00:00
send_os = gajim . config . get ( ' send_os_info ' )
if send_os :
2005-04-26 21:33:01 +00:00
qp . setTagData ( ' os ' , get_os_info ( ) )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( iq_obj )
2005-05-13 17:20:13 +00:00
raise common . xmpp . NodeProcessed
2005-04-12 11:46:20 +00:00
def _VersionResultCB ( self , con , iq_obj ) :
2005-04-20 10:21:33 +00:00
gajim . log . debug ( ' VersionResultCB ' )
2005-04-12 11:46:20 +00: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 ( )
2005-11-03 09:21:12 +00:00
who = self . get_full_jid ( iq_obj )
jid_stripped , resource = gajim . get_room_and_nick_from_fjid ( who )
self . dispatch ( ' OS_INFO ' , ( jid_stripped , resource , client_info , os_info ) )
2005-12-06 22:08:10 +00:00
2005-10-05 10:13:31 +00:00
def parse_data_form ( self , node ) :
2005-04-20 10:21:33 +00:00
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-10-27 13:22:42 +00:00
if data in ( ' yes ' , ' true ' , ' assent ' , ' 1 ' ) :
2005-04-20 10:21:33 +00: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 ' )
tags = option_tag . getTags ( ' value ' )
dic [ i ] [ ' options ' ] [ j ] [ ' values ' ] = [ ]
for tag in tags :
dic [ i ] [ ' options ' ] [ j ] [ ' values ' ] . append ( tag . getData ( ) )
j + = 1
Merged revisions 4987-4989,4991-4996,4999,5003 via svnmerge from
svn://svn.gajim.org/gajim/trunk
........
r4987 | nk | 2006-01-03 04:00:51 -0700 (Tue, 03 Jan 2006) | 1 line
commit 48x48 transport online/offline imgs by Grenshad (I pngcrushed them)
........
r4988 | nk | 2006-01-03 04:32:01 -0700 (Tue, 03 Jan 2006) | 1 line
icon in notification window not always jabber now. MSN if he uses msn etc. thanks stian barmen for helping me test
........
r4989 | nk | 2006-01-03 04:40:44 -0700 (Tue, 03 Jan 2006) | 1 line
all strings I got report about them, are not translatable; pot/po update
........
r4991 | asterix | 2006-01-03 08:08:21 -0700 (Tue, 03 Jan 2006) | 2 lines
don't remove the jid entry in _contacts[account] when we remove a contact
........
r4992 | asterix | 2006-01-03 08:18:30 -0700 (Tue, 03 Jan 2006) | 2 lines
fix logic
........
r4993 | asterix | 2006-01-03 09:04:14 -0700 (Tue, 03 Jan 2006) | 2 lines
a GC_Contact can have a resource if we knoe his real JID
........
r4994 | asterix | 2006-01-03 09:32:58 -0700 (Tue, 03 Jan 2006) | 2 lines
missing argument in create_gc_contact
........
r4995 | asterix | 2006-01-03 10:36:41 -0700 (Tue, 03 Jan 2006) | 2 lines
we save gc_contact vcard instance in instances[self.account]['infos'][Fake_jid]
........
r4996 | asterix | 2006-01-03 11:17:43 -0700 (Tue, 03 Jan 2006) | 2 lines
in DataForm, a field of type 'list-single' can have no <value> element. Create a default one in such a case to prevent TB
........
r4999 | asterix | 2006-01-04 05:52:26 -0700 (Wed, 04 Jan 2006) | 2 lines
prevent TB when we move a contact that was in no group
........
r5003 | asterix | 2006-01-04 09:03:42 -0700 (Wed, 04 Jan 2006) | 2 lines
handle correctly unlabeled option values in DataForms
........
2006-01-05 03:17:36 +00:00
if not label :
label = dic [ i ] [ ' options ' ] [ j ] [ ' values ' ] [ 0 ]
dic [ i ] [ ' options ' ] [ j ] [ ' label ' ] = label
if not dic [ i ] . has_key ( ' values ' ) :
dic [ i ] [ ' values ' ] = [ dic [ i ] [ ' options ' ] [ 0 ] [ ' values ' ] [ 0 ] ]
2005-04-20 10:21:33 +00:00
i + = 1
2005-10-05 10:13:31 +00:00
return dic
2005-12-06 22:08:10 +00:00
2005-10-05 10:13:31 +00:00
def _MucOwnerCB ( self , con , iq_obj ) :
gajim . log . debug ( ' MucOwnerCB ' )
qp = iq_obj . getQueryPayload ( )
node = None
for q in qp :
if q . getNamespace ( ) == common . xmpp . NS_DATA :
node = q
if not node :
return
dic = self . parse_data_form ( node )
2005-11-02 22:08:31 +00:00
self . dispatch ( ' GC_CONFIG ' , ( self . get_full_jid ( iq_obj ) , dic ) )
2005-04-12 11:46:20 +00:00
2005-04-25 22:22:23 +00:00
def _MucErrorCB ( self , con , iq_obj ) :
gajim . log . debug ( ' MucErrorCB ' )
2005-11-02 22:08:31 +00:00
jid = self . get_full_jid ( iq_obj )
2005-04-25 22:22:23 +00:00
errmsg = iq_obj . getError ( )
errcode = iq_obj . getErrorCode ( )
self . dispatch ( ' MSGERROR ' , ( jid , errcode , errmsg ) )
2005-05-08 17:00:41 +00:00
def _getRosterCB ( self , con , iq_obj ) :
2005-06-10 11:26:37 +00:00
if not self . connection :
return
2005-11-24 21:11:44 +00:00
raw_roster = self . connection . getRoster ( ) . getRaw ( )
2005-11-03 14:46:56 +00:00
roster = { }
2005-11-24 21:11:44 +00:00
for jid in raw_roster :
2005-11-24 21:05:18 +00:00
try :
j = helpers . parse_jid ( jid )
except :
2005-12-23 23:33:00 +00:00
print >> sys . stderr , _ ( ' JID %s is not RFC compliant. It will not be added to your roster. Use roster management tools such as http://jru.jabberstudio.org/ to remove it ' ) % jid
2005-11-24 21:05:18 +00:00
else :
2005-11-24 21:11:44 +00:00
roster [ j ] = raw_roster [ jid ]
2005-10-11 15:39:51 +00:00
2005-11-15 19:41:43 +00:00
# Remove or jid
our_jid = helpers . parse_jid ( gajim . get_jid_from_account ( self . name ) )
if roster . has_key ( our_jid ) :
del roster [ our_jid ]
2005-05-08 17:00:41 +00:00
self . dispatch ( ' ROSTER ' , roster )
2005-10-03 16:14:41 +00:00
# continue connection
2005-09-08 07:36:37 +00:00
if self . connected > 1 and self . continue_connect_info :
show = self . continue_connect_info [ 0 ]
msg = self . continue_connect_info [ 1 ]
signed = self . continue_connect_info [ 2 ]
self . connected = STATUS_LIST . index ( show )
sshow = helpers . get_xmpp_show ( show )
2005-10-03 16:14:41 +00:00
# send our presence
2005-09-08 07:36:37 +00:00
if show == ' invisible ' :
self . send_invisible_presence ( msg , signed , True )
return
prio = unicode ( gajim . config . get_per ( ' accounts ' , self . name ,
' priority ' ) )
2005-10-31 20:51:45 +00:00
vcard = self . get_cached_vcard ( jid )
2005-11-01 13:05:51 +00:00
if vcard and vcard . has_key ( ' PHOTO ' ) and vcard [ ' PHOTO ' ] . has_key ( ' SHA ' ) :
2005-10-31 20:51:45 +00:00
self . vcard_sha = vcard [ ' PHOTO ' ] [ ' SHA ' ]
2005-09-08 07:36:37 +00:00
p = common . xmpp . Presence ( typ = None , priority = prio , show = sshow )
p = self . add_sha ( p )
if msg :
p . setStatus ( msg )
if signed :
2005-09-18 19:52:06 +00:00
p . setTag ( common . xmpp . NS_SIGNED + ' x ' ) . setData ( signed )
2005-09-08 07:36:37 +00:00
if self . connection :
self . connection . send ( p )
self . dispatch ( ' STATUS ' , show )
2005-10-03 16:14:41 +00:00
# ask our VCard
2005-09-08 07:36:37 +00:00
self . request_vcard ( None )
2005-10-03 16:14:41 +00:00
# Get bookmarks from private namespace
2005-09-08 07:36:37 +00:00
self . get_bookmarks ( )
2005-11-30 17:46:36 +00:00
#Inform GUI we just signed in
self . dispatch ( ' SIGNED_IN ' , ( ) )
2005-09-08 07:36:37 +00:00
self . continue_connect_info = None
2005-06-07 18:21:36 +00:00
def _PrivateCB ( self , con , iq_obj ) :
2005-06-11 17:21:30 +00:00
'''
2005-06-07 18:21:36 +00:00
Private Data ( JEP 048 and 049 )
2005-06-11 17:21:30 +00:00
'''
gajim . log . debug ( ' PrivateCB ' )
storage = iq_obj . getTag ( ' query ' ) . getTag ( ' storage ' )
2005-06-07 18:21:36 +00:00
try :
2005-12-06 22:08:10 +00:00
ns = storage . getNamespace ( )
2005-06-07 18:21:36 +00:00
except AttributeError :
#Its a result for a 'set' Iq, so we don't do anything here
2005-06-11 17:21:30 +00:00
return
2005-12-06 22:08:10 +00:00
2005-06-11 17:21:30 +00:00
if ns == ' storage:bookmarks ' :
2005-06-07 18:21:36 +00:00
#Bookmarked URLs and Conferences
#http://www.jabber.org/jeps/jep-0048.html
2005-06-11 17:21:30 +00:00
confs = storage . getTags ( ' conference ' )
2005-06-07 18:21:36 +00:00
for conf in confs :
2005-08-18 19:06:24 +00:00
autojoin_val = conf . getAttr ( ' autojoin ' )
if autojoin_val is None : # not there (it's optional)
2005-11-18 13:12:16 +00:00
autojoin_val = False
2005-06-11 17:21:30 +00:00
bm = { ' name ' : conf . getAttr ( ' name ' ) ,
2005-09-18 19:52:06 +00:00
' jid ' : conf . getAttr ( ' jid ' ) ,
' autojoin ' : autojoin_val ,
' password ' : conf . getTagData ( ' password ' ) ,
' nick ' : conf . getTagData ( ' nick ' ) }
2005-06-07 18:21:36 +00:00
2005-06-09 20:35:44 +00:00
self . bookmarks . append ( bm )
2005-06-11 17:21:30 +00:00
self . dispatch ( ' BOOKMARKS ' , self . bookmarks )
elif ns == ' gajim:prefs ' :
2005-06-07 18:21:36 +00:00
#Preferences data
#http://www.jabber.org/jeps/jep-0049.html
#TODO: implement this
2005-08-05 13:29:39 +00:00
pass
2005-12-06 22:08:10 +00:00
2005-08-05 13:29:39 +00:00
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 )
2005-12-06 22:08:10 +00:00
2005-08-05 13:29:39 +00:00
def _HttpAuthCB ( self , con , iq_obj ) :
2005-08-06 10:11:02 +00:00
gajim . log . debug ( ' HttpAuthCB ' )
2005-08-05 13:29:39 +00:00
opt = gajim . config . get_per ( ' accounts ' , self . name , ' http_auth ' )
2005-10-27 13:22:42 +00:00
if opt in ( ' yes ' , ' no ' ) :
2005-08-05 13:29:39 +00:00
self . build_http_auth_answer ( iq_obj , opt )
else :
2005-11-13 01:48:48 +00:00
id = iq_obj . getTagAttr ( ' confirm ' , ' id ' )
2005-08-05 13:29:39 +00:00
method = iq_obj . getTagAttr ( ' confirm ' , ' method ' )
url = iq_obj . getTagAttr ( ' confirm ' , ' url ' )
2005-11-13 01:48:48 +00:00
self . dispatch ( ' HTTP_AUTH ' , ( method , url , id , iq_obj ) ) ;
2005-08-05 13:29:39 +00:00
raise common . xmpp . NodeProcessed
2005-06-07 18:21:36 +00:00
2005-05-10 16:53:28 +00:00
def _ErrorCB ( self , con , iq_obj ) :
errmsg = iq_obj . getError ( )
errcode = iq_obj . getErrorCode ( )
2005-11-02 22:08:31 +00:00
jid_from = self . get_full_jid ( iq_obj )
2005-08-26 00:52:44 +00:00
id = unicode ( iq_obj . getID ( ) )
2005-08-03 16:21:23 +00:00
self . dispatch ( ' ERROR_ANSWER ' , ( id , jid_from , errmsg , errcode ) )
2005-12-06 22:08:10 +00:00
2005-06-22 14:54:02 +00:00
def _StanzaArrivedCB ( self , con , obj ) :
2005-08-27 00:07:43 +00:00
self . last_io = time . time ( )
2005-05-10 16:53:28 +00:00
2005-09-10 09:25:06 +00:00
def _IqCB ( self , con , iq_obj ) :
id = iq_obj . getID ( )
2005-11-19 19:33:11 +00:00
# Check if we were waiting a timeout for this id
found_tim = None
for tim in self . awaiting_timeouts :
if id == self . awaiting_timeouts [ tim ] [ 0 ] :
found_tim = tim
break
if found_tim :
del self . awaiting_timeouts [ found_tim ]
2005-09-10 09:25:06 +00:00
if id not in self . awaiting_answers :
return
2005-11-13 17:51:37 +00:00
if self . awaiting_answers [ id ] [ 0 ] == VCARD_PUBLISHED :
2005-09-10 09:25:06 +00:00
if iq_obj . getType ( ) == ' result ' :
self . dispatch ( ' VCARD_PUBLISHED ' , ( ) )
2005-11-13 17:51:37 +00:00
vcard_iq = self . awaiting_answers [ id ] [ 1 ]
# Save vcard to HD
if vcard_iq . getTag ( ' PHOTO ' ) and vcard_iq . getTag ( ' PHOTO ' ) . getTag ( ' SHA ' ) :
new_sha = vcard_iq . getTag ( ' PHOTO ' ) . getTagData ( ' SHA ' )
else :
new_sha = ' '
# Save it to file
our_jid = gajim . get_jid_from_account ( self . name )
path_to_file = os . path . join ( gajim . VCARDPATH , our_jid )
fil = open ( path_to_file , ' w ' )
fil . write ( str ( vcard_iq ) )
fil . close ( )
# Send new presence if sha changed and we are not invisible
if self . vcard_sha != new_sha and STATUS_LIST [ self . connected ] != \
' invisible ' :
self . vcard_sha = new_sha
sshow = helpers . get_xmpp_show ( STATUS_LIST [ self . connected ] )
prio = unicode ( gajim . config . get_per ( ' accounts ' , self . name ,
' priority ' ) )
p = common . xmpp . Presence ( typ = None , priority = prio ,
show = sshow , status = self . status )
p = self . add_sha ( p )
self . to_be_sent . append ( p )
2005-09-10 09:25:06 +00:00
elif iq_obj . getType ( ) == ' error ' :
self . dispatch ( ' VCARD_NOT_PUBLISHED ' , ( ) )
2005-11-28 16:26:19 +00:00
elif self . awaiting_answers [ id ] [ 0 ] == VCARD_ARRIVED :
# If vcard is empty, we send to the interface an empty vcard so that
# it knows it arrived
if not iq_obj . getTag ( ' vCard ' ) :
jid = self . awaiting_answers [ id ] [ 1 ]
our_jid = gajim . get_jid_from_account ( self . name )
2005-11-29 20:17:51 +00:00
if jid and jid != our_jid :
2005-11-28 16:26:19 +00:00
self . dispatch ( ' VCARD ' , { ' jid ' : jid } )
2005-11-30 13:59:16 +00:00
jid = gajim . get_jid_without_resource ( jid )
2005-11-29 20:17:51 +00:00
# Write an empty file
path_to_file = os . path . join ( gajim . VCARDPATH , jid )
fil = open ( path_to_file , ' w ' )
fil . close ( )
2005-09-10 09:25:06 +00:00
del self . awaiting_answers [ id ]
2005-09-06 11:54:23 +00:00
def _event_dispatcher ( self , realm , event , data ) :
2005-06-14 10:29:36 +00:00
if realm == common . xmpp . NS_REGISTER :
if event == common . xmpp . features . REGISTER_DATA_RECEIVED :
2005-10-05 10:13:31 +00:00
# data is (agent, DataFrom, is_form)
2005-07-20 20:00:57 +00:00
if self . new_account_info and \
self . new_account_info [ ' hostname ' ] == data [ 0 ] :
2005-07-07 20:45:24 +00: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 20:00:57 +00:00
if not common . xmpp . features . register ( self . connection , data [ 0 ] ,
req ) :
2005-11-04 19:06:54 +00:00
self . dispatch ( ' ACC_NOT_OK ' , ( self . connection . lastErr ) )
2005-07-07 20:45:24 +00:00
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-11-04 21:27:14 +00:00
self . dispatch ( ' ACC_OK ' , ( self . new_account_info ) )
2005-07-07 20:45:24 +00:00
self . new_account_info = None
2005-11-04 21:27:14 +00:00
self . connection = None
2005-07-07 20:45:24 +00:00
return
2005-10-05 10:13:31 +00:00
is_form = data [ 2 ]
if is_form :
conf = self . parse_data_form ( data [ 1 ] )
else :
conf = data [ 1 ] . asDict ( )
self . dispatch ( ' REGISTER_AGENT_INFO ' , ( data [ 0 ] , conf , is_form ) )
2005-08-05 23:43:28 +00:00
elif realm == ' ' :
if event == common . xmpp . transports . DATA_RECEIVED :
2005-12-10 13:51:23 +00:00
self . dispatch ( ' STANZA_ARRIVED ' , unicode ( data , errors = ' ignore ' ) )
2005-08-05 23:43:28 +00:00
elif event == common . xmpp . transports . DATA_SENT :
2005-08-26 00:52:44 +00:00
self . dispatch ( ' STANZA_SENT ' , unicode ( data ) )
2005-06-14 10:29:36 +00:00
2005-11-04 08:19:15 +00:00
def select_next_host ( self , hosts ) :
hosts_best_prio = [ ]
best_prio = 65535
sum_weight = 0
for h in hosts :
if h [ ' prio ' ] < best_prio :
hosts_best_prio = [ h ]
best_prio = h [ ' prio ' ]
sum_weight = h [ ' weight ' ]
elif h [ ' prio ' ] == best_prio :
hosts_best_prio . append ( h )
sum_weight + = h [ ' weight ' ]
if len ( hosts_best_prio ) == 1 :
return hosts_best_prio [ 0 ]
r = random . randint ( 0 , sum_weight )
min_w = sum_weight
# We return the one for which has the minimum weight and weight >= r
for h in hosts_best_prio :
if h [ ' weight ' ] > = r :
if h [ ' weight ' ] < = min_w :
min_w = h [ ' weight ' ]
return h
2005-10-14 18:55:48 +00:00
def connect ( self , data = None ) :
2005-06-29 12:57:46 +00:00
""" Connect and authenticate to the Jabber server
2005-10-14 18:55:48 +00:00
Returns connection , and connection type ( ' tls ' , ' ssl ' , ' tcp ' , ' ' )
data MUST contain name , hostname , resource , usessl , proxy ,
use_custom_host , custom_host ( if use_custom_host ) , custom_port ( if
use_custom_host ) , """
2005-10-04 10:49:58 +00:00
if self . connection :
2005-10-17 11:18:42 +00:00
return self . connection , ' '
2005-10-04 10:49:58 +00:00
2005-10-14 18:55:48 +00:00
if data :
name = data [ ' name ' ]
hostname = data [ ' hostname ' ]
resource = data [ ' resource ' ]
usessl = data [ ' usessl ' ]
try_connecting_for_foo_secs = 45
p = data [ ' proxy ' ]
use_srv = True
use_custom = data [ ' use_custom_host ' ]
if use_custom :
custom_h = data [ ' custom_host ' ]
custom_p = data [ ' custom_port ' ]
else :
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 ' )
usessl = gajim . config . get_per ( ' accounts ' , self . name , ' usessl ' )
try_connecting_for_foo_secs = gajim . config . get_per ( ' accounts ' ,
self . name , ' try_connecting_for_foo_secs ' )
p = gajim . config . get_per ( ' accounts ' , self . name , ' proxy ' )
use_srv = gajim . config . get_per ( ' accounts ' , self . name , ' use_srv ' )
use_custom = gajim . config . get_per ( ' accounts ' , self . name ,
' use_custom_host ' )
custom_h = gajim . config . get_per ( ' accounts ' , self . name , ' custom_host ' )
custom_p = gajim . config . get_per ( ' accounts ' , self . name , ' custom_port ' )
2005-04-12 11:46:20 +00:00
2005-05-26 13:35:58 +00:00
#create connection if it doesn't already exist
2005-04-18 09:18:50 +00:00
self . connected = 1
2005-07-04 07:28:42 +00:00
if p and p in gajim . config . get_per ( ' proxies ' ) :
2005-06-08 15:48:53 +00: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 11:06:58 +00:00
else :
proxy = None
2005-06-13 21:16:41 +00:00
2005-06-14 10:26:01 +00:00
h = hostname
p = 5222
2005-08-04 23:29:41 +00:00
# autodetect [for SSL in 5223/443 and for TLS if broadcasted]
secur = None
2005-06-14 10:26:01 +00:00
if usessl :
p = 5223
2005-10-07 14:46:10 +00:00
secur = 1 # 1 means force SSL no matter what the port will be
2005-09-16 15:19:01 +00:00
use_srv = False # wants ssl? disable srv lookup
2005-10-14 18:55:48 +00:00
if use_custom :
h = custom_h
p = custom_p
2005-09-16 15:19:01 +00:00
use_srv = False
2005-06-18 11:37:29 +00:00
2005-11-04 08:19:15 +00:00
hosts = [ ]
2005-09-18 19:52:06 +00:00
# SRV resolver
2005-11-06 20:58:22 +00:00
if use_srv and ( HAS_DNSPYTHON or HAS_PYDNS ) :
2005-11-07 13:11:26 +00:00
# query should not be Unicode instance or dnspython TBs!
query = ' _xmpp-client._tcp. ' + h . encode ( ' utf-8 ' )
2005-11-04 08:19:15 +00:00
try :
2005-11-06 20:58:22 +00:00
if HAS_DNSPYTHON :
2005-11-20 10:51:22 +00:00
try :
answers = [ x for x in dns . resolver . query ( query , ' SRV ' ) ]
if answers :
for a in answers :
2005-12-06 22:08:10 +00:00
target = dns . name . from_text ( str ( a . target ) )
# target is f.e. talk.google.com. remove last dot
target = target . to_text ( omit_final_dot = True )
2005-12-06 17:37:54 +00:00
hosts . append ( { ' host ' : target ,
2005-11-20 10:51:22 +00:00
' port ' : int ( a . port ) ,
' prio ' : int ( a . priority ) ,
' weight ' : int ( a . weight ) } )
except :
pass
2005-11-06 20:58:22 +00:00
elif HAS_PYDNS :
2005-11-04 08:19:15 +00:00
# ensure we haven't cached an old configuration
DNS . ParseResolvConf ( )
response = DNS . Request ( ) . req ( query , qtype = ' SRV ' )
answers = response . answers
if len ( answers ) > 0 :
# ignore the priority and weight for now
for a in answers :
2005-11-07 14:04:18 +00:00
prio , weight , port , host = a [ ' data ' ]
2005-11-04 08:19:15 +00:00
hosts . append ( { ' host ' : host ,
' port ' : port ,
' prio ' : prio ,
' weight ' : weight } )
except :
2005-11-06 20:29:08 +00:00
gajim . log . debug ( ' An error occurred while looking up %s : ' % query )
2005-11-19 15:49:45 +00:00
try :
traceback . print_exc ( )
except IOError :
pass
2005-09-18 19:52:06 +00:00
# end of SRV resolver
2005-11-04 08:19:15 +00:00
if len ( hosts ) == 0 : # SRV fails or misconfigred on the server
hosts = [ { ' host ' : h , ' port ' : p , ' prio ' : 10 , ' weight ' : 10 } ]
con_type = None
while len ( hosts ) and not con_type :
2005-11-07 14:04:18 +00:00
if gajim . verbose :
con = common . xmpp . Client ( hostname , caller = self )
else :
con = common . xmpp . Client ( hostname , debug = [ ] , caller = self )
common . xmpp . dispatcher . DefaultTimeout = try_connecting_for_foo_secs
con . UnregisterDisconnectHandler ( con . DisconnectHandler )
2005-11-04 08:19:15 +00:00
host = self . select_next_host ( hosts )
2005-11-04 14:42:56 +00:00
hosts . remove ( host )
2005-11-04 08:19:15 +00:00
con_type = con . connect ( ( host [ ' host ' ] , host [ ' port ' ] ) , proxy = proxy ,
secure = secur )
if not self . connected : # We went offline during connecting process
return None , ' '
2005-11-04 14:42:56 +00:00
if not con_type :
gajim . log . debug ( ' Could not connect to %s : %s ' % ( host [ ' host ' ] ,
host [ ' port ' ] ) )
2005-05-26 13:35:58 +00:00
if not con_type :
2005-09-10 12:05:48 +00:00
if not self . retrycount :
2005-09-05 13:28:09 +00:00
self . connected = 0
self . dispatch ( ' STATUS ' , ' offline ' )
2005-10-14 18:55:48 +00:00
self . dispatch ( ' ERROR ' , ( _ ( ' Could not connect to " %s " ' ) % h ,
2005-09-06 09:44:34 +00:00
_ ( ' Check your connection or try again later. ' ) ) )
2005-10-17 11:18:42 +00:00
return None , ' '
2005-11-20 13:27:37 +00:00
self . connected_hostname = host [ ' host ' ]
2005-11-07 14:04:18 +00:00
con . RegisterDisconnectHandler ( self . _disconnectedReconnCB )
2005-11-04 14:42:56 +00:00
gajim . log . debug ( _ ( ' Connected to server %s : %s with %s ' ) % ( host [ ' host ' ] ,
2005-11-04 15:36:25 +00:00
host [ ' port ' ] , con_type ) )
2005-10-14 18:55:48 +00:00
return con , con_type
2005-06-29 15:06:05 +00:00
2005-10-14 18:55:48 +00:00
def connect_and_auth ( self ) :
con , con_type = self . connect ( )
if not con_type :
return None
2005-09-01 17:44:57 +00:00
self . peerhost = con . get_peerhost ( )
2005-06-29 15:06:05 +00:00
2005-08-09 17:21:35 +00:00
# notify the gui about con_type
self . dispatch ( ' CON_TYPE ' , con_type )
2005-04-12 11:46:20 +00:00
2005-04-26 18:45:54 +00:00
con . RegisterHandler ( ' message ' , self . _messageCB )
con . RegisterHandler ( ' presence ' , self . _presenceCB )
2005-05-27 16:43:38 +00:00
con . RegisterHandler ( ' iq ' , self . _vCardCB , ' result ' ,
2005-04-26 18:45:54 +00:00
common . xmpp . NS_VCARD )
2005-05-27 16:43:38 +00:00
con . RegisterHandler ( ' iq ' , self . _rosterSetCB , ' set ' ,
2005-04-26 18:45:54 +00:00
common . xmpp . NS_ROSTER )
2005-12-06 22:08:10 +00:00
con . RegisterHandler ( ' iq ' , self . _siSetCB , ' set ' ,
2005-07-30 10:19:52 +00:00
common . xmpp . NS_SI )
2005-12-06 22:08:10 +00:00
con . RegisterHandler ( ' iq ' , self . _siErrorCB , ' error ' ,
2005-08-23 21:52:56 +00:00
common . xmpp . NS_SI )
2005-12-06 22:08:10 +00:00
con . RegisterHandler ( ' iq ' , self . _siResultCB , ' result ' ,
2005-08-03 14:04:54 +00:00
common . xmpp . NS_SI )
2005-12-06 22:08:10 +00:00
con . RegisterHandler ( ' iq ' , self . _discoGetCB , ' get ' ,
2005-07-30 15:06:35 +00:00
common . xmpp . NS_DISCO )
2005-12-06 22:08:10 +00:00
con . RegisterHandler ( ' iq ' , self . _bytestreamSetCB , ' set ' ,
2005-07-30 10:19:52 +00:00
common . xmpp . NS_BYTESTREAM )
2005-12-06 22:08:10 +00:00
con . RegisterHandler ( ' iq ' , self . _bytestreamResultCB , ' result ' ,
2005-08-03 14:04:54 +00:00
common . xmpp . NS_BYTESTREAM )
2005-08-06 16:31:41 +00:00
con . RegisterHandler ( ' iq ' , self . _bytestreamErrorCB , ' error ' ,
common . xmpp . NS_BYTESTREAM )
2005-05-27 16:43:38 +00:00
con . RegisterHandler ( ' iq ' , self . _DiscoverItemsCB , ' result ' ,
2005-04-26 18:45:54 +00:00
common . xmpp . NS_DISCO_ITEMS )
2005-10-30 09:58:13 +00:00
con . RegisterHandler ( ' iq ' , self . _DiscoverItemsErrorCB , ' error ' ,
common . xmpp . NS_DISCO_ITEMS )
2005-05-27 16:43:38 +00:00
con . RegisterHandler ( ' iq ' , self . _DiscoverInfoCB , ' result ' ,
2005-04-26 18:45:54 +00:00
common . xmpp . NS_DISCO_INFO )
2005-10-30 09:58:13 +00:00
con . RegisterHandler ( ' iq ' , self . _DiscoverInfoErrorCB , ' error ' ,
common . xmpp . NS_DISCO_INFO )
2005-05-27 16:43:38 +00:00
con . RegisterHandler ( ' iq ' , self . _VersionCB , ' get ' ,
2005-04-26 18:45:54 +00:00
common . xmpp . NS_VERSION )
2005-05-27 16:43:38 +00:00
con . RegisterHandler ( ' iq ' , self . _VersionResultCB , ' result ' ,
2005-04-26 18:45:54 +00:00
common . xmpp . NS_VERSION )
2005-05-27 16:43:38 +00:00
con . RegisterHandler ( ' iq ' , self . _MucOwnerCB , ' result ' ,
2005-04-26 18:45:54 +00:00
common . xmpp . NS_MUC_OWNER )
2005-05-27 16:43:38 +00:00
con . RegisterHandler ( ' iq ' , self . _getRosterCB , ' result ' ,
2005-05-08 17:00:41 +00:00
common . xmpp . NS_ROSTER )
2005-06-07 18:21:36 +00:00
con . RegisterHandler ( ' iq ' , self . _PrivateCB , ' result ' ,
common . xmpp . NS_PRIVATE )
2005-08-05 13:29:39 +00:00
con . RegisterHandler ( ' iq ' , self . _HttpAuthCB , ' get ' ,
common . xmpp . NS_HTTP_AUTH )
Merged revisions 5017-5020,5022-5029 via svnmerge from
svn://svn.gajim.org/gajim/trunk
........
r5017 | asterix | 2006-01-06 01:55:51 -0700 (Fri, 06 Jan 2006) | 2 lines
use escape for pango markup
........
r5018 | asterix | 2006-01-06 02:21:39 -0700 (Fri, 06 Jan 2006) | 2 lines
missing new contacts function
........
r5019 | asterix | 2006-01-06 11:03:07 -0700 (Fri, 06 Jan 2006) | 2 lines
handle the click on toggle_gpg_encryption menuitem
........
r5020 | asterix | 2006-01-06 11:14:14 -0700 (Fri, 06 Jan 2006) | 2 lines
use the saved size even if a chat window is already opened
........
r5022 | asterix | 2006-01-07 03:43:47 -0700 (Sat, 07 Jan 2006) | 2 lines
we can now resume filetransfert
........
r5023 | asterix | 2006-01-07 03:56:31 -0700 (Sat, 07 Jan 2006) | 2 lines
[Knuckles] Google E-Mail Notification
........
r5024 | asterix | 2006-01-07 04:02:16 -0700 (Sat, 07 Jan 2006) | 2 lines
better string
........
r5025 | asterix | 2006-01-07 04:14:32 -0700 (Sat, 07 Jan 2006) | 2 lines
fix a TB
........
r5026 | asterix | 2006-01-07 05:36:55 -0700 (Sat, 07 Jan 2006) | 2 lines
we can now drag a file on a contact in the roster to send him a file
........
r5027 | asterix | 2006-01-07 06:26:28 -0700 (Sat, 07 Jan 2006) | 2 lines
contact.groups is always a list, even if emtpy
........
r5028 | asterix | 2006-01-07 06:54:30 -0700 (Sat, 07 Jan 2006) | 2 lines
make all buttons insensitive on a category row in disco
........
r5029 | asterix | 2006-01-07 07:19:25 -0700 (Sat, 07 Jan 2006) | 2 lines
auto open groupchat configuration window when we create a new room
........
2006-01-07 17:25:35 +00:00
con . RegisterHandler ( ' iq ' , self . _gMailCB , ' set ' ,
common . xmpp . NS_GMAILNOTIFY )
2005-05-10 16:53:28 +00:00
con . RegisterHandler ( ' iq ' , self . _ErrorCB , ' error ' )
2005-09-10 09:25:06 +00:00
con . RegisterHandler ( ' iq ' , self . _IqCB )
2005-06-22 14:54:02 +00:00
con . RegisterHandler ( ' iq ' , self . _StanzaArrivedCB )
con . RegisterHandler ( ' presence ' , self . _StanzaArrivedCB )
con . RegisterHandler ( ' message ' , self . _StanzaArrivedCB )
2005-04-26 18:45:54 +00:00
2005-10-14 18:55:48 +00: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 ' )
2005-05-11 16:37:01 +00:00
try :
2005-06-01 12:33:29 +00:00
auth = con . auth ( name , self . password , resource , 1 )
2005-05-11 16:37:01 +00:00
except IOError : #probably a timeout
2005-05-18 14:05:54 +00:00
self . connected = 0
2005-05-11 16:37:01 +00:00
self . dispatch ( ' STATUS ' , ' offline ' )
2005-10-14 18:55:48 +00:00
self . dispatch ( ' ERROR ' , ( _ ( ' Could not connect to " %s " ' ) % hostname ,
2005-06-13 12:35:53 +00:00
_ ( ' Check your connection or try again later ' ) ) )
2005-09-05 13:28:09 +00:00
return None
2005-10-07 09:55:29 +00:00
if not self . connected : # We went offline during connecting process
return None
2005-09-08 18:16:38 +00:00
if hasattr ( con , ' Resource ' ) :
self . server_resource = con . Resource
2005-05-11 16:37:01 +00:00
if auth :
2005-08-27 00:07:43 +00:00
self . last_io = time . time ( )
2005-04-12 11:46:20 +00:00
self . connected = 2
2005-06-29 15:09:10 +00:00
return con # return connection
2005-04-12 11:46:20 +00:00
else :
2005-11-06 15:51:18 +00:00
# Forget password if needed
if not gajim . config . get_per ( ' accounts ' , self . name , ' savepass ' ) :
self . password = None
2005-10-14 18:55:48 +00:00
gajim . log . debug ( " Couldn ' t authenticate to %s " % hostname )
2005-05-18 14:05:54 +00:00
self . connected = 0
2005-04-12 11:46:20 +00:00
self . dispatch ( ' STATUS ' , ' offline ' )
2005-10-14 18:55:48 +00:00
self . dispatch ( ' ERROR ' , ( _ ( ' Authentication failed with " %s " ' ) % hostname ,
2005-06-09 23:08:28 +00:00
_ ( ' Please check your login and password for correctness. ' ) ) )
2005-06-29 15:09:10 +00:00
return None
2005-05-31 13:53:22 +00:00
# END connect
2005-04-12 11:46:20 +00:00
def quit ( self , kill_core ) :
if kill_core :
if self . connected > 1 :
self . connected = 0
2005-07-03 12:36:13 +00:00
self . connection . disconnect ( )
2005-04-12 11:46:20 +00:00
return
2005-07-22 16:36:20 +00: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-12-06 22:08:10 +00:00
2005-07-22 16:36:20 +00: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 00:52:44 +00:00
prio = unicode ( gajim . config . get_per ( ' accounts ' , self . name , ' priority ' ) )
2005-07-22 16:36:20 +00:00
p = common . xmpp . Presence ( typ = ptype , priority = prio , show = show )
2005-08-07 21:42:32 +00:00
p = self . add_sha ( p )
2005-07-22 16:36:20 +00:00
if msg :
p . setStatus ( msg )
if signed :
p . setTag ( common . xmpp . NS_SIGNED + ' x ' ) . setData ( signed )
self . connection . send ( p )
2005-08-09 17:21:35 +00:00
self . dispatch ( ' STATUS ' , ' invisible ' )
2005-07-22 16:36:20 +00:00
if initial :
#ask our VCard
2005-08-08 13:34:48 +00:00
self . request_vcard ( None )
2005-07-22 16:36:20 +00:00
#Get bookmarks from private namespace
self . get_bookmarks ( )
2005-12-06 22:08:10 +00:00
2005-11-27 12:29:30 +00:00
#Inform GUI we just signed in
2005-11-27 12:42:42 +00:00
self . dispatch ( ' SIGNED_IN ' , ( ) )
2005-09-05 13:28:09 +00:00
def get_signed_msg ( self , msg ) :
signed = ' '
keyID = gajim . config . get_per ( ' accounts ' , self . name , ' keyid ' )
if keyID and USE_GPG :
use_gpg_agent = gajim . config . get ( ' use_gpg_agent ' )
2005-11-01 14:43:00 +00:00
if self . connected < 2 and self . gpg . passphrase is None and \
not use_gpg_agent :
2005-09-05 13:28:09 +00:00
# We didn't set a passphrase
self . dispatch ( ' ERROR ' , ( _ ( ' OpenPGP passphrase was not given ' ) ,
#%s is the account name here
_ ( ' You will be connected to %s without OpenPGP. ' ) % self . name ) )
elif self . gpg . passphrase is not None or use_gpg_agent :
signed = self . gpg . sign ( msg , keyID )
if signed == ' BAD_PASSPHRASE ' :
signed = ' '
if self . connected < 2 :
self . dispatch ( ' BAD_PASSPHRASE ' , ( ) )
return signed
def connect_and_init ( self , show , msg , signed ) :
2005-09-08 07:36:37 +00:00
self . continue_connect_info = [ show , msg , signed ]
2005-10-14 18:55:48 +00:00
self . connection = self . connect_and_auth ( )
2005-12-10 13:58:09 +00:00
if self . connection :
self . connection . initRoster ( )
2005-09-05 13:28:09 +00:00
2005-08-30 21:10:14 +00:00
def change_status ( self , show , msg , sync = False , auto = False ) :
2005-06-28 19:03:00 +00:00
if sync :
2005-08-30 21:10:14 +00:00
self . change_status2 ( show , msg , auto )
2005-06-28 19:03:00 +00:00
else :
2005-11-01 14:43:00 +00:00
t = threading . Thread ( target = self . change_status2 , args = ( show , msg ,
auto ) )
2005-06-28 19:03:00 +00:00
t . start ( )
2005-08-30 21:10:14 +00:00
def change_status2 ( self , show , msg , auto = False ) :
2005-05-13 18:54:44 +00:00
if not show in STATUS_LIST :
2005-04-12 11:46:20 +00:00
return - 1
2005-09-05 13:28:09 +00:00
sshow = helpers . get_xmpp_show ( show )
2005-08-01 18:19:36 +00:00
if not msg :
2005-09-08 07:10:59 +00:00
msg = ' '
keyID = gajim . config . get_per ( ' accounts ' , self . name , ' keyid ' )
if keyID and USE_GPG and not msg :
2005-08-01 18:19:36 +00:00
lowered_uf_status_msg = helpers . get_uf_show ( show ) . lower ( )
2005-09-08 07:10:59 +00:00
# do not show I'm invisible!
if lowered_uf_status_msg == _ ( ' invisible ' ) :
2005-08-14 14:32:10 +00:00
lowered_uf_status_msg = _ ( ' offline ' )
2005-08-01 18:19:36 +00:00
msg = _ ( " I ' m %s " ) % lowered_uf_status_msg
2005-08-30 21:10:14 +00:00
signed = ' '
2005-09-05 13:28:09 +00:00
if not auto and not show == ' offline ' :
signed = self . get_signed_msg ( msg )
2005-05-20 15:32:05 +00:00
self . status = msg
2005-05-19 17:50:19 +00:00
if show != ' offline ' and not self . connected :
2005-09-05 13:28:09 +00:00
self . connect_and_init ( show , msg , signed )
2005-04-26 18:45:54 +00:00
2005-05-19 17:50:19 +00:00
elif show == ' offline ' and self . connected :
2005-04-12 11:46:20 +00:00
self . connected = 0
2005-05-04 19:20:02 +00:00
if self . connection :
2005-05-27 12:07:20 +00:00
self . on_purpose = True
2005-05-20 15:32:05 +00:00
p = common . xmpp . Presence ( typ = ' unavailable ' )
2005-08-07 21:42:32 +00:00
p = self . add_sha ( p )
2005-05-20 15:32:05 +00:00
if msg :
p . setStatus ( msg )
2005-08-10 15:59:55 +00:00
self . remove_all_transfers ( )
2005-07-15 20:04:02 +00:00
if self . connection :
self . connection . send ( p )
2005-05-31 16:47:05 +00:00
try :
self . connection . disconnect ( )
except :
pass
2005-08-09 17:21:35 +00:00
self . dispatch ( ' STATUS ' , ' offline ' )
2005-04-18 09:18:50 +00:00
self . connection = None
2005-05-13 18:54:44 +00:00
elif show != ' offline ' and self . connected :
2005-07-22 16:36:20 +00:00
was_invisible = self . connected == STATUS_LIST . index ( ' invisible ' )
2005-05-13 18:54:44 +00:00
self . connected = STATUS_LIST . index ( show )
if show == ' invisible ' :
2005-07-22 16:36:20 +00: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 00:52:44 +00:00
prio = unicode ( gajim . config . get_per ( ' accounts ' , self . name ,
' priority ' ) )
2005-08-07 21:42:32 +00:00
p = common . xmpp . Presence ( typ = None , priority = prio , show = sshow )
p = self . add_sha ( p )
2005-05-20 15:32:05 +00:00
if msg :
p . setStatus ( msg )
if signed :
p . setTag ( common . xmpp . NS_SIGNED + ' x ' ) . setData ( signed )
2005-07-16 17:12:11 +00:00
if self . connection :
2005-07-15 20:04:02 +00:00
self . connection . send ( p )
2005-08-09 17:21:35 +00:00
self . dispatch ( ' STATUS ' , show )
2005-12-06 22:08:10 +00:00
2005-09-13 18:46:21 +00:00
def get_status ( self ) :
return STATUS_LIST [ self . connected ]
2005-04-12 11:46:20 +00:00
2005-08-06 12:33:20 +00: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 14:38:58 +00:00
def send_message ( self , jid , msg , keyID , type = ' chat ' , subject = ' ' , chatstate = None ) :
2005-04-14 07:42:26 +00:00
if not self . connection :
2005-04-12 11:46:20 +00:00
return
2005-07-19 14:38:58 +00:00
if not msg and chatstate is None :
2005-06-21 20:04:23 +00:00
return
2005-04-12 11:46:20 +00:00
msgtxt = msg
msgenc = ' '
if keyID and USE_GPG :
#encrypt
2005-05-27 14:16:34 +00:00
msgenc = self . gpg . encrypt ( msg , [ keyID ] )
2005-07-04 16:27:26 +00:00
if msgenc :
2005-07-06 12:13:54 +00: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 15:49:25 +00: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 11:46:20 +00:00
if msgenc :
2005-04-26 18:45:54 +00:00
msg_iq . setTag ( common . xmpp . NS_ENCRYPTED + ' x ' ) . setData ( msgenc )
2005-07-19 14:38:58 +00:00
# chatstates - if peer supports jep85, send chatstates
2005-11-13 01:48:48 +00:00
# please note that the only valid tag inside a message containing a <body>
# tag is the active event
2005-07-21 15:23:18 +00:00
if chatstate is not None :
2005-07-22 00:34:08 +00:00
msg_iq . setTag ( chatstate , { } ,
namespace = ' http://jabber.org/protocol/chatstates ' )
2005-12-06 22:08:10 +00:00
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( msg_iq )
2005-12-04 22:58:38 +00:00
no_log_for = gajim . config . get_per ( ' accounts ' , self . name , ' no_log_for ' )
2005-12-04 22:23:41 +00:00
ji = gajim . get_jid_without_resource ( jid )
if self . name not in no_log_for and ji not in no_log_for :
log_msg = msg
if subject :
log_msg = _ ( ' Subject: %s \n %s ' ) % ( subject , msg )
if log_msg :
if type == ' chat ' :
kind = ' chat_msg_sent '
else :
kind = ' single_msg_sent '
gajim . logger . write ( kind , jid , log_msg )
2005-04-12 11:46:20 +00:00
self . dispatch ( ' MSGSENT ' , ( jid , msg , keyID ) )
2005-07-04 21:30:00 +00:00
def send_stanza ( self , stanza ) :
''' send a stanza untouched '''
if not self . connection :
return
self . to_be_sent . append ( stanza )
2005-04-14 07:42:26 +00:00
def request_subscription ( self , jid , msg ) :
2005-04-12 11:46:20 +00:00
if not self . connection :
return
gajim . log . debug ( ' subscription request for %s ' % jid )
2005-08-07 21:42:32 +00:00
p = common . xmpp . Presence ( jid , ' subscribe ' )
p = self . add_sha ( p )
2005-04-12 11:46:20 +00:00
if not msg :
msg = _ ( ' I would like to add you to my roster. ' )
2005-08-07 21:42:32 +00:00
p . setStatus ( msg )
self . to_be_sent . append ( p )
2005-04-12 11:46:20 +00:00
2005-04-14 07:42:26 +00:00
def send_authorization ( self , jid ) :
2005-04-12 11:46:20 +00:00
if not self . connection :
return
2005-08-07 21:42:32 +00:00
p = common . xmpp . Presence ( jid , ' subscribed ' )
p = self . add_sha ( p )
self . to_be_sent . append ( p )
2005-04-12 11:46:20 +00:00
2005-04-14 07:42:26 +00:00
def refuse_authorization ( self , jid ) :
2005-04-12 11:46:20 +00:00
if not self . connection :
return
2005-08-07 21:42:32 +00:00
p = common . xmpp . Presence ( jid , ' unsubscribed ' )
p = self . add_sha ( p )
self . to_be_sent . append ( p )
2005-04-12 11:46:20 +00:00
2005-09-28 14:35:06 +00:00
def unsubscribe ( self , jid , remove_auth = True ) :
2005-04-12 11:46:20 +00:00
if not self . connection :
return
2005-09-28 14:35:06 +00:00
if remove_auth :
2005-04-26 18:45:54 +00:00
self . connection . getRoster ( ) . delItem ( jid )
2005-09-07 15:57:01 +00:00
else :
self . connection . getRoster ( ) . Unsubscribe ( jid )
2005-04-12 11:46:20 +00:00
2005-05-11 09:08:06 +00:00
def _continue_unsubscribe ( self , con , iq_obj , agent ) :
self . connection . getRoster ( ) . delItem ( agent )
2005-04-12 11:46:20 +00:00
2005-05-08 17:33:08 +00:00
def unsubscribe_agent ( self , agent ) :
if not self . connection :
return
2005-05-11 09:08:06 +00: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 17:33:08 +00:00
{ ' agent ' : agent } )
return
2005-07-19 14:38:58 +00:00
def update_contact ( self , jid , name , groups ) :
2005-04-12 11:46:20 +00:00
if self . connection :
2005-04-30 08:48:50 +00:00
self . connection . getRoster ( ) . setItem ( jid = jid , name = name ,
2005-04-26 18:45:54 +00:00
groups = groups )
2005-04-12 11:46:20 +00:00
2005-11-21 15:09:04 +00:00
def _ReceivedRegInfo ( self , con , resp , agent ) :
common . xmpp . features . _ReceivedRegInfo ( con , resp , agent )
self . _IqCB ( con , resp )
2005-05-08 20:56:11 +00:00
def request_register_agent_info ( self , agent ) :
2005-04-12 11:46:20 +00:00
if not self . connection :
return None
2005-11-19 19:33:11 +00:00
iq = common . xmpp . Iq ( ' get ' , common . xmpp . NS_REGISTER , to = agent )
id = self . connection . getAnID ( )
iq . setID ( id )
# Wait the answer during 30 secondes
self . awaiting_timeouts [ time . time ( ) + 30 ] = ( id ,
_ ( ' Registration information for transport %s has not arrived in time ' % \
agent ) )
2005-11-21 15:09:04 +00:00
self . connection . SendAndCallForResponse ( iq , self . _ReceivedRegInfo ,
{ ' agent ' : agent } )
2005-04-26 18:45:54 +00:00
2005-10-05 10:13:31 +00:00
def register_agent ( self , agent , info , is_form = False ) :
2005-04-12 11:46:20 +00:00
if not self . connection :
return
2005-10-05 10:13:31 +00:00
if is_form :
iq = common . xmpp . Iq ( ' set ' , common . xmpp . NS_REGISTER , to = agent )
query = iq . getTag ( ' query ' )
self . build_data_from_dict ( query , info )
self . to_be_sent . append ( iq )
else :
# FIXME: Blocking
common . xmpp . features . register ( self . connection , agent , info )
2005-04-12 11:46:20 +00:00
2005-07-07 20:45:24 +00: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 11:46:20 +00:00
# If a connection already exist we cannot create a new account
if self . connection :
return
2005-10-14 18:55:48 +00:00
con , con_type = self . connect ( config )
2005-05-26 13:35:58 +00:00
if not con_type :
2005-11-04 19:06:54 +00:00
self . dispatch ( ' ACC_NOT_OK ' ,
( _ ( ' Could not connect to " %s " ' ) % config [ ' hostname ' ] ) )
return
2005-06-29 12:57:46 +00:00
2005-07-07 20:45:24 +00:00
self . new_account_info = config
2005-10-14 18:55:48 +00:00
self . connection = con
2005-05-31 13:53:22 +00:00
self . name = name
2005-10-14 18:55:48 +00:00
common . xmpp . features . getRegInfo ( con , config [ ' hostname ' ] )
2005-04-12 11:46:20 +00: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-02 23:07:26 +00:00
to_whom_jid = jid
2005-07-02 23:03:11 +00:00
if resource :
2005-07-02 23:07:26 +00:00
to_whom_jid + = ' / ' + resource
2005-07-02 23:03:11 +00:00
iq = common . xmpp . Iq ( to = to_whom_jid , typ = ' get ' , queryNS = \
2005-04-26 18:45:54 +00:00
common . xmpp . NS_VERSION )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( iq )
2005-04-12 11:46:20 +00:00
2005-10-31 17:31:30 +00:00
def get_cached_vcard ( self , fjid ) :
''' return the vcard as a dict
return { } if vcard was too old
return None if we don ' t have cached vcard ' ' '
jid = gajim . get_jid_without_resource ( fjid )
path_to_file = os . path . join ( gajim . VCARDPATH , jid )
2005-10-31 10:23:33 +00:00
if os . path . isfile ( path_to_file ) :
# We have the vcard cached
f = open ( path_to_file )
c = f . read ( )
2005-11-13 12:31:13 +00:00
f . close ( )
2005-10-31 10:23:33 +00:00
card = common . xmpp . Node ( node = c )
vcard = self . node_to_dict ( card )
2005-11-04 19:06:54 +00:00
if vcard . has_key ( ' PHOTO ' ) :
if not isinstance ( vcard [ ' PHOTO ' ] , dict ) :
del vcard [ ' PHOTO ' ]
elif vcard [ ' PHOTO ' ] . has_key ( ' SHA ' ) :
cached_sha = vcard [ ' PHOTO ' ] [ ' SHA ' ]
if self . vcard_shas . has_key ( jid ) and self . vcard_shas [ jid ] != \
cached_sha :
2005-11-29 10:16:31 +00:00
# user change his vcard so don't use the cached one
2005-11-04 19:06:54 +00:00
return { }
2005-10-31 17:31:30 +00:00
vcard [ ' jid ' ] = jid
vcard [ ' resource ' ] = gajim . get_resource_from_jid ( fjid )
2005-10-31 10:23:33 +00:00
return vcard
2005-10-31 17:31:30 +00:00
return None
2005-10-31 10:23:33 +00:00
2005-05-24 19:18:32 +00:00
def request_vcard ( self , jid = None ) :
2005-10-31 10:23:33 +00:00
''' request the VCARD '''
2005-04-12 11:46:20 +00:00
if not self . connection :
return
2005-05-24 19:18:32 +00:00
iq = common . xmpp . Iq ( typ = ' get ' )
if jid :
iq . setTo ( jid )
2005-04-26 18:45:54 +00:00
iq . setTag ( common . xmpp . NS_VCARD + ' vCard ' )
2005-11-28 16:26:19 +00:00
id = self . connection . getAnID ( )
iq . setID ( id )
self . awaiting_answers [ id ] = ( VCARD_ARRIVED , jid )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( iq )
2005-04-12 11:46:20 +00:00
#('VCARD', {entry1: data, entry2: {entry21: data, ...}, ...})
2005-12-06 22:08:10 +00:00
2005-04-12 11:46:20 +00:00
def send_vcard ( self , vcard ) :
if not self . connection :
return
2005-04-26 18:45:54 +00:00
iq = common . xmpp . Iq ( typ = ' set ' )
iq2 = iq . setTag ( common . xmpp . NS_VCARD + ' vCard ' )
2005-06-07 08:50:47 +00:00
for i in vcard :
2005-06-06 15:29:27 +00:00
if i == ' jid ' :
continue
2005-11-01 13:10:38 +00:00
if isinstance ( vcard [ i ] , dict ) :
2005-06-07 08:50:47 +00: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 15:29:27 +00:00
else :
iq2 . addChild ( i ) . setData ( vcard [ i ] )
2005-11-13 17:51:37 +00:00
2005-09-10 09:25:06 +00:00
id = self . connection . getAnID ( )
iq . setID ( id )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( iq )
2005-04-12 11:46:20 +00:00
2005-11-13 17:51:37 +00:00
# Add the sha of the avatar
if vcard . has_key ( ' PHOTO ' ) and isinstance ( vcard [ ' PHOTO ' ] , dict ) and \
vcard [ ' PHOTO ' ] . has_key ( ' BINVAL ' ) :
photo = vcard [ ' PHOTO ' ] [ ' BINVAL ' ]
2005-12-05 08:45:39 +00:00
photo_decoded = base64 . decodestring ( photo )
avatar_sha = sha . sha ( photo_decoded ) . hexdigest ( )
2005-11-13 17:51:37 +00:00
iq2 . getTag ( ' PHOTO ' ) . setTagData ( ' SHA ' , avatar_sha )
2005-11-19 19:33:11 +00:00
self . awaiting_answers [ id ] = ( VCARD_PUBLISHED , iq2 )
2005-11-13 17:51:37 +00:00
2005-06-07 18:21:36 +00: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 21:30:00 +00:00
self . to_be_sent . append ( iq )
2005-06-07 18:21:36 +00:00
def get_bookmarks ( self ) :
''' Get Bookmarks from storage as described in JEP 0048 '''
2005-06-11 14:14:50 +00:00
self . bookmarks = [ ] #avoid multiple bookmarks when re-connecting
2005-06-07 18:21:36 +00:00
if not self . connection :
return
iq = common . xmpp . Iq ( typ = ' get ' )
2005-12-25 15:56:36 +00:00
iq2 = iq . addChild ( name = " query " , namespace = " jabber:iq:private " )
iq2 . addChild ( name = " storage " , namespace = " storage:bookmarks " )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( iq )
2005-06-07 18:21:36 +00:00
def store_bookmarks ( self ) :
''' Send bookmarks to the storage namespace '''
2005-06-10 15:45:09 +00:00
if not self . connection :
return
2005-06-07 18:21:36 +00:00
iq = common . xmpp . Iq ( typ = ' set ' )
2005-07-04 21:30:00 +00:00
iq2 = iq . addChild ( name = ' query ' , namespace = ' jabber:iq:private ' )
iq3 = iq2 . addChild ( name = ' storage ' , namespace = ' storage:bookmarks ' )
2005-06-07 18:21:36 +00:00
for bm in self . bookmarks :
2005-07-04 21:30:00 +00: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 18:21:36 +00:00
2005-04-12 12:23:08 +00:00
def send_agent_status ( self , agent , ptype ) :
2005-04-12 11:46:20 +00:00
if not self . connection :
return
2005-04-26 18:45:54 +00:00
p = common . xmpp . Presence ( to = agent , typ = ptype )
2005-08-07 21:42:32 +00:00
p = self . add_sha ( p )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( p )
2005-04-12 11:46:20 +00:00
2005-04-18 12:17:43 +00:00
def join_gc ( self , nick , room , server , password ) :
2005-04-12 11:46:20 +00:00
if not self . connection :
return
2005-09-05 13:28:09 +00:00
show = helpers . get_xmpp_show ( STATUS_LIST [ self . connected ] )
2005-05-13 18:54:44 +00:00
p = common . xmpp . Presence ( to = ' %s @ %s / %s ' % ( room , server , nick ) ,
2005-06-04 14:27:09 +00:00
show = show , status = self . status )
Merged in trunk updates, including meta_contacts
Merged revisions 4951,4962-4969 via svnmerge from
svn://svn.gajim.org/gajim/trunk
........
r4951 | nk | 2005-12-30 16:50:36 -0700 (Fri, 30 Dec 2005) | 1 line
fixes in greek transl
........
r4962 | asterix | 2006-01-01 11:41:04 -0700 (Sun, 01 Jan 2006) | 2 lines
merge meta_contacts branch with trunk. Meta contacts are not in gajim yet, but framework is here. We now use gajim.contacts.many_functions() to handle contacts and groupchat_contacts.
........
r4963 | asterix | 2006-01-01 11:43:24 -0700 (Sun, 01 Jan 2006) | 2 lines
correct contacts file
........
r4964 | asterix | 2006-01-01 11:47:26 -0700 (Sun, 01 Jan 2006) | 2 lines
dict.remove() doesn't exists, it's del dict[]
........
r4965 | asterix | 2006-01-01 11:50:15 -0700 (Sun, 01 Jan 2006) | 2 lines
some missing commits from branch
........
r4966 | asterix | 2006-01-01 11:53:30 -0700 (Sun, 01 Jan 2006) | 2 lines
end of gc_contact.nick -> gc_contact.name
........
r4967 | asterix | 2006-01-01 12:05:59 -0700 (Sun, 01 Jan 2006) | 2 lines
new ACE option: send_sha_in_gc_presence that allow to send sha info in groupchat presences
........
r4968 | asterix | 2006-01-01 12:12:36 -0700 (Sun, 01 Jan 2006) | 2 lines
0.9.1-2 in debian that solve the group bug (commit [4924])
........
r4969 | asterix | 2006-01-01 12:31:13 -0700 (Sun, 01 Jan 2006) | 2 lines
typo
........
2006-01-01 20:06:26 +00:00
if gajim . config . get ( ' send_sha_in_gc_presence ' ) :
p = self . add_sha ( p )
2005-05-18 09:18:29 +00:00
t = p . setTag ( common . xmpp . NS_MUC + ' x ' )
if password :
t . setTagData ( ' password ' , password )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( p )
2005-12-20 16:18:17 +00:00
#last date/time in history to avoid duplicate
jid = ' %s @ %s ' % ( room , server )
2005-12-24 22:00:28 +00:00
last_log = gajim . logger . get_last_date_that_has_logs ( jid )
2005-12-26 14:15:17 +00:00
if last_log is None :
2005-12-24 22:00:28 +00:00
last_log = 0
self . last_history_line [ jid ] = last_log
2005-04-12 11:46:20 +00:00
def send_gc_message ( self , jid , msg ) :
if not self . connection :
return
2005-04-26 18:45:54 +00:00
msg_iq = common . xmpp . Message ( jid , msg , typ = ' groupchat ' )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( msg_iq )
2005-04-12 11:46:20 +00:00
self . dispatch ( ' MSGSENT ' , ( jid , msg ) )
def send_gc_subject ( self , jid , subject ) :
if not self . connection :
return
2005-04-26 18:45:54 +00:00
msg_iq = common . xmpp . Message ( jid , typ = ' groupchat ' , subject = subject )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( msg_iq )
2005-04-12 11:46:20 +00:00
2005-04-20 10:21:33 +00:00
def request_gc_config ( self , room_jid ) :
2005-05-27 16:43:38 +00:00
iq = common . xmpp . Iq ( typ = ' get ' , queryNS = common . xmpp . NS_MUC_OWNER ,
2005-04-26 18:45:54 +00:00
to = room_jid )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( iq )
2005-06-29 08:28:12 +00:00
2005-06-18 23:44:33 +00:00
def change_gc_nick ( self , room_jid , nick ) :
2005-06-18 22:09:31 +00:00
if not self . connection :
return
2005-08-07 21:42:32 +00:00
p = common . xmpp . Presence ( to = ' %s / %s ' % ( room_jid , nick ) )
2005-10-07 10:54:45 +00:00
p = self . add_sha ( p )
2005-08-07 21:42:32 +00:00
self . to_be_sent . append ( p )
2005-04-20 10:21:33 +00:00
2005-04-12 11:46:20 +00:00
def send_gc_status ( self , nick , jid , show , status ) :
if not self . connection :
return
2005-06-03 22:49:07 +00:00
ptype = None
2005-04-12 11:46:20 +00:00
if show == ' offline ' :
2005-04-12 12:23:08 +00:00
ptype = ' unavailable '
2005-09-05 13:28:09 +00:00
show = helpers . get_xmpp_show ( show )
2005-08-07 21:42:32 +00:00
p = common . xmpp . Presence ( to = ' %s / %s ' % ( jid , nick ) , typ = ptype ,
show = show , status = status )
Merged in trunk updates, including meta_contacts
Merged revisions 4951,4962-4969 via svnmerge from
svn://svn.gajim.org/gajim/trunk
........
r4951 | nk | 2005-12-30 16:50:36 -0700 (Fri, 30 Dec 2005) | 1 line
fixes in greek transl
........
r4962 | asterix | 2006-01-01 11:41:04 -0700 (Sun, 01 Jan 2006) | 2 lines
merge meta_contacts branch with trunk. Meta contacts are not in gajim yet, but framework is here. We now use gajim.contacts.many_functions() to handle contacts and groupchat_contacts.
........
r4963 | asterix | 2006-01-01 11:43:24 -0700 (Sun, 01 Jan 2006) | 2 lines
correct contacts file
........
r4964 | asterix | 2006-01-01 11:47:26 -0700 (Sun, 01 Jan 2006) | 2 lines
dict.remove() doesn't exists, it's del dict[]
........
r4965 | asterix | 2006-01-01 11:50:15 -0700 (Sun, 01 Jan 2006) | 2 lines
some missing commits from branch
........
r4966 | asterix | 2006-01-01 11:53:30 -0700 (Sun, 01 Jan 2006) | 2 lines
end of gc_contact.nick -> gc_contact.name
........
r4967 | asterix | 2006-01-01 12:05:59 -0700 (Sun, 01 Jan 2006) | 2 lines
new ACE option: send_sha_in_gc_presence that allow to send sha info in groupchat presences
........
r4968 | asterix | 2006-01-01 12:12:36 -0700 (Sun, 01 Jan 2006) | 2 lines
0.9.1-2 in debian that solve the group bug (commit [4924])
........
r4969 | asterix | 2006-01-01 12:31:13 -0700 (Sun, 01 Jan 2006) | 2 lines
typo
........
2006-01-01 20:06:26 +00:00
if gajim . config . get ( ' send_sha_in_gc_presence ' ) :
p = self . add_sha ( p )
2005-11-30 17:54:34 +00:00
# send instantly so when we go offline, status is sent to gc before we
# disconnect from jabber server
self . connection . send ( p )
2005-04-12 11:46:20 +00:00
2005-07-02 18:33:51 +00:00
def gc_set_role ( self , room_jid , nick , role , reason = ' ' ) :
2005-07-19 14:38:58 +00:00
''' role is for all the life of the room so it ' s based on nick '''
2005-04-12 11:46:20 +00:00
if not self . connection :
return
2005-04-26 18:45:54 +00: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 18:33:51 +00:00
if reason :
item . addChild ( name = ' reason ' , payload = reason )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( iq )
2005-04-12 11:46:20 +00:00
2005-07-02 18:33:51 +00:00
def gc_set_affiliation ( self , room_jid , jid , affiliation , reason = ' ' ) :
2005-07-19 14:38:58 +00:00
''' affiliation is for all the life of the room so it ' s based on jid '''
2005-04-12 11:46:20 +00:00
if not self . connection :
return
2005-04-26 18:45:54 +00: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 18:33:51 +00:00
if reason :
item . addChild ( name = ' reason ' , payload = reason )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( iq )
2005-04-12 11:46:20 +00:00
2005-10-05 10:13:31 +00:00
def build_data_from_dict ( self , query , config ) :
2005-05-31 13:53:22 +00:00
x = query . setTag ( common . xmpp . NS_DATA + ' x ' , attrs = { ' type ' : ' submit ' } )
2005-04-20 10:21:33 +00:00
i = 0
while config . has_key ( i ) :
2005-04-25 09:30:24 +00:00
if not config [ i ] . has_key ( ' type ' ) :
i + = 1
continue
if config [ i ] [ ' type ' ] == ' fixed ' :
i + = 1
continue
2005-04-27 22:14:28 +00:00
tag = x . addChild ( ' field ' )
2005-04-20 10:21:33 +00:00
if config [ i ] . has_key ( ' var ' ) :
2005-04-26 18:45:54 +00:00
tag . setAttr ( ' var ' , config [ i ] [ ' var ' ] )
2005-04-20 10:21:33 +00:00
if config [ i ] . has_key ( ' values ' ) :
2005-11-22 23:10:08 +00:00
for val in config [ i ] [ ' values ' ] :
2005-04-20 10:21:33 +00:00
if val == False :
2005-04-25 09:30:24 +00:00
val = ' 0 '
2005-04-20 10:21:33 +00:00
elif val == True :
2005-04-25 09:30:24 +00:00
val = ' 1 '
2005-11-22 23:10:08 +00:00
# Force to create a new child
tag . addChild ( ' value ' ) . addData ( val )
2005-04-20 10:21:33 +00:00
i + = 1
2005-10-05 10:13:31 +00:00
def send_gc_config ( self , room_jid , config ) :
iq = common . xmpp . Iq ( typ = ' set ' , to = room_jid , queryNS = \
common . xmpp . NS_MUC_OWNER )
query = iq . getTag ( ' query ' )
self . build_data_from_dict ( query , config )
2005-07-04 21:30:00 +00:00
self . to_be_sent . append ( iq )
2005-04-20 10:21:33 +00:00
2005-04-12 11:46:20 +00:00
def gpg_passphrase ( self , passphrase ) :
if USE_GPG :
2005-08-30 21:10:14 +00:00
use_gpg_agent = gajim . config . get ( ' use_gpg_agent ' )
if use_gpg_agent :
self . gpg . passphrase = None
else :
self . gpg . passphrase = passphrase
2005-04-12 11:46:20 +00:00
2005-05-29 21:34:01 +00:00
def ask_gpg_keys ( self ) :
if USE_GPG :
keys = self . gpg . get_keys ( )
return keys
return None
2005-04-12 11:46:20 +00:00
def ask_gpg_secrete_keys ( self ) :
if USE_GPG :
keys = self . gpg . get_secret_keys ( )
return keys
return None
2005-10-30 16:50:05 +00:00
def change_password ( self , password ) :
2005-04-12 11:46:20 +00:00
if not self . connection :
return
hostname = gajim . config . get_per ( ' accounts ' , self . name , ' hostname ' )
2005-10-30 16:50:05 +00:00
username = gajim . config . get_per ( ' accounts ' , self . name , ' name ' )
2005-04-26 18:45:54 +00: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 21:30:00 +00:00
self . to_be_sent . append ( iq )
2005-04-12 11:46:20 +00:00
2005-04-20 12:23:41 +00:00
def unregister_account ( self ) :
if self . connected == 0 :
2005-10-14 18:55:48 +00:00
self . connection = self . connect_and_auth ( )
2005-04-20 12:23:41 +00:00
if self . connected > 1 :
hostname = gajim . config . get_per ( ' accounts ' , self . name , ' hostname ' )
2005-04-26 18:45:54 +00:00
iq = common . xmpp . Iq ( typ = ' set ' , to = hostname )
q = iq . setTag ( common . xmpp . NS_REGISTER + ' query ' ) . setTag ( ' remove ' )
2005-12-10 13:58:09 +00:00
self . connection . send ( iq )
2005-12-10 16:23:45 +00:00
return True
return False
2005-04-19 22:29:38 +00:00
2005-09-09 22:00:01 +00:00
def send_invite ( self , room , to , reason = ' ' ) :
''' sends invitation '''
message = common . xmpp . Message ( to = room )
2005-11-01 14:43:00 +00:00
c = message . addChild ( name = ' x ' , namespace = common . xmpp . NS_MUC_USER )
c = c . addChild ( name = ' invite ' , attrs = { ' to ' : to } )
2005-09-09 22:00:01 +00:00
if reason != ' ' :
2005-11-01 14:43:00 +00:00
c . setTagData ( ' reason ' , reason )
2005-09-09 22:00:01 +00:00
self . to_be_sent . append ( message )
2005-06-25 23:25:17 +00:00
def send_keepalive ( self ) :
2005-08-27 00:07:43 +00:00
# nothing received for the last foo seconds (60 secs by default)
self . to_be_sent . append ( ' ' )
2005-06-25 23:25:17 +00:00
2005-04-18 09:18:50 +00:00
def process ( self , timeout ) :
2005-11-19 19:33:11 +00:00
# Check if a timeout append
if len ( self . awaiting_timeouts ) :
first_tim = self . awaiting_timeouts . keys ( ) [ 0 ]
if time . time ( ) > first_tim :
self . dispatch ( ' INFORMATION ' , ( _ ( ' Timeout ' ) ,
self . awaiting_timeouts [ first_tim ] [ 1 ] ) )
del self . awaiting_timeouts [ first_tim ]
2005-09-05 13:28:09 +00:00
if self . time_to_reconnect :
if self . connected < 2 :
if time . time ( ) > self . time_to_reconnect :
self . _reconnect ( )
else :
self . time_to_reconnect = None
2005-04-12 11:46:20 +00:00
if not self . connection :
return
if self . connected :
2005-06-29 08:28:12 +00: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 10:19:52 +00:00
tosend = self . to_be_sent . pop ( 0 )
2005-11-19 19:33:11 +00:00
2005-07-30 10:19:52 +00:00
self . connection . send ( tosend )
2005-08-27 00:07:43 +00:00
t = time . time ( )
self . last_io = t
self . last_sent . append ( t )
2005-05-18 13:42:12 +00:00
try :
2005-08-27 00:07:43 +00: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-25 23:25:17 +00:00
self . send_keepalive ( )
2005-06-29 08:28:12 +00:00
2005-07-03 12:42:53 +00:00
if self . connection :
self . connection . Process ( timeout )
2005-05-18 18:57:54 +00:00
except :
2005-09-03 12:54:45 +00:00
gajim . log . debug ( _ ( ' A protocol error has occured: ' ) )
2005-11-19 15:49:45 +00:00
try :
traceback . print_exc ( )
except IOError :
pass
2005-05-18 13:42:12 +00:00
self . connected = 0
self . dispatch ( ' STATUS ' , ' offline ' )
2005-05-23 10:46:22 +00:00
if not self . connection :
return
2005-05-18 13:42:12 +00:00
try :
self . connection . disconnect ( )
except :
2005-09-03 12:54:45 +00:00
gajim . log . debug ( _ ( ' A protocol error has occured: ' ) )
2005-11-19 15:49:45 +00:00
try :
traceback . print_exc ( )
except IOError :
pass
2005-05-18 13:42:12 +00:00
self . connection = None
2005-05-31 13:53:22 +00:00
# END Connection