gajim-plural/src/common/gajim.py

356 lines
11 KiB
Python
Raw Normal View History

2005-04-15 19:02:23 +02:00
## common/gajim.py
##
## Copyright (C) 2003-2007 Yann Le Boulanger <asterix@lagaule.org>
2006-04-04 19:09:29 +02:00
## Copyright (C) 2005-2006 Nikos Kouremenos <kourem@gmail.com>
## Copyright (C) 2005-2006 Dimitur Kirov <dkirov@gmail.com>
## Copyright (C) 2005-2006 Travis Shirk <travis@pobox.com>
2005-04-15 19:02:23 +02:00
##
## This file is part of Gajim.
##
## Gajim is free software; you can redistribute it and/or modify
2005-04-15 19:02:23 +02:00
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 3 only.
2005-04-15 19:02:23 +02:00
##
## Gajim is distributed in the hope that it will be useful,
2005-04-15 19:02:23 +02:00
## 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 Gajim. If not, see <http://www.gnu.org/licenses/>.
##
2005-04-15 19:02:23 +02:00
import sys
2005-04-15 19:02:23 +02:00
import logging
import locale
import config
from contacts import Contacts
from events import Events
2005-04-15 19:02:23 +02:00
2006-10-11 20:27:55 +02:00
try:
import defs
except ImportError:
print >> sys.stderr, '''defs.py is missing!
If you start gajim from svn:
* Make sure you have GNU autotools installed.
This includes the following packages:
automake >= 1.8
autoconf >= 2.59
intltool-0.35
libtool
* Run
$ sh autogen.sh
* Optionally, install gajim
$ make
$ sudo make install
**** Note for translators ****
You can get the latest string updates, by running:
$ cd po/
$ make update-po
'''
2006-10-11 20:27:55 +02:00
sys.exit(1)
interface = None # The actual interface (the gtk one for the moment)
config = config.Config()
version = config.get('version')
connections = {} # 'account name': 'account (connection.Connection) instance'
verbose = False
2005-05-17 22:31:43 +02:00
h = logging.StreamHandler()
f = logging.Formatter('%(asctime)s %(name)s: %(message)s', '%d %b %Y %H:%M:%S')
h.setFormatter(f)
2005-04-15 19:02:23 +02:00
log = logging.getLogger('Gajim')
2005-05-17 22:31:43 +02:00
log.addHandler(h)
import logger
logger = logger.Logger() # init the logger
2005-11-22 15:46:37 +01:00
import configpaths
gajimpaths = configpaths.gajimpaths
2005-11-22 12:54:33 +01:00
LOGPATH = gajimpaths['LOG'] # deprecated
VCARD_PATH = gajimpaths['VCARD']
AVATAR_PATH = gajimpaths['AVATAR']
MY_EMOTS_PATH = gajimpaths['MY_EMOTS']
MY_ICONSETS_PATH = gajimpaths['MY_ICONSETS']
TMP = gajimpaths['TMP']
DATA_DIR = gajimpaths['DATA']
HOME_DIR = gajimpaths['HOME']
2006-02-10 14:03:32 +01:00
try:
LANG = locale.getdefaultlocale()[0] # en_US, fr_FR, el_GR etc..
except (ValueError, locale.Error):
# unknown locale, use en is better than fail
LANG = None
if LANG is None:
2005-06-25 09:37:14 +02:00
LANG = 'en'
else:
LANG = LANG[:2] # en, fr, el etc..
gmail_domains = ['gmail.com', 'googlemail.com']
transport_type = {} # list the type of transport
last_message_time = {} # list of time of the latest incomming message
# {acct1: {jid1: time1, jid2: time2}, }
encrypted_chats = {} # list of encrypted chats {acct1: [jid1, jid2], ..}
contacts = Contacts()
2005-11-14 11:51:32 +01:00
gc_connected = {} # tell if we are connected to the room or not {acct: {room_jid: True}}
gc_passwords = {} # list of the pass required to enter a room {room_jid: password}
automatic_rooms = {} # list of rooms that must be automaticaly configured and for which we have a list of invities {account: {room_jid: {'invities': []}}}
groups = {} # list of groups
newly_added = {} # list of contacts that has just signed in
to_be_removed = {} # list of contacts that has just signed out
events = Events()
nicks = {} # list of our nick names in each account
# should we block 'contact signed in' notifications for this account?
# this is only for the first 30 seconds after we change our show
# to something else than offline
# can also contain account/transport_jid to block notifications for contacts
# from this transport
block_signed_in_notifications = {}
con_types = {} # type of each connection (ssl, tls, tcp, ...)
sleeper_state = {} # whether we pass auto away / xa or not
#'off': don't use sleeper for this account
#'online': online and use sleeper
#'autoaway': autoaway and use sleeper
#'autoxa': autoxa and use sleeper
status_before_autoaway = {}
# jid of transport contacts for which we need to ask avatar when transport will
# be online
transport_avatar = {} # {transport_jid: [jid_list]}
# Is Gnome configured to activate on single click ?
single_click = False
2005-08-16 21:26:11 +02:00
SHOW_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
'invisible', 'error']
# zeroconf account name
ZEROCONF_ACC_NAME = 'Local'
priority_dict = {}
for status in ('online', 'chat', 'away', 'xa', 'dnd', 'invisible'):
priority_dict[status] = config.get('autopriority' + status)
HAVE_PYCRYPTO = True
try:
import Crypto
except ImportError:
HAVE_PYCRYPTO = False
HAVE_PYSEXY = True
try:
import sexy
except ImportError:
HAVE_PYSEXY = False
def get_nick_from_jid(jid):
pos = jid.find('@')
return jid[:pos]
def get_server_from_jid(jid):
2005-09-11 19:06:37 +02:00
pos = jid.find('@') + 1 # after @
return jid[pos:]
def get_nick_from_fjid(jid):
# fake jid is the jid for a contact in a room
# gaim@conference.jabber.no/nick/nick-continued
return jid.split('/', 1)[1]
2006-10-09 02:27:03 +02:00
def get_name_and_server_from_jid(jid):
name = get_nick_from_jid(jid)
server = get_server_from_jid(jid)
2006-10-09 02:27:03 +02:00
return name, server
def get_room_and_nick_from_fjid(jid):
# fake jid is the jid for a contact in a room
# gaim@conference.jabber.no/nick/nick-continued
# return ('gaim@conference.jabber.no', 'nick/nick-continued')
l = jid.split('/', 1)
if len(l) == 1: # No nick
l.append('')
return l
def get_real_jid_from_fjid(account, fjid):
'''returns real jid or returns None
if we don't know the real jid'''
room_jid, nick = get_room_and_nick_from_fjid(fjid)
if not nick: # It's not a fake_jid, it is a real jid
2005-11-02 12:13:05 +01:00
return fjid # we return the real jid
real_jid = fjid
if interface.msg_win_mgr.get_control(room_jid, account):
# It's a pm, so if we have real jid it's in contact.jid
gc_contact = contacts.get_gc_contact(account, room_jid, nick)
if not gc_contact:
return
# gc_contact.jid is None when it's not a real jid (we don't know real jid)
real_jid = gc_contact.jid
return real_jid
def get_room_from_fjid(jid):
return get_room_and_nick_from_fjid(jid)[0]
def get_contact_name_from_jid(account, jid):
c = contacts.get_first_contact_from_jid(account, jid)
return c.name
2005-07-22 02:34:08 +02:00
def get_jid_without_resource(jid):
return jid.split('/')[0]
def construct_fjid(room_jid, nick):
''' nick is in utf8 (taken from treeview); room_jid is in unicode'''
# fake jid is the jid for a contact in a room
# gaim@conference.jabber.org/nick
if isinstance(nick, str):
nick = unicode(nick, 'utf-8')
return room_jid + '/' + nick
def get_resource_from_jid(jid):
2005-10-07 15:45:58 +02:00
jids = jid.split('/', 1)
if len(jids) > 1:
return jids[1] # abc@doremi.org/res/res-continued
else:
return ''
'''\
[15:34:28] <asterix> we should add contact.fake_jid I think
[15:34:46] <asterix> so if we know real jid, it wil be in contact.jid, or we look in contact.fake_jid
[15:32:54] <asterix> they can have resource if we know the real jid
[15:33:07] <asterix> and that resource is in contact.resource
'''
def get_number_of_accounts():
'''returns the number of ALL accounts'''
return len(connections.keys())
2005-08-26 15:11:20 +02:00
def get_number_of_connected_accounts(accounts_list = None):
'''returns the number of CONNECTED accounts
you can optionally pass an accounts_list
and if you do those will be checked, else all will be checked'''
connected_accounts = 0
if accounts_list is None:
accounts = connections.keys()
else:
accounts = accounts_list
for account in accounts:
if account_is_connected(account):
connected_accounts = connected_accounts + 1
return connected_accounts
def account_is_connected(account):
if account not in connections:
return False
if connections[account].connected > 1: # 0 is offline, 1 is connecting
return True
else:
return False
def account_is_disconnected(account):
return not account_is_connected(account)
def get_number_of_securely_connected_accounts():
'''returns the number of the accounts that are SSL/TLS connected'''
num_of_secured = 0
for account in connections:
if account_is_securely_connected(account):
num_of_secured += 1
return num_of_secured
def account_is_securely_connected(account):
if account in con_types and con_types[account] in ('tls', 'ssl'):
return True
else:
return False
2005-08-26 15:15:16 +02:00
def get_transport_name_from_jid(jid, use_config_setting = True):
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 04:17:36 +01:00
'''returns 'aim', 'gg', 'irc' etc
if JID is not from transport returns None'''
2005-08-26 16:44:46 +02:00
#FIXME: jid can be None! one TB I saw had this problem:
# in the code block # it is a groupchat presence in handle_event_notify
# jid was None. Yann why?
if not jid or (use_config_setting and not config.get('use_transports_iconsets')):
2005-08-26 15:11:20 +02:00
return
host = get_server_from_jid(jid)
if host in transport_type:
return transport_type[host]
# host is now f.e. icq.foo.org or just icq (sometimes on hacky transports)
host_splitted = host.split('.')
if len(host_splitted) != 0:
# now we support both 'icq.' and 'icq' but not icqsucks.org
host = host_splitted[0]
2006-11-26 13:56:44 +01:00
if host in ('aim', 'irc', 'icq', 'msn', 'sms', 'tlen', 'weather', 'yahoo'):
return host
elif host == 'gg':
return 'gadu-gadu'
elif host == 'jit':
return 'icq'
2005-10-24 16:32:13 +02:00
else:
return None
2005-08-26 15:11:20 +02:00
def jid_is_transport(jid):
# if not '@' or '@' starts the jid then it is transport
if jid.find('@') <= 0:
return True
2006-05-01 15:26:07 +02:00
return False
def get_jid_from_account(account_name):
2006-02-26 15:13:13 +01:00
'''return the jid we use in the given account'''
name = config.get_per('accounts', account_name, 'name')
2005-09-09 23:03:53 +02:00
hostname = config.get_per('accounts', account_name, 'hostname')
jid = name + '@' + hostname
return jid
2006-02-26 15:13:13 +01:00
def get_our_jids():
'''returns a list of the jids we use in our accounts'''
our_jids = list()
for account in contacts.get_accounts():
our_jids.append(get_jid_from_account(account))
return our_jids
def get_hostname_from_account(account_name, use_srv = False):
'''returns hostname (if custom hostname is used, that is returned)'''
if use_srv and connections[account_name].connected_hostname:
return connections[account_name].connected_hostname
if config.get_per('accounts', account_name, 'use_custom_host'):
return config.get_per('accounts', account_name, 'custom_host')
return config.get_per('accounts', account_name, 'hostname')
def get_notification_image_prefix(jid):
'''returns the prefix for the notification images'''
transport_name = get_transport_name_from_jid(jid)
if transport_name in ('aim', 'icq', 'msn', 'yahoo'):
prefix = transport_name
else:
prefix = 'jabber'
return prefix
def get_name_from_jid(account, jid):
'''returns from JID's shown name and if no contact returns jids'''
contact = contacts.get_first_contact_from_jid(account, jid)
if contact:
actor = contact.get_shown_name()
else:
actor = jid
return actor
def get_priority(account, show):
'''return the priority an account must have'''
if not show:
show = 'online'
2006-10-09 02:27:03 +02:00
if show in ('online', 'chat', 'away', 'xa', 'dnd', 'invisible') and \
config.get_per('accounts', account, 'adjust_priority_with_status'):
return config.get_per('accounts', account, 'autopriority_' + show)
return config.get_per('accounts', account, 'priority')