Module dbus_proxy
Simple API around GLib's GIO:GDBusProxy built on top of lgi.
Info:
- Copyright: (2017) Stefano Mazzucco,(2018 - 2020) Stefano Mazzucco and contributors
- Release: v0.10.3
- License: Apache License, version 2.0
- Author: Stefano Mazzucco
and contributors
_proxy Functions
Proxy | A proxy object
Proxy objects act as intermediares between your lua code and DBus. |
Proxy:connect_signal (callback, signal_name[, sender_name]) | Connect a callback function to a signal. |
Proxy:on_properties_changed (callback) | Call a function when the properties of the proxy object change. |
Proxy:new (opts) | Create a new proxy object |
_bus Functions
Bus | Available connections to the DBus daemon. |
_variant Functions
variant.strip (v) | Strip an lgi.GLib.VariantType object of its types |
_monitored Functions
monitored.new (opts[, cb]) | Create a monitored proxy object from the given options. |
_proxy Functions
- Proxy
-
A proxy object
Proxy objects act as intermediares between your lua code and DBus. All the properties, methods and signals of the object are exposed. Be aware that properties, methods and signals will likely be written in
CamelCase
since this it the convention in DBus (e.g.proxy.SomeProperty
orproxy:SomeMethod()
). Please refer to the documentation of the object you are proxying for more information.When a property in a DBus object changes, the same change is reflected in the proxy. Similarly, when a signal is emitted, the proxy object is notified accordingly.
Additionally, the following fields reflect the corresponding
g-*
properties:connection
: g-connectionflags
: g-flagsinterface
: g-interface-namename
: g-namename_owner
: g-name-ownerobject_path
: g-object-path
Some proxy methods may report errors (see the documentation of the object your are proxying). In that case you can check them with the usual error-checking pattern as shown in the usage example.
For all this to work though, the code must run inside GLib's main event loop. This can be achieved in two ways:
Create a main loop and run it when the application starts:
local GLib = require("lgi").GLib -- Set up the application, then do: local main_loop = GLib.MainLoop() main_loop:run() -- use main_loop:quit() to stop the main loop.
Use more fine-grained control by running an iteration at a time from the main context; this is particularly useful when you want to integrate your code with an external main loop:
local GLib = require("lgi").GLib -- Set up the code, then do local ctx = GLib.MainLoop():get_context() -- Run a single non-blocking iteration if ctx:iteration() == true then print("something changed!") end -- Run a single blocking iteration if ctx:iteration(true) == true then print("something changed here too!") end
NOTE
If you use the Awesome Window Manager, the code will be already running inside a main loop.
Usage:
p = require("dbus_proxy") proxy = p.Proxy:new( { bus = p.Bus.SYSTEM, name = "com.example.BusName", interface = "com.example.InterfaceName", path = "/com/example/objectPath" } ) res, err = proxy:SomeMethod() -- Check whether an error occurred. if not res and err then print("Error:", err) print("Error code:", err.code) end proxy:SomeMethodWithArguments("hello", 123) proxy.SomeProperty -- Asynchronous method calls are also supported, they have the "Async" -- suffix. For example: local function callback_fn(proxy, context, success, failure) if failure ~= nil then -- error from the DBus Method print("Error:", failure) print("Error code:", failure.code) -- add the data from the DBus method to the context context.failure = failure return end -- add the data from the DBus method to the context context.success = success end local my_context = {call_id = "my-id"} some_proxy:SomeMethodWithArgumentsAsync(callback_fn, my_context, "hello", 123) -- Do something else while waiting for the callback to be called with the -- result
- Proxy:connect_signal (callback, signal_name[, sender_name])
-
Connect a callback function to a signal.
Parameters:
- callback function a callback function to be called. The proxy object itself and the parameters from the signal as (simple lua types) will be passed to the callback when the signal is emitted
- signal_name string the name of the signal
- sender_name
string
the name of the sender. This may have the form
of a well known name (e.g.
"org.freedesktop.DBus"
) or a specific connection name ( e.g.":1.113"
). See also the Bus Names section of the DBus tutorial. If specified, only signals from this sender will be taken into account. (optional)
Usage:
proxy:connect_signal( function (p, x, y) assert(p == proxy) print("SomeSignalName emitted with params: ", x, y) end, "SomeSignalName" )
- Proxy:on_properties_changed (callback)
-
Call a function when the properties of the proxy object change.
Parameters:
- callback
function
a function that will be called when the
properties change. The callback will receive the proxy object itself and two
tables:
changed_properties
(a table where the keys are the properties that changed and the values the new values) andinvalidated_properties
(an array containg the names of the invalidated properties). Either may be empty. The local cache has already been updated when the signal is emitted, so the properties on the object will be up-to-date
Usage:
proxy:on_properties_changed(function (p, changed, invalidated) assert(p == proxy) print("******") print("changed properties:") for k, v in pairs(changed) do print("name", k, "ne value", v) end print("invalidated properties") for _, v in ipairs(invalidated) do print("name", v) end print("******") end)
- callback
function
a function that will be called when the
properties change. The callback will receive the proxy object itself and two
tables:
- Proxy:new (opts)
-
Create a new proxy object
Parameters:
- opts
table
table that specifies what DBus object should be proxied. The
opts
table should have the following fields:bus
: a DBus connection from the Bus tableinterface
: a (string) representing the interface namename
: a (string) representing the Bus namepath
: a (string) representing the object pathflags
: one of thelgi.Gio.DBusProxyFlags
; defaults tolgi.Gio.DBusProxyFlags.NONE
(optional)
Returns:
-
a new proxy object
- opts
table
_bus Functions
- Bus
-
Available connections to the DBus daemon. Fields on this table
can only be accessed. Trying to set fields will result in an error.
Fields:
- SESSION Connection to the session bus for this process
- SYSTEM Connection to the system bus for this process
- any_valid_dbus_address
Connection to the
DBus address.
If an invalid address is passed, its value will be
nil
.
Usage:
Bus = require("dbus_proxy").Bus system_bus = Bus.SYSTEM session_bus = Bus.SESSION -- This is a string that looks like -- "unix:path=/run/user/1000/bus" address = os.getenv("DBUS_SESSION_BUS_ADDRESS") bus = Bus[address] assert("Gio.DBusConnection" == bus._name) invalid1 = Bus["something really wrong"] assert(nil == invalid1) invalid2 = Bus.this_will_not_work assert(nil == invalid2)
_variant Functions
- variant.strip (v)
-
Strip an
lgi.GLib.VariantType
object of its typesParameters:
- v
lgi.GLib.VariantType
an
lgi.GLib.VariantType
object
Returns:
- numeric types will be returned as lua numbers
- booleans are preserved
- string are preserved,
- object paths (e.g.
/org/freedesktop/DBus
) will be returned as strings too - arrays (homogeneous types, signature
a
) and tuples (mixed types, signature()
) will be returned as lua arrays - dictionaries (signature
{}
) will be returned as lua tables
simple lua data (nested structures will be stripped too). The C to lua type correspondence is straightforward:
Usage:
GVariant = require("lgi").GLib.VariantType -- strip a nested variant v1 = GVariant("v", GVariant("s", "in a variant")) stripped1 = variant.strip(v1) -- "in a variant" -- strip a dictionary of variants v2 = GVariant("a{sv}", {one = GVariant("i", 123), two = GVariant("s", "Lua!")}) stripped2 = variant.strip(v2) -- {one = 123, two = "Lua!"} -- strip a nested array v3 = GVariant("aai", {{1, 2, 3}, {4, 1, 2, 3}}) stripped3 = variant.strip(v3) -- {{1, 2, 3}, {4, 1, 2, 3}, n=2}
- v
lgi.GLib.VariantType
an
_monitored Functions
- monitored.new (opts[, cb])
-
Create a monitored proxy object from the given options.
This function creates a monitored Proxy object that can come "live" as soon as the referenced DBus name is available.
When the name is available (i.e. connected), the object will have the exact same behavior as a normal Proxy object.
When the name is not available, the object will raise an error when trying to access properties or call methods of the Proxy object with the exception of the
name
property.Parameters:
- opts
table
options that specify the DBus object to be proxied. In
addition to the fields documented in Proxy:new, the optional
watcher_flags
can be set to eitherlgi.Gio.BusNameWatcherFlags.NONE
(the default) orlgi.Gio.BusNameWatcherFlags.AUTO_START
. The latter will ask the bus to launch an owner for the name if there is no owner when beginning to watch the name (see also the GBusNameWatcherFlags documentation on the GNOME website) - cb func A callback function called with two parameters: the proxy object, and a boolean that is true when the DBus name appears and false when it vanishes. (optional)
Returns:
is_connected
a boolean property that indicates whether the monitored proxy is actually connected. It can be checked before calling methods or accessing other properties on the object to avoid errors.
a Proxy object with extra properties:
See also:
Usage:
p = require("dbus_proxy") opts = { bus = p.Bus.SYSTEM, name = "com.example.BusName", interface = "com.example.InterfaceName", path = "/com/example/objectPath" } function callback(proxy, appeared) if appeared then -- proxy.is_connected is true proxy:SomeMethod() else -- proxy.is_connected is false end end proxy = p.monitored.new(opts, callback)
- opts
table
options that specify the DBus object to be proxied. In
addition to the fields documented in Proxy:new, the optional