ruby-dbus 0.11.2 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
- - ">="
|