root/branches/gajim_0.11.1/src/common/gajim.py

Revision 7787, 10.4 kB (checked in by asterix, 23 months ago)

merge changeset from trunk except pyopenssl stuff

  • Property svn:eol-style set to LF
Line 
1##      common/gajim.py
2##
3## Copyright (C) 2003-2006 Yann Le Boulanger <asterix@lagaule.org>
4## Copyright (C) 2005-2006 Nikos Kouremenos <kourem@gmail.com>
5## Copyright (C) 2005-2006 Dimitur Kirov <dkirov@gmail.com>
6## Copyright (C) 2005-2006 Travis Shirk <travis@pobox.com>
7##
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published
10## by the Free Software Foundation; version 2 only.
11##
12## This program is distributed in the hope that it will be useful,
13## but WITHOUT ANY WARRANTY; without even the implied warranty of
14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15## GNU General Public License for more details.
16##
17
18import sys
19import logging
20import locale
21
22import config
23from contacts import Contacts
24from events import Events
25
26try:
27        import defs
28except ImportError:
29        print >> sys.stderr, '''defs.py is missing!
30
31If you start gajim from svn:
32 * Make sure you have GNU autotools installed.
33   This includes the following packages:
34    automake >= 1.8
35    autoconf >= 2.59
36    intltool-0.35
37    libtool
38 * Run
39    $ sh autogen.sh
40 * Optionally, install gajim
41    $ make
42    $ sudo make install
43
44**** Note for translators ****
45 You can get the latest string updates, by running:
46    $ cd po/
47    $ make update-po
48
49'''
50        sys.exit(1)
51
52interface = None # The actual interface (the gtk one for the moment)
53config = config.Config()
54version = config.get('version')
55connections = {} # 'account name': 'account (connection.Connection) instance'
56verbose = False
57
58h = logging.StreamHandler()
59f = logging.Formatter('%(asctime)s %(name)s: %(message)s', '%d %b %Y %H:%M:%S')
60h.setFormatter(f)
61log = logging.getLogger('Gajim')
62log.addHandler(h)
63
64import logger
65logger = logger.Logger() # init the logger
66
67import configpaths
68gajimpaths = configpaths.gajimpaths
69
70LOGPATH = gajimpaths['LOG'] # deprecated
71VCARD_PATH = gajimpaths['VCARD']
72AVATAR_PATH = gajimpaths['AVATAR']
73MY_EMOTS_PATH = gajimpaths['MY_EMOTS']
74TMP = gajimpaths['TMP']
75DATA_DIR = gajimpaths['DATA']
76HOME_DIR = gajimpaths['HOME']
77
78try:
79        LANG = locale.getdefaultlocale()[0] # en_US, fr_FR, el_GR etc..
80except (ValueError, locale.Error):
81        # unknown locale, use en is better than fail
82        LANG = None
83if LANG is None:
84        LANG = 'en'
85else:
86        LANG = LANG[:2] # en, fr, el etc..
87
88gmail_domains = ['gmail.com', 'googlemail.com']
89
90transport_type = {} # list the type of transport
91
92last_message_time = {} # list of time of the latest incomming message
93                                                        # {acct1: {jid1: time1, jid2: time2}, }
94encrypted_chats = {} # list of encrypted chats {acct1: [jid1, jid2], ..}
95
96contacts = Contacts()
97gc_connected = {} # tell if we are connected to the room or not {acct: {room_jid: True}}
98gc_passwords = {} # list of the pass required to enter a room {room_jid: password}
99automatic_rooms = {} # list of rooms that must be automaticaly configured and for which we have a list of invities {account: {room_jid: {'invities': []}}}
100
101groups = {} # list of groups
102newly_added = {} # list of contacts that has just signed in
103to_be_removed = {} # list of contacts that has just signed out
104
105events = Events()
106
107nicks = {} # list of our nick names in each account
108# should we block 'contact signed in' notifications for this account?
109# this is only for the first 30 seconds after we change our show
110# to something else than offline
111# can also contain account/transport_jid to block notifications for contacts
112# from this transport
113block_signed_in_notifications = {}
114con_types = {} # type of each connection (ssl, tls, tcp, ...)
115
116sleeper_state = {} # whether we pass auto away / xa or not
117#'off': don't use sleeper for this account
118#'online': online and use sleeper
119#'autoaway': autoaway and use sleeper
120#'autoxa': autoxa and use sleeper
121status_before_autoaway = {}
122
123# jid of transport contacts for which we need to ask avatar when transport will
124# be online
125transport_avatar = {} # {transport_jid: [jid_list]}
126
127SHOW_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
128        'invisible']
129
130# zeroconf account name
131ZEROCONF_ACC_NAME = 'Local'
132priority_dict = {}
133for status in ('online', 'chat', 'away', 'xa', 'dnd', 'invisible'):
134        priority_dict[status] = config.get('autopriority' + status)
135
136def get_nick_from_jid(jid):
137        pos = jid.find('@')
138        return jid[:pos]
139
140def get_server_from_jid(jid):
141        pos = jid.find('@') + 1 # after @
142        return jid[pos:]
143
144def get_nick_from_fjid(jid):
145        # fake jid is the jid for a contact in a room
146        # gaim@conference.jabber.no/nick/nick-continued
147        return jid.split('/', 1)[1]
148
149def get_name_and_server_from_jid(jid):
150        name = get_nick_from_jid(jid)
151        server = get_server_from_jid(jid)
152        return name, server
153
154def get_room_and_nick_from_fjid(jid):
155        # fake jid is the jid for a contact in a room
156        # gaim@conference.jabber.no/nick/nick-continued
157        # return ('gaim@conference.jabber.no', 'nick/nick-continued')
158        l = jid.split('/', 1)
159        if len(l) == 1: # No nick
160                l.append('')
161        return l
162
163def get_real_jid_from_fjid(account, fjid):
164        '''returns real jid or returns None
165        if we don't know the real jid'''
166        room_jid, nick = get_room_and_nick_from_fjid(fjid)
167        if not nick: # It's not a fake_jid, it is a real jid
168                return fjid # we return the real jid
169        real_jid = fjid
170        if interface.msg_win_mgr.get_control(room_jid, account):
171                # It's a pm, so if we have real jid it's in contact.jid
172                gc_contact = contacts.get_gc_contact(account, room_jid, nick)
173                if not gc_contact:
174                        return
175                # gc_contact.jid is None when it's not a real jid (we don't know real jid)
176                real_jid = gc_contact.jid
177        return real_jid
178
179def get_room_from_fjid(jid):
180        return get_room_and_nick_from_fjid(jid)[0]
181
182def get_contact_name_from_jid(account, jid):
183        c = contacts.get_first_contact_from_jid(account, jid)
184        return c.name
185
186def get_jid_without_resource(jid):
187        return jid.split('/')[0]
188
189def construct_fjid(room_jid, nick):
190        ''' nick is in utf8 (taken from treeview); room_jid is in unicode'''
191        # fake jid is the jid for a contact in a room
192        # gaim@conference.jabber.org/nick
193        if isinstance(nick, str):
194                nick = unicode(nick, 'utf-8')
195        return room_jid + '/' + nick
196
197def get_resource_from_jid(jid):
198        jids = jid.split('/', 1)
199        if len(jids) > 1:
200                return jids[1] # abc@doremi.org/res/res-continued
201        else:
202                return ''
203        '''\
204[15:34:28] <asterix> we should add contact.fake_jid I think
205[15:34:46] <asterix> so if we know real jid, it wil be in contact.jid, or we look in contact.fake_jid
206[15:32:54] <asterix> they can have resource if we know the real jid
207[15:33:07] <asterix> and that resource is in contact.resource
208'''
209
210def get_number_of_accounts():
211        '''returns the number of ALL accounts'''
212        return len(connections.keys())
213
214def get_number_of_connected_accounts(accounts_list = None):
215        '''returns the number of CONNECTED accounts
216        you can optionally pass an accounts_list
217        and if you do those will be checked, else all will be checked'''
218        connected_accounts = 0
219        if accounts_list is None:
220                accounts = connections.keys()
221        else:
222                accounts = accounts_list
223        for account in accounts:
224                if account_is_connected(account):
225                        connected_accounts = connected_accounts + 1
226        return connected_accounts
227
228def account_is_connected(account):
229        if account not in connections:
230                return False
231        if connections[account].connected > 1: # 0 is offline, 1 is connecting
232                return True
233        else:
234                return False
235
236def account_is_disconnected(account):
237        return not account_is_connected(account)
238
239def get_number_of_securely_connected_accounts():
240        '''returns the number of the accounts that are SSL/TLS connected'''
241        num_of_secured = 0
242        for account in connections:
243                if account_is_securely_connected(account):
244                        num_of_secured += 1
245        return num_of_secured
246
247def account_is_securely_connected(account):
248        if account in con_types and con_types[account] in ('tls', 'ssl'):
249                return True
250        else:
251                return False
252
253def get_transport_name_from_jid(jid, use_config_setting = True):
254        '''returns 'aim', 'gg', 'irc' etc
255        if JID is not from transport returns None'''
256        #FIXME: jid can be None! one TB I saw had this problem:
257        # in the code block # it is a groupchat presence in handle_event_notify
258        # jid was None. Yann why?
259        if not jid or (use_config_setting and not config.get('use_transports_iconsets')):
260                return
261
262        host = get_server_from_jid(jid)
263        if host in transport_type:
264                return transport_type[host]
265
266        # host is now f.e. icq.foo.org or just icq (sometimes on hacky transports)
267        host_splitted = host.split('.')
268        if len(host_splitted) != 0:
269                # now we support both 'icq.' and 'icq' but not icqsucks.org
270                host = host_splitted[0]
271
272        if host in ('aim', 'irc', 'icq', 'msn', 'sms', 'tlen', 'weather', 'yahoo'):
273                return host
274        elif host == 'gg':
275                return 'gadu-gadu'
276        elif host == 'jit':
277                return 'icq'
278        else:
279                return None
280
281def jid_is_transport(jid):
282        # if not '@' or '@' starts the jid then it is transport
283        if jid.find('@') <= 0:
284                return True
285        return False
286
287def get_jid_from_account(account_name):
288        '''return the jid we use in the given account'''
289        name = config.get_per('accounts', account_name, 'name')
290        hostname = config.get_per('accounts', account_name, 'hostname')
291        jid = name + '@' + hostname
292        return jid
293
294def get_our_jids():
295        '''returns a list of the jids we use in our accounts'''
296        our_jids = list()
297        for account in contacts.get_accounts():
298                our_jids.append(get_jid_from_account(account))
299        return our_jids
300
301def get_hostname_from_account(account_name, use_srv = False):
302        '''returns hostname (if custom hostname is used, that is returned)'''
303        if use_srv and connections[account_name].connected_hostname:
304                return connections[account_name].connected_hostname
305        if config.get_per('accounts', account_name, 'use_custom_host'):
306                return config.get_per('accounts', account_name, 'custom_host')
307        return config.get_per('accounts', account_name, 'hostname')
308
309def get_notification_image_prefix(jid):
310        '''returns the prefix for the notification images'''
311        transport_name = get_transport_name_from_jid(jid)
312        if transport_name in ('aim', 'icq', 'msn', 'yahoo'):
313                prefix = transport_name
314        else:
315                prefix = 'jabber'
316        return prefix
317
318def get_name_from_jid(account, jid):
319        '''returns from JID's shown name and if no contact returns jids'''
320        contact = contacts.get_first_contact_from_jid(account, jid)
321        if contact:
322                actor = contact.get_shown_name()
323        else:
324                actor = jid
325        return actor
326
327def get_priority(account, show):
328        '''return the priority an account must have'''
329        if not show:
330                show = 'online'
331
332        if show in ('online', 'chat', 'away', 'xa', 'dnd', 'invisible') and \
333        config.get_per('accounts', account, 'adjust_priority_with_status'):
334                return config.get_per('accounts', account, 'autopriority_' + show)
335        return config.get_per('accounts', account, 'priority')
Note: See TracBrowser for help on using the browser.