[lorien420] Notification Daemon Popups are now clickable! CONGRAAAAAAATS Andrew Sayman
This commit is contained in:
parent
612716e2db
commit
6e413e7f5a
3 changed files with 325 additions and 164 deletions
117
src/dbus_support.py
Normal file
117
src/dbus_support.py
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
## dbus_support.py
|
||||||
|
##
|
||||||
|
## Contributors for this file:
|
||||||
|
## - Andrew Sayman <lorien420@myrealbox.com>
|
||||||
|
##
|
||||||
|
## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org>
|
||||||
|
## Vincent Hanquez <tab@snarc.org>
|
||||||
|
## Copyright (C) 2005 Yann Le Boulanger <asterix@lagaule.org>
|
||||||
|
## Vincent Hanquez <tab@snarc.org>
|
||||||
|
## Nikos Kouremenos <nkour@jabber.org>
|
||||||
|
## Dimitur Kirov <dkirov@gmail.com>
|
||||||
|
## Travis Shirk <travis@pobox.com>
|
||||||
|
## Norman Rasmussen <norman@rasmussen.co.za>
|
||||||
|
##
|
||||||
|
## 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
|
||||||
|
|
||||||
|
from common import exceptions
|
||||||
|
from common import i18n
|
||||||
|
_ = i18n._
|
||||||
|
|
||||||
|
try:
|
||||||
|
import dbus
|
||||||
|
version = getattr(dbus, 'version', (0, 20, 0))
|
||||||
|
except ImportError:
|
||||||
|
version = (0, 0, 0)
|
||||||
|
|
||||||
|
if version >= (0, 41, 0):
|
||||||
|
import dbus.service
|
||||||
|
import dbus.glib # cause dbus 0.35+ doesn't return signal replies without it
|
||||||
|
|
||||||
|
supported = True
|
||||||
|
if 'dbus' not in globals() and not os.name == 'nt':
|
||||||
|
print _('D-Bus python bindings are missing in this computer')
|
||||||
|
print _('D-Bus capabilities of Gajim cannot be used')
|
||||||
|
supported = False
|
||||||
|
# dbus 0.23 leads to segfault with threads_init()
|
||||||
|
if sys.version[:4] >= '2.4' and version[1] < 30:
|
||||||
|
supported = False
|
||||||
|
|
||||||
|
class SessionBus:
|
||||||
|
'''A Singleton for the DBus SessionBus'''
|
||||||
|
def __init__(self):
|
||||||
|
self.session_bus = None
|
||||||
|
|
||||||
|
def SessionBus(self):
|
||||||
|
if not supported:
|
||||||
|
raise exceptions.DbusNotSupported
|
||||||
|
|
||||||
|
if not self.present():
|
||||||
|
raise exceptions.SessionBusNotPresent
|
||||||
|
return self.session_bus
|
||||||
|
|
||||||
|
def bus(self):
|
||||||
|
return self.SessionBus()
|
||||||
|
|
||||||
|
def present(self):
|
||||||
|
if not supported:
|
||||||
|
return False
|
||||||
|
if self.session_bus is None:
|
||||||
|
try:
|
||||||
|
self.session_bus = dbus.SessionBus()
|
||||||
|
except dbus.DBusException:
|
||||||
|
self.session_bus = None
|
||||||
|
return False
|
||||||
|
if self.session_bus is None:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
session_bus = SessionBus()
|
||||||
|
|
||||||
|
def get_interface(interface, path):
|
||||||
|
'''Returns an interface on the current SessionBus. If the interface isn't
|
||||||
|
running, it tries to start it first.'''
|
||||||
|
if not supported:
|
||||||
|
return None
|
||||||
|
if session_bus.present():
|
||||||
|
bus = session_bus.SessionBus()
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
obj = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
|
||||||
|
dbus_iface = dbus.Interface(obj, 'org.freedesktop.DBus')
|
||||||
|
running_services = dbus_iface.ListNames()
|
||||||
|
started = True
|
||||||
|
if interface not in running_services:
|
||||||
|
# try to start the service
|
||||||
|
if dbus_iface.StartServiceByName(interface, dbus.UInt32(0)) == 1:
|
||||||
|
started = True
|
||||||
|
else:
|
||||||
|
started = False
|
||||||
|
if not started:
|
||||||
|
return None
|
||||||
|
obj = bus.get_object(interface, path)
|
||||||
|
return dbus.Interface(obj, interface)
|
||||||
|
except Exception, e:
|
||||||
|
print >> sys.stderr, e
|
||||||
|
return None
|
||||||
|
except dbus.DBusException, e:
|
||||||
|
# This exception could give useful info about why notification breaks
|
||||||
|
print >> sys.stderr, e
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_notifications_interface():
|
||||||
|
'''Returns the notifications interface.'''
|
||||||
|
return get_interface('org.freedesktop.Notifications','/org/freedesktop/Notifications')
|
317
src/notify.py
317
src/notify.py
|
@ -28,152 +28,36 @@
|
||||||
## GNU General Public License for more details.
|
## GNU General Public License for more details.
|
||||||
##
|
##
|
||||||
|
|
||||||
HAS_DBUS = True
|
|
||||||
|
|
||||||
try:
|
|
||||||
import dbus
|
|
||||||
except ImportError:
|
|
||||||
HAS_DBUS = False
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import gajim
|
import gajim
|
||||||
import dialogs
|
import dialogs
|
||||||
|
import gobject
|
||||||
|
|
||||||
from common import gajim
|
from common import gajim
|
||||||
|
from common import exceptions
|
||||||
from common import i18n
|
from common import i18n
|
||||||
i18n.init()
|
i18n.init()
|
||||||
_ = i18n._
|
_ = i18n._
|
||||||
|
|
||||||
|
import dbus_support
|
||||||
def dbus_get_interface():
|
if dbus_support.supported:
|
||||||
try:
|
import dbus
|
||||||
interface = 'org.freedesktop.Notifications'
|
if dbus_support.version >= (0, 41, 0):
|
||||||
path = '/org/freedesktop/Notifications'
|
import dbus.glib
|
||||||
bus = dbus.SessionBus()
|
import dbus.service
|
||||||
obj = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
|
|
||||||
dbus_iface = dbus.Interface(obj, 'org.freedesktop.DBus')
|
|
||||||
running_services = dbus_iface.ListNames()
|
|
||||||
started = True
|
|
||||||
if interface not in running_services:
|
|
||||||
# try to start the service (notif-daemon)
|
|
||||||
if dbus_iface.StartServiceByName(interface, dbus.UInt32(0)) == 1:
|
|
||||||
started = True
|
|
||||||
else:
|
|
||||||
started = False
|
|
||||||
if not started:
|
|
||||||
return None
|
|
||||||
obj = bus.get_object(interface, path)
|
|
||||||
return dbus.Interface(obj, interface)
|
|
||||||
except Exception, e:
|
|
||||||
return None
|
|
||||||
except dbus.DBusException, e:
|
|
||||||
# This exception could give useful info about why notification breaks
|
|
||||||
print >> sys.stderr, e
|
|
||||||
return None
|
|
||||||
|
|
||||||
def dbus_available():
|
|
||||||
if not HAS_DBUS:
|
|
||||||
return False
|
|
||||||
if dbus_get_interface() is None:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def dbus_notify(event_type, jid, account, msg_type = '', file_props = None):
|
|
||||||
if jid in gajim.contacts[account]:
|
|
||||||
actor = gajim.get_first_contact_instance_from_jid(account, jid).name
|
|
||||||
else:
|
|
||||||
actor = jid
|
|
||||||
|
|
||||||
# default value of txt
|
|
||||||
txt = actor
|
|
||||||
|
|
||||||
img = 'chat.png' # img to display
|
|
||||||
ntype = 'im' # Notification Type
|
|
||||||
|
|
||||||
if event_type == _('Contact Signed In'):
|
|
||||||
img = 'online.png'
|
|
||||||
ntype = 'presence.online'
|
|
||||||
elif event_type == _('Contact Signed Out'):
|
|
||||||
img = 'offline.png'
|
|
||||||
ntype = 'presence.offline'
|
|
||||||
elif event_type in (_('New Message'), _('New Single Message'),
|
|
||||||
_('New Private Message')):
|
|
||||||
img = 'chat.png' # FIXME: better img and split events
|
|
||||||
ntype = 'im.received'
|
|
||||||
if event_type == _('New Private Message'):
|
|
||||||
room_jid, nick = gajim.get_room_and_nick_from_fjid(jid)
|
|
||||||
room_name,t = gajim.get_room_name_and_server_from_room_jid(room_jid)
|
|
||||||
txt = _('%(nickname)s in room %(room_name)s has sent you a new message.')\
|
|
||||||
% {'nickname': nick, 'room_name': room_name}
|
|
||||||
else:
|
|
||||||
#we talk about a name here
|
|
||||||
txt = _('%s has sent you a new message.') % actor
|
|
||||||
elif event_type == _('File Transfer Request'):
|
|
||||||
img = 'requested.png' # FIXME: better img
|
|
||||||
ntype = 'transfer'
|
|
||||||
#we talk about a name here
|
|
||||||
txt = _('%s wants to send you a file.') % actor
|
|
||||||
elif event_type == _('File Transfer Error'):
|
|
||||||
img = 'error.png' # FIXME: better img
|
|
||||||
ntype = 'transfer.error'
|
|
||||||
elif event_type in (_('File Transfer Completed'), _('File Transfer Stopped')):
|
|
||||||
img = 'closed.png' # # FIXME: better img and split events
|
|
||||||
ntype = 'transfer.complete'
|
|
||||||
if file_props is not None:
|
|
||||||
if file_props['type'] == 'r':
|
|
||||||
# get the name of the sender, as it is in the roster
|
|
||||||
sender = unicode(file_props['sender']).split('/')[0]
|
|
||||||
name = gajim.get_first_contact_instance_from_jid(
|
|
||||||
account, sender).name
|
|
||||||
filename = os.path.basename(file_props['file-name'])
|
|
||||||
if event_type == _('File Transfer Completed'):
|
|
||||||
txt = _('You successfully received %(filename)s from %(name)s.')\
|
|
||||||
% {'filename': filename, 'name': name}
|
|
||||||
else: # ft stopped
|
|
||||||
txt = _('File transfer of %(filename)s from %(name)s stopped.')\
|
|
||||||
% {'filename': filename, 'name': name}
|
|
||||||
else:
|
|
||||||
receiver = file_props['receiver']
|
|
||||||
if hasattr(receiver, 'jid'):
|
|
||||||
receiver = receiver.jid
|
|
||||||
receiver = receiver.split('/')[0]
|
|
||||||
# get the name of the contact, as it is in the roster
|
|
||||||
name = gajim.get_first_contact_instance_from_jid(
|
|
||||||
account, receiver).name
|
|
||||||
filename = os.path.basename(file_props['file-name'])
|
|
||||||
if event_type == _('File Transfer Completed'):
|
|
||||||
txt = _('You successfully sent %(filename)s to %(name)s.')\
|
|
||||||
% {'filename': filename, 'name': name}
|
|
||||||
else: # ft stopped
|
|
||||||
txt = _('File transfer of %(filename)s to %(name)s stopped.')\
|
|
||||||
% {'filename': filename, 'name': name}
|
|
||||||
else:
|
|
||||||
txt = ''
|
|
||||||
|
|
||||||
iconset = gajim.config.get('iconset')
|
|
||||||
if not iconset:
|
|
||||||
iconset = 'sun'
|
|
||||||
# FIXME: use 32x32 or 48x48 someday
|
|
||||||
path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16', img)
|
|
||||||
path = os.path.abspath(path)
|
|
||||||
notif = dbus_get_interface()
|
|
||||||
if notif is None:
|
|
||||||
raise dbus.DBusException()
|
|
||||||
notif.Notify(dbus.String(_('Gajim')),
|
|
||||||
dbus.String(path), dbus.UInt32(0), ntype, dbus.Byte(0),
|
|
||||||
dbus.String(event_type), dbus.String(txt),
|
|
||||||
[dbus.String(path)], [''], [''], True, dbus.UInt32(5))
|
|
||||||
|
|
||||||
def notify(event_type, jid, account, msg_type = '', file_props = None):
|
def notify(event_type, jid, account, msg_type = '', file_props = None):
|
||||||
if dbus_available() and gajim.config.get('use_notif_daemon'):
|
'''Notifies a user of an event. It first tries to a valid implementation of
|
||||||
|
the Desktop Notification Specification. If that fails, then we fall back to
|
||||||
|
the older style PopupNotificationWindow method.'''
|
||||||
|
if gajim.config.get('use_notif_daemon') and dbus_support.supported:
|
||||||
try:
|
try:
|
||||||
dbus_notify(event_type, jid, account, msg_type, file_props)
|
DesktopNotification(event_type, jid, account, msg_type, file_props)
|
||||||
return
|
return
|
||||||
except dbus.DBusException, e:
|
except dbus.DBusException, e:
|
||||||
# Connection to DBus failed, try popup
|
# Connection to DBus failed, try popup
|
||||||
pass
|
print >> sys.stderr, e
|
||||||
except TypeError, e:
|
except TypeError, e:
|
||||||
# This means that we sent the message incorrectly
|
# This means that we sent the message incorrectly
|
||||||
print >> sys.stderr, e
|
print >> sys.stderr, e
|
||||||
|
@ -181,4 +65,177 @@ def notify(event_type, jid, account, msg_type = '', file_props = None):
|
||||||
msg_type, file_props)
|
msg_type, file_props)
|
||||||
gajim.interface.roster.popup_notification_windows.append(instance)
|
gajim.interface.roster.popup_notification_windows.append(instance)
|
||||||
|
|
||||||
|
class NotificationResponseManager:
|
||||||
|
'''Collects references to pending DesktopNotifications and manages there
|
||||||
|
signalling. This is necessary due to a bug in DBus where you can't remove
|
||||||
|
a signal from an interface once it's connected.'''
|
||||||
|
def __init__(self):
|
||||||
|
self.pending = {}
|
||||||
|
self.interface = None
|
||||||
|
|
||||||
|
def attach_to_interface(self):
|
||||||
|
if self.interface is not None:
|
||||||
|
return
|
||||||
|
self.interface = dbus_support.get_notifications_interface()
|
||||||
|
self.interface.connect_to_signal('ActionInvoked', self.on_action_invoked)
|
||||||
|
self.interface.connect_to_signal('NotificationClosed', self.on_closed)
|
||||||
|
|
||||||
|
def on_action_invoked(self, id, reason):
|
||||||
|
if self.pending.has_key(id):
|
||||||
|
notification = self.pending[id]
|
||||||
|
notification.on_action_invoked(id, reason)
|
||||||
|
del self.pending[id]
|
||||||
|
else:
|
||||||
|
# This happens in the case of a race condition where the user clicks
|
||||||
|
# on a popup before the program finishes registering this callback
|
||||||
|
gobject.timeout_add(1000, self.on_action_invoked, id, reason)
|
||||||
|
|
||||||
|
def on_closed(self, id, reason):
|
||||||
|
if self.pending.has_key(id):
|
||||||
|
del self.pending[id]
|
||||||
|
|
||||||
|
notification_response_manager = NotificationResponseManager()
|
||||||
|
|
||||||
|
class DesktopNotification:
|
||||||
|
'''A DesktopNotification that interfaces with DBus via the Desktop
|
||||||
|
Notification specification'''
|
||||||
|
def __init__(self, event_type, jid, account, msg_type = '', file_props = None):
|
||||||
|
self.account = account
|
||||||
|
self.jid = jid
|
||||||
|
self.msg_type = msg_type
|
||||||
|
self.file_props = file_props
|
||||||
|
|
||||||
|
if jid in gajim.contacts[account]:
|
||||||
|
actor = gajim.get_first_contact_instance_from_jid(account, jid).name
|
||||||
|
else:
|
||||||
|
actor = jid
|
||||||
|
|
||||||
|
# default value of txt
|
||||||
|
txt = actor
|
||||||
|
|
||||||
|
img = 'chat.png' # img to display
|
||||||
|
ntype = 'im' # Notification Type
|
||||||
|
|
||||||
|
if event_type == _('Contact Signed In'):
|
||||||
|
img = 'online.png'
|
||||||
|
ntype = 'presence.online'
|
||||||
|
elif event_type == _('Contact Signed Out'):
|
||||||
|
img = 'offline.png'
|
||||||
|
ntype = 'presence.offline'
|
||||||
|
elif event_type in (_('New Message'), _('New Single Message'),
|
||||||
|
_('New Private Message')):
|
||||||
|
img = 'chat.png' # FIXME: better img and split events
|
||||||
|
ntype = 'im.received'
|
||||||
|
if event_type == _('New Private Message'):
|
||||||
|
room_jid, nick = gajim.get_room_and_nick_from_fjid(jid)
|
||||||
|
room_name,t = gajim.get_room_name_and_server_from_room_jid(room_jid)
|
||||||
|
txt = _('%(nickname)s in room %(room_name)s has sent you a new message.')\
|
||||||
|
% {'nickname': nick, 'room_name': room_name}
|
||||||
|
else:
|
||||||
|
#we talk about a name here
|
||||||
|
txt = _('%s has sent you a new message.') % actor
|
||||||
|
elif event_type == _('File Transfer Request'):
|
||||||
|
img = 'requested.png' # FIXME: better img
|
||||||
|
ntype = 'transfer'
|
||||||
|
#we talk about a name here
|
||||||
|
txt = _('%s wants to send you a file.') % actor
|
||||||
|
elif event_type == _('File Transfer Error'):
|
||||||
|
img = 'error.png' # FIXME: better img
|
||||||
|
ntype = 'transfer.error'
|
||||||
|
elif event_type in (_('File Transfer Completed'), _('File Transfer Stopped')):
|
||||||
|
img = 'closed.png' # # FIXME: better img and split events
|
||||||
|
ntype = 'transfer.complete'
|
||||||
|
if file_props is not None:
|
||||||
|
if file_props['type'] == 'r':
|
||||||
|
# get the name of the sender, as it is in the roster
|
||||||
|
sender = unicode(file_props['sender']).split('/')[0]
|
||||||
|
name = gajim.get_first_contact_instance_from_jid(
|
||||||
|
account, sender).name
|
||||||
|
filename = os.path.basename(file_props['file-name'])
|
||||||
|
if event_type == _('File Transfer Completed'):
|
||||||
|
txt = _('You successfully received %(filename)s from %(name)s.')\
|
||||||
|
% {'filename': filename, 'name': name}
|
||||||
|
else: # ft stopped
|
||||||
|
txt = _('File transfer of %(filename)s from %(name)s stopped.')\
|
||||||
|
% {'filename': filename, 'name': name}
|
||||||
|
else:
|
||||||
|
receiver = file_props['receiver']
|
||||||
|
if hasattr(receiver, 'jid'):
|
||||||
|
receiver = receiver.jid
|
||||||
|
receiver = receiver.split('/')[0]
|
||||||
|
# get the name of the contact, as it is in the roster
|
||||||
|
name = gajim.get_first_contact_instance_from_jid(
|
||||||
|
account, receiver).name
|
||||||
|
filename = os.path.basename(file_props['file-name'])
|
||||||
|
if event_type == _('File Transfer Completed'):
|
||||||
|
txt = _('You successfully sent %(filename)s to %(name)s.')\
|
||||||
|
% {'filename': filename, 'name': name}
|
||||||
|
else: # ft stopped
|
||||||
|
txt = _('File transfer of %(filename)s to %(name)s stopped.')\
|
||||||
|
% {'filename': filename, 'name': name}
|
||||||
|
else:
|
||||||
|
txt = ''
|
||||||
|
|
||||||
|
iconset = gajim.config.get('iconset')
|
||||||
|
if not iconset:
|
||||||
|
iconset = 'sun'
|
||||||
|
# FIXME: use 32x32 or 48x48 someday
|
||||||
|
path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16', img)
|
||||||
|
path = os.path.abspath(path)
|
||||||
|
self.notif = dbus_support.get_notifications_interface()
|
||||||
|
if self.notif is None:
|
||||||
|
raise dbus.DBusException()
|
||||||
|
self.id = self.notif.Notify(dbus.String(_('Gajim')),
|
||||||
|
dbus.String(path), dbus.UInt32(0), ntype, dbus.Byte(0),
|
||||||
|
dbus.String(event_type), dbus.String(txt),
|
||||||
|
[dbus.String(path)], {'default':0}, [''], True, dbus.UInt32(5))
|
||||||
|
notification_response_manager.attach_to_interface()
|
||||||
|
notification_response_manager.pending[self.id] = self
|
||||||
|
|
||||||
|
def on_action_invoked(self, id, reason):
|
||||||
|
if self.notif is None:
|
||||||
|
return
|
||||||
|
self.notif.CloseNotification(dbus.UInt32(id))
|
||||||
|
self.notif = None
|
||||||
|
# use Contact class, new_chat expects it that way
|
||||||
|
# is it in the roster?
|
||||||
|
if gajim.contacts[self.account].has_key(self.jid):
|
||||||
|
contact = gajim.get_contact_instance_with_highest_priority(
|
||||||
|
self.account, self.jid)
|
||||||
|
else:
|
||||||
|
from gajim import Contact
|
||||||
|
keyID = ''
|
||||||
|
attached_keys = gajim.config.get_per('accounts', self.account,
|
||||||
|
'attached_gpg_keys').split()
|
||||||
|
if self.jid in attached_keys:
|
||||||
|
keyID = attached_keys[attached_keys.index(jid) + 1]
|
||||||
|
if self.msg_type.find('file') != 0:
|
||||||
|
if self.msg_type == 'pm':
|
||||||
|
room_jid, nick = self.jid.split('/', 1)
|
||||||
|
show = gajim.gc_contacts[self.account][room_jid][nick].show
|
||||||
|
contact = Contact(jid = self.jid, name = nick, groups = ['none'],
|
||||||
|
show = show, sub = 'none')
|
||||||
|
else:
|
||||||
|
contact = Contact(jid = self.jid, name = self.jid.split('@')[0],
|
||||||
|
groups = [_('not in the roster')], show = 'not in the roster',
|
||||||
|
status = _('not in the roster'), sub = 'none', keyID = keyID)
|
||||||
|
gajim.contacts[self.account][self.jid] = [contact]
|
||||||
|
gajim.interface.roster.add_contact_to_roster(contact.jid,
|
||||||
|
self.account)
|
||||||
|
|
||||||
|
if self.msg_type == 'pm': # It's a private message
|
||||||
|
gajim.interface.roster.new_chat(contact, self.account)
|
||||||
|
chats_window = gajim.interface.instances[self.account]['chats'][self.jid]
|
||||||
|
chats_window.set_active_tab(self.jid)
|
||||||
|
chats_window.window.present()
|
||||||
|
elif self.msg_type in ('normal', 'file-request', 'file-request-error',
|
||||||
|
'file-send-error', 'file-error', 'file-stopped', 'file-completed'):
|
||||||
|
# Get the first single message event
|
||||||
|
ev = gajim.get_first_event(self.account, self.jid, self.msg_type)
|
||||||
|
gajim.interface.roster.open_event(self.account, self.jid, ev)
|
||||||
|
|
||||||
|
else: # 'chat'
|
||||||
|
gajim.interface.roster.new_chat(contact, self.account)
|
||||||
|
chats_window = gajim.interface.instances[self.account]['chats'][self.jid]
|
||||||
|
chats_window.set_active_tab(self.jid)
|
||||||
|
chats_window.window.present()
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
## - Yann Le Boulanger <asterix@lagaule.org>
|
## - Yann Le Boulanger <asterix@lagaule.org>
|
||||||
## - Nikos Kouremenos <kourem@gmail.com>
|
## - Nikos Kouremenos <kourem@gmail.com>
|
||||||
## - Dimitur Kirov <dkirov@gmail.com>
|
## - Dimitur Kirov <dkirov@gmail.com>
|
||||||
|
## - Andrew Sayman <lorien420@myrealbox.com>
|
||||||
##
|
##
|
||||||
## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org>
|
## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org>
|
||||||
## Vincent Hanquez <tab@snarc.org>
|
## Vincent Hanquez <tab@snarc.org>
|
||||||
|
@ -38,20 +39,17 @@ from common import i18n
|
||||||
from dialogs import AddNewContactWindow
|
from dialogs import AddNewContactWindow
|
||||||
_ = i18n._
|
_ = i18n._
|
||||||
|
|
||||||
try:
|
import dbus_support
|
||||||
|
if dbus_support.supported:
|
||||||
import dbus
|
import dbus
|
||||||
_version = getattr(dbus, 'version', (0, 20, 0))
|
if dbus_support.version >= (0, 41, 0):
|
||||||
except ImportError:
|
import dbus.service
|
||||||
_version = (0, 0, 0)
|
import dbus.glib # cause dbus 0.35+ doesn't return signal replies without it
|
||||||
|
DbusPrototype = dbus.service.Object
|
||||||
if _version >= (0, 41, 0):
|
elif dbus_support.version >= (0, 20, 0):
|
||||||
import dbus.service
|
DbusPrototype = dbus.Object
|
||||||
import dbus.glib # cause dbus 0.35+ doesn't return signal replies without it
|
else: #dbus is not defined
|
||||||
DbusPrototype = dbus.service.Object
|
DbusPrototype = str
|
||||||
elif _version >= (0, 20, 0):
|
|
||||||
DbusPrototype = dbus.Object
|
|
||||||
else: #dbus is not defined
|
|
||||||
DbusPrototype = str
|
|
||||||
|
|
||||||
INTERFACE = 'org.gajim.dbus.RemoteInterface'
|
INTERFACE = 'org.gajim.dbus.RemoteInterface'
|
||||||
OBJ_PATH = '/org/gajim/dbus/RemoteObject'
|
OBJ_PATH = '/org/gajim/dbus/RemoteObject'
|
||||||
|
@ -63,23 +61,12 @@ STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
|
||||||
class Remote:
|
class Remote:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.signal_object = None
|
self.signal_object = None
|
||||||
if 'dbus' not in globals() and not os.name == 'nt':
|
session_bus = dbus_support.session_bus.SessionBus()
|
||||||
print _('D-Bus python bindings are missing in this computer')
|
|
||||||
print _('D-Bus capabilities of Gajim cannot be used')
|
|
||||||
raise exceptions.DbusNotSupported
|
|
||||||
# dbus 0.23 leads to segfault with threads_init()
|
|
||||||
if sys.version[:4] >= '2.4' and _version[1] < 30:
|
|
||||||
raise exceptions.DbusNotSupported
|
|
||||||
|
|
||||||
try:
|
|
||||||
session_bus = dbus.SessionBus()
|
|
||||||
except:
|
|
||||||
raise exceptions.SessionBusNotPresent
|
|
||||||
|
|
||||||
if _version[1] >= 41:
|
if dbus_support.version[1] >= 41:
|
||||||
service = dbus.service.BusName(SERVICE, bus=session_bus)
|
service = dbus.service.BusName(SERVICE, bus=session_bus)
|
||||||
self.signal_object = SignalObject(service)
|
self.signal_object = SignalObject(service)
|
||||||
elif _version[1] <= 40 and _version[1] >= 20:
|
elif dbus_support.version[1] <= 40 and dbus_support.version[1] >= 20:
|
||||||
service=dbus.Service(SERVICE, session_bus)
|
service=dbus.Service(SERVICE, session_bus)
|
||||||
self.signal_object = SignalObject(service)
|
self.signal_object = SignalObject(service)
|
||||||
|
|
||||||
|
@ -97,9 +84,9 @@ class SignalObject(DbusPrototype):
|
||||||
self.vcard_account = None
|
self.vcard_account = None
|
||||||
|
|
||||||
# register our dbus API
|
# register our dbus API
|
||||||
if _version[1] >= 41:
|
if dbus_support.version[1] >= 41:
|
||||||
DbusPrototype.__init__(self, service, OBJ_PATH)
|
DbusPrototype.__init__(self, service, OBJ_PATH)
|
||||||
elif _version[1] >= 30:
|
elif dbus_support.version[1] >= 30:
|
||||||
DbusPrototype.__init__(self, OBJ_PATH, service)
|
DbusPrototype.__init__(self, OBJ_PATH, service)
|
||||||
else:
|
else:
|
||||||
DbusPrototype.__init__(self, OBJ_PATH, service,
|
DbusPrototype.__init__(self, OBJ_PATH, service,
|
||||||
|
@ -123,7 +110,7 @@ class SignalObject(DbusPrototype):
|
||||||
|
|
||||||
def raise_signal(self, signal, arg):
|
def raise_signal(self, signal, arg):
|
||||||
''' raise a signal, with a single string message '''
|
''' raise a signal, with a single string message '''
|
||||||
if _version[1] >= 30:
|
if dbus_support.version[1] >= 30:
|
||||||
from dbus import dbus_bindings
|
from dbus import dbus_bindings
|
||||||
message = dbus_bindings.Signal(OBJ_PATH, INTERFACE, signal)
|
message = dbus_bindings.Signal(OBJ_PATH, INTERFACE, signal)
|
||||||
i = message.get_iter(True)
|
i = message.get_iter(True)
|
||||||
|
@ -437,7 +424,7 @@ class SignalObject(DbusPrototype):
|
||||||
|
|
||||||
def _get_real_arguments(self, args, desired_length):
|
def _get_real_arguments(self, args, desired_length):
|
||||||
# supresses the first 'message' argument, which is set in dbus 0.23
|
# supresses the first 'message' argument, which is set in dbus 0.23
|
||||||
if _version[1] == 20:
|
if dbus_support.version[1] == 20:
|
||||||
args=args[1:]
|
args=args[1:]
|
||||||
if desired_length > 0:
|
if desired_length > 0:
|
||||||
args = list(args)
|
args = list(args)
|
||||||
|
@ -473,14 +460,14 @@ class SignalObject(DbusPrototype):
|
||||||
return repr(contact_dict)
|
return repr(contact_dict)
|
||||||
|
|
||||||
|
|
||||||
if _version[1] >= 30 and _version[1] <= 40:
|
if dbus_support.version[1] >= 30 and dbus_support.version[1] <= 40:
|
||||||
method = dbus.method
|
method = dbus.method
|
||||||
signal = dbus.signal
|
signal = dbus.signal
|
||||||
elif _version[1] >= 41:
|
elif dbus_support.version[1] >= 41:
|
||||||
method = dbus.service.method
|
method = dbus.service.method
|
||||||
signal = dbus.service.signal
|
signal = dbus.service.signal
|
||||||
|
|
||||||
if _version[1] >= 30:
|
if dbus_support.version[1] >= 30:
|
||||||
# prevent using decorators, because they are not supported
|
# prevent using decorators, because they are not supported
|
||||||
# on python < 2.4
|
# on python < 2.4
|
||||||
# FIXME: use decorators when python2.3 (and dbus 0.23) is OOOOOOLD
|
# FIXME: use decorators when python2.3 (and dbus 0.23) is OOOOOOLD
|
||||||
|
|
Loading…
Add table
Reference in a new issue