ruby-dbus 0.8.0 → 0.9.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.
- data/NEWS +13 -0
- data/{README → README.md} +10 -10
- data/Rakefile +4 -12
- data/VERSION +1 -1
- data/doc/Reference.md +196 -0
- data/doc/{tutorial/index.markdown → Tutorial.md} +0 -0
- data/doc/ex-calling-methods.body.rb +8 -0
- data/doc/ex-calling-methods.rb +3 -0
- data/doc/ex-properties.body.rb +9 -0
- data/doc/ex-properties.rb +3 -0
- data/doc/ex-setup.rb +7 -0
- data/doc/ex-signal.body.rb +20 -0
- data/doc/ex-signal.rb +3 -0
- data/doc/example-helper.rb +6 -0
- data/lib/dbus.rb +2 -1
- data/lib/dbus/auth.rb +10 -12
- data/lib/dbus/bus.rb +17 -12
- data/lib/dbus/introspect.rb +92 -41
- data/lib/dbus/logger.rb +31 -0
- data/lib/dbus/message.rb +16 -58
- data/lib/dbus/type.rb +32 -64
- data/lib/dbus/xml.rb +4 -2
- data/ruby-dbus.gemspec +3 -3
- data/test/bus_driver_test.rb +0 -4
- data/test/introspection_test.rb +31 -0
- data/test/service_newapi.rb +16 -9
- data/test/session_bus_test_manual.rb +0 -4
- data/test/signal_test.rb +34 -9
- data/test/t6-loop.rb +5 -9
- data/test/thread_safety_test.rb +0 -4
- data/test/type_test.rb +22 -0
- metadata +36 -43
data/NEWS
CHANGED
@@ -5,6 +5,19 @@ Note about bug numbers:
|
|
5
5
|
Issue#1 - http://github.com/mvidner/ruby-dbus/issues#issue/1
|
6
6
|
bnc#1 - https://bugzilla.novell.com/show_bug.cgi?id=1
|
7
7
|
|
8
|
+
== Ruby D-Bus 0.9.0 - 2012-11-06
|
9
|
+
|
10
|
+
Features:
|
11
|
+
* When calling methods, the interface can be left unspecified if unambiguous
|
12
|
+
(Damiano Stoffie)
|
13
|
+
* YARD documentation, Reference.md
|
14
|
+
|
15
|
+
Bug fixes:
|
16
|
+
* Introspection attribute "direction" can be omitted
|
17
|
+
as allowed by the specification (Noah Meyerhans).
|
18
|
+
* ProxyObjectInterface#on_signal no longer needs the "bus" parameter
|
19
|
+
(Issue#31, by Damiano Stoffie)
|
20
|
+
|
8
21
|
== Ruby D-Bus 0.8.0 - 2012-09-20
|
9
22
|
|
10
23
|
Features:
|
data/{README → README.md}
RENAMED
@@ -1,17 +1,17 @@
|
|
1
|
-
|
1
|
+
# Ruby D-Bus README
|
2
2
|
|
3
3
|
Ruby D-Bus provides an implementation of the D-Bus protocol such that the
|
4
4
|
D-Bus system can be used in the Ruby programming language.
|
5
5
|
|
6
|
-
|
6
|
+
## Requirements
|
7
7
|
|
8
|
-
|
8
|
+
- Ruby 1.8.7 or 1.9
|
9
9
|
|
10
|
-
|
10
|
+
## Installation
|
11
11
|
|
12
|
-
|
12
|
+
- `gem install ruby-dbus`
|
13
13
|
|
14
|
-
|
14
|
+
## Features
|
15
15
|
|
16
16
|
Ruby D-Bus currently supports the following features:
|
17
17
|
|
@@ -27,14 +27,14 @@ Ruby D-Bus currently supports the following features:
|
|
27
27
|
allows for introspection.
|
28
28
|
* Emitting signals on exported objects.
|
29
29
|
|
30
|
-
|
30
|
+
## Usage
|
31
31
|
|
32
32
|
See some of the examples in the examples/ subdirectory of the tarball.
|
33
|
-
Also, check out the included tutorial (in Markdown format) in doc/
|
33
|
+
Also, check out the included tutorial (in Markdown format) in doc/Tutorial.md
|
34
34
|
or view it online on
|
35
|
-
https://github.com/mvidner/ruby-dbus/blob/master/doc/
|
35
|
+
<https://github.com/mvidner/ruby-dbus/blob/master/doc/Tutorial.md> .
|
36
36
|
|
37
|
-
|
37
|
+
## License
|
38
38
|
|
39
39
|
Ruby D-Bus is free software; you can redistribute it and/or modify it
|
40
40
|
under the terms of the GNU Lesser General Public License as published by the
|
data/Rakefile
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
require 'rake'
|
3
|
-
require 'rake/gempackagetask'
|
4
3
|
require 'fileutils'
|
5
4
|
include FileUtils
|
6
5
|
require 'tmpdir'
|
@@ -33,10 +32,9 @@ end
|
|
33
32
|
end
|
34
33
|
end
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
# no other formats needed
|
35
|
+
desc "Build the gem file"
|
36
|
+
task :package do
|
37
|
+
sh "gem build ruby-dbus.gemspec"
|
40
38
|
end
|
41
39
|
|
42
40
|
desc "Build a package from a clone of the local Git repo"
|
@@ -46,7 +44,7 @@ task :package_git do |t|
|
|
46
44
|
cd temp do
|
47
45
|
sh "rake package"
|
48
46
|
end
|
49
|
-
|
47
|
+
cp Dir.glob("#{temp}/*.gem"), "."
|
50
48
|
end
|
51
49
|
end
|
52
50
|
|
@@ -56,9 +54,3 @@ Rake::RDocTask.new do |rd|
|
|
56
54
|
# rd.options << "--diagram"
|
57
55
|
# rd.options << "--all"
|
58
56
|
end
|
59
|
-
|
60
|
-
desc "Render the tutorial in HTML"
|
61
|
-
task :tutorial => "doc/tutorial/index.html"
|
62
|
-
file "doc/tutorial/index.html" => "doc/tutorial/index.markdown" do |t|
|
63
|
-
sh "markdown #{t.prerequisites[0]} > #{t.name}"
|
64
|
-
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.9.0
|
data/doc/Reference.md
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
Ruby D-Bus Reference
|
2
|
+
====================
|
3
|
+
|
4
|
+
This is a reference-style documentation. It's not [a tutorial for
|
5
|
+
beginners](http://dbus.freedesktop.org/doc/dbus-tutorial.html), the
|
6
|
+
reader should have knowledge of basic DBus concepts.
|
7
|
+
|
8
|
+
Client Side
|
9
|
+
-----------
|
10
|
+
|
11
|
+
This section should be enough if you only want to consume DBus APIs.
|
12
|
+
|
13
|
+
### Basic Concepts
|
14
|
+
|
15
|
+
#### Setting Up
|
16
|
+
|
17
|
+
The following code is assumed as a prolog to all following ones
|
18
|
+
|
19
|
+
{include:file:doc/ex-setup.rb}
|
20
|
+
|
21
|
+
#### Calling Methods
|
22
|
+
|
23
|
+
1. {DBus.session_bus Connect to the session bus};
|
24
|
+
{DBus::Connection#[] get the screensaver service}
|
25
|
+
{DBus::Service#object and its screensaver object}.
|
26
|
+
2. Perform {DBus::ProxyObject#introspect explicit introspection}
|
27
|
+
to define the interfaces and methods
|
28
|
+
on the {DBus::ProxyObject object proxy}
|
29
|
+
([I#28](https://github.com/mvidner/ruby-dbus/issues/28)).
|
30
|
+
3. Call one of its methods in a loop, solving [xkcd#196](http://xkcd.com/196).
|
31
|
+
|
32
|
+
{include:file:doc/ex-calling-methods.body.rb}
|
33
|
+
|
34
|
+
##### Retrieving Return Values
|
35
|
+
|
36
|
+
A method proxy always returns an array of values. This is to
|
37
|
+
accomodate the rare cases of a DBus method specifying more than one
|
38
|
+
*out* parameter. For nearly all methods you should use `Method[0]` or
|
39
|
+
`Method.first`
|
40
|
+
([I#30](https://github.com/mvidner/ruby-dbus/issues/30)).
|
41
|
+
|
42
|
+
|
43
|
+
# wrong
|
44
|
+
if upower_i.SuspendAllowed # [false] is true!
|
45
|
+
upower_i.Suspend
|
46
|
+
end
|
47
|
+
|
48
|
+
# right
|
49
|
+
if upower_i.SuspendAllowed[0]
|
50
|
+
upower_i.Suspend
|
51
|
+
end
|
52
|
+
|
53
|
+
#### Accessing Properties
|
54
|
+
|
55
|
+
To access properties, think of the {DBus::ProxyObjectInterface interface} as a
|
56
|
+
{DBus::ProxyObjectInterface#[] hash} keyed by strings,
|
57
|
+
or use {DBus::ProxyObjectInterface#all_properties} to get
|
58
|
+
an actual Hash of them.
|
59
|
+
|
60
|
+
{include:file:doc/ex-properties.body.rb}
|
61
|
+
|
62
|
+
(TODO a writable property example)
|
63
|
+
|
64
|
+
Note that unlike for methods where the interface is inferred if unambiguous,
|
65
|
+
for properties the interface must be explicitly chosen.
|
66
|
+
That is because {DBus::ProxyObject} uses the {DBus::ProxyObject Hash#[]} API
|
67
|
+
to provide the {DBus::ProxyObjectInterface interfaces}, not the properties.
|
68
|
+
|
69
|
+
#### Asynchronous Operation
|
70
|
+
|
71
|
+
If a method call has a block attached, it is asynchronous and the block
|
72
|
+
is invoked on receiving a method_return message or an error message
|
73
|
+
|
74
|
+
##### Main Loop
|
75
|
+
|
76
|
+
For asynchronous operation an event loop is necessary. Use {DBus::Main}:
|
77
|
+
|
78
|
+
# [set up signal handlers...]
|
79
|
+
main = DBus::Main.new
|
80
|
+
main << mybus
|
81
|
+
main.run
|
82
|
+
|
83
|
+
Alternately, run the GLib main loop and add your DBus connections to it via
|
84
|
+
{DBus::Connection#glibize}.
|
85
|
+
|
86
|
+
#### Receiving Signals
|
87
|
+
|
88
|
+
To receive signals for a specific object and interface, use
|
89
|
+
{DBus::ProxyObjectInterface#on\_signal}(name, &block) or
|
90
|
+
{DBus::ProxyObject#on_signal}(name, &block), for the default interface.
|
91
|
+
|
92
|
+
{include:file:doc/ex-signal.body.rb}
|
93
|
+
|
94
|
+
### Intermediate Concepts
|
95
|
+
#### Names
|
96
|
+
#### Types and Values, D-Bus -> Ruby
|
97
|
+
|
98
|
+
D-Bus booleans, numbers, strings, arrays and dictionaries become their straightforward Ruby counterparts.
|
99
|
+
|
100
|
+
Structs become arrays.
|
101
|
+
|
102
|
+
Object paths become strings.
|
103
|
+
|
104
|
+
Variants are simply unpacked to become their contained type.
|
105
|
+
(ISSUE: prevents proper round-tripping!)
|
106
|
+
|
107
|
+
#### Types and Values, Ruby -> D-Bus
|
108
|
+
|
109
|
+
D-Bus has stricter typing than Ruby, so the library must decide
|
110
|
+
which D-Bus type to choose. Most of the time the choice is dictated
|
111
|
+
by the D-Bus signature. However if the signature expects a Variant
|
112
|
+
(which is the case for all Properties!) then an explicit mechanism is needed.
|
113
|
+
|
114
|
+
1. A pair [{DBus::Type::Type}, value] specifies to marshall *value* as
|
115
|
+
that specified type.
|
116
|
+
The pair can be produced by {DBus.variant}(signature, value) which
|
117
|
+
gives the same result as [{DBus.type}(signature), value].
|
118
|
+
|
119
|
+
ISSUE: using something else than cryptic signatures is even more painful
|
120
|
+
than remembering the signatures!
|
121
|
+
|
122
|
+
2. Other values are tried to fit one of these:
|
123
|
+
Boolean, Double, Array of Variants, Hash of String keyed Variants,
|
124
|
+
String, Int32, Int64.
|
125
|
+
|
126
|
+
3. **Deprecated:** A pair [String, value], where String is a valid
|
127
|
+
signature of a single complete type, marshalls value as that
|
128
|
+
type. This will hit you when you rely on method (2) but happen to have
|
129
|
+
a particular string value in an array.
|
130
|
+
|
131
|
+
|
132
|
+
`nil` is not allowed by D-Bus and attempting to send it raises an exception
|
133
|
+
(but see [I#16](https://github.com/mvidner/ruby-dbus/issues/16)).
|
134
|
+
|
135
|
+
foo_i['Bar'] = DBus.variant("au", [0, 1, 1, 2, 3, 5, 8])
|
136
|
+
|
137
|
+
|
138
|
+
#### Errors
|
139
|
+
|
140
|
+
D-Bus calls can reply with an error instead of a return value. An error is
|
141
|
+
translated to a Ruby exception, an instance of {DBus::Error}.
|
142
|
+
|
143
|
+
begin
|
144
|
+
network_manager.sleep
|
145
|
+
rescue DBus::Error => e
|
146
|
+
puts e unless e.name == "org.freedesktop.NetworkManager.AlreadyAsleepOrAwake"
|
147
|
+
end
|
148
|
+
|
149
|
+
#### Interfaces
|
150
|
+
|
151
|
+
Methods, properties and signals of a D-Bus object always belong to one of its interfaces.
|
152
|
+
|
153
|
+
Methods can be called without specifying their interface, as long as there is no ambiguity.
|
154
|
+
There are two ways to resolve ambiguities:
|
155
|
+
|
156
|
+
1. assign an interface name to {DBus::ProxyObject#default_iface}.
|
157
|
+
|
158
|
+
2. get a specific {DBus::ProxyObjectInterface interface} of the object,
|
159
|
+
with {DBus::ProxyObject#[]} and call methods from there.
|
160
|
+
|
161
|
+
Signals and properties only work with a specific interface.
|
162
|
+
|
163
|
+
#### Thread Safety
|
164
|
+
Not there. An [incomplete attempt] was made.
|
165
|
+
### Advanced Concepts
|
166
|
+
#### Bus Addresses
|
167
|
+
#### Without Introspection
|
168
|
+
#### Name Overloading
|
169
|
+
|
170
|
+
Service Side
|
171
|
+
------------
|
172
|
+
|
173
|
+
When you want to provide a DBus API.
|
174
|
+
|
175
|
+
(check that client and service side have their counterparts)
|
176
|
+
|
177
|
+
### Basic
|
178
|
+
#### Exporting a Method
|
179
|
+
##### Interfaces
|
180
|
+
##### Methods
|
181
|
+
##### Bus Names
|
182
|
+
##### Errors
|
183
|
+
#### Exporting Properties
|
184
|
+
### Advanced
|
185
|
+
#### Inheritance
|
186
|
+
#### Names
|
187
|
+
|
188
|
+
Specification Conformance
|
189
|
+
-------------------------
|
190
|
+
|
191
|
+
This section lists the known deviations from version 0.19 of
|
192
|
+
[the specification][spec].
|
193
|
+
|
194
|
+
[spec]: http://dbus.freedesktop.org/doc/dbus-specification.html
|
195
|
+
|
196
|
+
1. Properties support is basic.
|
File without changes
|
@@ -0,0 +1,9 @@
|
|
1
|
+
sysbus = DBus.system_bus
|
2
|
+
upower_s = sysbus['org.freedesktop.UPower']
|
3
|
+
upower_o = upower_s.object '/org/freedesktop/UPower'
|
4
|
+
upower_o.introspect
|
5
|
+
upower_i = upower_o['org.freedesktop.UPower']
|
6
|
+
|
7
|
+
on_battery = upower_i['OnBattery']
|
8
|
+
|
9
|
+
puts "Is the computer on battery now? #{on_battery}"
|
data/doc/ex-setup.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
sysbus = DBus.system_bus
|
2
|
+
login_s = sysbus['org.freedesktop.login1'] # part of systemd
|
3
|
+
login_o = login_s.object '/org/freedesktop/login1'
|
4
|
+
login_o.introspect
|
5
|
+
login_o.default_iface = 'org.freedesktop.login1.Manager'
|
6
|
+
|
7
|
+
# to trigger this signal, login on the Linux console
|
8
|
+
login_o.on_signal("SessionNew") do |name, opath|
|
9
|
+
puts "New session: #{name}"
|
10
|
+
|
11
|
+
session_o = login_s.object(opath)
|
12
|
+
session_o.introspect
|
13
|
+
session_i = session_o['org.freedesktop.login1.Session']
|
14
|
+
uid, user_opath = session_i['User']
|
15
|
+
puts "Its UID: #{uid}"
|
16
|
+
end
|
17
|
+
|
18
|
+
main = DBus::Main.new
|
19
|
+
main << sysbus
|
20
|
+
main.run
|
data/doc/ex-signal.rb
ADDED
data/lib/dbus.rb
CHANGED
data/lib/dbus/auth.rb
CHANGED
@@ -6,8 +6,6 @@
|
|
6
6
|
# License, version 2.1 as published by the Free Software Foundation.
|
7
7
|
# See the file "COPYING" for the exact licensing terms.
|
8
8
|
|
9
|
-
$debug = $DEBUG #it's all over the state machine
|
10
|
-
|
11
9
|
require 'rbconfig'
|
12
10
|
|
13
11
|
module DBus
|
@@ -74,12 +72,12 @@ module DBus
|
|
74
72
|
c_challenge = Array.new(s_challenge.bytesize/2).map{|obj|obj=rand(255).to_s}.join
|
75
73
|
# Search cookie file for id
|
76
74
|
path = File.join(ENV['HOME'], '.dbus-keyrings', context)
|
77
|
-
|
75
|
+
DBus.logger.debug "path: #{path.inspect}"
|
78
76
|
File.foreach(path) do |line|
|
79
77
|
if line.index(id) == 0
|
80
78
|
# Right line of file, read cookie
|
81
79
|
cookie = line.split(' ')[2].chomp
|
82
|
-
|
80
|
+
DBus.logger.debug "cookie: #{cookie.inspect}"
|
83
81
|
# Concatenate and encrypt
|
84
82
|
to_encrypt = [s_challenge, c_challenge, cookie].join(':')
|
85
83
|
sha = Digest::SHA1.hexdigest(to_encrypt)
|
@@ -158,7 +156,7 @@ module DBus
|
|
158
156
|
raise AuthenticationFailed if @auth_list.size == 0
|
159
157
|
@authenticator = @auth_list.shift.new
|
160
158
|
auth_msg = ["AUTH", @authenticator.name, @authenticator.authenticate]
|
161
|
-
|
159
|
+
DBus.logger.debug "auth_msg: #{auth_msg.inspect}"
|
162
160
|
send(auth_msg)
|
163
161
|
rescue AuthenticationFailed
|
164
162
|
@socket.close
|
@@ -179,7 +177,7 @@ module DBus
|
|
179
177
|
break if data.include? crlf #crlf means line finished, the TCP socket keeps on listening, so we break
|
180
178
|
end
|
181
179
|
readline = data.chomp.split(" ")
|
182
|
-
|
180
|
+
DBus.logger.debug "readline: #{readline.inspect}"
|
183
181
|
return readline
|
184
182
|
end
|
185
183
|
|
@@ -195,7 +193,7 @@ module DBus
|
|
195
193
|
def next_state
|
196
194
|
msg = next_msg
|
197
195
|
if @state == :Starting
|
198
|
-
|
196
|
+
DBus.logger.debug ":Starting msg: #{msg[0].inspect}"
|
199
197
|
case msg[0]
|
200
198
|
when "OK"
|
201
199
|
@state = :WaitingForOk
|
@@ -205,15 +203,15 @@ module DBus
|
|
205
203
|
@state = :WaitingForData
|
206
204
|
end
|
207
205
|
end
|
208
|
-
|
206
|
+
DBus.logger.debug "state: #{@state}"
|
209
207
|
case @state
|
210
208
|
when :WaitingForData
|
211
|
-
|
209
|
+
DBus.logger.debug ":WaitingForData msg: #{msg[0].inspect}"
|
212
210
|
case msg[0]
|
213
211
|
when "DATA"
|
214
212
|
chall = msg[1]
|
215
213
|
resp, chall = @authenticator.data(chall)
|
216
|
-
|
214
|
+
DBus.logger.debug ":WaitingForData/DATA resp: #{resp.inspect}"
|
217
215
|
case resp
|
218
216
|
when :AuthContinue
|
219
217
|
send("DATA", chall)
|
@@ -239,7 +237,7 @@ module DBus
|
|
239
237
|
@state = :WaitingForData
|
240
238
|
end
|
241
239
|
when :WaitingForOk
|
242
|
-
|
240
|
+
DBus.logger.debug ":WaitingForOk msg: #{msg[0].inspect}"
|
243
241
|
case msg[0]
|
244
242
|
when "OK"
|
245
243
|
send("BEGIN")
|
@@ -255,7 +253,7 @@ module DBus
|
|
255
253
|
@state = :WaitingForOk
|
256
254
|
end
|
257
255
|
when :WaitingForReject
|
258
|
-
|
256
|
+
DBus.logger.debug ":WaitingForReject msg: #{msg[0].inspect}"
|
259
257
|
case msg[0]
|
260
258
|
when "REJECT"
|
261
259
|
next_authenticator
|