Skip to content
Snippets Groups Projects
gajim.py 10.8 KiB
Newer Older
Yann Leboulanger's avatar
Yann Leboulanger committed
##	common/gajim.py
##
nkour's avatar
nkour committed
## Copyright (C) 2003-2006 Yann Le Boulanger <asterix@lagaule.org>
## 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>
Yann Leboulanger's avatar
Yann Leboulanger committed
##
## 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.
##

nkour's avatar
nkour committed
import tempfile
Yann Leboulanger's avatar
Yann Leboulanger committed
import logging
from contacts import Contacts
sb's avatar
sb committed
from events import Events
Yann Leboulanger's avatar
Yann Leboulanger committed

interface = None # The actual interface (the gtk one for the moment)
sb's avatar
sb committed
version = config.get('version')
dkirov's avatar
dkirov committed
connections = {} # 'account name': 'account (connection.Connection) instance'

h = logging.StreamHandler()
f = logging.Formatter('%(asctime)s %(name)s: %(message)s', '%d %b %Y %H:%M:%S')
h.setFormatter(f)
Yann Leboulanger's avatar
Yann Leboulanger committed
log = logging.getLogger('Gajim')
log.addHandler(h)

import logger
logger = logger.Logger() # init the logger
	DATA_DIR = os.path.join('..', 'data')
		# Documents and Settings\[User Name]\Application Data\Gajim
nkour's avatar
nkour committed
		LOGPATH = os.path.join(os.environ['appdata'], 'Gajim', 'Logs') # deprecated
nkour's avatar
nkour committed
		VCARD_PATH = os.path.join(os.environ['appdata'], 'Gajim', 'Vcards')
nkour's avatar
nkour committed
		AVATAR_PATH = os.path.join(os.environ['appdata'], 'Gajim', 'Avatars')
		MY_EMOTS_PATH = os.path.join(os.environ['appdata'], 'Gajim', 'Emoticons')
nkour's avatar
nkour committed
		LOGPATH = 'Logs' # deprecated
nkour's avatar
nkour committed
		VCARD_PATH = 'Vcards'
nkour's avatar
nkour committed
		AVATAR_PATH = 'Avatars'
nkour's avatar
nkour committed
else: # Unices
	DATA_DIR = '../data'
	LOGPATH = os.path.expanduser('~/.gajim/logs') # deprecated
nkour's avatar
nkour committed
	VCARD_PATH = os.path.expanduser('~/.gajim/vcards')
nkour's avatar
nkour committed
	AVATAR_PATH = os.path.expanduser('~/.gajim/avatars')
	MY_EMOTS_PATH = os.path.expanduser('~/.gajim/emoticons')
nkour's avatar
nkour committed

HOME_DIR = os.path.expanduser('~')
nkour's avatar
nkour committed
TMP = tempfile.gettempdir()

try:
	LOGPATH = LOGPATH.decode(sys.getfilesystemencoding())
nkour's avatar
nkour committed
	VCARD_PATH = VCARD_PATH.decode(sys.getfilesystemencoding())
	TMP = TMP.decode(sys.getfilesystemencoding())
	AVATAR_PATH = AVATAR_PATH.decode(sys.getfilesystemencoding())
	MY_EMOTS_PATH = MY_EMOTS_PATH.decode(sys.getfilesystemencoding())
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
	LANG = 'en'
else:
	LANG = LANG[:2] # en, fr, el etc..
sb's avatar
sb committed
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()
Yann Leboulanger's avatar
Yann Leboulanger committed
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}
sb's avatar
sb committed
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
sb's avatar
sb committed
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
sb's avatar
sb committed
# 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
nkour's avatar
nkour committed
SHOW_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
	'invisible']
# zeroconf account name
ZEROCONF_ACC_NAME = 'Local'
dkirov's avatar
dkirov committed
priority_dict = {}
for status in ('online', 'chat', 'away', 'xa', 'dnd', 'invisible'):
	priority_dict[status] = config.get('autopriority' + status)
def get_nick_from_jid(jid):
	pos = jid.find('@')
	return jid[:pos]

def get_server_from_jid(jid):
nkour's avatar
nkour committed
	pos = jid.find('@') + 1 # after @
def get_nick_from_fjid(jid):
	# fake jid is the jid for a contact in a room
	# gaim@conference.jabber.no/nick/nick-continued
def get_room_name_and_server_from_room_jid(jid):
	room_name = get_nick_from_jid(jid)
	server = get_server_from_jid(jid)
	return room_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)

def get_real_jid_from_fjid(account, fjid):
	room_jid, nick = get_room_and_nick_from_fjid(fjid)
	if not nick: # It's not a fake_jid, it is a real jid
Yann Leboulanger's avatar
Yann Leboulanger committed
		return fjid # we return the real jid
	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
nicfit's avatar
nicfit committed
		gc_contact = contacts.get_gc_contact(account, room_jid, nick)
		if not gc_contact:
nicfit's avatar
nicfit committed
		# gc_contact.jid is None when it's not a real jid (we don't know real jid)
		real_jid = gc_contact.jid
def get_room_from_fjid(jid):
	return get_room_and_nick_from_fjid(jid)[0]
def get_contact_name_from_jid(account, jid):
nicfit's avatar
nicfit committed
	c = contacts.get_first_contact_from_jid(account, jid)
	return c.name
nkour's avatar
nkour committed
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
	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())
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
dkirov's avatar
dkirov committed
	for account in accounts:
		if account_is_connected(account):
			connected_accounts = connected_accounts + 1
	return connected_accounts

dkirov's avatar
dkirov committed
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

nkour's avatar
nkour committed
def get_transport_name_from_jid(jid, use_config_setting = True):
	'''returns 'aim', 'gg', 'irc' etc
	if JID is not from transport returns None'''
	#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')):
nkour's avatar
nkour committed
		return
sb's avatar
sb committed

sb's avatar
sb committed
	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]

	if host == 'aim':
nkour's avatar
nkour committed
		return 'aim'
sb's avatar
sb committed
		return 'gadu-gadu'
nkour's avatar
nkour committed
		return 'irc'
nkour's avatar
nkour committed
		return 'icq'
	elif host == 'jit':
		return 'icq'
nkour's avatar
nkour committed
		return 'msn'
nkour's avatar
nkour committed
		return 'sms'
nkour's avatar
nkour committed
		return 'tlen'
nkour's avatar
nkour committed
		return 'yahoo'
nkour's avatar
nkour committed
	else:
		return None
nkour's avatar
nkour committed

def jid_is_transport(jid):
	# if not '@' or '@' starts the jid then it is transport
	if jid.find('@') <= 0:
		return True
Yann Leboulanger's avatar
Yann Leboulanger committed
	return False

def get_jid_from_account(account_name):
nkour's avatar
nkour committed
	'''return the jid we use in the given account'''
	name = config.get_per('accounts', account_name, 'name')
nkour's avatar
nkour committed
	hostname = config.get_per('accounts', account_name, 'hostname')
	jid = name + '@' + hostname
	return jid
nkour's avatar
nkour committed
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
dkirov's avatar
dkirov committed

def get_priority(account, show):
	'''return the priority an account must have'''
	if not show:
		show = 'online'
	if show in priority_dict and config.get_per('accounts', account,
	'adjust_priority_with_status'):
		return priority_dict[show]
	return config.get_per('accounts', account, 'priority')