ruby-dbus 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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