1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
|
## common/gajim.py
##
## Gajim Team:
## - Yann Le Boulanger <asterix@lagaule.org>
## - Nikos Kouremenos <kourem@gmail.com>
##
## Copyright (C) 2003-2005 Gajim Team
##
## 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 sys
import logging
import mutex
import config
interface = None # The actual interface (the gtk one for the moment)
version = '0.9'
config = config.Config()
connections = {}
verbose = False
h = logging.StreamHandler()
f = logging.Formatter('%(asctime)s %(name)s: %(message)s', '%d %b %Y %H:%M:%S')
h.setFormatter(f)
log = logging.getLogger('Gajim')
log.addHandler(h)
import logger
logger = logger.Logger() # init the logger
if os.name == 'nt':
DATA_DIR = os.path.join('..', 'data')
try:
# Documents and Settings\[User Name]\Application Data\Gajim
LOGPATH = os.path.join(os.environ['appdata'], 'Gajim', 'Logs') # deprecated
VCARDPATH = os.path.join(os.environ['appdata'], 'Gajim', 'Vcards')
except KeyError:
# win9x, in cwd
LOGPATH = 'Logs' # deprecated
VCARDPATH = 'Vcards'
else: # Unices
DATA_DIR = '../data'
LOGPATH = os.path.expanduser('~/.gajim/logs') # deprecated
VCARDPATH = os.path.expanduser('~/.gajim/vcards')
try:
LOGPATH = LOGPATH.decode(sys.getfilesystemencoding())
VCARDPATH = VCARDPATH.decode(sys.getfilesystemencoding())
except:
pass
LANG = os.getenv('LANG') # en_US, fr_FR, el_GR etc..
if LANG:
LANG = LANG[:2] # en, fr, el etc..
else:
LANG = 'en'
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 = {} # list of contacts {acct: {jid1: [C1, C2]}, } one Contact per resource
gc_contacts = {} # list of contacts that are in gc {acct: {room_jid: {nick: C}}}
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}
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
awaiting_events = {} # list of messages/FT reveived but not printed
# awaiting_events[jid] = (type, (data1, data2, ...))
# if type in ('chat', 'normal'): data = (message, subject, kind, time,
# encrypted, resource)
# kind can be (incoming, error)
# if type in file-request, file-request-error, file-send-error, file-error,
# file-completed, file-stopped:
# data = file_props
nicks = {} # list of our nick names in each account
allow_notifications = {} # do we allow notifications for each account ?
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 = {}
#queues of events from connections...
events_for_ui = {}
#... and its mutex
mutex_events_for_ui = mutex.mutex()
SHOW_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
'invisible']
def get_nick_from_jid(jid):
pos = jid.find('@')
return jid[:pos]
def get_server_from_jid(jid):
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]
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)
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
return fjid # we return the real jid
real_jid = fjid
gcs = interface.instances[account]['gc']
if gcs.has_key(room_jid):
# It's a pm, so if we have real jid it's in contact.jid
if not gc_contacts[account][room_jid].has_key(nick):
return
contact = gc_contacts[account][room_jid][nick]
# contact.jid is None when it's not a real jid (we don't know real jid)
real_jid = contact.jid
return real_jid
def get_room_from_fjid(jid):
return get_room_and_nick_from_fjid(jid)[0]
def get_contact_instances_from_jid(account, jid):
''' we may have two or more resources on that jid '''
if jid in contacts[account]:
contacts_instances = contacts[account][jid]
return contacts_instances
def get_first_contact_instance_from_jid(account, jid):
contact = None
if jid in contacts[account]:
contact = contacts[account][jid][0]
else: # it's fake jid
#FIXME: problem see comment in next line
room, nick = \
get_room_and_nick_from_fjid(jid) # if we ban/kick we now real jid
if gc_contacts[account].has_key(room) and \
nick in gc_contacts[account][room]:
contact = gc_contacts[account][room][nick]
return contact
def get_contact_instance_with_highest_priority(account, jid):
contact_instances = contacts[account][jid]
return get_highest_prio_contact_from_contacts(contact_instances)
def get_contact_name_from_jid(account, jid):
return contacts[account][jid][0].name
def get_highest_prio_contact_from_contacts(contacts):
prim_contact = None # primary contact
for contact in contacts:
if prim_contact == None or int(contact.priority) > \
int(prim_contact.priority):
prim_contact = contact
return prim_contact
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):
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():
return len(connections.keys())
def get_transport_name_from_jid(jid, use_config_setting = True):
'''returns 'aim', 'gg', 'irc' etc'''
#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')):
return
host = jid.split('@')[-1]
if host.startswith('aim'):
return 'aim'
elif host.startswith('gadugadu'):
return 'gadugadu'
elif host.startswith('gg'):
return 'gadugadu'
elif host.startswith('irc'):
return 'irc'
# abc@icqsucks.org will match as ICQ, but what to do..
elif host.startswith('icq'):
return 'icq'
elif host.startswith('msn'):
return 'msn'
elif host.startswith('sms'):
return 'sms'
elif host.startswith('tlen'):
return 'tlen'
elif host.startswith('weather'):
return 'weather'
elif host.startswith('yahoo'):
return 'yahoo'
else:
return None
def jid_is_transport(jid):
aim = jid.startswith('aim.')
gg = jid.startswith('gg.') # gadugadu
irc = jid.startswith('irc.')
icq = jid.startswith('icq.')
msn = jid.startswith('msn.')
sms = jid.startswith('sms.')
tlen = jid.startswith('tlen.')
yahoo = jid.startswith('yahoo.')
if aim or gg or irc or icq or msn or sms or yahoo or tlen:
is_transport = True
else:
is_transport = False
return is_transport
def get_jid_from_account(account_name):
name = config.get_per('accounts', account_name, 'name')
hostname = config.get_per('accounts', account_name, 'hostname')
jid = name + '@' + hostname
return jid
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_first_event(account, jid, typ = None):
'''returns the first event of the given type from the awaiting_events queue'''
if not awaiting_events[account].has_key(jid):
return None
q = awaiting_events[account][jid]
if not typ:
return q[0]
for ev in q:
if ev[0] == typ:
return ev
return None
def popup_window(account):
autopopup = config.get('autopopup')
autopopupaway = config.get('autopopupaway')
if autopopup and (autopopupaway or connections[account].connected > 3):
return True
return False
def show_notification(account):
if config.get('notify_on_new_message'):
# check OUR status and if we allow notifications for that status
if config.get('autopopupaway'): # always show notification
return True
if connections[account].connected in (2, 3): # we're online or chat
return True
return False
|