1 # Copyright (C) 2006, 2007 Ulrik Sverdrup
3 # dragbox -- Commandline drag-and-drop tool for GNOME
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
20 class Error(Exception):
23 class ServiceUnavailable(Error
):
26 class NotEnabledError(ImportError, Error
):
29 def _clear_dbus_environment():
31 This is an evil run-on-import function to reset
34 Here we try unsetting DBUS_SESSION_BUS_ADDRESS to
35 make dbus recover it from the current X session.
38 from os
import unsetenv
, getenv
39 from utils
import print_debug
40 bus_address_env_name
= "DBUS_SESSION_BUS_ADDRESS"
43 print_debug("Unsetting %s, to defend against stale environment" %
45 unsetenv(bus_address_env_name
)
47 _clear_dbus_environment()
50 from dbus
.mainloop
.glib
import DBusGMainLoop
51 DBusGMainLoop(set_as_default
=True)
52 from dbus
.gobject_service
import ExportedGObject
54 raise NotEnabledError("Dbus not available")
58 default_object_path
= "/default"
59 service_interface
= "org.gna.DragboxInterface"
60 default_service_name
= "org.gna.dragbox"
62 class Service(ExportedGObject
):
64 Provides a dbus server controller
66 Exported interface methods:
67 activate - sends signal activate
68 send_files - sends signal files-received
69 send_texts - sends signal texts-received
71 send_file, send_text: Send single objects. These
72 exported methods are for external methods to simplify
73 their interaction with dragbox.
75 data-requested signal: parameters send_callback and error_callback
76 on error, call error_callback with an exception instance. otherwise
77 send_callback should be called with two lists: datas, types.
79 __gtype_name__
= "Service"
81 @dbus.service
.method(service_interface
)
82 def send_file(self
, f
):
88 @dbus.service
.method(service_interface
)
89 def send_files(self
, data
):
91 data: list of absolute paths
93 self
.emit("files-received", data
)
95 @dbus.service
.method(service_interface
)
96 def send_text(self
, t
):
102 @dbus.service
.method(service_interface
)
103 def send_texts(self
, data
):
105 data: list of text strings
107 self
.emit("texts-received", data
)
109 @dbus.service
.method(service_interface
)
112 activate application (bring to front)
114 self
.emit("activate")
116 @dbus.service
.method(service_interface
, out_signature
="asas",
117 async_callbacks
=("send_callback", "error_callback"))
118 def get_data(self
, send_callback
, error_callback
):
120 activate application (bring to front)
122 self
.emit("data-requested", send_callback
, error_callback
)
124 # See Service class declaration for
125 # documentation of the signals
126 gobject
.type_register(Service
)
127 gobject
.signal_new("files-received", Service
, gobject
.SIGNAL_RUN_LAST
,
128 gobject
.TYPE_BOOLEAN
, (gobject
.TYPE_PYOBJECT
, ))
129 gobject
.signal_new("texts-received", Service
, gobject
.SIGNAL_RUN_LAST
,
130 gobject
.TYPE_BOOLEAN
, (gobject
.TYPE_PYOBJECT
, ))
131 gobject
.signal_new("activate", Service
, gobject
.SIGNAL_RUN_LAST
,
132 gobject
.TYPE_BOOLEAN
, ())
133 gobject
.signal_new("data-requested", Service
, gobject
.SIGNAL_RUN_LAST
,
134 gobject
.TYPE_BOOLEAN
, (gobject
.TYPE_PYOBJECT
, gobject
.TYPE_PYOBJECT
))
136 def make_service(identifier
=None):
138 Return a service object
140 identifier: The service identifier, or None to use the default
142 service_name
= _make_service_name(identifier
)
143 session_bus
= dbus
.SessionBus()
144 bus_name
= dbus
.service
.BusName(service_name
, bus
=session_bus
)
145 # return an instance of the Service
146 return Service(bus_name
, object_path
=default_object_path
)
148 def _make_service_name(identifier
):
150 Make a service name from the string identifier
152 Return default service name if identifier is None
155 accept
= "abcdefghijklmnopqrstuvwxyz"
156 name
= "".join(c
for c
in identifier
.lower() if c
in accept
)
159 return default_service_name
161 return default_service_name
+ "." + identifier
163 def _get_dbus_interface(bus
):
165 Return the interface of the main dbus object on the given bus
167 dbus_name
= 'org.freedesktop.DBus'
168 dbus_object_path
= '/org/freedesktop/DBus'
169 dbusobj
= bus
.get_object(dbus_name
, dbus_object_path
)
170 return dbus
.Interface(dbusobj
, dbus_name
)
172 def _get_dbus_session_bus():
174 Get the dbus SessionBus
176 Raises ServiceUnavailable if dbus is not available
178 from utils
import print_debug
182 bus
= dbus
.SessionBus()
184 raise ServiceUnavailable("Could not get dbus session bus")
189 Yield available dragbox services by identifier
191 bus
= _get_dbus_session_bus()
192 iface
= _get_dbus_interface(bus
)
193 bus_names
= iface
.ListNames()
194 for name
in bus_names
:
195 if name
.startswith(default_service_name
):
196 if name
== default_service_name
:
199 basename
= name
.replace(default_service_name
+ ".", "")
202 class Connection(object):
204 Tries to connect to previously started Service
206 def __init__(self
, identifier
=None):
208 Create a connection to a running instance
210 identifier: service identifier, or None to use the default
212 Throws ServiceUnavailable if no service found
214 bus
= _get_dbus_session_bus()
216 service_name
= _make_service_name(identifier
)
217 # Check with dbus if service is available
218 dbusiface
= _get_dbus_interface(bus
)
219 if dbusiface
.NameHasOwner(service_name
):
220 proxy_obj
= bus
.get_object(service_name
, default_object_path
)
222 self
.iface
= dbus
.Interface(proxy_obj
, service_interface
)
225 raise ServiceUnavailable("%s not found" % service_name
)
227 def get_interface(self
):
229 Returns the dbus interface to the "Service"