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
- 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. |
build_params (args) | Build a lgi.GLib.Variant tuple that can be used to call a method |
call (proxy, interface, method, args) | Synchronously call a method with arguments from a given interface on a proxy object. |
call_async (proxy, interface, method, user_callback, context, args) | Asynchronously call a method with arguments from a given interface on a proxy object. |
get_property (proxy, name) | Get a cached property out of a proxy object |
set_property (proxy, name, opts) | Set a cached property of a proxy object |
introspect (proxy) | Get the XML representation of a proxy object |
build_args (method, list) | Build arguments for a method call. |
generate_method (interface_name, method) | Generate a synchronous method. |
generate_async_method (interface_name, method) | Generate an asynchronous method. |
generate_accessor (property) | Generate the accessor table for a property |
generate_fields (proxy) | Generate the fields of a proxy object. |
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
- build_params (args)
-
Build a lgi.GLib.Variant tuple that can be used to call a method
Parameters:
- args
[type=table] an array of tables that have the
type
andvalue
fields. For example{ {type = "s", value = "a string"}, {type = "v", value = lgi.GLib.Variant("s", "a string variant")} }
Returns:
-
lgi.GLib.Variant
tuple or
nil
if no arguments are passed.See also:
- args
- call (proxy, interface, method, args)
-
Synchronously call a method with arguments from a given interface on a proxy object.
Parameters:
- proxy Proxy a Proxy object
- interface string the interface name
- method string the method name
- args
lgi.GLib.Variant
lgi.GLib.Variant
tuple arguments
to be passed to
method
See also:
- call_async (proxy, interface, method, user_callback, context, args)
-
Asynchronously call a method with arguments from a given interface on a proxy object.
Internally, it uses
gdbusproxycall
and
gdbusproxycall_finish.
Parameters:
- proxy Proxy a Proxy object.
- interface string the interface name.
- method string the method name
- user_callback
function
callback function that accepts four
arguments:
proxy
(the Proxy object),context
arbitrary context data (see also thecontext
parameter of this function),success
(the data, if any, returned by the DBus method in case of success),failure
(the data, if any, returned by the DBus method in case of failure) - context
any
context data that will be passed to
user_callback
. - args
lgi.GLib.Variant
lgi.GLib.Variant
tuple arguments
to be passed to
method
See also:
- get_property (proxy, name)
-
Get a cached property out of a proxy object
Parameters:
- proxy Proxy a proxy object
- name string the name of the property
Returns:
-
the value of the property
- set_property (proxy, name, opts)
-
Set a cached property of a proxy object
Parameters:
- proxy Proxy a proxy object
- name string the name of the property
- opts
table
containing the following attributes:
-value
the value to be set
-signature
the DBus signature as a string
- introspect (proxy)
-
Get the XML representation of a proxy object
Parameters:
- proxy Proxy a proxy object
Returns:
-
a string with the XML representation of the object
- build_args (method, list)
-
Build arguments for a method call.
Parameters:
- method lgi.Gio.DBusMethodInfo the method info object
- list any of arguments as lua types
Returns:
-
lgi.GLib.Variant
tuple or
nil
if no arguments are passed.See also:
- generate_method (interface_name, method)
-
Generate a synchronous method.
Parameters:
- interface_name string the interface name
- method lgi.Gio.DBusMethodInfo the method info object
Returns:
-
a function that wraps build_args and call so the method can be called
by passing the arguments as simple lua types.
See also:
- generate_async_method (interface_name, method)
-
Generate an asynchronous method.
Parameters:
- interface_name string the interface name
- method lgi.Gio.DBusMethodInfo the method info object
Returns:
-
a function that wraps build_args and call_async so the method can be called
by passing the arguments as simple lua types.
See also:
- generate_accessor (property)
-
Generate the accessor table for a property
Parameters:
- property lgi.Gio.DBusPropertyInfo the property info object
Returns:
-
a table with the
getter
andsetter
fields that wrap get_property and set_property respectively. If the property is not readable or writeable, the functions will return an error when attempting to read/write the property.See also:
- generate_fields (proxy)
-
Generate the fields of a proxy object.
This function will attach properties, methods and signals to the proxy object. To be used during initialization. NOTE This function will not generate fields for nested nodes, if any.
Parameters:
- proxy Proxy a proxy object
- 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