ruby-dbus 0.11.2 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/NEWS +9 -0
- data/README.md +2 -2
- data/VERSION +1 -1
- data/doc/Reference.md +47 -14
- data/examples/gdbus/gdbus +8 -7
- data/examples/gdbus/gdbus.glade +98 -184
- data/examples/simple/get_id.rb +19 -0
- data/lib/dbus.rb +1 -0
- data/lib/dbus/api_options.rb +24 -0
- data/lib/dbus/bus.rb +20 -5
- data/lib/dbus/proxy_object.rb +5 -6
- data/lib/dbus/proxy_object_factory.rb +3 -2
- data/lib/dbus/proxy_object_interface.rb +23 -8
- data/ruby-dbus.gemspec +1 -1
- data/spec/property_spec.rb +19 -2
- data/spec/value_spec.rb +15 -3
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25c36fdb17d7d5c19b83d451de704117b285fb56
|
4
|
+
data.tar.gz: 3f6ddb8bb599e3cd616a1e3ebf9f15394e3acd17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fe993c938add6a07d8432c3ae846fa93bf3b75bf6403dd04271f9401c09b41de3dbdd5487567500fe21d5abe1ec6ec8b0b8bd98c82c00ad9932253cfb5de9bb
|
7
|
+
data.tar.gz: 02d8d3c914d5c3b74b759e8e7eabce7bb1aa6a9c7cd1620645ed69f345639e85ab00353757502440c6fb601b6d11c9ac4df290c60eb576c5d49e1af9deeb47b7
|
data/NEWS
CHANGED
@@ -7,6 +7,15 @@ Note about bug numbers:
|
|
7
7
|
|
8
8
|
== Unreleased
|
9
9
|
|
10
|
+
== Ruby D-Bus 0.12.0 - 2016-09-12
|
11
|
+
|
12
|
+
API:
|
13
|
+
* Added proxy objects whose methods return single values instead of arrays
|
14
|
+
(use Service#[] instead of Service#object; Issue#30).
|
15
|
+
|
16
|
+
Requirements:
|
17
|
+
* Require ruby 2.0.0, stopped supporting 1.9.3.
|
18
|
+
|
10
19
|
== Ruby D-Bus 0.11.2 - 2016-09-11
|
11
20
|
|
12
21
|
Bug fixes:
|
data/README.md
CHANGED
@@ -31,7 +31,7 @@ via [UPower](http://upower.freedesktop.org/docs/UPower.html#UPower:OnBattery)
|
|
31
31
|
require "dbus"
|
32
32
|
sysbus = DBus.system_bus
|
33
33
|
upower_service = sysbus["org.freedesktop.UPower"]
|
34
|
-
upower_object = upower_service
|
34
|
+
upower_object = upower_service["/org/freedesktop/UPower"]
|
35
35
|
upower_object.introspect
|
36
36
|
upower_interface = upower_object["org.freedesktop.UPower"]
|
37
37
|
on_battery = upower_interface["OnBattery"]
|
@@ -43,7 +43,7 @@ via [UPower](http://upower.freedesktop.org/docs/UPower.html#UPower:OnBattery)
|
|
43
43
|
|
44
44
|
## Requirements
|
45
45
|
|
46
|
-
- Ruby
|
46
|
+
- Ruby 2.0 or newer.
|
47
47
|
|
48
48
|
|
49
49
|
## Installation
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.12.0
|
data/doc/Reference.md
CHANGED
@@ -24,7 +24,7 @@ is simply "dbus"
|
|
24
24
|
|
25
25
|
1. {DBus.session_bus Connect to the session bus};
|
26
26
|
{DBus::Connection#[] get the screensaver service}
|
27
|
-
{DBus::Service#
|
27
|
+
{DBus::Service#[] and its screensaver object}.
|
28
28
|
2. Perform {DBus::ProxyObject#introspect explicit introspection}
|
29
29
|
to define the interfaces and methods
|
30
30
|
on the {DBus::ProxyObject object proxy}
|
@@ -32,9 +32,10 @@ is simply "dbus"
|
|
32
32
|
3. Call one of its methods in a loop, solving [xkcd#196](http://xkcd.com/196).
|
33
33
|
|
34
34
|
|
35
|
+
|
35
36
|
mybus = DBus.session_bus
|
36
37
|
service = mybus['org.freedesktop.ScreenSaver']
|
37
|
-
object = service
|
38
|
+
object = service['/ScreenSaver']
|
38
39
|
object.introspect
|
39
40
|
loop do
|
40
41
|
object.SimulateUserActivity
|
@@ -43,20 +44,47 @@ is simply "dbus"
|
|
43
44
|
|
44
45
|
##### Retrieving Return Values
|
45
46
|
|
46
|
-
A method proxy
|
47
|
+
A method proxy simply returns a value.
|
48
|
+
In this example SuspendAllowed returns a boolean:
|
49
|
+
|
50
|
+
mybus = DBus.session_bus
|
51
|
+
pm_s = mybus['org.freedesktop.PowerManagement']
|
52
|
+
pm_o = pm_s['/org/freedesktop/PowerManagement']
|
53
|
+
pm_o.introspect
|
54
|
+
pm_i = pm_o['org.freedesktop.PowerManagement']
|
55
|
+
|
56
|
+
if pm_i.CanSuspend
|
57
|
+
pm_i.Suspend
|
58
|
+
end
|
59
|
+
|
60
|
+
###### Multiple Return Values
|
61
|
+
|
62
|
+
In former versions of this library,
|
63
|
+
a method proxy always returned an array of values. This was to
|
47
64
|
accomodate the rare cases of a DBus method specifying more than one
|
48
|
-
*out* parameter. For
|
65
|
+
*out* parameter. For compatibility, the behavior is preserved if you
|
66
|
+
construct a {DBus::ProxyObject} with {DBus::ApiOptions::A0},
|
67
|
+
which is what {DBus::Service#object} does.
|
68
|
+
|
69
|
+
For nearly all methods you used `Method[0]` or
|
49
70
|
`Method.first`
|
50
71
|
([I#30](https://github.com/mvidner/ruby-dbus/issues/30)).
|
51
72
|
|
73
|
+
mybus = DBus.session_bus
|
74
|
+
pm_s = mybus['org.freedesktop.PowerManagement']
|
75
|
+
# use legacy compatibility API
|
76
|
+
pm_o = pm_s.object['/org/freedesktop/PowerManagement']
|
77
|
+
pm_o.introspect
|
78
|
+
pm_i = pm_o['org.freedesktop.PowerManagement']
|
79
|
+
|
52
80
|
# wrong
|
53
|
-
if
|
54
|
-
|
55
|
-
end
|
81
|
+
# if pm_i.CanSuspend
|
82
|
+
# pm_i.Suspend # [false] is true!
|
83
|
+
# end
|
56
84
|
|
57
85
|
# right
|
58
|
-
if
|
59
|
-
|
86
|
+
if pm_i.CanSuspend[0]
|
87
|
+
pm_i.Suspend
|
60
88
|
end
|
61
89
|
|
62
90
|
#### Accessing Properties
|
@@ -68,7 +96,7 @@ an actual Hash of them.
|
|
68
96
|
|
69
97
|
sysbus = DBus.system_bus
|
70
98
|
upower_s = sysbus['org.freedesktop.UPower']
|
71
|
-
upower_o = upower_s
|
99
|
+
upower_o = upower_s['/org/freedesktop/UPower']
|
72
100
|
upower_o.introspect
|
73
101
|
upower_i = upower_o['org.freedesktop.UPower']
|
74
102
|
|
@@ -112,6 +140,9 @@ To receive signals for a specific object and interface, use
|
|
112
140
|
login_o.introspect
|
113
141
|
login_o.default_iface = 'org.freedesktop.login1.Manager'
|
114
142
|
|
143
|
+
main = DBus::Main.new
|
144
|
+
main << sysbus
|
145
|
+
|
115
146
|
# to trigger this signal, login on the Linux console
|
116
147
|
login_o.on_signal("SessionNew") do |name, opath|
|
117
148
|
puts "New session: #{name}"
|
@@ -121,10 +152,9 @@ To receive signals for a specific object and interface, use
|
|
121
152
|
session_i = session_o['org.freedesktop.login1.Session']
|
122
153
|
uid, user_opath = session_i['User']
|
123
154
|
puts "Its UID: #{uid}"
|
155
|
+
main.quit
|
124
156
|
end
|
125
157
|
|
126
|
-
main = DBus::Main.new
|
127
|
-
main << sysbus
|
128
158
|
main.run
|
129
159
|
|
130
160
|
### Intermediate Concepts
|
@@ -174,7 +204,7 @@ If the signature expects a Variant
|
|
174
204
|
|
175
205
|
If a byte array (`ay`) is expected you can pass a String too.
|
176
206
|
The bytes sent are according to the string's
|
177
|
-
[encoding](http://ruby-doc.org/core-
|
207
|
+
[encoding](http://ruby-doc.org/core-2.0.0/Encoding.html).
|
178
208
|
|
179
209
|
##### nil
|
180
210
|
|
@@ -187,8 +217,11 @@ The bytes sent are according to the string's
|
|
187
217
|
D-Bus calls can reply with an error instead of a return value. An error is
|
188
218
|
translated to a Ruby exception, an instance of {DBus::Error}.
|
189
219
|
|
220
|
+
nm_o = DBus.system_bus["org.freedesktop.NetworkManager"]["/org/freedesktop/NetworkManager"]
|
221
|
+
nm_o.introspect
|
222
|
+
nm = nm_o["org.freedesktop.NetworkManager"]
|
190
223
|
begin
|
191
|
-
|
224
|
+
nm.Sleep(false)
|
192
225
|
rescue DBus::Error => e
|
193
226
|
puts e unless e.name == "org.freedesktop.NetworkManager.AlreadyAsleepOrAwake"
|
194
227
|
end
|
data/examples/gdbus/gdbus
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
# -- Arnaud
|
7
7
|
|
8
8
|
require 'dbus'
|
9
|
-
require
|
9
|
+
require "gtk2"
|
10
10
|
|
11
11
|
$enable_system = false
|
12
12
|
|
@@ -74,25 +74,26 @@ end
|
|
74
74
|
|
75
75
|
class DBusUI
|
76
76
|
def initialize
|
77
|
-
@glade =
|
78
|
-
|
79
|
-
|
77
|
+
@glade = Gtk::Builder.new
|
78
|
+
@glade << "gdbus.glade"
|
79
|
+
|
80
|
+
@sessiontreeview = @glade.get_object("sessiontreeview")
|
80
81
|
setup_treeview_renderer(@sessiontreeview, 'D-Bus Objects')
|
81
82
|
@sessiontreeview.selection.signal_connect("changed") do |selection|
|
82
83
|
on_treeview_selection_changed(selection)
|
83
84
|
end
|
84
85
|
|
85
|
-
@systemtreeview = @glade.
|
86
|
+
@systemtreeview = @glade.get_object("systemtreeview")
|
86
87
|
setup_treeview_renderer(@systemtreeview, 'D-Bus Objects')
|
87
88
|
@systemtreeview.selection.signal_connect("changed") do |selection|
|
88
89
|
on_treeview_selection_changed(selection)
|
89
90
|
end
|
90
91
|
|
91
|
-
@methsigtreeview = @glade.
|
92
|
+
@methsigtreeview = @glade.get_object("methsigtreeview")
|
92
93
|
# ierk
|
93
94
|
setup_methodview_renderer(@methsigtreeview)
|
94
95
|
|
95
|
-
@window = @glade.
|
96
|
+
@window = @glade.get_object("window1")
|
96
97
|
@window.show_all
|
97
98
|
start_buses
|
98
99
|
end
|
data/examples/gdbus/gdbus.glade
CHANGED
@@ -1,184 +1,98 @@
|
|
1
|
-
<?xml version="1.0"
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
<
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
<property name="shadow_type">GTK_SHADOW_IN</property>
|
100
|
-
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
101
|
-
|
102
|
-
<child>
|
103
|
-
<widget class="GtkTreeView" id="systemtreeview">
|
104
|
-
<property name="visible">True</property>
|
105
|
-
<property name="can_focus">True</property>
|
106
|
-
<property name="headers_visible">True</property>
|
107
|
-
<property name="rules_hint">False</property>
|
108
|
-
<property name="reorderable">False</property>
|
109
|
-
<property name="enable_search">True</property>
|
110
|
-
<property name="fixed_height_mode">False</property>
|
111
|
-
<property name="hover_selection">False</property>
|
112
|
-
<property name="hover_expand">False</property>
|
113
|
-
</widget>
|
114
|
-
</child>
|
115
|
-
</widget>
|
116
|
-
<packing>
|
117
|
-
<property name="tab_expand">False</property>
|
118
|
-
<property name="tab_fill">True</property>
|
119
|
-
</packing>
|
120
|
-
</child>
|
121
|
-
|
122
|
-
<child>
|
123
|
-
<widget class="GtkLabel" id="label2">
|
124
|
-
<property name="visible">True</property>
|
125
|
-
<property name="label" translatable="yes">System</property>
|
126
|
-
<property name="use_underline">False</property>
|
127
|
-
<property name="use_markup">False</property>
|
128
|
-
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
129
|
-
<property name="wrap">False</property>
|
130
|
-
<property name="selectable">False</property>
|
131
|
-
<property name="xalign">0.5</property>
|
132
|
-
<property name="yalign">0.5</property>
|
133
|
-
<property name="xpad">0</property>
|
134
|
-
<property name="ypad">0</property>
|
135
|
-
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
136
|
-
<property name="width_chars">-1</property>
|
137
|
-
<property name="single_line_mode">False</property>
|
138
|
-
<property name="angle">0</property>
|
139
|
-
</widget>
|
140
|
-
<packing>
|
141
|
-
<property name="type">tab</property>
|
142
|
-
</packing>
|
143
|
-
</child>
|
144
|
-
</widget>
|
145
|
-
<packing>
|
146
|
-
<property name="shrink">True</property>
|
147
|
-
<property name="resize">False</property>
|
148
|
-
</packing>
|
149
|
-
</child>
|
150
|
-
|
151
|
-
<child>
|
152
|
-
<widget class="GtkScrolledWindow" id="scrolledwindow4">
|
153
|
-
<property name="visible">True</property>
|
154
|
-
<property name="can_focus">True</property>
|
155
|
-
<property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
|
156
|
-
<property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
|
157
|
-
<property name="shadow_type">GTK_SHADOW_IN</property>
|
158
|
-
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
159
|
-
|
160
|
-
<child>
|
161
|
-
<widget class="GtkTreeView" id="methsigtreeview">
|
162
|
-
<property name="visible">True</property>
|
163
|
-
<property name="can_focus">True</property>
|
164
|
-
<property name="headers_visible">True</property>
|
165
|
-
<property name="rules_hint">False</property>
|
166
|
-
<property name="reorderable">False</property>
|
167
|
-
<property name="enable_search">True</property>
|
168
|
-
<property name="fixed_height_mode">False</property>
|
169
|
-
<property name="hover_selection">False</property>
|
170
|
-
<property name="hover_expand">False</property>
|
171
|
-
<signal name="row_activated" handler="on_method_activated" last_modification_time="Sat, 17 Mar 2007 14:49:13 GMT"/>
|
172
|
-
</widget>
|
173
|
-
</child>
|
174
|
-
</widget>
|
175
|
-
<packing>
|
176
|
-
<property name="shrink">True</property>
|
177
|
-
<property name="resize">False</property>
|
178
|
-
</packing>
|
179
|
-
</child>
|
180
|
-
</widget>
|
181
|
-
</child>
|
182
|
-
</widget>
|
183
|
-
|
184
|
-
</glade-interface>
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<interface>
|
3
|
+
<!-- interface-requires gtk+ 2.6 -->
|
4
|
+
<!-- interface-naming-policy toplevel-contextual -->
|
5
|
+
<object class="GtkWindow" id="window1">
|
6
|
+
<property name="visible">True</property>
|
7
|
+
<property name="can_focus">False</property>
|
8
|
+
<property name="title" translatable="yes">GD-Bus</property>
|
9
|
+
<property name="default_width">500</property>
|
10
|
+
<property name="default_height">400</property>
|
11
|
+
<signal name="delete-event" handler="on_window_delete_event" swapped="no"/>
|
12
|
+
<child>
|
13
|
+
<object class="GtkHPaned" id="hpaned1">
|
14
|
+
<property name="visible">True</property>
|
15
|
+
<property name="can_focus">True</property>
|
16
|
+
<child>
|
17
|
+
<object class="GtkNotebook" id="notebook1">
|
18
|
+
<property name="visible">True</property>
|
19
|
+
<property name="can_focus">True</property>
|
20
|
+
<child>
|
21
|
+
<object class="GtkScrolledWindow" id="scrolledwindow3">
|
22
|
+
<property name="visible">True</property>
|
23
|
+
<property name="can_focus">True</property>
|
24
|
+
<property name="shadow_type">in</property>
|
25
|
+
<child>
|
26
|
+
<object class="GtkTreeView" id="sessiontreeview">
|
27
|
+
<property name="visible">True</property>
|
28
|
+
<property name="can_focus">True</property>
|
29
|
+
<signal name="row-activated" handler="on_sessiontreeview_row_activated" swapped="no"/>
|
30
|
+
</object>
|
31
|
+
</child>
|
32
|
+
</object>
|
33
|
+
</child>
|
34
|
+
<child type="tab">
|
35
|
+
<object class="GtkLabel" id="label1">
|
36
|
+
<property name="visible">True</property>
|
37
|
+
<property name="can_focus">False</property>
|
38
|
+
<property name="label" translatable="yes">Session</property>
|
39
|
+
</object>
|
40
|
+
<packing>
|
41
|
+
<property name="tab_fill">False</property>
|
42
|
+
</packing>
|
43
|
+
</child>
|
44
|
+
<child>
|
45
|
+
<object class="GtkScrolledWindow" id="scrolledwindow5">
|
46
|
+
<property name="visible">True</property>
|
47
|
+
<property name="can_focus">True</property>
|
48
|
+
<property name="shadow_type">in</property>
|
49
|
+
<child>
|
50
|
+
<object class="GtkTreeView" id="systemtreeview">
|
51
|
+
<property name="visible">True</property>
|
52
|
+
<property name="can_focus">True</property>
|
53
|
+
</object>
|
54
|
+
</child>
|
55
|
+
</object>
|
56
|
+
<packing>
|
57
|
+
<property name="position">1</property>
|
58
|
+
</packing>
|
59
|
+
</child>
|
60
|
+
<child type="tab">
|
61
|
+
<object class="GtkLabel" id="label2">
|
62
|
+
<property name="visible">True</property>
|
63
|
+
<property name="can_focus">False</property>
|
64
|
+
<property name="label" translatable="yes">System</property>
|
65
|
+
</object>
|
66
|
+
<packing>
|
67
|
+
<property name="position">1</property>
|
68
|
+
<property name="tab_fill">False</property>
|
69
|
+
</packing>
|
70
|
+
</child>
|
71
|
+
</object>
|
72
|
+
<packing>
|
73
|
+
<property name="resize">False</property>
|
74
|
+
<property name="shrink">True</property>
|
75
|
+
</packing>
|
76
|
+
</child>
|
77
|
+
<child>
|
78
|
+
<object class="GtkScrolledWindow" id="scrolledwindow4">
|
79
|
+
<property name="visible">True</property>
|
80
|
+
<property name="can_focus">True</property>
|
81
|
+
<property name="shadow_type">in</property>
|
82
|
+
<child>
|
83
|
+
<object class="GtkTreeView" id="methsigtreeview">
|
84
|
+
<property name="visible">True</property>
|
85
|
+
<property name="can_focus">True</property>
|
86
|
+
<signal name="row-activated" handler="on_method_activated" swapped="no"/>
|
87
|
+
</object>
|
88
|
+
</child>
|
89
|
+
</object>
|
90
|
+
<packing>
|
91
|
+
<property name="resize">False</property>
|
92
|
+
<property name="shrink">True</property>
|
93
|
+
</packing>
|
94
|
+
</child>
|
95
|
+
</object>
|
96
|
+
</child>
|
97
|
+
</object>
|
98
|
+
</interface>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
# find the library without external help
|
4
|
+
$:.unshift File.expand_path("../../../lib", __FILE__)
|
5
|
+
|
6
|
+
require "dbus"
|
7
|
+
|
8
|
+
bus = DBus::SystemBus.instance
|
9
|
+
driver_svc = bus["org.freedesktop.DBus"]
|
10
|
+
# p driver_svc
|
11
|
+
driver_obj = driver_svc["/"]
|
12
|
+
# p driver_obj
|
13
|
+
driver_obj.introspect
|
14
|
+
|
15
|
+
driver_ifc = driver_obj["org.freedesktop.DBus"]
|
16
|
+
# p driver_ifc
|
17
|
+
|
18
|
+
bus_id = driver_ifc.GetId
|
19
|
+
puts "The system bus id is #{bus_id}"
|
data/lib/dbus.rb
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
# License, version 2.1 as published by the Free Software Foundation.
|
9
9
|
# See the file "COPYING" for the exact licensing terms.
|
10
10
|
|
11
|
+
require_relative "dbus/api_options"
|
11
12
|
require_relative "dbus/auth"
|
12
13
|
require_relative "dbus/bus"
|
13
14
|
require_relative "dbus/core_ext/class/attribute"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# This file is part of the ruby-dbus project
|
2
|
+
# Copyright (C) 2016 Martin Vidner
|
3
|
+
#
|
4
|
+
# This library is free software; you can redistribute it and/or
|
5
|
+
# modify it under the terms of the GNU Lesser General Public
|
6
|
+
# License, version 2.1 as published by the Free Software Foundation.
|
7
|
+
# See the file "COPYING" for the exact licensing terms.
|
8
|
+
|
9
|
+
module DBus
|
10
|
+
class ApiOptions
|
11
|
+
# https://github.com/mvidner/ruby-dbus/issues/30
|
12
|
+
attr_accessor :proxy_method_returns_array
|
13
|
+
|
14
|
+
A0 = ApiOptions.new
|
15
|
+
A0.proxy_method_returns_array = true
|
16
|
+
A0.freeze
|
17
|
+
|
18
|
+
A1 = ApiOptions.new
|
19
|
+
A1.proxy_method_returns_array = false
|
20
|
+
A1.freeze
|
21
|
+
|
22
|
+
CURRENT = A1
|
23
|
+
end
|
24
|
+
end
|
data/lib/dbus/bus.rb
CHANGED
@@ -50,10 +50,20 @@ module DBus
|
|
50
50
|
|
51
51
|
# Retrieves an object at the given _path_.
|
52
52
|
# @return [ProxyObject]
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
def [](path)
|
54
|
+
object(path, api: ApiOptions::A1)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Retrieves an object at the given _path_
|
58
|
+
# whose methods always return an array.
|
59
|
+
# @return [ProxyObject]
|
60
|
+
def object(path, api: ApiOptions::A0)
|
61
|
+
node = get_node(path, _create = true)
|
62
|
+
if node.object.nil? || node.object.api != api
|
63
|
+
node.object = ProxyObject.new(
|
64
|
+
@bus, @name, path,
|
65
|
+
api: api
|
66
|
+
)
|
57
67
|
end
|
58
68
|
node.object
|
59
69
|
end
|
@@ -417,12 +427,17 @@ module DBus
|
|
417
427
|
end
|
418
428
|
|
419
429
|
# Set up a ProxyObject for the bus itself, since the bus is introspectable.
|
430
|
+
# @return [ProxyObject] that always returns an array
|
431
|
+
# ({DBus::ApiOptions#proxy_method_returns_array})
|
420
432
|
# Returns the object.
|
421
433
|
def proxy
|
422
434
|
if @proxy == nil
|
423
435
|
path = "/org/freedesktop/DBus"
|
424
436
|
dest = "org.freedesktop.DBus"
|
425
|
-
pof = DBus::ProxyObjectFactory.new(
|
437
|
+
pof = DBus::ProxyObjectFactory.new(
|
438
|
+
DBUSXMLINTRO, self, dest, path,
|
439
|
+
api: ApiOptions::A0
|
440
|
+
)
|
426
441
|
@proxy = pof.build["org.freedesktop.DBus"]
|
427
442
|
end
|
428
443
|
@proxy
|
data/lib/dbus/proxy_object.rb
CHANGED
@@ -27,13 +27,17 @@ module DBus
|
|
27
27
|
attr_reader :bus
|
28
28
|
# @return [String] The name of the default interface of the object.
|
29
29
|
attr_accessor :default_iface
|
30
|
+
# @api private
|
31
|
+
# @return [ApiOptions]
|
32
|
+
attr_reader :api
|
30
33
|
|
31
34
|
# Creates a new proxy object living on the given _bus_ at destination _dest_
|
32
35
|
# on the given _path_.
|
33
|
-
def initialize(bus, dest, path)
|
36
|
+
def initialize(bus, dest, path, api: ApiOptions::CURRENT)
|
34
37
|
@bus, @destination, @path = bus, dest, path
|
35
38
|
@interfaces = Hash.new
|
36
39
|
@subnodes = Array.new
|
40
|
+
@api = api
|
37
41
|
end
|
38
42
|
|
39
43
|
# Returns the interfaces of the object.
|
@@ -140,10 +144,5 @@ module DBus
|
|
140
144
|
raise NoMethodError, "undefined method `#{name}' for DBus interface `#{@default_iface}' on object `#{@path}'"
|
141
145
|
end
|
142
146
|
end
|
143
|
-
|
144
|
-
# Returns the singleton class of the object.
|
145
|
-
def singleton_class
|
146
|
-
(class << self ; self ; end)
|
147
|
-
end
|
148
147
|
end # class ProxyObject
|
149
148
|
end
|
@@ -14,8 +14,9 @@ module DBus
|
|
14
14
|
class ProxyObjectFactory
|
15
15
|
# Creates a new proxy object factory for the given introspection XML _xml_,
|
16
16
|
# _bus_, destination _dest_, and _path_.
|
17
|
-
def initialize(xml, bus, dest, path)
|
17
|
+
def initialize(xml, bus, dest, path, api: ApiOptions::CURRENT)
|
18
18
|
@xml, @bus, @path, @dest = xml, bus, path, dest
|
19
|
+
@api = api
|
19
20
|
end
|
20
21
|
|
21
22
|
# Investigates the sub-nodes of the proxy object _po_ based on the
|
@@ -33,7 +34,7 @@ module DBus
|
|
33
34
|
|
34
35
|
# Generates, sets up and returns the proxy object.
|
35
36
|
def build
|
36
|
-
po = ProxyObject.new(@bus, @dest, @path)
|
37
|
+
po = ProxyObject.new(@bus, @dest, @path, api: @api)
|
37
38
|
ProxyObjectFactory.introspect_into(po, @xml)
|
38
39
|
po
|
39
40
|
end
|
@@ -34,11 +34,6 @@ module DBus
|
|
34
34
|
@name
|
35
35
|
end
|
36
36
|
|
37
|
-
# Returns the singleton class of the interface.
|
38
|
-
def singleton_class
|
39
|
-
(class << self ; self ; end)
|
40
|
-
end
|
41
|
-
|
42
37
|
# Defines a method on the interface from the Method descriptor _m_.
|
43
38
|
def define_method_from_descriptor(m)
|
44
39
|
m.params.each do |fpar|
|
@@ -63,7 +58,12 @@ module DBus
|
|
63
58
|
par = fpar.type
|
64
59
|
msg.add_param(par, args.shift)
|
65
60
|
end
|
66
|
-
@object.bus.send_sync_or_async(msg, &reply_handler)
|
61
|
+
ret = @object.bus.send_sync_or_async(msg, &reply_handler)
|
62
|
+
if ret.nil? || @object.api.proxy_method_returns_array
|
63
|
+
ret
|
64
|
+
else
|
65
|
+
m.rets.size == 1 ? ret.first : ret
|
66
|
+
end
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
@@ -110,11 +110,20 @@ module DBus
|
|
110
110
|
PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"
|
111
111
|
|
112
112
|
# Read a property.
|
113
|
+
# @param propname [String]
|
113
114
|
def [](propname)
|
114
|
-
self.object[PROPERTY_INTERFACE].Get(self.name, propname)
|
115
|
+
ret = self.object[PROPERTY_INTERFACE].Get(self.name, propname)
|
116
|
+
# this method always returns the single property
|
117
|
+
if @object.api.proxy_method_returns_array
|
118
|
+
ret[0]
|
119
|
+
else
|
120
|
+
ret
|
121
|
+
end
|
115
122
|
end
|
116
123
|
|
117
124
|
# Write a property.
|
125
|
+
# @param propname [String]
|
126
|
+
# @param value [Object]
|
118
127
|
def []=(propname, value)
|
119
128
|
self.object[PROPERTY_INTERFACE].Set(self.name, propname, value)
|
120
129
|
end
|
@@ -122,7 +131,13 @@ module DBus
|
|
122
131
|
# Read all properties at once, as a hash.
|
123
132
|
# @return [Hash{String}]
|
124
133
|
def all_properties
|
125
|
-
self.object[PROPERTY_INTERFACE].GetAll(self.name)
|
134
|
+
ret = self.object[PROPERTY_INTERFACE].GetAll(self.name)
|
135
|
+
# this method always returns the single property
|
136
|
+
if @object.api.proxy_method_returns_array
|
137
|
+
ret[0]
|
138
|
+
else
|
139
|
+
ret
|
140
|
+
end
|
126
141
|
end
|
127
142
|
end # class ProxyObjectInterface
|
128
143
|
end
|
data/ruby-dbus.gemspec
CHANGED
@@ -14,7 +14,7 @@ GEMSPEC = Gem::Specification.new do |s|
|
|
14
14
|
s.homepage = "https://trac.luon.net/ruby-dbus"
|
15
15
|
s.files = FileList["{doc,examples,lib,spec}/**/*", "COPYING", "NEWS", "Rakefile", "README.md", "ruby-dbus.gemspec", "VERSION", ".rspec"].to_a.sort
|
16
16
|
s.require_path = "lib"
|
17
|
-
s.required_ruby_version = ">=
|
17
|
+
s.required_ruby_version = ">= 2.0.0"
|
18
18
|
s.add_development_dependency("packaging_rake_tasks")
|
19
19
|
s.add_development_dependency("rspec")
|
20
20
|
end
|
data/spec/property_spec.rb
CHANGED
@@ -5,8 +5,8 @@ require "dbus"
|
|
5
5
|
describe "PropertyTest" do
|
6
6
|
before(:each) do
|
7
7
|
session_bus = DBus::ASessionBus.new
|
8
|
-
svc = session_bus.service("org.ruby.service")
|
9
|
-
@obj = svc.object("/org/ruby/MyInstance")
|
8
|
+
@svc = session_bus.service("org.ruby.service")
|
9
|
+
@obj = @svc.object("/org/ruby/MyInstance")
|
10
10
|
@obj.introspect
|
11
11
|
@iface = @obj["org.ruby.SampleInterface"]
|
12
12
|
end
|
@@ -15,6 +15,14 @@ describe "PropertyTest" do
|
|
15
15
|
expect(@iface["ReadMe"]).to eq("READ ME")
|
16
16
|
end
|
17
17
|
|
18
|
+
it "tests property reading on a V1 object" do
|
19
|
+
obj = @svc["/org/ruby/MyInstance"]
|
20
|
+
obj.introspect
|
21
|
+
iface = obj["org.ruby.SampleInterface"]
|
22
|
+
|
23
|
+
expect(iface["ReadMe"]).to eq("READ ME")
|
24
|
+
end
|
25
|
+
|
18
26
|
it "tests property nonreading" do
|
19
27
|
expect { @iface["WriteMe"] }.to raise_error(DBus::Error, /not readable/)
|
20
28
|
end
|
@@ -43,6 +51,15 @@ describe "PropertyTest" do
|
|
43
51
|
expect(all.keys.sort).to eq(["ReadMe", "ReadOrWriteMe"])
|
44
52
|
end
|
45
53
|
|
54
|
+
it "tests get all on a V1 object" do
|
55
|
+
obj = @svc["/org/ruby/MyInstance"]
|
56
|
+
obj.introspect
|
57
|
+
iface = obj["org.ruby.SampleInterface"]
|
58
|
+
|
59
|
+
all = iface.all_properties
|
60
|
+
expect(all.keys.sort).to eq(["ReadMe", "ReadOrWriteMe"])
|
61
|
+
end
|
62
|
+
|
46
63
|
it "tests unknown property reading" do
|
47
64
|
expect { @iface["Spoon"] }.to raise_error(DBus::Error, /not found/)
|
48
65
|
end
|
data/spec/value_spec.rb
CHANGED
@@ -6,8 +6,8 @@ require "dbus"
|
|
6
6
|
describe "ValueTest" do
|
7
7
|
before(:each) do
|
8
8
|
session_bus = DBus::ASessionBus.new
|
9
|
-
svc = session_bus.service("org.ruby.service")
|
10
|
-
@obj = svc.object("/org/ruby/MyInstance")
|
9
|
+
@svc = session_bus.service("org.ruby.service")
|
10
|
+
@obj = @svc.object("/org/ruby/MyInstance")
|
11
11
|
@obj.introspect # necessary
|
12
12
|
@obj.default_iface = "org.ruby.SampleInterface"
|
13
13
|
end
|
@@ -36,7 +36,19 @@ describe "ValueTest" do
|
|
36
36
|
empty_hash = {}
|
37
37
|
expect(@obj.bounce_variant(empty_hash)[0]).to eq(empty_hash)
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
|
+
it "retrieves a single return value with API V1" do
|
41
|
+
obj = @svc["/org/ruby/MyInstance"]
|
42
|
+
obj.introspect
|
43
|
+
obj.default_iface = "org.ruby.SampleInterface"
|
44
|
+
|
45
|
+
expect(obj.bounce_variant("cuckoo")).to eq("cuckoo")
|
46
|
+
expect(obj.bounce_variant(["coucou", "kuku"])).to eq(["coucou", "kuku"])
|
47
|
+
expect(obj.bounce_variant([])).to eq([])
|
48
|
+
empty_hash = {}
|
49
|
+
expect(obj.bounce_variant(empty_hash)).to eq(empty_hash)
|
50
|
+
end
|
51
|
+
|
40
52
|
# these are ambiguous
|
41
53
|
it "tests pairs with a string" do
|
42
54
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-dbus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ruby DBus Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: packaging_rake_tasks
|
@@ -63,10 +63,12 @@ files:
|
|
63
63
|
- examples/service/call_service.rb
|
64
64
|
- examples/service/service_newapi.rb
|
65
65
|
- examples/simple/call_introspect.rb
|
66
|
+
- examples/simple/get_id.rb
|
66
67
|
- examples/simple/properties.rb
|
67
68
|
- examples/utils/listnames.rb
|
68
69
|
- examples/utils/notify.rb
|
69
70
|
- lib/dbus.rb
|
71
|
+
- lib/dbus/api_options.rb
|
70
72
|
- lib/dbus/auth.rb
|
71
73
|
- lib/dbus/bus.rb
|
72
74
|
- lib/dbus/core_ext/array/extract_options.rb
|
@@ -125,7 +127,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
125
127
|
requirements:
|
126
128
|
- - ">="
|
127
129
|
- !ruby/object:Gem::Version
|
128
|
-
version:
|
130
|
+
version: 2.0.0
|
129
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
132
|
requirements:
|
131
133
|
- - ">="
|