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 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:
@@ -1,17 +1,17 @@
1
- = Ruby D-Bus README
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
- == Requirements
6
+ ## Requirements
7
7
 
8
- * Ruby 1.8.7 or 1.9
8
+ - Ruby 1.8.7 or 1.9
9
9
 
10
- == Installation
10
+ ## Installation
11
11
 
12
- * gem install ruby-dbus
12
+ - `gem install ruby-dbus`
13
13
 
14
- == Feature
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
- == Usage
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/tutorial/
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/tutorial/index.markdown .
35
+ <https://github.com/mvidner/ruby-dbus/blob/master/doc/Tutorial.md> .
36
36
 
37
- == License
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
- load "ruby-dbus.gemspec"
37
-
38
- Rake::GemPackageTask.new(GEMSPEC) do |pkg|
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
- cp_r "#{temp}/pkg", "."
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.8.0
1
+ 0.9.0
@@ -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.
@@ -0,0 +1,8 @@
1
+ mybus = DBus.session_bus
2
+ service = mybus['org.freedesktop.ScreenSaver']
3
+ object = service.object '/ScreenSaver'
4
+ object.introspect
5
+ loop do
6
+ object.SimulateUserActivity
7
+ sleep 5 * 60
8
+ end
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+ require 'example-helper.rb'
3
+ example 'ex-calling-methods.body.rb'
@@ -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}"
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+ require 'example-helper.rb'
3
+ example 'ex-properties.body.rb'
@@ -0,0 +1,7 @@
1
+ #! /usr/bin/env ruby
2
+ require 'rubygems' # Not needed since Ruby 1.9
3
+ require 'dbus' # The gem is 'ruby-dbus' but the require is 'dbus'
4
+
5
+ # Connect to a well-known address. Most apps need only one of them.
6
+ mybus = DBus.session_bus
7
+ sysbus = DBus.system_bus
@@ -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
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+ require 'example-helper.rb'
3
+ example 'ex-signal.body.rb'
@@ -0,0 +1,6 @@
1
+ # Fin
2
+ $:.unshift File.expand_path("../../lib", __FILE__)
3
+ load 'ex-setup.rb'
4
+ def example(filename)
5
+ eval(File.read(filename), binding, filename, 1)
6
+ end
@@ -12,7 +12,8 @@ require 'dbus/type'
12
12
  require 'dbus/introspect'
13
13
  require 'dbus/error'
14
14
  require 'dbus/export'
15
- require 'dbus/bus.rb'
15
+ require 'dbus/bus'
16
+ require 'dbus/logger'
16
17
  require 'dbus/marshall'
17
18
  require 'dbus/message'
18
19
  require 'dbus/matchrule'
@@ -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
- puts "DEBUG: path: #{path.inspect}" if $debug
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
- puts "DEBUG: cookie: #{cookie.inspect}" if $debug
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
- puts "DEBUG: auth_msg: #{auth_msg.inspect}" if $debug
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
- puts "DEBUG: readline: #{readline.inspect}" if $debug
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
- puts "DEBUG: :Starting msg: #{msg[0].inspect}" if $debug
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
- puts "DEBUG: state: #{@state}" if $debug
206
+ DBus.logger.debug "state: #{@state}"
209
207
  case @state
210
208
  when :WaitingForData
211
- puts "DEBUG: :WaitingForData msg: #{msg[0].inspect}" if $debug
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
- puts "DEBUG: :WaitingForData/DATA resp: #{resp.inspect}" if $debug
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
- puts "DEBUG: :WaitingForOk msg: #{msg[0].inspect}" if $debug
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
- puts "DEBUG: :WaitingForReject msg: #{msg[0].inspect}" if $debug
256
+ DBus.logger.debug ":WaitingForReject msg: #{msg[0].inspect}"
259
257
  case msg[0]
260
258
  when "REJECT"
261
259
  next_authenticator