correctly set transient window for muc error dialogs. Fixes #6943
[gajim.git] / plugins / dbus_plugin / plugin.py
blobb7289aed0ad776d6102aaf681da6ac85d39557da
1 # -*- coding: utf-8 -*-
3 ## Copyright (C) 2005-2006 Yann Leboulanger <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 Andrew Sayman <lorien420@myrealbox.com>
7 ## Copyright (C) 2007 Lukas Petrovicky <lukas@petrovicky.net>
8 ## Copyright (C) 2007 Julien Pivotto <roidelapluie@gmail.com>
9 ## Copyright (C) 2007 Travis Shirk <travis@pobox.com>
10 ## Copyright (C) 2008 Mateusz Biliński <mateusz@bilinski.it>
12 ## This file is part of Gajim.
14 ## Gajim is free software; you can redistribute it and/or modify
15 ## it under the terms of the GNU General Public License as published
16 ## by the Free Software Foundation; version 3 only.
18 ## Gajim is distributed in the hope that it will be useful,
19 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ## GNU General Public License for more details.
23 ## You should have received a copy of the GNU General Public License
24 ## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
26 '''
27 D-BUS Support plugin.
29 Based on src/remote_control.py
31 :author: Mateusz Biliński <mateusz@bilinski.it>
32 :since: 8th August 2008
33 :copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
34 :license: GPL
35 '''
36 import os
37 import new
39 import gobject
42 from common import dbus_support
43 if dbus_support.supported:
44 import dbus
45 if dbus_support:
46 INTERFACE = 'org.gajim.dbusplugin.RemoteInterface'
47 OBJ_PATH = '/org/gajim/dbusplugin/RemoteObject'
48 SERVICE = 'org.gajim.dbusplugin'
50 import dbus.service
51 import dbus.glib
52 # type mapping
54 # in most cases it is a utf-8 string
55 DBUS_STRING = dbus.String
57 # general type (for use in dicts, where all values should have the same type)
58 DBUS_BOOLEAN = dbus.Boolean
59 DBUS_DOUBLE = dbus.Double
60 DBUS_INT32 = dbus.Int32
61 # dictionary with string key and binary value
62 DBUS_DICT_SV = lambda : dbus.Dictionary({}, signature="sv")
63 # dictionary with string key and value
64 DBUS_DICT_SS = lambda : dbus.Dictionary({}, signature="ss")
65 # empty type (there is no equivalent of None on D-Bus, but historically gajim
66 # used 0 instead)
67 DBUS_NONE = lambda : dbus.Int32(0)
69 def get_dbus_struct(obj):
70 ''' recursively go through all the items and replace
71 them with their casted dbus equivalents
72 '''
73 if obj is None:
74 return DBUS_NONE()
75 if isinstance(obj, (unicode, str)):
76 return DBUS_STRING(obj)
77 if isinstance(obj, int):
78 return DBUS_INT32(obj)
79 if isinstance(obj, float):
80 return DBUS_DOUBLE(obj)
81 if isinstance(obj, bool):
82 return DBUS_BOOLEAN(obj)
83 if isinstance(obj, (list, tuple)):
84 result = dbus.Array([get_dbus_struct(i) for i in obj],
85 signature='v')
86 if result == []:
87 return DBUS_NONE()
88 return result
89 if isinstance(obj, dict):
90 result = DBUS_DICT_SV()
91 for key, value in obj.items():
92 result[DBUS_STRING(key)] = get_dbus_struct(value)
93 if result == {}:
94 return DBUS_NONE()
95 return result
96 # unknown type
97 return DBUS_NONE()
99 class SignalObject(dbus.service.Object):
100 ''' Local object definition for /org/gajim/dbus/RemoteObject.
101 (This docstring is not be visible,
102 because the clients can access only the remote object.)'''
104 def __init__(self, bus_name):
105 self.first_show = True
106 self.vcard_account = None
108 # register our dbus API
109 dbus.service.Object.__init__(self, bus_name, OBJ_PATH)
111 @dbus.service.signal(INTERFACE, signature='av')
112 def Roster(self, account_and_data):
113 pass
115 @dbus.service.signal(INTERFACE, signature='av')
116 def AccountPresence(self, status_and_account):
117 pass
119 @dbus.service.signal(INTERFACE, signature='av')
120 def ContactPresence(self, account_and_array):
121 pass
123 @dbus.service.signal(INTERFACE, signature='av')
124 def ContactAbsence(self, account_and_array):
125 pass
127 @dbus.service.signal(INTERFACE, signature='av')
128 def ContactStatus(self, account_and_array):
129 pass
131 @dbus.service.signal(INTERFACE, signature='av')
132 def NewMessage(self, account_and_array):
133 pass
135 @dbus.service.signal(INTERFACE, signature='av')
136 def Subscribe(self, account_and_array):
137 pass
139 @dbus.service.signal(INTERFACE, signature='av')
140 def Subscribed(self, account_and_array):
141 pass
143 @dbus.service.signal(INTERFACE, signature='av')
144 def Unsubscribed(self, account_and_jid):
145 pass
147 @dbus.service.signal(INTERFACE, signature='av')
148 def NewAccount(self, account_and_array):
149 pass
151 @dbus.service.signal(INTERFACE, signature='av')
152 def VcardInfo(self, account_and_vcard):
153 pass
155 @dbus.service.signal(INTERFACE, signature='av')
156 def LastStatusTime(self, account_and_array):
157 pass
159 @dbus.service.signal(INTERFACE, signature='av')
160 def OsInfo(self, account_and_array):
161 pass
163 @dbus.service.signal(INTERFACE, signature='av')
164 def GCPresence(self, account_and_array):
165 pass
167 @dbus.service.signal(INTERFACE, signature='av')
168 def GCMessage(self, account_and_array):
169 pass
171 @dbus.service.signal(INTERFACE, signature='av')
172 def RosterInfo(self, account_and_array):
173 pass
175 @dbus.service.signal(INTERFACE, signature='av')
176 def NewGmail(self, account_and_array):
177 pass
179 @dbus.service.signal(INTERFACE, signature='av')
180 def EntityTime(self, account_and_array):
181 pass
183 def raise_signal(self, signal, arg):
184 '''raise a signal, with a single argument of unspecified type
185 Instead of obj.raise_signal("Foo", bar), use obj.Foo(bar).'''
186 getattr(self, signal)(arg)
188 @dbus.service.method(INTERFACE, in_signature='s', out_signature='s')
189 def get_status(self, account):
190 '''Returns status (show to be exact) which is the global one
191 unless account is given'''
192 if not account:
193 # If user did not ask for account, returns the global status
194 return DBUS_STRING(helpers.get_global_show())
195 # return show for the given account
196 index = gajim.connections[account].connected
197 return DBUS_STRING(gajim.SHOW_LIST[index])
199 @dbus.service.method(INTERFACE, in_signature='s', out_signature='s')
200 def get_status_message(self, account):
201 '''Returns status which is the global one
202 unless account is given'''
203 if not account:
204 # If user did not ask for account, returns the global status
205 return DBUS_STRING(str(helpers.get_global_status()))
206 # return show for the given account
207 status = gajim.connections[account].status
208 return DBUS_STRING(status)
210 def _get_account_and_contact(self, account, jid):
211 '''get the account (if not given) and contact instance from jid'''
212 connected_account = None
213 contact = None
214 accounts = gajim.contacts.get_accounts()
215 # if there is only one account in roster, take it as default
216 # if user did not ask for account
217 if not account and len(accounts) == 1:
218 account = accounts[0]
219 if account:
220 if gajim.connections[account].connected > 1: # account is connected
221 connected_account = account
222 contact = gajim.contacts.get_contact_with_highest_priority(account,
223 jid)
224 else:
225 for account in accounts:
226 contact = gajim.contacts.get_contact_with_highest_priority(account,
227 jid)
228 if contact and gajim.connections[account].connected > 1:
229 # account is connected
230 connected_account = account
231 break
232 if not contact:
233 contact = jid
235 return connected_account, contact
237 def _get_account_for_groupchat(self, account, room_jid):
238 '''get the account which is connected to groupchat (if not given)
239 or check if the given account is connected to the groupchat'''
240 connected_account = None
241 accounts = gajim.contacts.get_accounts()
242 # if there is only one account in roster, take it as default
243 # if user did not ask for account
244 if not account and len(accounts) == 1:
245 account = accounts[0]
246 if account:
247 if gajim.connections[account].connected > 1 and \
248 room_jid in gajim.gc_connected[account] and \
249 gajim.gc_connected[account][room_jid]:
250 # account and groupchat are connected
251 connected_account = account
252 else:
253 for account in accounts:
254 if gajim.connections[account].connected > 1 and \
255 room_jid in gajim.gc_connected[account] and \
256 gajim.gc_connected[account][room_jid]:
257 # account and groupchat are connected
258 connected_account = account
259 break
260 return connected_account
262 @dbus.service.method(INTERFACE, in_signature='sss', out_signature='b')
263 def send_file(self, file_path, jid, account):
264 '''send file, located at 'file_path' to 'jid', using account
265 (optional) 'account' '''
266 jid = self._get_real_jid(jid, account)
267 connected_account, contact = self._get_account_and_contact(account, jid)
269 if connected_account:
270 if file_path[:7] == 'file://':
271 file_path=file_path[7:]
272 if os.path.isfile(file_path): # is it file?
273 gajim.interface.instances['file_transfers'].send_file(
274 connected_account, contact, file_path)
275 return DBUS_BOOLEAN(True)
276 return DBUS_BOOLEAN(False)
278 def _send_message(self, jid, message, keyID, account, type = 'chat',
279 subject = None):
280 '''can be called from send_chat_message (default when send_message)
281 or send_single_message'''
282 if not jid or not message:
283 return DBUS_BOOLEAN(False)
284 if not keyID:
285 keyID = ''
287 connected_account, contact = self._get_account_and_contact(account, jid)
288 if connected_account:
289 connection = gajim.connections[connected_account]
290 connection.send_message(jid, message, keyID, type, subject)
291 return DBUS_BOOLEAN(True)
292 return DBUS_BOOLEAN(False)
294 @dbus.service.method(INTERFACE, in_signature='ssss', out_signature='b')
295 def send_chat_message(self, jid, message, keyID, account):
296 '''Send chat 'message' to 'jid', using account (optional) 'account'.
297 if keyID is specified, encrypt the message with the pgp key '''
298 jid = self._get_real_jid(jid, account)
299 return self._send_message(jid, message, keyID, account)
301 @dbus.service.method(INTERFACE, in_signature='sssss', out_signature='b')
302 def send_single_message(self, jid, subject, message, keyID, account):
303 '''Send single 'message' to 'jid', using account (optional) 'account'.
304 if keyID is specified, encrypt the message with the pgp key '''
305 jid = self._get_real_jid(jid, account)
306 return self._send_message(jid, message, keyID, account, type, subject)
308 @dbus.service.method(INTERFACE, in_signature='sss', out_signature='b')
309 def send_groupchat_message(self, room_jid, message, account):
310 '''Send 'message' to groupchat 'room_jid',
311 using account (optional) 'account'.'''
312 if not room_jid or not message:
313 return DBUS_BOOLEAN(False)
314 connected_account = self._get_account_for_groupchat(account, room_jid)
315 if connected_account:
316 connection = gajim.connections[connected_account]
317 connection.send_gc_message(room_jid, message)
318 return DBUS_BOOLEAN(True)
319 return DBUS_BOOLEAN(False)
321 @dbus.service.method(INTERFACE, in_signature='ss', out_signature='b')
322 def open_chat(self, jid, account):
323 '''Shows the tabbed window for new message to 'jid', using account
324 (optional) 'account' '''
325 if not jid:
326 raise MissingArgument
327 return DBUS_BOOLEAN(False)
328 jid = self._get_real_jid(jid, account)
329 try:
330 jid = helpers.parse_jid(jid)
331 except:
332 # Jid is not conform, ignore it
333 return DBUS_BOOLEAN(False)
335 if account:
336 accounts = [account]
337 else:
338 accounts = gajim.connections.keys()
339 if len(accounts) == 1:
340 account = accounts[0]
341 connected_account = None
342 first_connected_acct = None
343 for acct in accounts:
344 if gajim.connections[acct].connected > 1: # account is online
345 contact = gajim.contacts.get_first_contact_from_jid(acct, jid)
346 if gajim.interface.msg_win_mgr.has_window(jid, acct):
347 connected_account = acct
348 break
349 # jid is in roster
350 elif contact:
351 connected_account = acct
352 break
353 # we send the message to jid not in roster, because account is
354 # specified, or there is only one account
355 elif account:
356 connected_account = acct
357 elif first_connected_acct is None:
358 first_connected_acct = acct
360 # if jid is not a conntact, open-chat with first connected account
361 if connected_account is None and first_connected_acct:
362 connected_account = first_connected_acct
364 if connected_account:
365 gajim.interface.new_chat_from_jid(connected_account, jid)
366 # preserve the 'steal focus preservation'
367 win = gajim.interface.msg_win_mgr.get_window(jid,
368 connected_account).window
369 if win.get_property('visible'):
370 win.window.focus()
371 return DBUS_BOOLEAN(True)
372 return DBUS_BOOLEAN(False)
374 @dbus.service.method(INTERFACE, in_signature='sss', out_signature='b')
375 def change_status(self, status, message, account):
376 ''' change_status(status, message, account). account is optional -
377 if not specified status is changed for all accounts. '''
378 if status not in ('offline', 'online', 'chat',
379 'away', 'xa', 'dnd', 'invisible'):
380 return DBUS_BOOLEAN(False)
381 if account:
382 gobject.idle_add(gajim.interface.roster.send_status, account,
383 status, message)
384 else:
385 # account not specified, so change the status of all accounts
386 for acc in gajim.contacts.get_accounts():
387 if not gajim.config.get_per('accounts', acc,
388 'sync_with_global_status'):
389 continue
390 gobject.idle_add(gajim.interface.roster.send_status, acc,
391 status, message)
392 return DBUS_BOOLEAN(False)
394 @dbus.service.method(INTERFACE, in_signature='', out_signature='')
395 def show_next_pending_event(self):
396 '''Show the window(s) with next pending event in tabbed/group chats.'''
397 if gajim.events.get_nb_events():
398 gajim.interface.systray.handle_first_event()
400 @dbus.service.method(INTERFACE, in_signature='s', out_signature='a{sv}')
401 def contact_info(self, jid):
402 '''get vcard info for a contact. Return cached value of the vcard.
404 if not isinstance(jid, unicode):
405 jid = unicode(jid)
406 if not jid:
407 raise MissingArgument
408 return DBUS_DICT_SV()
409 jid = self._get_real_jid(jid)
411 cached_vcard = gajim.connections.values()[0].get_cached_vcard(jid)
412 if cached_vcard:
413 return get_dbus_struct(cached_vcard)
415 # return empty dict
416 return DBUS_DICT_SV()
418 @dbus.service.method(INTERFACE, in_signature='', out_signature='as')
419 def list_accounts(self):
420 '''list register accounts'''
421 result = gajim.contacts.get_accounts()
422 result_array = dbus.Array([], signature='s')
423 if result and len(result) > 0:
424 for account in result:
425 result_array.append(DBUS_STRING(account))
426 return result_array
428 @dbus.service.method(INTERFACE, in_signature='s', out_signature='a{ss}')
429 def account_info(self, account):
430 '''show info on account: resource, jid, nick, prio, message'''
431 result = DBUS_DICT_SS()
432 if gajim.connections.has_key(account):
433 # account is valid
434 con = gajim.connections[account]
435 index = con.connected
436 result['status'] = DBUS_STRING(gajim.SHOW_LIST[index])
437 result['name'] = DBUS_STRING(con.name)
438 result['jid'] = DBUS_STRING(gajim.get_jid_from_account(con.name))
439 result['message'] = DBUS_STRING(con.status)
440 result['priority'] = DBUS_STRING(unicode(con.priority))
441 result['resource'] = DBUS_STRING(unicode(gajim.config.get_per(
442 'accounts', con.name, 'resource')))
443 return result
445 @dbus.service.method(INTERFACE, in_signature='s', out_signature='aa{sv}')
446 def list_contacts(self, account):
447 '''list all contacts in the roster. If the first argument is specified,
448 then return the contacts for the specified account'''
449 result = dbus.Array([], signature='aa{sv}')
450 accounts = gajim.contacts.get_accounts()
451 if len(accounts) == 0:
452 return result
453 if account:
454 accounts_to_search = [account]
455 else:
456 accounts_to_search = accounts
457 for acct in accounts_to_search:
458 if acct in accounts:
459 for jid in gajim.contacts.get_jid_list(acct):
460 item = self._contacts_as_dbus_structure(
461 gajim.contacts.get_contacts(acct, jid))
462 if item:
463 result.append(item)
464 return result
466 @dbus.service.method(INTERFACE, in_signature='', out_signature='')
467 def toggle_roster_appearance(self):
468 ''' shows/hides the roster window '''
469 win = gajim.interface.roster.window
470 if win.get_property('visible'):
471 gobject.idle_add(win.hide)
472 else:
473 win.present()
474 # preserve the 'steal focus preservation'
475 if self._is_first():
476 win.window.focus()
477 else:
478 win.window.focus(long(time()))
480 @dbus.service.method(INTERFACE, in_signature='', out_signature='')
481 def toggle_ipython(self):
482 ''' shows/hides the ipython window '''
483 win = gajim.ipython_window
484 if win:
485 if win.window.is_visible():
486 gobject.idle_add(win.hide)
487 else:
488 win.show_all()
489 win.present()
490 else:
491 gajim.interface.create_ipython_window()
493 @dbus.service.method(INTERFACE, in_signature='', out_signature='a{ss}')
494 def prefs_list(self):
495 prefs_dict = DBUS_DICT_SS()
496 def get_prefs(data, name, path, value):
497 if value is None:
498 return
499 key = ''
500 if path is not None:
501 for node in path:
502 key += node + '#'
503 key += name
504 prefs_dict[DBUS_STRING(key)] = DBUS_STRING(value[1])
505 gajim.config.foreach(get_prefs)
506 return prefs_dict
508 @dbus.service.method(INTERFACE, in_signature='', out_signature='b')
509 def prefs_store(self):
510 try:
511 gajim.interface.save_config()
512 except Exception, e:
513 return DBUS_BOOLEAN(False)
514 return DBUS_BOOLEAN(True)
516 @dbus.service.method(INTERFACE, in_signature='s', out_signature='b')
517 def prefs_del(self, key):
518 if not key:
519 return DBUS_BOOLEAN(False)
520 key_path = key.split('#', 2)
521 if len(key_path) != 3:
522 return DBUS_BOOLEAN(False)
523 if key_path[2] == '*':
524 gajim.config.del_per(key_path[0], key_path[1])
525 else:
526 gajim.config.del_per(key_path[0], key_path[1], key_path[2])
527 return DBUS_BOOLEAN(True)
529 @dbus.service.method(INTERFACE, in_signature='s', out_signature='b')
530 def prefs_put(self, key):
531 if not key:
532 return DBUS_BOOLEAN(False)
533 key_path = key.split('#', 2)
534 if len(key_path) < 3:
535 subname, value = key.split('=', 1)
536 gajim.config.set(subname, value)
537 return DBUS_BOOLEAN(True)
538 subname, value = key_path[2].split('=', 1)
539 gajim.config.set_per(key_path[0], key_path[1], subname, value)
540 return DBUS_BOOLEAN(True)
542 @dbus.service.method(INTERFACE, in_signature='ss', out_signature='b')
543 def add_contact(self, jid, account):
544 if account:
545 if account in gajim.connections and \
546 gajim.connections[account].connected > 1:
547 # if given account is active, use it
548 AddNewContactWindow(account = account, jid = jid)
549 else:
550 # wrong account
551 return DBUS_BOOLEAN(False)
552 else:
553 # if account is not given, show account combobox
554 AddNewContactWindow(account = None, jid = jid)
555 return DBUS_BOOLEAN(True)
557 @dbus.service.method(INTERFACE, in_signature='ss', out_signature='b')
558 def remove_contact(self, jid, account):
559 jid = self._get_real_jid(jid, account)
560 accounts = gajim.contacts.get_accounts()
562 # if there is only one account in roster, take it as default
563 if account:
564 accounts = [account]
565 contact_exists = False
566 for account in accounts:
567 contacts = gajim.contacts.get_contacts(account, jid)
568 if contacts:
569 gajim.connections[account].unsubscribe(jid)
570 for contact in contacts:
571 gajim.interface.roster.remove_contact(contact, account)
572 gajim.contacts.remove_jid(account, jid)
573 contact_exists = True
574 return DBUS_BOOLEAN(contact_exists)
576 def _is_first(self):
577 if self.first_show:
578 self.first_show = False
579 return True
580 return False
582 def _get_real_jid(self, jid, account = None):
583 '''get the real jid from the given one: removes xmpp: or get jid from nick
584 if account is specified, search only in this account
586 if account:
587 accounts = [account]
588 else:
589 accounts = gajim.connections.keys()
590 if jid.startswith('xmpp:'):
591 return jid[5:] # len('xmpp:') = 5
592 nick_in_roster = None # Is jid a nick ?
593 for account in accounts:
594 # Does jid exists in roster of one account ?
595 if gajim.contacts.get_contacts(account, jid):
596 return jid
597 if not nick_in_roster:
598 # look in all contact if one has jid as nick
599 for jid_ in gajim.contacts.get_jid_list(account):
600 c = gajim.contacts.get_contacts(account, jid_)
601 if c[0].name == jid:
602 nick_in_roster = jid_
603 break
604 if nick_in_roster:
605 # We have not found jid in roster, but we found is as a nick
606 return nick_in_roster
607 # We have not found it as jid nor as nick, probably a not in roster jid
608 return jid
610 def _contacts_as_dbus_structure(self, contacts):
611 ''' get info from list of Contact objects and create dbus dict '''
612 if not contacts:
613 return None
614 prim_contact = None # primary contact
615 for contact in contacts:
616 if prim_contact is None or contact.priority > prim_contact.priority:
617 prim_contact = contact
618 contact_dict = DBUS_DICT_SV()
619 contact_dict['name'] = DBUS_STRING(prim_contact.name)
620 contact_dict['show'] = DBUS_STRING(prim_contact.show)
621 contact_dict['jid'] = DBUS_STRING(prim_contact.jid)
622 if prim_contact.keyID:
623 keyID = None
624 if len(prim_contact.keyID) == 8:
625 keyID = prim_contact.keyID
626 elif len(prim_contact.keyID) == 16:
627 keyID = prim_contact.keyID[8:]
628 if keyID:
629 contact_dict['openpgp'] = keyID
630 contact_dict['resources'] = dbus.Array([], signature='(sis)')
631 for contact in contacts:
632 resource_props = dbus.Struct((DBUS_STRING(contact.resource),
633 dbus.Int32(contact.priority), DBUS_STRING(contact.status)))
634 contact_dict['resources'].append(resource_props)
635 contact_dict['groups'] = dbus.Array([], signature='(s)')
636 for group in prim_contact.groups:
637 contact_dict['groups'].append((DBUS_STRING(group),))
638 return contact_dict
640 @dbus.service.method(INTERFACE, in_signature='', out_signature='s')
641 def get_unread_msgs_number(self):
642 return DBUS_STRING(str(gajim.events.get_nb_events()))
644 @dbus.service.method(INTERFACE, in_signature='s', out_signature='b')
645 def start_chat(self, account):
646 if not account:
647 # error is shown in gajim-remote check_arguments(..)
648 return DBUS_BOOLEAN(False)
649 NewChatDialog(account)
650 return DBUS_BOOLEAN(True)
652 @dbus.service.method(INTERFACE, in_signature='ss', out_signature='')
653 def send_xml(self, xml, account):
654 if account:
655 gajim.connections[account].send_stanza(xml)
656 else:
657 for acc in gajim.contacts.get_accounts():
658 gajim.connections[acc].send_stanza(xml)
660 @dbus.service.method(INTERFACE, in_signature='ssss', out_signature='')
661 def join_room(self, room_jid, nick, password, account):
662 if not account:
663 # get the first connected account
664 accounts = gajim.connections.keys()
665 for acct in accounts:
666 if gajim.account_is_connected(acct):
667 account = acct
668 break
669 if not account:
670 return
671 if not nick:
672 nick = ''
673 gajim.interface.instances[account]['join_gc'] = \
674 JoinGroupchatWindow(account, room_jid, nick)
675 else:
676 gajim.interface.join_gc_room(account, room_jid, nick, password)
678 from common import gajim
679 from common import helpers
680 from time import time
681 from dialogs import AddNewContactWindow, NewChatDialog, JoinGroupchatWindow
683 from plugins import GajimPlugin
684 from plugins.helpers import log_calls, log
685 from common import ged
687 class DBusPlugin(GajimPlugin):
689 @log_calls('DBusPlugin')
690 def init(self):
691 self.config_dialog = None
692 #self.gui_extension_points = {}
693 #self.config_default_values = {}
695 self.events_names = ['Roster', 'AccountPresence', 'ContactPresence',
696 'ContactAbsence', 'ContactStatus', 'NewMessage',
697 'Subscribe', 'Subscribed', 'Unsubscribed',
698 'NewAccount', 'VcardInfo', 'LastStatusTime',
699 'OsInfo', 'GCPresence', 'GCMessage', 'RosterInfo',
700 'NewGmail', 'EntityTime']
702 self.signal_object = None
704 self.events_handlers = {}
705 self._set_handling_methods()
707 @log_calls('DBusPlugin')
708 def activate(self):
709 session_bus = dbus_support.session_bus.SessionBus()
711 bus_name = dbus.service.BusName(SERVICE, bus=session_bus)
712 self.signal_object = SignalObject(bus_name)
714 @log_calls('DBusPlugin')
715 def deactivate(self):
716 self.signal_object.remove_from_connection()
717 self.signal_object = None
719 @log_calls('DBusPlugin')
720 def _set_handling_methods(self):
721 for event_name in self.events_names:
722 setattr(self, event_name,
723 new.instancemethod(
724 self._generate_handling_method(event_name),
725 self,
726 DBusPlugin))
727 self.events_handlers[event_name] = (ged.POSTCORE,
728 getattr(self, event_name))
730 def _generate_handling_method(self, event_name):
731 def handler(self, arg):
732 #print "Handler of event %s called"%(event_name)
733 if self.signal_object:
734 getattr(self.signal_object, event_name)(get_dbus_struct(arg))
736 return handler