2005-04-12 23:09:06 +02:00
## common/connection.py
2005-04-12 13:46:20 +02:00
##
## Gajim Team:
## - Yann Le Boulanger <asterix@lagaule.org>
## - Vincent Hanquez <tab@snarc.org>
## - Nikos Kouremenos <nkour@jabber.org>
##
## Copyright (C) 2003-2005 Gajim Team
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 2 only.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
import sys
import os
import time
2005-05-18 18:42:28 +02:00
import sre
2005-05-20 19:30:29 +02:00
import traceback
2005-04-27 20:26:31 +02:00
from calendar import timegm
2005-04-12 13:46:20 +02:00
2005-04-26 20:45:54 +02:00
import common . xmpp
2005-04-12 13:46:20 +02:00
2005-05-27 07:56:17 +02:00
from common import helpers
2005-04-14 09:42:26 +02:00
from common import gajim
from common import GnuPG
2005-04-13 11:41:44 +02:00
USE_GPG = GnuPG . USE_GPG
2005-04-12 13:46:20 +02:00
from common import i18n
_ = i18n . _
2005-04-30 10:48:50 +02:00
STATUS_LIST = [ ' offline ' , ' connecting ' , ' online ' , ' chat ' , ' away ' , ' xa ' , ' dnd ' ,
2005-04-12 13:46:20 +02:00
' invisible ' ]
distro_info = {
2005-04-19 15:14:41 +02:00
' Arch Linux ' : ' /etc/arch-release ' ,
' Aurox Linux ' : ' /etc/aurox-release ' ,
' Conectiva Linux ' : ' /etc/conectiva-release ' ,
' Debian GNU/Linux ' : ' /etc/debian_release ' ,
' Debian GNU/Linux ' : ' /etc/debian_version ' ,
' Fedora Linux ' : ' /etc/fedora-release ' ,
' Gentoo Linux ' : ' /etc/gentoo-release ' ,
' Linux from Scratch ' : ' /etc/lfs-release ' ,
' Mandrake Linux ' : ' /etc/mandrake-release ' ,
' Slackware Linux ' : ' /etc/slackware-release ' ,
' Slackware Linux ' : ' /etc/slackware-version ' ,
' Solaris/Sparc ' : ' /etc/release ' ,
2005-06-04 22:54:21 +02:00
' Source Mage ' : ' /etc/sourcemage_version ' ,
2005-05-18 19:02:46 +02:00
' SUSE Linux ' : ' /etc/SuSE-release ' ,
2005-04-19 15:14:41 +02:00
' Sun JDS ' : ' /etc/sun-release ' ,
' PLD Linux ' : ' /etc/pld-release ' ,
' Yellow Dog Linux ' : ' /etc/yellowdog-release ' ,
2005-04-12 13:46:20 +02:00
# many distros use the /etc/redhat-release for compatibility
# so Redhat is the last
2005-04-19 15:14:41 +02:00
' Redhat Linux ' : ' /etc/redhat-release '
2005-04-12 13:46:20 +02:00
}
def get_os_info ( ) :
2005-04-17 01:15:03 +02:00
if os . name == ' nt ' :
2005-04-19 15:14:41 +02:00
win_version = {
( 1 , 4 , 0 ) : ' 95 ' ,
( 1 , 4 , 10 ) : ' 98 ' ,
( 1 , 4 , 90 ) : ' ME ' ,
( 2 , 4 , 0 ) : ' NT ' ,
( 2 , 5 , 0 ) : ' 2000 ' ,
2005-04-17 01:15:03 +02:00
( 2 , 5 , 1 ) : ' XP '
2005-04-19 15:14:41 +02:00
} [ os . sys . getwindowsversion ( ) [ 3 ] ,
os . sys . getwindowsversion ( ) [ 0 ] ,
2005-04-17 01:15:03 +02:00
os . sys . getwindowsversion ( ) [ 1 ] ]
return ' Windows ' + ' ' + win_version
2005-04-26 20:45:54 +02:00
elif os . name == ' posix ' :
2005-04-12 13:46:20 +02:00
executable = ' lsb_release '
params = ' --id --codename --release --short '
for path in os . environ [ ' PATH ' ] . split ( ' : ' ) :
full_path_to_executable = os . path . join ( path , executable )
if os . path . exists ( full_path_to_executable ) :
command = executable + params
child_stdin , child_stdout = os . popen2 ( command )
output = child_stdout . readline ( ) . strip ( )
child_stdout . close ( )
child_stdin . close ( )
2005-05-18 18:42:28 +02:00
# some distros put n/a in places so remove them
2005-05-20 18:46:07 +02:00
pattern = sre . compile ( r ' n/a ' , sre . IGNORECASE )
2005-05-18 18:42:28 +02:00
output = sre . sub ( pattern , ' ' , output )
2005-04-12 13:46:20 +02:00
return output
# lsb_release executable not available, so parse files
2005-04-19 15:14:41 +02:00
for distro_name in distro_info :
path_to_file = distro_info [ distro_name ]
2005-04-12 13:46:20 +02:00
if os . path . exists ( path_to_file ) :
fd = open ( path_to_file )
2005-06-04 23:52:49 +02:00
text = fd . readline ( ) . strip ( ) #get only first line
2005-04-12 13:46:20 +02:00
fd . close ( )
if path_to_file . endswith ( ' version ' ) :
2005-06-04 22:54:21 +02:00
# sourcemage_version has all the info we need
2005-06-06 02:11:48 +02:00
if not os . path . basename ( path_to_file ) . startswith ( ' sourcemage ' ) :
2005-06-04 22:54:21 +02:00
text = distro_name + ' ' + text
2005-04-19 15:14:41 +02:00
elif path_to_file . endswith ( ' aurox-release ' ) : # file doesn't have version
text = distro_name
elif path_to_file . endswith ( ' lfs-release ' ) : # file just has version
text = distro_name + ' ' + text
2005-04-12 13:46:20 +02:00
return text
2005-05-11 13:09:53 +02:00
return ' N/A '
2005-04-12 13:46:20 +02:00
2005-04-19 15:14:41 +02:00
class Connection :
""" Connection class """
2005-04-14 11:38:08 +02:00
def __init__ ( self , name ) :
2005-05-26 15:35:58 +02:00
# dict of function to be called for each event
2005-05-08 22:56:11 +02:00
self . handlers = { ' ROSTER ' : [ ] , ' WARNING ' : [ ] , ' ERROR ' : [ ] , ' STATUS ' : [ ] ,
' NOTIFY ' : [ ] , ' MSG ' : [ ] , ' MSGERROR ' : [ ] , ' MSGSENT ' : [ ] ,
' SUBSCRIBED ' : [ ] , ' UNSUBSCRIBED ' : [ ] , ' SUBSCRIBE ' : [ ] ,
' AGENT_INFO ' : [ ] , ' REGISTER_AGENT_INFO ' : [ ] , ' AGENT_INFO_ITEMS ' : [ ] ,
' AGENT_INFO_INFO ' : [ ] , ' QUIT ' : [ ] , ' ACC_OK ' : [ ] , ' MYVCARD ' : [ ] ,
' OS_INFO ' : [ ] , ' VCARD ' : [ ] , ' GC_MSG ' : [ ] , ' GC_SUBJECT ' : [ ] ,
2005-05-10 18:53:28 +02:00
' GC_CONFIG ' : [ ] , ' BAD_PASSPHRASE ' : [ ] , ' ROSTER_INFO ' : [ ] ,
' ERROR_ANSWER ' : [ ] }
2005-04-12 13:46:20 +02:00
self . name = name
self . connected = 0 # offline
2005-04-26 20:45:54 +02:00
self . connection = None # xmpppy instance
2005-04-12 13:46:20 +02:00
self . gpg = None
2005-05-13 20:54:44 +02:00
self . status = ' '
2005-04-12 13:46:20 +02:00
self . myVCardID = [ ]
2005-05-27 14:07:20 +02:00
self . on_purpose = False
2005-04-14 13:06:58 +02:00
self . password = gajim . config . get_per ( ' accounts ' , name , ' password ' )
2005-04-14 11:38:08 +02:00
if USE_GPG :
self . gpg = GnuPG . GnuPG ( )
gajim . config . set ( ' usegpg ' , True )
else :
gajim . config . set ( ' usegpg ' , False )
2005-04-12 13:46:20 +02:00
# END __init__
2005-06-07 03:10:24 +02:00
def dispatch ( self , event , pritext , sectext = ' ' ) :
2005-04-12 13:46:20 +02:00
if not event in self . handlers :
return
for handler in self . handlers [ event ] :
2005-06-07 03:10:24 +02:00
if len ( sectext ) :
handler ( self . name , pritext , sectext )
else :
handler ( self . name , pritext )
2005-04-12 13:46:20 +02:00
2005-05-31 15:53:22 +02:00
# this is in features.py but it is blocking
def _discover ( self , ns , jid , node = None ) :
2005-05-23 12:46:22 +02:00
if not self . connection :
return
2005-04-26 20:45:54 +02:00
iq = common . xmpp . Iq ( typ = ' get ' , to = jid , queryNS = ns )
if node :
iq . setQuerynode ( node )
self . connection . send ( iq )
def discoverItems ( self , jid , node = None ) :
''' According to JEP-0030: jid is mandatory,
name , node , action is optional . '''
self . _discover ( common . xmpp . NS_DISCO_ITEMS , jid , node )
def discoverInfo ( self , jid , node = None ) :
''' According to JEP-0030:
For identity : category , name is mandatory , type is optional .
For feature : var is mandatory '''
self . _discover ( common . xmpp . NS_DISCO_INFO , jid , node )
2005-04-12 13:46:20 +02:00
def _vCardCB ( self , con , vc ) :
2005-06-07 03:10:24 +02:00
""" Called when we receive a vCard
2005-04-12 13:46:20 +02:00
Parse the vCard and send it to plugins """
2005-05-24 21:18:32 +02:00
frm = vc . getFrom ( )
if frm :
frm = frm . getStripped ( )
else :
name = gajim . config . get_per ( ' accounts ' , self . name , ' name ' )
hostname = gajim . config . get_per ( ' accounts ' , self . name , ' hostname ' )
frm = name + ' @ ' + hostname
vcard = { ' jid ' : frm }
2005-04-26 20:45:54 +02:00
if vc . getTag ( ' vCard ' ) . getNamespace ( ) == common . xmpp . NS_VCARD :
2005-04-12 13:46:20 +02:00
card = vc . getChildren ( ) [ 0 ]
for info in card . getChildren ( ) :
if info . getChildren ( ) == [ ] :
vcard [ info . getName ( ) ] = info . getData ( )
else :
vcard [ info . getName ( ) ] = { }
for c in info . getChildren ( ) :
vcard [ info . getName ( ) ] [ c . getName ( ) ] = c . getData ( )
if vc . getID ( ) in self . myVCardID :
self . myVCardID . remove ( vc . getID ( ) )
self . dispatch ( ' MYVCARD ' , vcard )
else :
self . dispatch ( ' VCARD ' , vcard )
2005-04-26 20:45:54 +02:00
2005-04-12 13:46:20 +02:00
def _messageCB ( self , con , msg ) :
2005-06-07 03:10:24 +02:00
""" Called when we receive a message """
2005-05-20 13:23:08 +02:00
msgtxt = msg . getBody ( )
2005-05-27 17:36:41 +02:00
if not msg . getTag ( ' body ' ) : #no <body>
return
2005-04-12 14:23:08 +02:00
mtype = msg . getType ( )
2005-04-12 13:46:20 +02:00
tim = msg . getTimestamp ( )
tim = time . strptime ( tim , ' % Y % m %d T % H: % M: % S ' )
2005-04-27 20:26:31 +02:00
tim = time . localtime ( timegm ( tim ) )
2005-05-30 12:41:55 +02:00
encrypted = False
2005-04-26 20:45:54 +02:00
xtags = msg . getTags ( ' x ' )
2005-04-12 13:46:20 +02:00
encTag = None
decmsg = ' '
for xtag in xtags :
2005-04-26 20:45:54 +02:00
if xtag . getNamespace ( ) == common . xmpp . NS_ENCRYPTED :
2005-04-12 13:46:20 +02:00
encTag = xtag
break
if encTag and USE_GPG :
#decrypt
encmsg = encTag . getData ( )
keyID = gajim . config . get_per ( ' accounts ' , self . name , ' keyid ' )
if keyID :
decmsg = self . gpg . decrypt ( encmsg , keyID )
if decmsg :
msgtxt = decmsg
2005-05-30 12:41:55 +02:00
encrypted = True
2005-04-12 14:23:08 +02:00
if mtype == ' error ' :
2005-04-12 13:46:20 +02:00
self . dispatch ( ' MSGERROR ' , ( str ( msg . getFrom ( ) ) , \
msg . getErrorCode ( ) , msg . getError ( ) , msgtxt , tim ) )
2005-04-12 14:23:08 +02:00
elif mtype == ' groupchat ' :
2005-04-12 13:46:20 +02:00
subject = msg . getSubject ( )
if subject :
self . dispatch ( ' GC_SUBJECT ' , ( str ( msg . getFrom ( ) ) , subject ) )
else :
self . dispatch ( ' GC_MSG ' , ( str ( msg . getFrom ( ) ) , msgtxt , tim ) )
2005-04-16 11:36:18 +02:00
gajim . logger . write ( ' gc ' , msgtxt , str ( msg . getFrom ( ) ) , tim = tim )
2005-04-12 13:46:20 +02:00
else :
2005-04-16 11:36:18 +02:00
gajim . logger . write ( ' incoming ' , msgtxt , str ( msg . getFrom ( ) ) , tim = tim )
2005-05-30 12:41:55 +02:00
self . dispatch ( ' MSG ' , ( str ( msg . getFrom ( ) ) , msgtxt , tim , encrypted ) )
2005-04-12 13:46:20 +02:00
# END messageCB
def _presenceCB ( self , con , prs ) :
2005-06-07 03:10:24 +02:00
""" Called when we receive a presence """
2005-04-12 13:46:20 +02:00
who = str ( prs . getFrom ( ) )
prio = prs . getPriority ( )
if not prio :
prio = 0
2005-04-12 14:23:08 +02:00
ptype = prs . getType ( )
2005-06-04 00:49:07 +02:00
if ptype == ' available ' : ptype = None
2005-04-12 14:23:08 +02:00
gajim . log . debug ( ' PresenceCB : %s ' % ptype )
2005-04-26 20:45:54 +02:00
xtags = prs . getTags ( ' x ' )
2005-04-12 13:46:20 +02:00
sigTag = None
keyID = ' '
status = prs . getStatus ( )
for xtag in xtags :
2005-04-26 20:45:54 +02:00
if xtag . getNamespace ( ) == common . xmpp . NS_SIGNED :
2005-04-12 13:46:20 +02:00
sigTag = xtag
break
if sigTag and USE_GPG :
#verify
sigmsg = sigTag . getData ( )
keyID = self . gpg . verify ( status , sigmsg )
2005-06-04 00:49:07 +02:00
if not ptype :
2005-04-12 13:46:20 +02:00
show = prs . getShow ( )
if not show :
show = ' online '
2005-04-12 14:23:08 +02:00
elif ptype == ' unavailable ' :
2005-04-16 11:36:18 +02:00
show = ' offline '
2005-04-12 14:23:08 +02:00
elif ptype == ' subscribe ' :
2005-04-12 13:46:20 +02:00
gajim . log . debug ( ' subscribe request from %s ' % who )
if gajim . config . get ( ' alwaysauth ' ) or who . find ( " @ " ) < = 0 :
if self . connection :
2005-04-26 20:45:54 +02:00
self . connection . send ( common . xmpp . Presence ( who , ' subscribed ' ) )
2005-04-12 13:46:20 +02:00
if who . find ( " @ " ) < = 0 :
2005-06-04 02:37:49 +02:00
self . dispatch ( ' NOTIFY ' , ( prs . getFrom ( ) . getStripped ( ) . encode ( ' utf8 ' ) , \
' offline ' , ' offline ' , prs . getFrom ( ) . getResource ( ) . encode ( ' utf8 ' ) , prio , \
2005-04-12 13:46:20 +02:00
keyID , None , None , None , None , None , None ) )
else :
if not status :
status = _ ( ' I would like to add you to my roster. ' )
self . dispatch ( ' SUBSCRIBE ' , ( who , status ) )
2005-04-12 14:23:08 +02:00
elif ptype == ' subscribed ' :
2005-04-12 13:46:20 +02:00
jid = prs . getFrom ( )
2005-06-04 02:37:49 +02:00
self . dispatch ( ' SUBSCRIBED ' , ( jid . getStripped ( ) . encode ( ' utf8 ' ) , jid . getResource ( ) . encode ( ' utf8 ' ) ) )
self . dispatch ( ' UPDUSER ' , ( jid . getStripped ( ) . encode ( ' utf8 ' ) , jid . getNode ( ) , \
2005-04-14 09:42:26 +02:00
[ ' General ' ] ) )
2005-04-12 13:46:20 +02:00
#BE CAREFUL : no con.updateRosterItem() in a callback
gajim . log . debug ( ' we are now subscribed to %s ' % who )
2005-04-12 14:23:08 +02:00
elif ptype == ' unsubscribe ' :
2005-04-12 13:46:20 +02:00
gajim . log . debug ( ' unsubscribe request from %s ' % who )
2005-04-12 14:23:08 +02:00
elif ptype == ' unsubscribed ' :
2005-04-12 13:46:20 +02:00
gajim . log . debug ( ' we are now unsubscribed to %s ' % who )
self . dispatch ( ' UNSUBSCRIBED ' , prs . getFrom ( ) . getStripped ( ) )
2005-04-12 14:23:08 +02:00
elif ptype == ' error ' :
2005-04-12 13:46:20 +02:00
errmsg = prs . getError ( )
errcode = prs . getErrorCode ( )
2005-05-11 12:05:43 +02:00
if errcode == ' 409 ' : #conflict : Nick Conflict
2005-04-12 13:46:20 +02:00
self . dispatch ( ' ERROR ' , errmsg )
2005-05-24 23:32:52 +02:00
elif errcode == ' 502 ' : # Internal Timeout:
2005-06-04 02:37:49 +02:00
self . dispatch ( ' NOTIFY ' , ( prs . getFrom ( ) . getStripped ( ) . encode ( ' utf8 ' ) ,
' error ' , errmsg , prs . getFrom ( ) . getResource ( ) . encode ( ' utf8 ' ) , prio , keyID ,
2005-05-24 23:32:52 +02:00
prs . getRole ( ) , prs . getAffiliation ( ) , prs . getJid ( ) ,
prs . getReason ( ) , prs . getActor ( ) , prs . getStatusCode ( ) ) )
2005-04-12 13:46:20 +02:00
else :
2005-05-11 17:14:43 +02:00
self . dispatch ( ' ERROR_ANSWER ' , ( prs . getFrom ( ) . getStripped ( ) , errmsg ,
errcode ) )
2005-06-04 00:49:07 +02:00
if not ptype or ptype == ' unavailable ' :
2005-06-04 02:37:49 +02:00
jid = prs . getFrom ( )
gajim . logger . write ( ' status ' , status , jid . getStripped ( ) . encode ( ' utf8 ' ) , show )
account = prs . getFrom ( ) . getStripped ( ) . encode ( ' utf8 ' )
resource = prs . getFrom ( ) . getResource ( ) . encode ( ' utf8 ' )
self . dispatch ( ' NOTIFY ' , ( account , show , status ,
resource , prio , keyID , prs . getRole ( ) ,
2005-05-24 23:32:52 +02:00
prs . getAffiliation ( ) , prs . getJid ( ) , prs . getReason ( ) ,
2005-04-16 11:36:18 +02:00
prs . getActor ( ) , prs . getStatusCode ( ) ) )
2005-04-12 13:46:20 +02:00
# END presenceCB
2005-04-26 20:45:54 +02:00
def _disconnectedCB ( self ) :
2005-04-12 13:46:20 +02:00
""" Called when we are disconnected """
gajim . log . debug ( ' disconnectedCB ' )
2005-05-27 14:07:20 +02:00
if not self . connection :
return
self . connected = 0
self . dispatch ( ' STATUS ' , ' offline ' )
self . connection = None
if not self . on_purpose :
2005-06-07 03:10:24 +02:00
self . dispatch ( ' ERROR ' , _ ( ' Connection with account " %s " has been lost ' ) % \ self . name , _ ( ' To continue sending and receiving messages, you will need to reconnect. ' ) )
2005-05-27 14:07:20 +02:00
self . on_purpose = False
2005-04-12 13:46:20 +02:00
# END disconenctedCB
def _rosterSetCB ( self , con , iq_obj ) :
2005-04-20 12:21:33 +02:00
gajim . log . debug ( ' rosterSetCB ' )
2005-04-26 20:45:54 +02:00
for item in iq_obj . getTag ( ' query ' ) . getChildren ( ) :
2005-06-04 02:37:49 +02:00
jid = item . getAttr ( ' jid ' ) . encode ( ' utf8 ' )
2005-04-12 13:46:20 +02:00
name = item . getAttr ( ' name ' )
2005-06-04 02:37:49 +02:00
if name :
name = name . encode ( ' utf8 ' )
sub = item . getAttr ( ' subscription ' ) . encode ( ' utf8 ' )
2005-04-12 13:46:20 +02:00
ask = item . getAttr ( ' ask ' )
2005-06-04 02:37:49 +02:00
if ask :
ask = ask . encode ( ' utf8 ' )
2005-04-12 13:46:20 +02:00
groups = [ ]
for group in item . getTags ( ' group ' ) :
2005-06-04 02:37:49 +02:00
groups . append ( group . getData ( ) . encode ( ' utf8 ' ) )
2005-04-12 13:46:20 +02:00
self . dispatch ( ' ROSTER_INFO ' , ( jid , name , sub , ask , groups ) )
2005-05-11 09:55:17 +02:00
raise common . xmpp . NodeProcessed
2005-04-12 13:46:20 +02:00
def _BrowseResultCB ( self , con , iq_obj ) :
2005-04-20 12:21:33 +02:00
gajim . log . debug ( ' BrowseResultCB ' )
2005-04-12 13:46:20 +02:00
identities , features , items = [ ] , [ ] , [ ]
2005-05-07 14:24:19 +02:00
for q in iq_obj . getChildren ( ) :
if q . getNamespace ( ) != common . xmpp . NS_BROWSE :
continue
attr = { }
for key in q . getAttrs ( ) . keys ( ) :
attr [ key . encode ( ' utf8 ' ) ] = q . getAttr ( key ) . encode ( ' utf8 ' )
identities = [ attr ]
for node in q . getChildren ( ) :
if node . getName ( ) == ' ns ' :
features . append ( node . getData ( ) )
else :
infos = { }
for key in node . getAttrs ( ) . keys ( ) :
infos [ key . encode ( ' utf8 ' ) ] = node . getAttr ( key ) . encode ( ' utf8 ' )
infos [ ' category ' ] = node . getName ( )
items . append ( infos )
jid = str ( iq_obj . getFrom ( ) )
self . dispatch ( ' AGENT_INFO ' , ( jid , identities , features , items ) )
2005-04-12 13:46:20 +02:00
def _DiscoverItemsCB ( self , con , iq_obj ) :
2005-04-20 12:21:33 +02:00
gajim . log . debug ( ' DiscoverItemsCB ' )
2005-04-26 20:45:54 +02:00
q = iq_obj . getTag ( ' query ' )
2005-04-23 23:54:12 +02:00
node = q . getAttr ( ' node ' )
if not node :
node = ' '
2005-04-12 13:46:20 +02:00
qp = iq_obj . getQueryPayload ( )
items = [ ]
if not qp :
qp = [ ]
for i in qp :
attr = { }
2005-04-26 20:45:54 +02:00
for key in i . getAttrs ( ) :
attr [ key . encode ( ' utf8 ' ) ] = i . getAttrs ( ) [ key ] . encode ( ' utf8 ' )
2005-04-12 13:46:20 +02:00
items . append ( attr )
jid = str ( iq_obj . getFrom ( ) )
2005-04-23 23:54:12 +02:00
self . dispatch ( ' AGENT_INFO_ITEMS ' , ( jid , node , items ) )
2005-04-12 13:46:20 +02:00
def _DiscoverInfoErrorCB ( self , con , iq_obj ) :
2005-04-20 12:21:33 +02:00
gajim . log . debug ( ' DiscoverInfoErrorCB ' )
2005-04-26 20:45:54 +02:00
iq = common . xmpp . Iq ( to = iq_obj . getFrom ( ) , typ = ' get ' , queryNS = \
common . xmpp . NS_AGENTS )
con . send ( iq )
2005-04-12 13:46:20 +02:00
def _DiscoverInfoCB ( self , con , iq_obj ) :
2005-04-20 12:21:33 +02:00
gajim . log . debug ( ' DiscoverInfoCB ' )
2005-04-12 13:46:20 +02:00
# According to JEP-0030:
# For identity: category, name is mandatory, type is optional.
# For feature: var is mandatory
identities , features = [ ] , [ ]
2005-04-26 20:45:54 +02:00
q = iq_obj . getTag ( ' query ' )
2005-04-23 23:54:12 +02:00
node = q . getAttr ( ' node ' )
if not node :
node = ' '
2005-04-26 20:45:54 +02:00
qc = iq_obj . getQueryChildren ( )
if not qc :
qc = [ ]
for i in qc :
2005-04-12 13:46:20 +02:00
if i . getName ( ) == ' identity ' :
attr = { }
2005-04-26 20:45:54 +02:00
for key in i . getAttrs ( ) . keys ( ) :
attr [ key . encode ( ' utf8 ' ) ] = i . getAttr ( key ) . encode ( ' utf8 ' )
2005-04-12 13:46:20 +02:00
identities . append ( attr )
elif i . getName ( ) == ' feature ' :
features . append ( i . getAttr ( ' var ' ) )
jid = str ( iq_obj . getFrom ( ) )
if not identities :
2005-05-07 12:57:40 +02:00
self . connection . send ( common . xmpp . Iq ( typ = ' get ' , queryNS = \
common . xmpp . NS_AGENTS ) )
2005-04-12 13:46:20 +02:00
else :
2005-04-24 17:47:08 +02:00
self . dispatch ( ' AGENT_INFO_INFO ' , ( jid , node , identities , features ) )
2005-04-26 20:45:54 +02:00
self . discoverItems ( jid , node )
2005-04-12 13:46:20 +02:00
def _VersionCB ( self , con , iq_obj ) :
2005-04-20 12:21:33 +02:00
gajim . log . debug ( ' VersionCB ' )
2005-05-07 12:57:40 +02:00
iq_obj = iq_obj . buildReply ( ' result ' )
2005-04-12 13:46:20 +02:00
qp = iq_obj . getTag ( ' query ' )
2005-04-26 23:33:01 +02:00
qp . setTagData ( ' name ' , ' Gajim ' )
qp . setTagData ( ' version ' , gajim . version )
2005-04-24 02:31:48 +02:00
send_os = gajim . config . get ( ' send_os_info ' )
if send_os :
2005-04-26 23:33:01 +02:00
qp . setTagData ( ' os ' , get_os_info ( ) )
2005-05-07 12:57:40 +02:00
con . send ( iq_obj )
2005-05-13 19:20:13 +02:00
raise common . xmpp . NodeProcessed
2005-04-12 13:46:20 +02:00
def _VersionResultCB ( self , con , iq_obj ) :
2005-04-20 12:21:33 +02:00
gajim . log . debug ( ' VersionResultCB ' )
2005-04-12 13:46:20 +02:00
client_info = ' '
os_info = ' '
qp = iq_obj . getTag ( ' query ' )
if qp . getTag ( ' name ' ) :
client_info + = qp . getTag ( ' name ' ) . getData ( )
if qp . getTag ( ' version ' ) :
client_info + = ' ' + qp . getTag ( ' version ' ) . getData ( )
if qp . getTag ( ' os ' ) :
os_info + = qp . getTag ( ' os ' ) . getData ( )
jid = iq_obj . getFrom ( ) . getStripped ( )
2005-04-25 00:58:41 +02:00
resource = iq_obj . getFrom ( ) . getResource ( )
self . dispatch ( ' OS_INFO ' , ( jid , resource , client_info , os_info ) )
2005-04-20 12:21:33 +02:00
def _MucOwnerCB ( self , con , iq_obj ) :
gajim . log . debug ( ' MucOwnerCB ' )
qp = iq_obj . getQueryPayload ( )
node = None
for q in qp :
2005-04-26 20:45:54 +02:00
if q . getNamespace ( ) == common . xmpp . NS_DATA :
2005-04-20 12:21:33 +02:00
node = q
if not node :
return
# Parse the form
dic = { }
tag = node . getTag ( ' title ' )
if tag :
dic [ ' title ' ] = tag . getData ( )
tag = node . getTag ( ' instructions ' )
if tag :
dic [ ' instructions ' ] = tag . getData ( )
i = 0
for child in node . getChildren ( ) :
if child . getName ( ) != ' field ' :
continue
var = child . getAttr ( ' var ' )
ctype = child . getAttr ( ' type ' )
label = child . getAttr ( ' label ' )
if not var and ctype != ' fixed ' : # We must have var if type != fixed
continue
dic [ i ] = { }
if var :
dic [ i ] [ ' var ' ] = var
if ctype :
dic [ i ] [ ' type ' ] = ctype
if label :
dic [ i ] [ ' label ' ] = label
tags = child . getTags ( ' value ' )
if len ( tags ) :
dic [ i ] [ ' values ' ] = [ ]
for tag in tags :
data = tag . getData ( )
if ctype == ' boolean ' :
2005-04-24 18:14:50 +02:00
if data in [ ' yes ' , ' true ' , ' assent ' , ' 1 ' ] :
2005-04-20 12:21:33 +02:00
data = True
else :
data = False
dic [ i ] [ ' values ' ] . append ( data )
tag = child . getTag ( ' desc ' )
if tag :
dic [ i ] [ ' desc ' ] = tag . getData ( )
option_tags = child . getTags ( ' option ' )
if len ( option_tags ) :
dic [ i ] [ ' options ' ] = { }
j = 0
for option_tag in option_tags :
dic [ i ] [ ' options ' ] [ j ] = { }
label = option_tag . getAttr ( ' label ' )
if label :
dic [ i ] [ ' options ' ] [ j ] [ ' label ' ] = label
tags = option_tag . getTags ( ' value ' )
dic [ i ] [ ' options ' ] [ j ] [ ' values ' ] = [ ]
for tag in tags :
dic [ i ] [ ' options ' ] [ j ] [ ' values ' ] . append ( tag . getData ( ) )
j + = 1
i + = 1
self . dispatch ( ' GC_CONFIG ' , ( str ( iq_obj . getFrom ( ) ) , dic ) )
2005-04-12 13:46:20 +02:00
2005-04-26 00:22:23 +02:00
def _MucErrorCB ( self , con , iq_obj ) :
gajim . log . debug ( ' MucErrorCB ' )
jid = str ( iq_obj . getFrom ( ) )
errmsg = iq_obj . getError ( )
errcode = iq_obj . getErrorCode ( )
self . dispatch ( ' MSGERROR ' , ( jid , errcode , errmsg ) )
2005-05-08 19:00:41 +02:00
def _getRosterCB ( self , con , iq_obj ) :
roster = self . connection . getRoster ( ) . getRaw ( )
if not roster :
roster = { }
2005-06-04 02:37:49 +02:00
else :
for i in roster . keys ( ) :
props = roster [ i ]
if props . has_key ( ' name ' ) and props [ ' name ' ] :
props [ ' name ' ] = props [ ' name ' ] . encode ( ' utf8 ' )
if props . has_key ( ' groups ' ) and props [ ' groups ' ] :
props [ ' groups ' ] = map ( lambda e : e . encode ( ' utf8 ' ) , props [ ' groups ' ] )
if props . has_key ( ' resources ' ) and props [ ' resources ' ] :
props [ ' resources ' ] = map ( lambda e : e . encode ( ' utf8 ' ) , props [ ' resources ' ] )
del roster [ i ]
roster [ i . encode ( ' utf8 ' ) ] = props
2005-05-08 19:00:41 +02:00
name = gajim . config . get_per ( ' accounts ' , self . name , ' name ' )
hostname = gajim . config . get_per ( ' accounts ' , self . name , ' hostname ' )
if roster . has_key ( name + ' @ ' + hostname ) :
del roster [ name + ' @ ' + hostname ]
self . dispatch ( ' ROSTER ' , roster )
2005-05-10 18:53:28 +02:00
def _ErrorCB ( self , con , iq_obj ) :
errmsg = iq_obj . getError ( )
errcode = iq_obj . getErrorCode ( )
jid_from = str ( iq_obj . getFrom ( ) )
self . dispatch ( ' ERROR_ANSWER ' , ( jid_from , errmsg , errcode ) )
2005-04-12 13:46:20 +02:00
def connect ( self ) :
2005-05-21 03:28:18 +02:00
""" Connect and authenticate to the Jabber server """
2005-04-14 13:06:58 +02:00
name = gajim . config . get_per ( ' accounts ' , self . name , ' name ' )
2005-04-12 13:46:20 +02:00
hostname = gajim . config . get_per ( ' accounts ' , self . name , ' hostname ' )
resource = gajim . config . get_per ( ' accounts ' , self . name , ' resource ' )
2005-05-30 13:01:08 +02:00
usessl = gajim . config . get_per ( ' accounts ' , self . name , ' usessl ' )
2005-04-12 13:46:20 +02:00
2005-05-26 15:35:58 +02:00
#create connection if it doesn't already exist
2005-04-14 13:06:58 +02:00
if self . connection :
return self . connection
2005-04-18 11:18:50 +02:00
self . connected = 1
2005-04-14 13:06:58 +02:00
if gajim . config . get_per ( ' accounts ' , self . name , ' use_proxy ' ) :
2005-05-10 17:38:16 +02:00
proxy = { ' host ' : gajim . config . get_per ( ' accounts ' , self . name ,
2005-04-14 13:06:58 +02:00
' proxyhost ' ) }
2005-05-10 17:38:16 +02:00
proxy [ ' port ' ] = gajim . config . get_per ( ' accounts ' , self . name ,
2005-04-14 13:06:58 +02:00
' proxyport ' )
2005-05-10 17:38:16 +02:00
proxy [ ' user ' ] = gajim . config . get_per ( ' accounts ' , self . name ,
' proxyuser ' )
proxy [ ' password ' ] = gajim . config . get_per ( ' accounts ' , self . name ,
' proxypass ' )
2005-04-14 13:06:58 +02:00
else :
proxy = None
2005-05-28 20:20:27 +02:00
if gajim . verbose :
2005-05-08 19:00:41 +02:00
con = common . xmpp . Client ( hostname )
2005-04-14 13:06:58 +02:00
else :
2005-05-03 10:06:59 +02:00
con = common . xmpp . Client ( hostname , debug = [ ] )
2005-04-14 13:06:58 +02:00
#debug = [common.jabber.DBG_ALWAYS], log = sys.stderr, \
#connection=common.xmlstream.TCP_SSL, port=5223, proxy = proxy)
2005-05-23 11:53:05 +02:00
common . xmpp . dispatcher . DefaultTimeout = 45
2005-05-20 12:49:46 +02:00
con . UnregisterDisconnectHandler ( con . DisconnectHandler )
2005-04-26 20:45:54 +02:00
con . RegisterDisconnectHandler ( self . _disconnectedCB )
2005-05-30 13:01:08 +02:00
port = 5222
if usessl :
port = 5223
con_type = con . connect ( ( hostname , port ) , proxy = proxy ) #FIXME: blocking
2005-05-26 15:35:58 +02:00
if not con_type :
2005-05-30 16:08:48 +02:00
gajim . log . debug ( " Couldn ' t connect to %s " % self . name )
2005-05-18 16:05:54 +02:00
self . connected = 0
2005-04-12 13:46:20 +02:00
self . dispatch ( ' STATUS ' , ' offline ' )
2005-06-07 03:10:24 +02:00
self . dispatch ( ' ERROR ' , _ ( ' Could not connect to " %s " ' ) % self . name )
2005-04-14 13:06:58 +02:00
return None
2005-04-12 13:46:20 +02:00
2005-04-26 20:45:54 +02:00
con . RegisterHandler ( ' message ' , self . _messageCB )
con . RegisterHandler ( ' presence ' , self . _presenceCB )
2005-05-27 18:43:38 +02:00
con . RegisterHandler ( ' iq ' , self . _vCardCB , ' result ' ,
2005-04-26 20:45:54 +02:00
common . xmpp . NS_VCARD )
2005-05-27 18:43:38 +02:00
con . RegisterHandler ( ' iq ' , self . _rosterSetCB , ' set ' ,
2005-04-26 20:45:54 +02:00
common . xmpp . NS_ROSTER )
2005-05-27 18:43:38 +02:00
con . RegisterHandler ( ' iq ' , self . _BrowseResultCB , ' result ' ,
2005-04-26 20:45:54 +02:00
common . xmpp . NS_BROWSE )
2005-05-27 18:43:38 +02:00
con . RegisterHandler ( ' iq ' , self . _DiscoverItemsCB , ' result ' ,
2005-04-26 20:45:54 +02:00
common . xmpp . NS_DISCO_ITEMS )
2005-05-27 18:43:38 +02:00
con . RegisterHandler ( ' iq ' , self . _DiscoverInfoCB , ' result ' ,
2005-04-26 20:45:54 +02:00
common . xmpp . NS_DISCO_INFO )
2005-05-27 18:43:38 +02:00
con . RegisterHandler ( ' iq ' , self . _DiscoverInfoErrorCB , ' error ' ,
2005-04-26 20:45:54 +02:00
common . xmpp . NS_DISCO_INFO )
2005-05-27 18:43:38 +02:00
con . RegisterHandler ( ' iq ' , self . _VersionCB , ' get ' ,
2005-04-26 20:45:54 +02:00
common . xmpp . NS_VERSION )
2005-05-27 18:43:38 +02:00
con . RegisterHandler ( ' iq ' , self . _VersionResultCB , ' result ' ,
2005-04-26 20:45:54 +02:00
common . xmpp . NS_VERSION )
2005-05-27 18:43:38 +02:00
con . RegisterHandler ( ' iq ' , self . _MucOwnerCB , ' result ' ,
2005-04-26 20:45:54 +02:00
common . xmpp . NS_MUC_OWNER )
2005-05-27 18:43:38 +02:00
con . RegisterHandler ( ' iq ' , self . _getRosterCB , ' result ' ,
2005-05-08 19:00:41 +02:00
common . xmpp . NS_ROSTER )
2005-05-10 18:53:28 +02:00
con . RegisterHandler ( ' iq ' , self . _ErrorCB , ' error ' )
2005-04-26 20:45:54 +02:00
2005-04-12 13:46:20 +02:00
gajim . log . debug ( ' Connected to server ' )
2005-05-11 18:37:01 +02:00
try :
2005-05-31 15:53:22 +02:00
#FIXME: blocking
2005-06-01 14:33:29 +02:00
auth = con . auth ( name , self . password , resource , 1 )
2005-05-11 18:37:01 +02:00
except IOError : #probably a timeout
2005-05-18 16:05:54 +02:00
self . connected = 0
2005-05-11 18:37:01 +02:00
self . dispatch ( ' STATUS ' , ' offline ' )
2005-06-07 03:10:24 +02:00
self . dispatch ( ' ERROR ' , _ ( ' Could not connect to " %s " ' ) % self . name )
2005-05-11 18:37:01 +02:00
return None
if auth :
2005-05-08 19:00:41 +02:00
con . initRoster ( )
2005-04-12 13:46:20 +02:00
self . connected = 2
2005-04-14 13:06:58 +02:00
return con
2005-04-12 13:46:20 +02:00
else :
2005-05-30 16:08:48 +02:00
gajim . log . debug ( " Couldn ' t authenticate to %s " % self . name )
2005-05-18 16:05:54 +02:00
self . connected = 0
2005-04-12 13:46:20 +02:00
self . dispatch ( ' STATUS ' , ' offline ' )
2005-06-07 03:10:24 +02:00
self . dispatch ( ' ERROR ' , _ ( ' Authentication failed with " %s " ' % name ) , \
_ ( ' Please check your login and password for correctness. ' ) )
2005-04-14 13:06:58 +02:00
return None
2005-05-31 15:53:22 +02:00
# END connect
2005-04-12 13:46:20 +02:00
2005-04-14 09:58:54 +02:00
def register_handler ( self , event , function ) :
2005-04-12 13:46:20 +02:00
if event in self . handlers :
self . handlers [ event ] . append ( function )
2005-04-14 09:58:54 +02:00
def unregister_handler ( self , event , function ) :
2005-04-12 13:46:20 +02:00
if event in self . handlers :
if function in self . handlers [ event ] :
self . handlers [ event ] . remove ( function )
def quit ( self , kill_core ) :
if kill_core :
if self . connected > 1 :
self . connected = 0
self . connection . disconnect ( ' Disconnected ' )
return
def ask_roster ( self ) :
roster = { }
if self . connection :
roster = self . connection . getRoster ( ) . getRaw ( )
return roster
2005-05-13 20:54:44 +02:00
def change_status ( self , show , msg ) :
if not show in STATUS_LIST :
2005-04-12 13:46:20 +02:00
return - 1
2005-06-04 16:27:09 +02:00
sshow = show # show to be send
if show == ' online ' :
sshow = None
2005-04-12 13:46:20 +02:00
signed = ' '
keyID = gajim . config . get_per ( ' accounts ' , self . name , ' keyid ' )
if keyID and USE_GPG :
2005-05-20 17:32:05 +02:00
if not msg :
2005-05-27 00:02:01 +02:00
lowered_uf_status_msg = helpers . get_uf_show ( show ) . lower ( )
2005-06-01 23:40:33 +02:00
msg = _ ( " I ' m %s " ) % lowered_uf_status_msg
2005-04-12 13:46:20 +02:00
signed = self . gpg . sign ( msg , keyID )
if signed == ' BAD_PASSPHRASE ' :
signed = ' '
if self . connected < 2 :
self . dispatch ( ' BAD_PASSPHRASE ' , ( ) )
2005-05-20 17:32:05 +02:00
self . status = msg
2005-05-19 19:50:19 +02:00
if show != ' offline ' and not self . connected :
2005-04-14 13:06:58 +02:00
self . connection = self . connect ( )
2005-04-12 13:46:20 +02:00
if self . connected == 2 :
2005-05-13 20:54:44 +02:00
self . connected = STATUS_LIST . index ( show )
2005-04-12 13:46:20 +02:00
#send our presence
2005-06-04 00:49:07 +02:00
ptype = None
2005-05-13 20:54:44 +02:00
if show == ' invisible ' :
2005-04-12 14:23:08 +02:00
ptype = ' invisible '
2005-04-17 13:49:39 +02:00
prio = str ( gajim . config . get_per ( ' accounts ' , self . name , ' priority ' ) )
2005-06-04 16:27:09 +02:00
p = common . xmpp . Presence ( typ = ptype , priority = prio , show = sshow )
2005-05-20 17:32:05 +02:00
if msg :
p . setStatus ( msg )
2005-04-26 20:45:54 +02:00
if signed :
2005-04-26 23:33:01 +02:00
p . setTag ( common . xmpp . NS_SIGNED + ' x ' ) . setData ( signed )
2005-04-26 20:45:54 +02:00
self . connection . send ( p )
2005-05-13 20:54:44 +02:00
self . dispatch ( ' STATUS ' , show )
2005-04-12 13:46:20 +02:00
#ask our VCard
2005-05-24 21:18:32 +02:00
iq = self . request_vcard ( None )
2005-04-26 20:45:54 +02:00
self . myVCardID . append ( iq . getID ( ) )
2005-05-19 19:50:19 +02:00
elif show == ' offline ' and self . connected :
2005-04-12 13:46:20 +02:00
self . connected = 0
2005-05-04 21:20:02 +02:00
if self . connection :
2005-05-27 14:07:20 +02:00
self . on_purpose = True
2005-05-20 17:32:05 +02:00
p = common . xmpp . Presence ( typ = ' unavailable ' )
if msg :
p . setStatus ( msg )
self . connection . send ( p )
2005-05-31 18:47:05 +02:00
try :
self . connection . disconnect ( )
except :
pass
2005-04-12 13:46:20 +02:00
self . dispatch ( ' STATUS ' , ' offline ' )
2005-04-18 11:18:50 +02:00
self . connection = None
2005-05-13 20:54:44 +02:00
elif show != ' offline ' and self . connected :
self . connected = STATUS_LIST . index ( show )
2005-06-04 00:49:07 +02:00
ptype = None
2005-05-13 20:54:44 +02:00
if show == ' invisible ' :
2005-04-12 14:23:08 +02:00
ptype = ' invisible '
2005-04-17 13:49:39 +02:00
prio = str ( gajim . config . get_per ( ' accounts ' , self . name , ' priority ' ) )
2005-06-04 16:27:09 +02:00
p = common . xmpp . Presence ( typ = ptype , priority = prio , show = sshow )
2005-05-20 17:32:05 +02:00
if msg :
p . setStatus ( msg )
if signed :
p . setTag ( common . xmpp . NS_SIGNED + ' x ' ) . setData ( signed )
2005-04-26 20:45:54 +02:00
self . connection . send ( p )
2005-05-13 20:54:44 +02:00
self . dispatch ( ' STATUS ' , show )
2005-04-12 13:46:20 +02:00
2005-04-14 19:07:55 +02:00
def send_message ( self , jid , msg , keyID ) :
2005-04-14 09:42:26 +02:00
if not self . connection :
2005-04-12 13:46:20 +02:00
return
msgtxt = msg
msgenc = ' '
if keyID and USE_GPG :
#encrypt
2005-05-27 16:16:34 +02:00
msgenc = self . gpg . encrypt ( msg , [ keyID ] )
2005-04-12 13:46:20 +02:00
if msgenc : msgtxt = _ ( ' [this message is encrypted] ' )
2005-04-26 20:45:54 +02:00
msg_iq = common . xmpp . Message ( to = jid , body = msgtxt , typ = ' chat ' )
2005-04-12 13:46:20 +02:00
if msgenc :
2005-04-26 20:45:54 +02:00
msg_iq . setTag ( common . xmpp . NS_ENCRYPTED + ' x ' ) . setData ( msgenc )
2005-04-12 13:46:20 +02:00
self . connection . send ( msg_iq )
2005-04-16 11:36:18 +02:00
gajim . logger . write ( ' outgoing ' , msg , jid )
2005-04-12 13:46:20 +02:00
self . dispatch ( ' MSGSENT ' , ( jid , msg , keyID ) )
2005-04-14 09:42:26 +02:00
def request_subscription ( self , jid , msg ) :
2005-04-12 13:46:20 +02:00
if not self . connection :
return
gajim . log . debug ( ' subscription request for %s ' % jid )
2005-04-26 20:45:54 +02:00
pres = common . xmpp . Presence ( jid , ' subscribe ' )
2005-04-12 13:46:20 +02:00
if not msg :
msg = _ ( ' I would like to add you to my roster. ' )
pres . setStatus ( msg )
self . connection . send ( pres )
2005-04-14 09:42:26 +02:00
def send_authorization ( self , jid ) :
2005-04-12 13:46:20 +02:00
if not self . connection :
return
2005-04-26 20:45:54 +02:00
self . connection . send ( common . xmpp . Presence ( jid , ' subscribed ' ) )
2005-04-12 13:46:20 +02:00
2005-04-14 09:42:26 +02:00
def refuse_authorization ( self , jid ) :
2005-04-12 13:46:20 +02:00
if not self . connection :
return
2005-04-26 20:45:54 +02:00
self . connection . send ( common . xmpp . Presence ( jid , ' unsubscribed ' ) )
2005-04-12 13:46:20 +02:00
def unsubscribe ( self , jid ) :
if not self . connection :
return
delauth = gajim . config . get ( ' delauth ' )
delroster = gajim . config . get ( ' delroster ' )
if delauth :
2005-04-26 20:45:54 +02:00
self . connection . getRoster ( ) . Unsubscribe ( jid )
2005-04-12 13:46:20 +02:00
if delroster :
2005-04-26 20:45:54 +02:00
self . connection . getRoster ( ) . delItem ( jid )
2005-04-12 13:46:20 +02:00
2005-05-11 11:08:06 +02:00
def _continue_unsubscribe ( self , con , iq_obj , agent ) :
self . connection . getRoster ( ) . delItem ( agent )
2005-04-12 13:46:20 +02:00
self . dispatch ( ' AGENT_REMOVED ' , agent )
2005-05-08 19:33:08 +02:00
def unsubscribe_agent ( self , agent ) :
if not self . connection :
return
2005-05-11 11:08:06 +02:00
iq = common . xmpp . Iq ( ' set ' , common . xmpp . NS_REGISTER , to = agent )
iq . getTag ( ' query ' ) . setTag ( ' remove ' )
self . connection . SendAndCallForResponse ( iq , self . _continue_unsubscribe ,
2005-05-08 19:33:08 +02:00
{ ' agent ' : agent } )
return
2005-04-12 13:46:20 +02:00
def update_user ( self , jid , name , groups ) :
if self . connection :
2005-04-30 10:48:50 +02:00
self . connection . getRoster ( ) . setItem ( jid = jid , name = name ,
2005-04-26 20:45:54 +02:00
groups = groups )
2005-04-12 13:46:20 +02:00
2005-04-23 23:54:12 +02:00
def request_agents ( self , jid , node ) :
2005-04-12 13:46:20 +02:00
if self . connection :
2005-05-07 12:57:40 +02:00
self . connection . send ( common . xmpp . Iq ( to = jid , typ = ' get ' ,
queryNS = common . xmpp . NS_BROWSE ) )
2005-04-26 20:45:54 +02:00
self . discoverInfo ( jid , node )
2005-04-12 13:46:20 +02:00
2005-05-08 22:56:11 +02:00
def _receive_register_agent_info ( self , con , iq_obj , agent ) :
if not common . xmpp . isResultNode ( iq_obj ) :
return
iq = common . xmpp . Iq ( ' get ' , common . xmpp . NS_REGISTER , to = agent )
df = iq_obj . getTag ( ' query ' , namespace = common . xmpp . NS_REGISTER ) . \
getTag ( ' x ' , namespace = common . xmpp . NS_DATA )
if df :
df = common . xmpp . DataForm ( node = df )
self . dispatch ( ' REGISTER_AGENT_INFO ' , ( agent , df . asDict ( ) ) )
return
df = common . xmpp . DataForm ( typ = ' form ' )
for i in iq_obj . getQueryPayload ( ) :
if type ( i ) != type ( iq ) :
pass
elif i . getName ( ) == ' instructions ' :
df . addInstructions ( i . getData ( ) )
else :
df . setField ( i . getName ( ) ) . setValue ( i . getData ( ) )
self . dispatch ( ' REGISTER_AGENT_INFO ' , ( agent , df . asDict ( ) ) )
return
def request_register_agent_info ( self , agent ) :
2005-04-12 13:46:20 +02:00
if not self . connection :
return None
2005-05-08 22:56:11 +02:00
iq = common . xmpp . Iq ( ' get ' , common . xmpp . NS_REGISTER , to = agent )
self . connection . SendAndCallForResponse ( iq ,
self . _receive_register_agent_info , { ' agent ' : agent } )
return
2005-04-26 20:45:54 +02:00
def register_agent ( self , agent , info ) :
2005-04-12 13:46:20 +02:00
if not self . connection :
return
2005-05-31 15:53:22 +02:00
# FIXME: Blocking
common . xmpp . features . register ( self . connection , agent , info )
2005-04-12 13:46:20 +02:00
2005-05-10 11:20:35 +02:00
def new_account ( self , name , config ) :
2005-04-12 13:46:20 +02:00
# If a connection already exist we cannot create a new account
if self . connection :
return
2005-05-10 11:20:35 +02:00
if config [ ' use_proxy ' ] :
2005-05-10 17:38:16 +02:00
proxy = { ' host ' : config [ ' proxyhost ' ] , ' port ' : config [ ' proxyport ' ] ,
' user ' : config [ ' proxyuser ' ] , ' password ' : config [ ' proxypass ' ] }
2005-04-12 13:46:20 +02:00
else :
proxy = None
2005-05-31 15:53:22 +02:00
if gajim . verbose :
c = common . xmpp . Client ( server = config [ ' hostname ' ] )
else :
c = common . xmpp . Client ( server = config [ ' hostname ' ] , debug = [ ] )
common . xmpp . dispatcher . DefaultTimeout = 45
c . UnregisterDisconnectHandler ( c . DisconnectHandler )
c . RegisterDisconnectHandler ( self . _disconnectedCB )
port = 5222
# if usessl:
# port = 5223
#FIXME: blocking
con_type = c . connect ( ( config [ ' hostname ' ] , port ) , proxy = proxy )
2005-05-26 15:35:58 +02:00
if not con_type :
2005-05-30 16:08:48 +02:00
gajim . log . debug ( " Couldn ' t connect to %s " % name )
2005-06-07 03:10:24 +02:00
self . dispatch ( ' ERROR ' , _ ( ' Could not connect to " %s " ' ) % name ,
2005-06-07 03:14:08 +02:00
_ ( ' Check your connection or try again later ' ) )
2005-05-26 15:35:58 +02:00
return False
2005-05-31 15:53:22 +02:00
gajim . log . debug ( ' Connected to server ' )
# FIXME! This blocks!
req = common . xmpp . features . getRegInfo ( c , config [ ' hostname ' ] ) . asDict ( )
req [ ' username ' ] = config [ ' name ' ]
req [ ' password ' ] = config [ ' password ' ]
if not common . xmpp . features . register ( c , config [ ' hostname ' ] , req ) :
self . dispatch ( ' ERROR ' , _ ( ' Error: ' ) + c . lastErr )
return False
self . name = name
self . connected = 0
self . password = config [ ' password ' ]
if USE_GPG :
self . gpg = GnuPG . GnuPG ( )
gajim . config . set ( ' usegpg ' , True )
2005-04-12 13:46:20 +02:00
else :
2005-05-31 15:53:22 +02:00
gajim . config . set ( ' usegpg ' , False )
gajim . connections [ name ] = self
self . dispatch ( ' ACC_OK ' , ( name , config ) )
2005-04-12 13:46:20 +02:00
def account_changed ( self , new_name ) :
self . name = new_name
def request_os_info ( self , jid , resource ) :
if not self . connection :
return
2005-04-26 20:45:54 +02:00
iq = common . xmpp . Iq ( to = jid + ' / ' + resource , typ = ' get ' , queryNS = \
common . xmpp . NS_VERSION )
2005-04-12 13:46:20 +02:00
self . connection . send ( iq )
2005-05-24 21:18:32 +02:00
def request_vcard ( self , jid = None ) :
''' request the VCARD and return the iq '''
2005-04-12 13:46:20 +02:00
if not self . connection :
return
2005-05-24 21:18:32 +02:00
iq = common . xmpp . Iq ( typ = ' get ' )
if jid :
iq . setTo ( jid )
2005-04-26 20:45:54 +02:00
iq . setTag ( common . xmpp . NS_VCARD + ' vCard ' )
2005-04-12 13:46:20 +02:00
self . connection . send ( iq )
2005-05-24 21:18:32 +02:00
return iq
2005-06-06 17:29:27 +02:00
2005-04-12 13:46:20 +02:00
#('VCARD', {entry1: data, entry2: {entry21: data, ...}, ...})
def send_vcard ( self , vcard ) :
if not self . connection :
return
2005-06-07 00:58:06 +02:00
print vcard
2005-04-26 20:45:54 +02:00
iq = common . xmpp . Iq ( typ = ' set ' )
iq2 = iq . setTag ( common . xmpp . NS_VCARD + ' vCard ' )
2005-04-12 13:46:20 +02:00
for i in vcard . keys ( ) :
2005-06-06 17:29:27 +02:00
if i == ' jid ' :
continue
if type ( vcard [ i ] ) == type ( { } ) :
for j in vcard [ i ] . keys ( ) :
if type ( vcard [ i ] [ j ] ) == type ( { } ) :
iq3 = iq2 . addChild ( i )
iq3 . addChild ( j )
for k in vcard [ i ] [ j ] :
iq3 . addChild ( k ) . setData ( vcard [ i ] [ j ] [ k ] )
else :
iq3 = iq2 . addChild ( i )
2005-04-26 20:45:54 +02:00
iq3 . addChild ( j ) . setData ( vcard [ i ] [ j ] )
2005-06-06 17:29:27 +02:00
else :
iq2 . addChild ( i ) . setData ( vcard [ i ] )
2005-04-12 13:46:20 +02:00
self . connection . send ( iq )
2005-04-12 14:23:08 +02:00
def send_agent_status ( self , agent , ptype ) :
2005-04-12 13:46:20 +02:00
if not self . connection :
return
2005-04-26 20:45:54 +02:00
p = common . xmpp . Presence ( to = agent , typ = ptype )
2005-04-12 13:46:20 +02:00
self . connection . send ( p )
2005-04-18 14:17:43 +02:00
def join_gc ( self , nick , room , server , password ) :
2005-04-12 13:46:20 +02:00
if not self . connection :
return
2005-06-04 16:27:09 +02:00
show = STATUS_LIST [ self . connected ]
ptype = None
if show == ' online ' :
show = None
2005-05-13 20:54:44 +02:00
p = common . xmpp . Presence ( to = ' %s @ %s / %s ' % ( room , server , nick ) ,
2005-06-04 16:27:09 +02:00
show = show , status = self . status )
2005-05-18 11:18:29 +02:00
t = p . setTag ( common . xmpp . NS_MUC + ' x ' )
if password :
t . setTagData ( ' password ' , password )
2005-04-12 13:46:20 +02:00
self . connection . send ( p )
def send_gc_message ( self , jid , msg ) :
if not self . connection :
return
2005-04-26 20:45:54 +02:00
msg_iq = common . xmpp . Message ( jid , msg , typ = ' groupchat ' )
2005-04-12 13:46:20 +02:00
self . connection . send ( msg_iq )
self . dispatch ( ' MSGSENT ' , ( jid , msg ) )
def send_gc_subject ( self , jid , subject ) :
if not self . connection :
return
2005-04-26 20:45:54 +02:00
msg_iq = common . xmpp . Message ( jid , typ = ' groupchat ' , subject = subject )
2005-04-12 13:46:20 +02:00
self . connection . send ( msg_iq )
2005-04-20 12:21:33 +02:00
def request_gc_config ( self , room_jid ) :
2005-05-27 18:43:38 +02:00
iq = common . xmpp . Iq ( typ = ' get ' , queryNS = common . xmpp . NS_MUC_OWNER ,
2005-04-26 20:45:54 +02:00
to = room_jid )
2005-04-20 12:21:33 +02:00
self . connection . send ( iq )
2005-04-12 13:46:20 +02:00
def send_gc_status ( self , nick , jid , show , status ) :
if not self . connection :
return
2005-06-04 00:49:07 +02:00
ptype = None
2005-04-12 13:46:20 +02:00
if show == ' offline ' :
2005-04-12 14:23:08 +02:00
ptype = ' unavailable '
2005-04-12 13:46:20 +02:00
show = None
2005-06-04 16:27:09 +02:00
if show == ' online ' :
show = None
2005-05-27 18:43:38 +02:00
self . connection . send ( common . xmpp . Presence ( to = ' %s / %s ' % ( jid , nick ) ,
2005-04-26 20:45:54 +02:00
typ = ptype , show = show , status = status ) )
2005-04-12 13:46:20 +02:00
def gc_set_role ( self , room_jid , nick , role ) :
if not self . connection :
return
2005-04-26 20:45:54 +02:00
iq = common . xmpp . Iq ( typ = ' set ' , to = room_jid , queryNS = \
common . xmpp . NS_MUC_ADMIN )
item = iq . getTag ( ' query ' ) . setTag ( ' item ' )
item . setAttr ( ' nick ' , nick )
item . setAttr ( ' role ' , role )
2005-04-12 13:46:20 +02:00
self . connection . send ( iq )
def gc_set_affiliation ( self , room_jid , jid , affiliation ) :
if not self . connection :
return
2005-04-26 20:45:54 +02:00
iq = common . xmpp . Iq ( typ = ' set ' , to = room_jid , queryNS = \
common . xmpp . NS_MUC_ADMIN )
item = iq . getTag ( ' query ' ) . setTag ( ' item ' )
item . setAttr ( ' jid ' , jid )
item . setAttr ( ' affiliation ' , affiliation )
2005-04-12 13:46:20 +02:00
self . connection . send ( iq )
2005-04-20 12:21:33 +02:00
def send_gc_config ( self , room_jid , config ) :
2005-04-26 20:45:54 +02:00
iq = common . xmpp . Iq ( typ = ' set ' , to = room_jid , queryNS = \
common . xmpp . NS_MUC_OWNER )
query = iq . getTag ( ' query ' )
2005-05-31 15:53:22 +02:00
# FIXME: should really use XData class
x = query . setTag ( common . xmpp . NS_DATA + ' x ' , attrs = { ' type ' : ' submit ' } )
2005-04-20 12:21:33 +02:00
i = 0
while config . has_key ( i ) :
2005-04-25 11:30:24 +02:00
if not config [ i ] . has_key ( ' type ' ) :
i + = 1
continue
if config [ i ] [ ' type ' ] == ' fixed ' :
i + = 1
continue
2005-04-28 00:14:28 +02:00
tag = x . addChild ( ' field ' )
2005-04-20 12:21:33 +02:00
if config [ i ] . has_key ( ' var ' ) :
2005-04-26 20:45:54 +02:00
tag . setAttr ( ' var ' , config [ i ] [ ' var ' ] )
2005-04-20 12:21:33 +02:00
if config [ i ] . has_key ( ' values ' ) :
for val in config [ i ] [ ' values ' ] :
if val == False :
2005-04-25 11:30:24 +02:00
val = ' 0 '
2005-04-20 12:21:33 +02:00
elif val == True :
2005-04-25 11:30:24 +02:00
val = ' 1 '
2005-04-26 20:45:54 +02:00
tag . setTagData ( ' value ' , val )
2005-04-20 12:21:33 +02:00
i + = 1
self . connection . send ( iq )
2005-04-12 13:46:20 +02:00
def gpg_passphrase ( self , passphrase ) :
if USE_GPG :
self . gpg . passphrase = passphrase
2005-05-29 23:34:01 +02:00
def ask_gpg_keys ( self ) :
if USE_GPG :
keys = self . gpg . get_keys ( )
return keys
return None
2005-04-12 13:46:20 +02:00
def ask_gpg_secrete_keys ( self ) :
if USE_GPG :
keys = self . gpg . get_secret_keys ( )
return keys
return None
def change_password ( self , password , username ) :
if not self . connection :
return
hostname = gajim . config . get_per ( ' accounts ' , self . name , ' hostname ' )
2005-04-26 20:45:54 +02:00
iq = common . xmpp . Iq ( typ = ' set ' , to = hostname )
q = iq . setTag ( common . xmpp . NS_REGISTER + ' query ' )
q . setTagData ( ' username ' , username )
q . setTagData ( ' password ' , password )
2005-04-12 13:46:20 +02:00
self . connection . send ( iq )
2005-04-20 14:23:41 +02:00
def unregister_account ( self ) :
if self . connected == 0 :
self . connection = self . connect ( )
if self . connected > 1 :
hostname = gajim . config . get_per ( ' accounts ' , self . name , ' hostname ' )
2005-04-26 20:45:54 +02:00
iq = common . xmpp . Iq ( typ = ' set ' , to = hostname )
q = iq . setTag ( common . xmpp . NS_REGISTER + ' query ' ) . setTag ( ' remove ' )
2005-04-20 14:23:41 +02:00
self . connection . send ( iq )
2005-04-20 00:29:38 +02:00
2005-04-18 11:18:50 +02:00
def process ( self , timeout ) :
2005-04-12 13:46:20 +02:00
if not self . connection :
return
if self . connected :
2005-05-18 15:42:12 +02:00
try :
self . connection . Process ( timeout )
2005-05-18 20:57:54 +02:00
except :
2005-05-20 19:30:29 +02:00
gajim . log . debug ( ' error appeared while processing xmpp: ' )
traceback . print_exc ( )
2005-05-18 15:42:12 +02:00
self . connected = 0
self . dispatch ( ' STATUS ' , ' offline ' )
2005-05-23 12:46:22 +02:00
if not self . connection :
return
2005-05-18 15:42:12 +02:00
try :
self . connection . disconnect ( )
except :
2005-05-20 19:30:29 +02:00
gajim . log . debug ( ' error appeared while processing xmpp: ' )
traceback . print_exc ( )
2005-05-18 15:42:12 +02:00
self . connection = None
2005-05-31 15:53:22 +02:00
# END Connection