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 import os
35 import random
36 random.seed()
37
38 import signal
39 if os.name != 'nt':
40 signal.signal(signal.SIGPIPE, signal.SIG_DFL)
41 import getpass
42 import gobject
43
44 from common.connection import CommonConnection
45 from common import gajim
46 from common import GnuPG
47 from common.zeroconf import client_zeroconf
48 from common.zeroconf import zeroconf
49 from connection_handlers_zeroconf import *
50
64
66 """
67 Get name, host, port from config, or create zeroconf account with default
68 values
69 """
70 if not gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'name'):
71 gajim.log.debug('Creating zeroconf account')
72 gajim.config.add_per('accounts', gajim.ZEROCONF_ACC_NAME)
73 gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME,
74 'autoconnect', True)
75 gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'no_log_for',
76 '')
77 gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'password',
78 'zeroconf')
79 gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME,
80 'sync_with_global_status', True)
81
82 gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME,
83 'custom_port', 5298)
84 gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME,
85 'is_zeroconf', True)
86 gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME,
87 'use_ft_proxies', False)
88
89 self.host = unicode(socket.gethostname())
90 gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'hostname',
91 self.host)
92 self.port = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
93 'custom_port')
94 self.autoconnect = gajim.config.get_per('accounts',
95 gajim.ZEROCONF_ACC_NAME, 'autoconnect')
96 self.sync_with_global_status = gajim.config.get_per('accounts',
97 gajim.ZEROCONF_ACC_NAME, 'sync_with_global_status')
98 self.first = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
99 'zeroconf_first_name')
100 self.last = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
101 'zeroconf_last_name')
102 self.jabber_id = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
103 'zeroconf_jabber_id')
104 self.email = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
105 'zeroconf_email')
106
107 if not self.username:
108 self.username = unicode(getpass.getuser())
109 gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'name',
110 self.username)
111 else:
112 self.username = gajim.config.get_per('accounts',
113 gajim.ZEROCONF_ACC_NAME, 'name')
114
115
118
126
129
131 if self.connected:
132 self.connection.resolve_all()
133 diffs = self.roster.getDiffs()
134 for key in diffs:
135 self.roster.setItem(key)
136 self.dispatch('ROSTER_INFO', (key, self.roster.getName(key),
137 'both', 'no', self.roster.getGroups(key)))
138 self.dispatch('NOTIFY', (key, self.roster.getStatus(key),
139 self.roster.getMessage(key), 'local', 0, None, 0, None))
140
141 return self.call_resolve_timeout
142
143
145 self.roster.setItem(jid)
146 self.dispatch('ROSTER_INFO', (jid, self.roster.getName(jid), 'both', 'no',
147 self.roster.getGroups(jid)))
148 self.dispatch('NOTIFY', (jid, self.roster.getStatus(jid),
149 self.roster.getMessage(jid), 'local', 0, None, 0, None))
150
152 self.roster.delItem(jid)
153
154
155 self.dispatch('NOTIFY', (jid, 'offline', '', 'local', 0, None, 0, None))
156
158 """
159 Called when we are disconnected. Comes from network manager for example
160 we don't try to reconnect, network manager will tell us when we can
161 """
162 if gajim.account_is_connected(self.name):
163
164
165 self.old_show = STATUS_LIST[self.connected]
166 self.connected = 0
167 self.dispatch('STATUS', 'offline')
168
169 self.time_to_reconnect = 5
170 self.on_purpose = False
171
176
178 self.dispatch('ERROR', (_('Avahi error'),
179 _('%s\nLink-local messaging might not work properly.') % message))
180
181 - def connect(self, show='online', msg=''):
182 self.get_config_values_or_default()
183 if not self.connection:
184 self.connection = client_zeroconf.ClientZeroconf(self)
185 if not zeroconf.test_zeroconf():
186 self.dispatch('STATUS', 'offline')
187 self.status = 'offline'
188 self.dispatch('CONNECTION_LOST',
189 (_('Could not connect to "%s"') % self.name,
190 _('Please check if Avahi or Bonjour is installed.')))
191 self.disconnect()
192 return
193 result = self.connection.connect(show, msg)
194 if not result:
195 self.dispatch('STATUS', 'offline')
196 self.status = 'offline'
197 if result is False:
198 self.dispatch('CONNECTION_LOST',
199 (_('Could not start local service'),
200 _('Unable to bind to port %d.' % self.port)))
201 else:
202 self.dispatch('CONNECTION_LOST',
203 (_('Could not start local service'),
204 _('Please check if avahi-daemon is running.')))
205 self.disconnect()
206 return
207 else:
208 self.connection.announce()
209 self.roster = self.connection.getRoster()
210 self.dispatch('ROSTER', self.roster)
211
212
213 for jid in self.roster.keys():
214 self.dispatch('ROSTER_INFO', (jid, self.roster.getName(jid), 'both',
215 'no', self.roster.getGroups(jid)))
216 self.dispatch('NOTIFY', (jid, self.roster.getStatus(jid),
217 self.roster.getMessage(jid), 'local', 0, None, 0, None))
218
219 self.connected = STATUS_LIST.index(show)
220
221
222 self.call_resolve_timeout = True
223 gobject.timeout_add_seconds(5, self._on_resolve_timeout)
224 return True
225
234
247
262
264
265 check = True
266 if not self.connect(show, msg):
267 return
268 if show != 'invisible':
269 check = self.connection.announce()
270 else:
271 self.connected = STATUS_LIST.index(show)
272 self.dispatch('SIGNED_IN', ())
273
274
275 if check:
276 self.dispatch('STATUS', show)
277 else:
278
279 self.dispatch('STATUS', 'offline')
280 self.status = 'offline'
281 self.dispatch('CONNECTION_LOST',
282 (_('Could not change status of account "%s"') % self.name,
283 _('Please check if avahi-daemon is running.')))
284
286 if self.connection.remove_announce():
287 self.dispatch('STATUS', 'invisible')
288 else:
289
290 self.dispatch('STATUS', 'offline')
291 self.status = 'offline'
292 self.dispatch('CONNECTION_LOST',
293 (_('Could not change status of account "%s"') % self.name,
294 _('Please check if avahi-daemon is running.')))
295
298
309
310 - def send_message(self, jid, msg, keyID, type_='chat', subject='',
311 chatstate=None, msg_id=None, composing_xep=None, resource=None,
312 user_nick=None, xhtml=None, label=None, session=None, forward_from=None,
313 form_node=None, original_message=None, delayed=None, callback=None,
314 callback_args=[], now=True):
315
316 def on_send_ok(msg_id):
317 self.dispatch('MSGSENT', (jid, msg, keyID))
318 if callback:
319 callback(msg_id, *callback_args)
320
321 self.log_message(jid, msg, forward_from, session, original_message,
322 subject, type_)
323
324 def on_send_not_ok(reason):
325 reason += ' ' + _('Your message could not be sent.')
326 self.dispatch('MSGERROR', [jid, -1, reason, None, None, session])
327
328 def cb(jid, msg, keyID, forward_from, session, original_message, subject,
329 type_, msg_iq):
330 ret = self.connection.send(msg_iq, msg is not None, on_ok=on_send_ok,
331 on_not_ok=on_send_not_ok)
332
333 if ret == -1:
334
335 self.dispatch('MSGERROR', [jid, -1, _('Contact is offline. Your '
336 'message could not be sent.'), None, None, session])
337
338 self._prepare_message(jid, msg, keyID, type_=type_, subject=subject,
339 chatstate=chatstate, msg_id=msg_id, composing_xep=composing_xep,
340 resource=resource, user_nick=user_nick, xhtml=xhtml, session=session,
341 forward_from=forward_from, form_node=form_node,
342 original_message=original_message, delayed=delayed, callback=cb)
343
351
353 CommonConnection._event_dispatcher(self, realm, event, data)
354 if realm == '':
355 if event == common.xmpp.transports_nb.DATA_ERROR:
356 thread_id = data[1]
357 frm = unicode(data[0])
358 session = self.get_or_create_session(frm, thread_id)
359 self.dispatch('MSGERROR', [frm, -1,
360 _('Connection to host could not be established: Timeout while '
361 'sending data.'), None, None, session])
362
363
364