2006-07-27 22:36:21 +02:00
|
|
|
## common/zeroconf/connection_zeroconf.py
|
2006-05-26 16:27:42 +02:00
|
|
|
##
|
|
|
|
## Contributors for this file:
|
|
|
|
## - Yann Le Boulanger <asterix@lagaule.org>
|
|
|
|
## - Nikos Kouremenos <nkour@jabber.org>
|
|
|
|
## - Dimitur Kirov <dkirov@gmail.com>
|
|
|
|
## - Travis Shirk <travis@pobox.com>
|
2006-07-27 22:36:21 +02:00
|
|
|
## - Stefan Bethge <stefan@lanpartei.de>
|
2006-05-26 16:27:42 +02:00
|
|
|
##
|
|
|
|
## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org>
|
|
|
|
## Vincent Hanquez <tab@snarc.org>
|
2006-07-27 22:36:21 +02:00
|
|
|
## Copyright (C) 2006 Yann Le Boulanger <asterix@lagaule.org>
|
2006-05-26 16:27:42 +02:00
|
|
|
## 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>
|
2006-07-27 22:36:21 +02:00
|
|
|
## Stefan Bethge <stefan@lanpartei.de>
|
2006-05-26 16:27:42 +02: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.
|
|
|
|
##
|
|
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
import random
|
|
|
|
random.seed()
|
|
|
|
|
|
|
|
import signal
|
|
|
|
if os.name != 'nt':
|
|
|
|
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
2006-07-11 17:22:59 +02:00
|
|
|
import getpass
|
2006-06-13 23:19:39 +02:00
|
|
|
import gobject
|
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
from common import gajim
|
|
|
|
from common import GnuPG
|
2006-06-28 01:09:21 +02:00
|
|
|
from common.zeroconf import client_zeroconf
|
2006-05-26 16:27:42 +02:00
|
|
|
from connection_handlers_zeroconf import *
|
2006-05-29 17:36:18 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
USE_GPG = GnuPG.USE_GPG
|
|
|
|
|
|
|
|
class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
|
|
|
'''Connection class'''
|
|
|
|
def __init__(self, name):
|
|
|
|
ConnectionHandlersZeroconf.__init__(self)
|
2006-09-25 20:57:39 +02:00
|
|
|
# system username
|
|
|
|
self.username = None
|
2006-05-26 16:27:42 +02:00
|
|
|
self.name = name
|
2007-03-30 20:42:58 +02:00
|
|
|
self.server_resource = '' # zeroconf has no resource, fake an empty one
|
2006-05-26 16:27:42 +02:00
|
|
|
self.connected = 0 # offline
|
2006-06-13 23:19:39 +02:00
|
|
|
self.connection = None
|
2006-05-26 16:27:42 +02:00
|
|
|
self.gpg = None
|
2006-05-29 21:57:39 +02:00
|
|
|
self.is_zeroconf = True
|
2006-09-26 18:05:53 +02:00
|
|
|
self.privacy_rules_supported = False
|
2007-04-26 21:46:47 +02:00
|
|
|
self.blocked_contacts = []
|
2007-04-30 19:54:43 +02:00
|
|
|
self.blocked_groups = []
|
2006-05-26 16:27:42 +02:00
|
|
|
self.status = ''
|
|
|
|
self.old_show = ''
|
2006-10-04 02:10:49 +02:00
|
|
|
self.priority = 0
|
2006-06-13 23:19:39 +02:00
|
|
|
|
|
|
|
self.call_resolve_timeout = False
|
|
|
|
|
2007-04-25 12:25:22 +02:00
|
|
|
self.time_to_reconnect = None
|
2006-06-13 23:19:39 +02:00
|
|
|
#self.new_account_info = None
|
2006-06-14 00:50:18 +02:00
|
|
|
self.bookmarks = []
|
2006-06-13 23:19:39 +02:00
|
|
|
|
2006-06-28 00:28:49 +02:00
|
|
|
#we don't need a password, but must be non-empty
|
2006-09-25 22:14:17 +02:00
|
|
|
self.password = 'zeroconf'
|
2006-06-28 00:28:49 +02:00
|
|
|
|
2006-09-20 01:07:54 +02:00
|
|
|
self.autoconnect = False
|
|
|
|
self.sync_with_global_status = True
|
|
|
|
self.no_log_for = False
|
|
|
|
|
2007-03-30 21:14:07 +02:00
|
|
|
self.pep_supported = False
|
2006-05-26 16:27:42 +02:00
|
|
|
# Do we continue connection when we get roster (send presence,get vcard...)
|
|
|
|
self.continue_connect_info = None
|
|
|
|
if USE_GPG:
|
|
|
|
self.gpg = GnuPG.GnuPG()
|
|
|
|
gajim.config.set('usegpg', True)
|
|
|
|
else:
|
|
|
|
gajim.config.set('usegpg', False)
|
|
|
|
|
2006-07-11 17:22:59 +02:00
|
|
|
self.get_config_values_or_default()
|
2006-09-29 19:52:21 +02:00
|
|
|
|
2006-09-15 05:30:52 +02:00
|
|
|
self.muc_jid = {} # jid of muc server for each transport type
|
|
|
|
self.vcard_supported = False
|
2006-07-11 17:22:59 +02:00
|
|
|
|
|
|
|
def get_config_values_or_default(self):
|
|
|
|
''' get name, host, port from config, or
|
|
|
|
create zeroconf account with default values'''
|
2006-10-12 02:58:01 +02:00
|
|
|
|
2006-09-25 22:14:17 +02:00
|
|
|
if not gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'name'):
|
2006-10-12 02:58:01 +02:00
|
|
|
gajim.log.debug('Creating zeroconf account')
|
2006-09-25 22:14:17 +02:00
|
|
|
gajim.config.add_per('accounts', gajim.ZEROCONF_ACC_NAME)
|
|
|
|
gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'autoconnect', True)
|
|
|
|
gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'no_log_for', '')
|
|
|
|
gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'password', 'zeroconf')
|
|
|
|
gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'sync_with_global_status', True)
|
|
|
|
|
2006-09-25 22:36:59 +02:00
|
|
|
gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'custom_port', 5298)
|
2006-09-25 22:14:17 +02:00
|
|
|
gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'is_zeroconf', True)
|
2007-07-27 18:00:29 +02:00
|
|
|
#XXX make sure host is US-ASCII
|
|
|
|
self.host = unicode(socket.gethostname())
|
|
|
|
gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'hostname', self.host)
|
2006-09-25 22:36:59 +02:00
|
|
|
self.port = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'custom_port')
|
|
|
|
self.autoconnect = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'autoconnect')
|
|
|
|
self.sync_with_global_status = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'sync_with_global_status')
|
|
|
|
self.no_log_for = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'no_log_for')
|
|
|
|
self.first = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_first_name')
|
|
|
|
self.last = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_last_name')
|
|
|
|
self.jabber_id = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_jabber_id')
|
|
|
|
self.email = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_email')
|
2006-10-12 02:58:01 +02:00
|
|
|
|
|
|
|
if not self.username:
|
|
|
|
self.username = unicode(getpass.getuser())
|
|
|
|
gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'name', self.username)
|
|
|
|
else:
|
|
|
|
self.username = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'name')
|
2006-05-26 16:27:42 +02:00
|
|
|
# END __init__
|
2006-09-25 22:14:17 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
def dispatch(self, event, data):
|
2006-09-30 20:23:47 +02:00
|
|
|
if gajim.handlers.has_key(event):
|
|
|
|
gajim.handlers[event](self.name, data)
|
2006-05-26 16:27:42 +02:00
|
|
|
|
|
|
|
def _reconnect(self):
|
2007-04-25 12:25:22 +02:00
|
|
|
# Do not try to reco while we are already trying
|
|
|
|
self.time_to_reconnect = None
|
2006-05-26 16:27:42 +02:00
|
|
|
gajim.log.debug('reconnect')
|
2006-05-28 01:57:43 +02:00
|
|
|
|
2007-04-25 16:32:32 +02:00
|
|
|
# signed = self.get_signed_msg(self.status)
|
|
|
|
self.connect(self.old_show, self.status)
|
2006-09-29 16:39:29 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
def quit(self, kill_core):
|
|
|
|
if kill_core and self.connected > 1:
|
2006-09-18 00:19:10 +02:00
|
|
|
self.disconnect()
|
2006-05-26 16:27:42 +02:00
|
|
|
|
2006-09-18 00:19:10 +02:00
|
|
|
def disable_account(self):
|
|
|
|
self.disconnect()
|
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
def test_gpg_passphrase(self, password):
|
|
|
|
self.gpg.passphrase = password
|
|
|
|
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
|
|
|
signed = self.gpg.sign('test', keyID)
|
|
|
|
self.gpg.password = None
|
|
|
|
return signed != 'BAD_PASSPHRASE'
|
|
|
|
|
|
|
|
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')
|
|
|
|
if self.connected < 2 and self.gpg.passphrase is None and \
|
|
|
|
not use_gpg_agent:
|
|
|
|
# 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
|
2006-05-31 01:13:36 +02:00
|
|
|
|
2006-06-13 23:19:39 +02:00
|
|
|
def _on_resolve_timeout(self):
|
|
|
|
if self.connected:
|
2006-10-02 22:45:49 +02:00
|
|
|
self.connection.resolve_all()
|
2006-06-14 00:42:37 +02:00
|
|
|
diffs = self.roster.getDiffs()
|
|
|
|
for key in diffs:
|
2006-06-28 00:28:49 +02:00
|
|
|
self.roster.setItem(key)
|
2006-10-02 16:15:51 +02:00
|
|
|
self.dispatch('ROSTER_INFO', (key, self.roster.getName(key),
|
|
|
|
'both', 'no', self.roster.getGroups(key)))
|
|
|
|
self.dispatch('NOTIFY', (key, self.roster.getStatus(key),
|
2007-05-13 09:10:12 +02:00
|
|
|
self.roster.getMessage(key), 'local', 0, None, 0, None))
|
2006-09-29 01:38:55 +02:00
|
|
|
#XXX open chat windows don't get refreshed (full name), add that
|
2006-06-13 23:19:39 +02:00
|
|
|
return self.call_resolve_timeout
|
|
|
|
|
|
|
|
# callbacks called from zeroconf
|
2006-05-31 01:13:36 +02:00
|
|
|
def _on_new_service(self,jid):
|
2006-07-27 22:36:21 +02:00
|
|
|
self.roster.setItem(jid)
|
2006-09-17 18:01:12 +02:00
|
|
|
self.dispatch('ROSTER_INFO', (jid, self.roster.getName(jid), 'both', 'no', self.roster.getGroups(jid)))
|
2007-05-13 09:10:12 +02:00
|
|
|
self.dispatch('NOTIFY', (jid, self.roster.getStatus(jid), self.roster.getMessage(jid), 'local', 0, None, 0, None))
|
2006-06-02 20:46:52 +02:00
|
|
|
|
2006-09-25 22:36:59 +02:00
|
|
|
def _on_remove_service(self, jid):
|
2006-06-02 20:46:52 +02:00
|
|
|
self.roster.delItem(jid)
|
2006-06-13 23:19:39 +02:00
|
|
|
# 'NOTIFY' (account, (jid, status, status message, resource, priority,
|
2007-05-13 09:10:12 +02:00
|
|
|
# keyID, timestamp, contact_nickname))
|
|
|
|
self.dispatch('NOTIFY', (jid, 'offline', '', 'local', 0, None, 0, None))
|
2006-06-13 23:19:39 +02:00
|
|
|
|
2006-09-25 22:36:59 +02:00
|
|
|
def _on_disconnected(self):
|
|
|
|
self.disconnect()
|
|
|
|
self.dispatch('STATUS', 'offline')
|
|
|
|
self.dispatch('CONNECTION_LOST',
|
|
|
|
(_('Connection with account "%s" has been lost') % self.name,
|
|
|
|
_('To continue sending and receiving messages, you will need to reconnect.')))
|
|
|
|
self.status = 'offline'
|
2006-10-03 00:41:48 +02:00
|
|
|
self.disconnect()
|
2006-09-25 22:36:59 +02:00
|
|
|
|
2007-04-25 12:25:22 +02:00
|
|
|
def _disconnectedReconnCB(self):
|
|
|
|
'''Called when we are disconnected. Comes from network manager for example
|
|
|
|
we don't try to reconnect, network manager will tell us when we can'''
|
|
|
|
if gajim.account_is_connected(self.name):
|
|
|
|
# we cannot change our status to offline or connecting
|
|
|
|
# after we auth to server
|
|
|
|
self.old_show = STATUS_LIST[self.connected]
|
|
|
|
self.connected = 0
|
|
|
|
self.dispatch('STATUS', 'offline')
|
|
|
|
# random number to show we wait network manager to send us a reconenct
|
|
|
|
self.time_to_reconnect = 5
|
|
|
|
self.on_purpose = False
|
|
|
|
|
2006-10-12 04:21:23 +02:00
|
|
|
def _on_name_conflictCB(self, alt_name):
|
|
|
|
self.disconnect()
|
|
|
|
self.dispatch('STATUS', 'offline')
|
|
|
|
self.dispatch('ZC_NAME_CONFLICT', alt_name)
|
|
|
|
|
|
|
|
def _on_error(self, message):
|
|
|
|
self.dispatch('ERROR', (_('Avahi error'), _("%s\nLink-local messaging might not work properly.") % message))
|
2006-11-06 22:30:39 +01:00
|
|
|
|
2006-10-03 00:41:48 +02:00
|
|
|
def connect(self, show = 'online', msg = ''):
|
2006-09-23 19:05:20 +02:00
|
|
|
self.get_config_values_or_default()
|
2006-10-02 22:45:49 +02:00
|
|
|
if not self.connection:
|
|
|
|
self.connection = client_zeroconf.ClientZeroconf(self)
|
|
|
|
if not self.connection.test_avahi():
|
|
|
|
self.dispatch('STATUS', 'offline')
|
|
|
|
self.status = 'offline'
|
|
|
|
self.dispatch('CONNECTION_LOST',
|
|
|
|
(_('Could not connect to "%s"') % self.name,
|
|
|
|
_('Please check if Avahi is installed.')))
|
2006-10-03 00:41:48 +02:00
|
|
|
self.disconnect()
|
2006-10-02 22:45:49 +02:00
|
|
|
return
|
2006-10-12 01:11:54 +02:00
|
|
|
result = self.connection.connect(show, msg)
|
|
|
|
if not result:
|
2006-10-03 00:41:48 +02:00
|
|
|
self.dispatch('STATUS', 'offline')
|
2006-10-02 22:45:49 +02:00
|
|
|
self.status = 'offline'
|
2006-10-12 01:11:54 +02:00
|
|
|
if result is False:
|
|
|
|
self.dispatch('CONNECTION_LOST',
|
|
|
|
(_('Could not start local service'),
|
|
|
|
_('Unable to bind to port %d.' % self.port)))
|
|
|
|
else: # result is None
|
|
|
|
self.dispatch('CONNECTION_LOST',
|
2006-10-03 00:41:48 +02:00
|
|
|
(_('Could not start local service'),
|
|
|
|
_('Please check if avahi-daemon is running.')))
|
|
|
|
self.disconnect()
|
2006-10-02 22:45:49 +02:00
|
|
|
return
|
|
|
|
else:
|
|
|
|
self.connection.announce()
|
|
|
|
self.roster = self.connection.getRoster()
|
|
|
|
self.dispatch('ROSTER', self.roster)
|
2006-09-23 19:05:20 +02:00
|
|
|
|
2006-10-02 22:45:49 +02:00
|
|
|
#display contacts already detected and resolved
|
|
|
|
for jid in self.roster.keys():
|
|
|
|
self.dispatch('ROSTER_INFO', (jid, self.roster.getName(jid), 'both', 'no', self.roster.getGroups(jid)))
|
2007-05-13 09:10:12 +02:00
|
|
|
self.dispatch('NOTIFY', (jid, self.roster.getStatus(jid), self.roster.getMessage(jid), 'local', 0, None, 0, None))
|
2006-08-01 02:44:51 +02:00
|
|
|
|
2006-10-02 22:45:49 +02:00
|
|
|
self.connected = STATUS_LIST.index(show)
|
2006-08-01 02:44:51 +02:00
|
|
|
|
2006-10-02 22:45:49 +02:00
|
|
|
# refresh all contacts data every five seconds
|
|
|
|
self.call_resolve_timeout = True
|
|
|
|
gobject.timeout_add(5000, self._on_resolve_timeout)
|
|
|
|
return True
|
2006-06-28 00:28:49 +02:00
|
|
|
|
|
|
|
def disconnect(self, on_purpose = False):
|
|
|
|
self.connected = 0
|
|
|
|
self.time_to_reconnect = None
|
|
|
|
if self.connection:
|
2006-10-02 22:45:49 +02:00
|
|
|
self.connection.disconnect()
|
2006-06-28 00:28:49 +02:00
|
|
|
self.connection = None
|
|
|
|
# stop calling the timeout
|
|
|
|
self.call_resolve_timeout = False
|
2006-10-03 00:41:48 +02:00
|
|
|
|
2006-10-02 22:45:49 +02:00
|
|
|
def reannounce(self):
|
2006-09-29 19:40:11 +02:00
|
|
|
if self.connected:
|
|
|
|
txt = {}
|
|
|
|
txt['1st'] = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_first_name')
|
|
|
|
txt['last'] = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_last_name')
|
|
|
|
txt['jid'] = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_jabber_id')
|
|
|
|
txt['email'] = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'zeroconf_email')
|
2006-10-02 22:45:49 +02:00
|
|
|
self.connection.reannounce(txt)
|
|
|
|
|
|
|
|
def update_details(self):
|
2006-10-02 16:15:51 +02:00
|
|
|
if self.connection:
|
|
|
|
port = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'custom_port')
|
2006-10-09 19:48:32 +02:00
|
|
|
if port != self.port:
|
|
|
|
self.port = port
|
|
|
|
last_msg = self.connection.last_msg
|
|
|
|
self.disconnect()
|
|
|
|
if not self.connect(self.status, last_msg):
|
|
|
|
return
|
|
|
|
if self.status != 'invisible':
|
|
|
|
self.connection.announce()
|
2006-10-02 22:45:49 +02:00
|
|
|
else:
|
|
|
|
self.reannounce()
|
2006-10-02 16:15:51 +02:00
|
|
|
|
2007-04-22 21:45:19 +02:00
|
|
|
def change_status(self, show, msg, sync = False, auto = False):
|
2006-05-26 16:27:42 +02:00
|
|
|
if not show in STATUS_LIST:
|
|
|
|
return -1
|
2006-09-23 19:05:20 +02:00
|
|
|
self.status = show
|
2006-08-02 02:04:47 +02:00
|
|
|
|
2006-08-01 02:44:51 +02:00
|
|
|
check = True #to check for errors from zeroconf
|
2006-05-29 21:57:39 +02:00
|
|
|
# 'connect'
|
2006-05-26 16:27:42 +02:00
|
|
|
if show != 'offline' and not self.connected:
|
2006-10-03 00:41:48 +02:00
|
|
|
if not self.connect(show, msg):
|
2006-10-02 22:45:49 +02:00
|
|
|
return
|
2006-05-29 17:36:18 +02:00
|
|
|
if show != 'invisible':
|
2006-10-02 22:45:49 +02:00
|
|
|
check = self.connection.announce()
|
2006-05-29 17:36:18 +02:00
|
|
|
else:
|
2006-10-02 22:45:49 +02:00
|
|
|
self.connected = STATUS_LIST.index(show)
|
2006-05-26 16:27:42 +02:00
|
|
|
|
2006-05-29 21:57:39 +02:00
|
|
|
# 'disconnect'
|
2006-05-26 16:27:42 +02:00
|
|
|
elif show == 'offline' and self.connected:
|
2006-05-29 21:57:39 +02:00
|
|
|
self.disconnect()
|
2007-04-25 12:25:22 +02:00
|
|
|
self.time_to_reconnect = None
|
2006-09-15 05:30:52 +02:00
|
|
|
|
2006-05-28 01:57:43 +02:00
|
|
|
# update status
|
2006-05-26 16:27:42 +02:00
|
|
|
elif show != 'offline' and self.connected:
|
|
|
|
was_invisible = self.connected == STATUS_LIST.index('invisible')
|
|
|
|
self.connected = STATUS_LIST.index(show)
|
|
|
|
if show == 'invisible':
|
2006-10-02 22:45:49 +02:00
|
|
|
check = check and self.connection.remove_announce()
|
2006-08-01 02:44:51 +02:00
|
|
|
elif was_invisible:
|
2006-11-06 22:30:39 +01:00
|
|
|
if not self.connected:
|
|
|
|
check = check and self.connect(show, msg)
|
2006-10-02 22:45:49 +02:00
|
|
|
check = check and self.connection.announce()
|
2006-08-01 02:44:51 +02:00
|
|
|
if self.connection and not show == 'invisible':
|
2006-10-02 22:45:49 +02:00
|
|
|
check = check and self.connection.set_show_msg(show, msg)
|
2006-08-01 02:44:51 +02:00
|
|
|
|
2006-09-17 17:49:47 +02:00
|
|
|
#stay offline when zeroconf does something wrong
|
2006-08-01 02:44:51 +02:00
|
|
|
if check:
|
|
|
|
self.dispatch('STATUS', show)
|
|
|
|
else:
|
2006-11-06 22:30:39 +01:00
|
|
|
# show notification that avahi or system bus is down
|
2006-08-01 02:44:51 +02:00
|
|
|
self.dispatch('STATUS', 'offline')
|
2006-09-23 19:05:20 +02:00
|
|
|
self.status = 'offline'
|
2006-09-25 22:36:59 +02:00
|
|
|
self.dispatch('CONNECTION_LOST',
|
|
|
|
(_('Could not change status of account "%s"') % self.name,
|
|
|
|
_('Please check if avahi-daemon is running.')))
|
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
def get_status(self):
|
|
|
|
return STATUS_LIST[self.connected]
|
|
|
|
|
|
|
|
def send_message(self, jid, msg, keyID, type = 'chat', subject='',
|
2007-06-16 23:31:19 +02:00
|
|
|
chatstate = None, msg_id = None, composing_xep = None, resource = None,
|
2006-09-14 19:16:01 +02:00
|
|
|
user_nick = None):
|
2006-06-28 00:28:49 +02:00
|
|
|
fjid = jid
|
2007-04-22 12:32:26 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
if not msg and chatstate is None:
|
|
|
|
return
|
2007-04-22 12:32:26 +02:00
|
|
|
|
2006-11-06 22:30:39 +01:00
|
|
|
if self.status in ('invisible', 'offline'):
|
|
|
|
self.dispatch('MSGERROR', [unicode(jid), '-1', _('You are not connected or not visible to others. Your message could not be sent.'), None, None])
|
|
|
|
return
|
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
msgtxt = msg
|
|
|
|
msgenc = ''
|
|
|
|
if keyID and USE_GPG:
|
2007-04-22 12:32:26 +02:00
|
|
|
# encrypt
|
|
|
|
msgenc, error = self.gpg.encrypt(msg, [keyID])
|
|
|
|
if msgenc and not error:
|
2006-05-26 16:27:42 +02:00
|
|
|
msgtxt = '[This message is encrypted]'
|
|
|
|
lang = os.getenv('LANG')
|
|
|
|
if lang is not None or lang != 'en': # we're not english
|
|
|
|
msgtxt = _('[This message is encrypted]') +\
|
|
|
|
' ([This message is encrypted])' # one in locale and one en
|
2007-04-22 12:32:26 +02:00
|
|
|
else:
|
|
|
|
# Encryption failed, do not send message
|
|
|
|
tim = time.localtime()
|
|
|
|
self.dispatch('MSGNOTSENT', (jid, error, msgtxt, tim))
|
|
|
|
return 3
|
2006-06-28 00:28:49 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
if type == 'chat':
|
|
|
|
msg_iq = common.xmpp.Message(to = fjid, body = msgtxt, typ = type)
|
2007-04-22 12:32:26 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
else:
|
|
|
|
if subject:
|
|
|
|
msg_iq = common.xmpp.Message(to = fjid, body = msgtxt,
|
|
|
|
typ = 'normal', subject = subject)
|
|
|
|
else:
|
|
|
|
msg_iq = common.xmpp.Message(to = fjid, body = msgtxt,
|
|
|
|
typ = 'normal')
|
2006-06-28 00:28:49 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
if msgenc:
|
|
|
|
msg_iq.setTag(common.xmpp.NS_ENCRYPTED + ' x').setData(msgenc)
|
2007-04-22 12:32:26 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
# chatstates - if peer supports jep85 or jep22, send chatstates
|
|
|
|
# please note that the only valid tag inside a message containing a <body>
|
|
|
|
# tag is the active event
|
|
|
|
if chatstate is not None:
|
2007-06-16 23:31:19 +02:00
|
|
|
if composing_xep == 'XEP-0085' or not composing_xep:
|
2006-05-26 16:27:42 +02:00
|
|
|
# JEP-0085
|
|
|
|
msg_iq.setTag(chatstate, namespace = common.xmpp.NS_CHATSTATES)
|
2007-06-16 23:31:19 +02:00
|
|
|
if composing_xep == 'XEP-0022' or not composing_xep:
|
2006-05-26 16:27:42 +02:00
|
|
|
# JEP-0022
|
|
|
|
chatstate_node = msg_iq.setTag('x', namespace = common.xmpp.NS_EVENT)
|
|
|
|
if not msgtxt: # when no <body>, add <id>
|
|
|
|
if not msg_id: # avoid putting 'None' in <id> tag
|
|
|
|
msg_id = ''
|
|
|
|
chatstate_node.setTagData('id', msg_id)
|
|
|
|
# when msgtxt, requests JEP-0022 composing notification
|
|
|
|
if chatstate is 'composing' or msgtxt:
|
|
|
|
chatstate_node.addChild(name = 'composing')
|
2007-04-22 12:32:26 +02:00
|
|
|
|
2006-11-06 22:30:39 +01:00
|
|
|
if not self.connection.send(msg_iq, msg != None):
|
|
|
|
return
|
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
no_log_for = gajim.config.get_per('accounts', self.name, 'no_log_for')
|
|
|
|
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)
|
2006-06-28 00:28:49 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
self.dispatch('MSGSENT', (jid, msg, keyID))
|
2006-06-28 00:28:49 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
def send_stanza(self, stanza):
|
2006-05-28 01:57:43 +02:00
|
|
|
# send a stanza untouched
|
2006-05-26 16:27:42 +02:00
|
|
|
if not self.connection:
|
|
|
|
return
|
2006-11-06 22:30:39 +01:00
|
|
|
self.connection.send(stanza)
|
2006-05-26 16:27:42 +02:00
|
|
|
|
|
|
|
def ack_subscribed(self, jid):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (ack_subscribed)')
|
2006-05-26 16:27:42 +02:00
|
|
|
|
|
|
|
def ack_unsubscribed(self, jid):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (ack_unsubscribed)')
|
2006-05-26 16:27:42 +02:00
|
|
|
|
|
|
|
def request_subscription(self, jid, msg = '', name = '', groups = [],
|
|
|
|
auto_auth = False):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (request_subscription)')
|
2006-05-26 16:27:42 +02:00
|
|
|
|
|
|
|
def send_authorization(self, jid):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (send_authorization)')
|
2006-05-26 16:27:42 +02:00
|
|
|
|
|
|
|
def refuse_authorization(self, jid):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (refuse_authorization)')
|
2006-05-26 16:27:42 +02:00
|
|
|
|
|
|
|
def unsubscribe(self, jid, remove_auth = True):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (unsubscribe)')
|
2006-05-26 16:27:42 +02:00
|
|
|
|
|
|
|
def unsubscribe_agent(self, agent):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (unsubscribe_agent)')
|
2006-05-26 16:27:42 +02:00
|
|
|
|
2006-06-02 20:46:52 +02:00
|
|
|
def update_contact(self, jid, name, groups):
|
2006-05-26 16:27:42 +02:00
|
|
|
if self.connection:
|
|
|
|
self.connection.getRoster().setItem(jid = jid, name = name,
|
|
|
|
groups = groups)
|
|
|
|
|
|
|
|
def new_account(self, name, config, sync = False):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (new_account)')
|
2006-05-26 16:27:42 +02:00
|
|
|
|
|
|
|
def _on_new_account(self, con = None, con_type = None):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (_on_new_account)')
|
2006-05-26 16:27:42 +02:00
|
|
|
|
|
|
|
def account_changed(self, new_name):
|
|
|
|
self.name = new_name
|
|
|
|
|
|
|
|
def request_last_status_time(self, jid, resource):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (request_last_status_time)')
|
2006-09-29 16:39:29 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
def request_os_info(self, jid, resource):
|
2006-09-29 16:39:29 +02:00
|
|
|
gajim.log.debug('This should not happen (request_os_info)')
|
2006-05-26 16:27:42 +02:00
|
|
|
|
|
|
|
def get_settings(self):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (get_settings)')
|
2006-05-26 16:27:42 +02:00
|
|
|
|
|
|
|
def get_bookmarks(self):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (get_bookmarks)')
|
2006-05-28 01:57:43 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
def store_bookmarks(self):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (store_bookmarks)')
|
2006-07-11 20:17:25 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
def get_metacontacts(self):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (get_metacontacts)')
|
2006-07-11 20:17:25 +02:00
|
|
|
|
2006-05-26 16:27:42 +02:00
|
|
|
def send_agent_status(self, agent, ptype):
|
2006-09-15 05:30:52 +02:00
|
|
|
gajim.log.debug('This should not happen (send_agent_status)')
|
2006-05-26 16:27:42 +02:00
|
|
|
|
|
|
|
def gpg_passphrase(self, passphrase):
|
|
|
|
if USE_GPG:
|
|
|
|
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
|
|
|
if use_gpg_agent:
|
|
|
|
self.gpg.passphrase = None
|
|
|
|
else:
|
|
|
|
self.gpg.passphrase = passphrase
|
|
|
|
|
|
|
|
def ask_gpg_keys(self):
|
|
|
|
if USE_GPG:
|
|
|
|
keys = self.gpg.get_keys()
|
|
|
|
return keys
|
|
|
|
return None
|
|
|
|
|
|
|
|
def ask_gpg_secrete_keys(self):
|
|
|
|
if USE_GPG:
|
|
|
|
keys = self.gpg.get_secret_keys()
|
|
|
|
return keys
|
|
|
|
return None
|
|
|
|
|
2006-09-18 00:57:41 +02:00
|
|
|
def _event_dispatcher(self, realm, event, data):
|
|
|
|
if realm == '':
|
|
|
|
if event == common.xmpp.transports.DATA_RECEIVED:
|
|
|
|
self.dispatch('STANZA_ARRIVED', unicode(data, errors = 'ignore'))
|
|
|
|
elif event == common.xmpp.transports.DATA_SENT:
|
|
|
|
self.dispatch('STANZA_SENT', unicode(data))
|
|
|
|
|
2006-05-29 21:57:39 +02:00
|
|
|
# END ConnectionZeroconf
|