2010-01-10 20:14:17 +00:00
#!/usr/bin/python
# -*- coding:utf-8 -*-
#
# Copyright 2010 Le Coz Florent <louizatakk@fedoraproject.org>
#
# This file is part of Poezio.
#
# Poezio is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# Poezio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
2010-05-18 13:29:02 +00:00
"""
Defines the Connection class
"""
2010-03-24 16:44:55 +00:00
from gettext import ( bindtextdomain , textdomain , bind_textdomain_codeset ,
gettext as _ )
bindtextdomain ( ' poezio ' )
textdomain ( ' poezio ' )
bind_textdomain_codeset ( ' poezio ' , ' utf-8 ' )
import locale
locale . setlocale ( locale . LC_ALL , ' ' )
2010-01-10 20:14:17 +00:00
import sys
import xmpp
from config import config
2010-01-26 17:10:37 +00:00
from logging import logger
2010-01-10 20:14:17 +00:00
from handler import Handler
2010-03-18 19:43:44 +00:00
from common import exception_handler
2010-02-11 04:59:58 +00:00
import threading
2010-01-10 20:14:17 +00:00
2010-02-11 04:59:58 +00:00
class Connection ( threading . Thread ) :
2010-01-10 20:14:17 +00:00
"""
2010-01-21 01:54:50 +00:00
Receives everything from Jabber and emits the
appropriate signals
2010-01-10 20:14:17 +00:00
"""
def __init__ ( self , server , resource ) :
2010-02-11 04:59:58 +00:00
threading . Thread . __init__ ( self )
2010-01-10 20:14:17 +00:00
self . handler = Handler ( )
2010-05-11 10:38:57 +00:00
self . daemon = True # exit the program when this thread exits
2010-05-21 13:16:40 +00:00
if config . get ( ' jid ' , ' ' ) == ' ' :
self . server = server
else :
self . server = jid_get_domain ( config . get ( ' jid ' , ' ' ) )
2010-01-10 20:14:17 +00:00
self . resource = resource
self . online = 0 # 1:connected, 2:auth confirmed
self . jid = ' ' # we don't know our jid yet (anon account)
2010-01-26 19:33:40 +00:00
self . port = config . get ( ' port ' , 5222 )
2010-01-26 17:10:37 +00:00
self . client = xmpp . Client ( self . server , debug = [ ] )
2010-01-10 20:14:17 +00:00
def run ( self ) :
"""
2010-01-21 01:54:50 +00:00
run in a thread
2010-01-10 20:14:17 +00:00
connect to server
"""
2010-03-18 19:43:44 +00:00
sys . excepthook = exception_handler
2010-01-10 20:14:17 +00:00
if not self . connect_to_server ( self . server , self . port ) :
2010-03-24 16:44:55 +00:00
self . handler . emit ( ' error ' , msg = ' Could not connect to server ' )
2010-01-10 20:14:17 +00:00
sys . exit ( - 1 )
2010-05-21 13:16:40 +00:00
if not self . authenticate ( config . get ( ' jid ' , ' ' ) == ' ' ) :
2010-03-24 16:44:55 +00:00
self . handler . emit ( ' error ' , msg = ' Could not authenticate to server ' )
2010-01-10 20:14:17 +00:00
sys . exit ( - 1 )
2010-05-21 13:16:40 +00:00
# TODO, become invisible before sendInitPresence
2010-02-13 15:18:39 +00:00
self . client . sendInitPresence ( requestRoster = 0 )
2010-05-11 10:38:57 +00:00
self . online = 1 # 2 when confirmation of our auth is received
2010-01-10 20:14:17 +00:00
self . register_handlers ( )
2010-01-12 14:57:58 +00:00
while 1 :
self . process ( )
2010-01-10 20:14:17 +00:00
def connect_to_server ( self , server , port ) :
2010-05-21 13:16:40 +00:00
"""
Connect to the server
"""
2010-02-16 13:37:08 +00:00
if config . get ( ' use_proxy ' , ' false ' ) == ' true ' :
return self . client . connect ( ( server , port ) ,
{ ' host ' : config . get ( " proxy_server " , " " ) ,
' port ' : config . get ( " proxy_port " , 1080 ) ,
' user ' : config . get ( " proxy_user " , " " ) ,
2010-05-18 13:29:02 +00:00
' password ' : config . get ( " proxy_password " ,
" " )
2010-02-16 13:37:08 +00:00
} )
else :
return self . client . connect ( ( server , port ) )
2010-01-10 20:14:17 +00:00
def authenticate ( self , anon = True ) :
2010-05-18 13:29:02 +00:00
"""
Authenticate to the server
"""
2010-01-10 20:14:17 +00:00
if anon :
2010-03-24 16:44:55 +00:00
try :
self . client . auth ( None , " " , self . resource )
return True
except TypeError :
2010-06-13 14:09:50 +00:00
self . handler . emit ( ' error ' , msg = _ ( ' Error: Could not authenticate. Please make sure the server you chose ( %s ) supports anonymous authentication ' % ( config . get ( ' server ' , ' ' ) ) ) )
2010-05-21 13:16:40 +00:00
return False
2010-01-10 20:14:17 +00:00
else :
2010-05-21 13:16:40 +00:00
password = config . get ( ' password ' , ' ' )
jid = config . get ( ' jid ' , ' ' )
auth = self . client . auth ( jid_get_node ( jid ) , password , " salut " )
return auth
2010-01-10 20:14:17 +00:00
def register_handlers ( self ) :
2010-01-21 01:54:50 +00:00
"""
2010-05-18 13:29:02 +00:00
registers handlers from xmpppy signals
2010-01-21 01:54:50 +00:00
"""
2010-05-18 13:29:02 +00:00
self . client . RegisterHandler ( ' iq ' , self . on_get_time , typ = ' get ' ,
ns = " urn:xmpp:time " )
self . client . RegisterHandler ( ' iq ' , self . on_get_version , typ = ' get ' ,
ns = xmpp . NS_VERSION )
2010-03-18 19:43:44 +00:00
self . client . RegisterHandler ( ' presence ' , self . handler_presence )
self . client . RegisterHandler ( ' message ' , self . handler_message )
2010-03-24 18:01:22 +00:00
def error_message ( self , stanza ) :
2010-05-18 13:29:02 +00:00
"""
handles the error messages
"""
2010-03-24 18:01:22 +00:00
room_name = stanza . getFrom ( ) . getStripped ( )
2010-05-18 13:29:02 +00:00
self . handler . emit ( ' error-message ' , room = room_name ,
error = stanza . getTag ( ' error ' ) ,
msg = stanza . getError ( ) )
2010-03-24 18:01:22 +00:00
raise xmpp . protocol . NodeProcessed
2010-01-10 20:14:17 +00:00
def handler_presence ( self , connection , presence ) :
2010-05-18 13:29:02 +00:00
"""
handles the presence messages
"""
if not connection :
return
2010-03-24 18:01:22 +00:00
if presence . getType ( ) == ' error ' :
self . error_message ( presence )
return
2010-01-21 01:54:50 +00:00
fro = presence . getFrom ( )
2010-05-18 13:29:02 +00:00
toj = presence . getAttr ( ' to ' )
if fro == toj : # own presence
2010-01-10 20:14:17 +00:00
self . online = 2
2010-05-18 13:29:02 +00:00
self . jid = toj
2010-01-29 16:24:44 +00:00
self . handler . emit ( ' on-connected ' , jid = fro )
2010-01-10 20:14:17 +00:00
return
2010-01-21 01:54:50 +00:00
self . handler . emit ( ' room-presence ' , stanza = presence )
2010-03-19 03:30:51 +00:00
raise xmpp . protocol . NodeProcessed
2010-01-10 20:14:17 +00:00
2010-03-18 19:43:44 +00:00
def handler_delayed_message ( self , connection , message ) :
2010-05-18 13:29:02 +00:00
"""
handles the delayed messages
These are received when we join a muc and we are sent the
recent history
"""
if not connection :
return
2010-03-19 03:30:51 +00:00
self . handler . emit ( ' room-delayed-message ' , stanza = message )
raise xmpp . protocol . NodeProcessed
2010-03-18 19:43:44 +00:00
2010-01-21 01:54:50 +00:00
def handler_message ( self , connection , message ) :
2010-05-18 13:29:02 +00:00
"""
handles the common messages
"""
if not connection :
return
2010-03-24 18:01:22 +00:00
if message . getType ( ) == ' error ' :
self . error_message ( message )
return
2010-06-13 13:51:02 +00:00
if message . getType ( ) == ' groupchat ' :
self . handler . emit ( ' room-message ' , stanza = message )
else :
self . handler . emit ( ' private-message ' , stanza = message )
2010-03-19 03:30:51 +00:00
raise xmpp . protocol . NodeProcessed
2010-01-12 14:57:58 +00:00
2010-01-10 20:14:17 +00:00
def process ( self , timeout = 10 ) :
2010-05-18 13:29:02 +00:00
"""
Main connection loop
It just waits for something to process ( something is received
or something has to be sent )
"""
2010-01-10 20:14:17 +00:00
if self . online :
2010-03-18 19:43:44 +00:00
self . client . Process ( timeout )
2010-01-10 20:14:17 +00:00
else :
2010-05-18 13:29:02 +00:00
logger . warning ( ' disconnecting... ' )
2010-01-21 01:54:50 +00:00
sys . exit ( )
2010-02-14 03:51:03 +00:00
def on_get_version ( self , connection , iq ) :
2010-05-18 13:29:02 +00:00
"""
Handles the iq requesting our software version
"""
if not connection :
return
2010-02-14 03:51:03 +00:00
self . handler . emit ( ' send-version ' , iq_obj = iq )
def on_get_time ( self , connection , iq ) :
2010-05-18 13:29:02 +00:00
"""
handles the iq requesting our time
"""
if not connection :
return
2010-02-14 03:51:03 +00:00
self . handler . emit ( ' send-time ' , iq_obj = iq )
2010-05-21 13:16:40 +00:00
def jid_get_node ( jid ) :
if isinstance ( jid , basestring ) :
jid = xmpp . JID ( jid )
return jid . getNode ( )
def jid_get_domain ( jid ) :
if isinstance ( jid , basestring ) :
jid = xmpp . JID ( jid )
return jid . getDomain ( )
2010-06-13 13:51:02 +00:00
def is_jid_the_same ( a , b ) :
if isinstance ( a , basestring ) :
a = xmpp . JID ( a )
if isinstance ( b , basestring ) :
b = xmpp . JID ( b )
return a . bareMatch ( b )