ruby-dbus 0.14.0 → 0.17.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 +5 -5
- data/NEWS.md +44 -0
- data/README.md +3 -5
- data/Rakefile +26 -8
- data/VERSION +1 -1
- data/doc/Reference.md +84 -1
- data/examples/doc/_extract_examples +5 -0
- data/examples/gdbus/gdbus +21 -20
- data/examples/service/call_service.rb +1 -1
- data/lib/dbus/auth.rb +8 -8
- data/lib/dbus/bus.rb +23 -11
- data/lib/dbus/bus_name.rb +27 -0
- data/lib/dbus/core_ext/class/attribute.rb +23 -41
- data/lib/dbus/core_ext/module/redefine_method.rb +51 -0
- data/lib/dbus/introspect.rb +71 -26
- data/lib/dbus/marshall.rb +2 -1
- data/lib/dbus/message_queue.rb +17 -14
- data/lib/dbus/object.rb +380 -0
- data/lib/dbus/object_path.rb +24 -0
- data/lib/dbus/proxy_object.rb +11 -2
- data/lib/dbus/proxy_object_interface.rb +1 -0
- data/lib/dbus/type.rb +18 -0
- data/lib/dbus/xml.rb +4 -8
- data/lib/dbus.rb +3 -2
- data/ruby-dbus.gemspec +11 -9
- data/spec/binding_spec.rb +6 -2
- data/spec/bus_name_spec.rb +25 -0
- data/spec/client_robustness_spec.rb +25 -0
- data/spec/introspect_xml_parser_spec.rb +13 -13
- data/spec/main_loop_spec.rb +1 -1
- data/spec/object_path_spec.rb +23 -0
- data/spec/property_spec.rb +53 -3
- data/spec/proxy_object_spec.rb +9 -0
- data/spec/service_newapi.rb +20 -66
- data/spec/session_bus_spec.rb +6 -6
- data/spec/signal_spec.rb +33 -18
- data/spec/spec_helper.rb +23 -11
- data/spec/tools/dbus-limited-session.conf +4 -0
- data/spec/type_spec.rb +2 -2
- metadata +32 -15
- data/lib/dbus/core_ext/array/extract_options.rb +0 -31
- data/lib/dbus/core_ext/kernel/singleton_class.rb +0 -8
- data/lib/dbus/core_ext/module/remove_method.rb +0 -14
- data/lib/dbus/export.rb +0 -130
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ee629ce8a78d7cd23f718103cfd622d2a5fd67c51dab6b2a88e453c512c608f3
|
4
|
+
data.tar.gz: a8995a9526e3b957d32c503de7ad5ef781e5c464925fec8e2107eda4529aa447
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 531e01c12aed4aeedaa5ce55fec2fee0c3da714211adc768c8990d2ce79509e6b925bc06d4308e9628cff109b9880dbea72878e7aeaf23c8e5fb19ddf8a249e2
|
7
|
+
data.tar.gz: 6449aa2798ed78d29c430423a92d7c8a921fd4ea244eea11fb8a84ca2eb880a4e6860325dc6a05254dc432b971d4929fc4d3a5057e423939c0574a687e7680f7
|
data/NEWS.md
CHANGED
@@ -2,6 +2,50 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## Ruby D-Bus 0.17.0 - 2022-02-11
|
6
|
+
|
7
|
+
API:
|
8
|
+
* Export properties with `dbus_attr_accessor`, `dbus_reader` etc. ([#86][]).
|
9
|
+
|
10
|
+
Bug fixes:
|
11
|
+
* Depend on rexml which is separate since Ruby 3.0 ([#87][],
|
12
|
+
by Toshiaki Asai).
|
13
|
+
Nokogiri is faster but bigger so it remains optional.
|
14
|
+
* Fix connection in case ~/.dbus-keyrings has multiple cookies, showing
|
15
|
+
as "Oops: undefined method `zero?' for nil:NilClass".
|
16
|
+
* Add the missing name to the root introspection node.
|
17
|
+
|
18
|
+
[#86]: https://github.com/mvidner/ruby-dbus/pull/86
|
19
|
+
[#87]: https://github.com/mvidner/ruby-dbus/pull/87
|
20
|
+
|
21
|
+
## Ruby D-Bus 0.16.0 - 2019-10-15
|
22
|
+
|
23
|
+
API:
|
24
|
+
* An invalid service name or an invalid object path will raise
|
25
|
+
instead of being sent to the bus. The bus would then drop the connection,
|
26
|
+
producing EOFError here ([#80][]).
|
27
|
+
|
28
|
+
[#80]: https://github.com/mvidner/ruby-dbus/issues/80
|
29
|
+
|
30
|
+
## Ruby D-Bus 0.15.0 - 2018-04-30
|
31
|
+
|
32
|
+
API:
|
33
|
+
* Accessing an unknown interface will raise instead of returning nil ([#74][]).
|
34
|
+
|
35
|
+
Bug fixes:
|
36
|
+
* Fixed a conflict with activesupport 5.2 ([#71])
|
37
|
+
|
38
|
+
[#71]: https://github.com/mvidner/ruby-dbus/issues/71
|
39
|
+
[#74]: https://github.com/mvidner/ruby-dbus/pull/74
|
40
|
+
|
41
|
+
## Ruby D-Bus 0.14.1 - 2018-01-05
|
42
|
+
|
43
|
+
Bug fixes:
|
44
|
+
* Allow registering signal handlers while a signal is being handled
|
45
|
+
([#70][], Jan Biniok).
|
46
|
+
|
47
|
+
[#70]: https://github.com/mvidner/ruby-dbus/pull/70
|
48
|
+
|
5
49
|
## Ruby D-Bus 0.14.0 - 2017-10-13
|
6
50
|
|
7
51
|
Bug fixes:
|
data/README.md
CHANGED
@@ -11,14 +11,13 @@ Ruby D-Bus is a pure Ruby library for writing clients and services for D-Bus.
|
|
11
11
|
[![Coverage Status][CS img]][Coverage Status]
|
12
12
|
|
13
13
|
[Gem Version]: https://rubygems.org/gems/ruby-dbus
|
14
|
-
[Build Status]: https://
|
15
|
-
[travis pull requests]: https://travis-ci.org/mvidner/ruby-dbus/pull_requests
|
14
|
+
[Build Status]: https://github.com/mvidner/ruby-dbus/actions?query=branch%3Amaster
|
16
15
|
[Dependency Status]: https://gemnasium.com/mvidner/ruby-dbus
|
17
16
|
[Code Climate]: https://codeclimate.com/github/mvidner/ruby-dbus
|
18
17
|
[Coverage Status]: https://coveralls.io/r/mvidner/ruby-dbus
|
19
18
|
|
20
19
|
[GV img]: https://badge.fury.io/rb/ruby-dbus.png
|
21
|
-
[BS img]: https://
|
20
|
+
[BS img]: https://github.com/mvidner/ruby-dbus/workflows/CI/badge.svg?branch=master
|
22
21
|
[DS img]: https://gemnasium.com/mvidner/ruby-dbus.png
|
23
22
|
[CC img]: https://codeclimate.com/github/mvidner/ruby-dbus.png
|
24
23
|
[CS img]: https://coveralls.io/repos/mvidner/ruby-dbus/badge.png?branch=master
|
@@ -32,7 +31,6 @@ via [UPower](http://upower.freedesktop.org/docs/UPower.html#UPower:OnBattery)
|
|
32
31
|
sysbus = DBus.system_bus
|
33
32
|
upower_service = sysbus["org.freedesktop.UPower"]
|
34
33
|
upower_object = upower_service["/org/freedesktop/UPower"]
|
35
|
-
upower_object.introspect
|
36
34
|
upower_interface = upower_object["org.freedesktop.UPower"]
|
37
35
|
on_battery = upower_interface["OnBattery"]
|
38
36
|
if on_battery
|
@@ -43,7 +41,7 @@ via [UPower](http://upower.freedesktop.org/docs/UPower.html#UPower:OnBattery)
|
|
43
41
|
|
44
42
|
## Requirements
|
45
43
|
|
46
|
-
- Ruby 2.
|
44
|
+
- Ruby 2.1 or newer.
|
47
45
|
|
48
46
|
|
49
47
|
## Installation
|
data/Rakefile
CHANGED
@@ -9,6 +9,12 @@ begin
|
|
9
9
|
rescue LoadError
|
10
10
|
nil
|
11
11
|
end
|
12
|
+
begin
|
13
|
+
require "yard"
|
14
|
+
rescue LoadError
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
12
18
|
require "packaging"
|
13
19
|
|
14
20
|
Packaging.configuration do |conf|
|
@@ -29,7 +35,7 @@ task test: :spec
|
|
29
35
|
|
30
36
|
RSpec::Core::RakeTask.new("bare:spec")
|
31
37
|
|
32
|
-
|
38
|
+
["spec"].each do |tname|
|
33
39
|
desc "Run bare:#{tname} in the proper environment"
|
34
40
|
task tname do |_t|
|
35
41
|
cd "spec/tools" do
|
@@ -38,12 +44,6 @@ RSpec::Core::RakeTask.new("bare:spec")
|
|
38
44
|
end
|
39
45
|
end
|
40
46
|
|
41
|
-
if ENV["TRAVIS"]
|
42
|
-
require "coveralls/rake/task"
|
43
|
-
Coveralls::RakeTask.new
|
44
|
-
task default: "coveralls:push"
|
45
|
-
end
|
46
|
-
|
47
47
|
# remove tarball implementation and create gem for this gemfile
|
48
48
|
Rake::Task[:tarball].clear
|
49
49
|
|
@@ -68,4 +68,22 @@ namespace :doc do
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
|
71
|
+
if Object.const_defined? :RuboCop
|
72
|
+
if RUBY_VERSION.start_with?("2.")
|
73
|
+
RuboCop::RakeTask.new
|
74
|
+
else
|
75
|
+
desc "Run RuboCop (dummy)"
|
76
|
+
task :rubocop do
|
77
|
+
warn "The code is not adapted to recent RuboCop yet,\n" \
|
78
|
+
"and the old one no longer works with Ruby 3.x.\n" \
|
79
|
+
"Switch back to Ruby 2.x to run it."
|
80
|
+
end
|
81
|
+
end
|
82
|
+
else
|
83
|
+
desc "Run RuboCop (dummy)"
|
84
|
+
task :rubocop do
|
85
|
+
warn "RuboCop not installed"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
YARD::Rake::YardocTask.new if Object.const_defined? :YARD
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.17.0
|
data/doc/Reference.md
CHANGED
@@ -179,7 +179,7 @@ If the signature expects a Variant
|
|
179
179
|
ISSUE: using something else than cryptic signatures is even more painful
|
180
180
|
than remembering the signatures!
|
181
181
|
|
182
|
-
|
182
|
+
`foo_i["Bar"] = DBus.variant("au", [0, 1, 1, 2, 3, 5, 8])`
|
183
183
|
|
184
184
|
2. Other values are tried to fit one of these:
|
185
185
|
Boolean, Double, Array of Variants, Hash of String keyed Variants,
|
@@ -244,14 +244,97 @@ When you want to provide a DBus API.
|
|
244
244
|
(check that client and service side have their counterparts)
|
245
245
|
|
246
246
|
### Basic
|
247
|
+
|
247
248
|
#### Exporting a Method
|
249
|
+
|
248
250
|
##### Interfaces
|
251
|
+
|
249
252
|
##### Methods
|
253
|
+
|
250
254
|
##### Bus Names
|
255
|
+
|
251
256
|
##### Errors
|
257
|
+
|
252
258
|
#### Exporting Properties
|
259
|
+
|
260
|
+
Similar to plain Ruby attributes, declared with
|
261
|
+
|
262
|
+
- {https://docs.ruby-lang.org/en/3.1/Module.html#method-i-attr_accessor attr_accessor}
|
263
|
+
- {https://docs.ruby-lang.org/en/3.1/Module.html#method-i-attr_reader attr_reader}
|
264
|
+
- {https://docs.ruby-lang.org/en/3.1/Module.html#method-i-attr_writer attr_writer}
|
265
|
+
|
266
|
+
These methods declare the attributes and export them as properties:
|
267
|
+
|
268
|
+
- {DBus::Object.dbus_attr_accessor}
|
269
|
+
- {DBus::Object.dbus_attr_reader}
|
270
|
+
- {DBus::Object.dbus_attr_writer}
|
271
|
+
|
272
|
+
For making properties out of Ruby methods (which are not attributes), use:
|
273
|
+
|
274
|
+
- {DBus::Object.dbus_accessor}
|
275
|
+
- {DBus::Object.dbus_reader}
|
276
|
+
- {DBus::Object.dbus_writer}
|
277
|
+
|
278
|
+
Note that the properties are declared in the Ruby naming convention with
|
279
|
+
`snake_case` and D-Bus sees them `CamelCased`. Use the `dbus_name` argument
|
280
|
+
for overriding this.
|
281
|
+
|
282
|
+
|
283
|
+
|
284
|
+
class Note < DBus::Object
|
285
|
+
dbus_interface "net.vidner.Example.Properties" do
|
286
|
+
# A read-write property "Title",
|
287
|
+
# with `title` and `title=` accessing @title.
|
288
|
+
dbus_attr_accessor :title, DBus::Type::STRING
|
289
|
+
|
290
|
+
# A read-only property "Author"
|
291
|
+
# (type specified via DBus signature)
|
292
|
+
# with `author` reading `@author`
|
293
|
+
dbus_attr_reader :author, "s"
|
294
|
+
|
295
|
+
# A read-only property `Clock`
|
296
|
+
def clock
|
297
|
+
Time.now.to_s
|
298
|
+
end
|
299
|
+
dbus_reader :clock, "s"
|
300
|
+
|
301
|
+
# Name mapping: `CreationTime`
|
302
|
+
def creation_time
|
303
|
+
"1993-01-01 00:00:00 +0100"
|
304
|
+
end
|
305
|
+
dbus_reader :creation_time, "s"
|
306
|
+
|
307
|
+
dbus_attr_accessor :book_volume, DBus::Type::VARIANT, dbus_name: "Volume"
|
308
|
+
end
|
309
|
+
|
310
|
+
dbus_interface "net.vidner.Example.Audio" do
|
311
|
+
dbus_attr_accessor :speaker_volume, DBus::Type::BYTE, dbus_name: "Volume"
|
312
|
+
end
|
313
|
+
|
314
|
+
# Must assign values because `nil` would crash our connection
|
315
|
+
def initialize(opath)
|
316
|
+
super
|
317
|
+
@title = "Ahem"
|
318
|
+
@author = "Martin"
|
319
|
+
@book_volume = 1
|
320
|
+
@speaker_volume = 11
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
obj = Note.new("/net/vidner/Example/Properties")
|
325
|
+
|
326
|
+
bus = DBus::SessionBus.instance
|
327
|
+
service = bus.request_service("net.vidner.Example")
|
328
|
+
service.export(obj)
|
329
|
+
|
330
|
+
main = DBus::Main.new
|
331
|
+
main << bus
|
332
|
+
main.run
|
333
|
+
|
253
334
|
### Advanced
|
335
|
+
|
254
336
|
#### Inheritance
|
337
|
+
|
255
338
|
#### Names
|
256
339
|
|
257
340
|
Specification Conformance
|
@@ -4,6 +4,9 @@ if ARGV[0].nil?
|
|
4
4
|
exit
|
5
5
|
end
|
6
6
|
|
7
|
+
base_url = "https://github.com/mvidner/ruby-dbus/blob/master/"
|
8
|
+
base_url += ARGV[0].gsub("../", "")
|
9
|
+
|
7
10
|
File.open(ARGV[0]) do |f|
|
8
11
|
title = nil
|
9
12
|
setup = ""
|
@@ -20,7 +23,9 @@ File.open(ARGV[0]) do |f|
|
|
20
23
|
setup = example
|
21
24
|
else
|
22
25
|
File.open("#{basename}.rb", "w") do |e|
|
26
|
+
anchor = title.downcase.gsub(/ +/, "-")
|
23
27
|
e.write setup
|
28
|
+
e.write "# #{base_url}##{anchor}\n"
|
24
29
|
e.write example
|
25
30
|
e.chmod(0o755)
|
26
31
|
end
|
data/examples/gdbus/gdbus
CHANGED
@@ -119,25 +119,26 @@ class DBusUI
|
|
119
119
|
model = Gtk::ListStore.new(String, String, DBus::Method,
|
120
120
|
DBus::ProxyObjectInterface)
|
121
121
|
@methsigtreeview.model = model
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
122
|
+
return unless selected
|
123
|
+
|
124
|
+
intf = selected[1]
|
125
|
+
return unless intf
|
126
|
+
|
127
|
+
intf.methods.keys.sort.each do |mi|
|
128
|
+
m = intf.methods[mi]
|
129
|
+
subiter = model.append
|
130
|
+
subiter[0] = beautify_method(m)
|
131
|
+
subiter[1] = "M"
|
132
|
+
subiter[2] = m
|
133
|
+
subiter[3] = intf
|
134
|
+
end
|
135
|
+
intf.signals.keys.sort.each do |mi|
|
136
|
+
m = intf.signals[mi]
|
137
|
+
subiter = model.append
|
138
|
+
subiter[0] = beautify_method(m)
|
139
|
+
subiter[1] = "S"
|
140
|
+
subiter[2] = m
|
141
|
+
subiter[3] = intf
|
141
142
|
end
|
142
143
|
end
|
143
144
|
|
@@ -226,7 +227,7 @@ class DBusUI
|
|
226
227
|
|
227
228
|
def introspect_services(model, bus)
|
228
229
|
el = @introspect_array.shift
|
229
|
-
if
|
230
|
+
if el !~ /^:/
|
230
231
|
iter = model.append(nil)
|
231
232
|
iter[0] = el
|
232
233
|
puts "introspecting: #{el}"
|
@@ -14,7 +14,7 @@ player.test_variant(["s", "coucou"])
|
|
14
14
|
player.on_signal("SomethingJustHappened") do |u, v|
|
15
15
|
puts "SomethingJustHappened: #{u} #{v}"
|
16
16
|
end
|
17
|
-
player.hello("
|
17
|
+
player.hello("Hey", "there!")
|
18
18
|
p player["org.ruby.AnotherInterface"].Reverse("Hello world!")
|
19
19
|
|
20
20
|
main = DBus::Main.new
|
data/lib/dbus/auth.rb
CHANGED
@@ -73,7 +73,7 @@ module DBus
|
|
73
73
|
path = File.join(ENV["HOME"], ".dbus-keyrings", context)
|
74
74
|
DBus.logger.debug "path: #{path.inspect}"
|
75
75
|
File.foreach(path) do |line|
|
76
|
-
if line.
|
76
|
+
if line.start_with?(id)
|
77
77
|
# Right line of file, read cookie
|
78
78
|
cookie = line.split(" ")[2].chomp
|
79
79
|
DBus.logger.debug "cookie: #{cookie.inspect}"
|
@@ -87,14 +87,14 @@ module DBus
|
|
87
87
|
return response
|
88
88
|
end
|
89
89
|
end
|
90
|
+
return if @retries <= 0
|
91
|
+
|
90
92
|
# a little rescue magic
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
data(hexdata)
|
97
|
-
end
|
93
|
+
puts "ERROR: Could not auth, will now exit."
|
94
|
+
puts "ERROR: Unable to locate cookie, retry in 1 second."
|
95
|
+
@retries -= 1
|
96
|
+
sleep 1
|
97
|
+
data(hexdata)
|
98
98
|
end
|
99
99
|
|
100
100
|
# encode plain to hex
|
data/lib/dbus/bus.rb
CHANGED
@@ -17,7 +17,7 @@ require "singleton"
|
|
17
17
|
# Module containing all the D-Bus modules and classes.
|
18
18
|
module DBus
|
19
19
|
# This represents a remote service. It should not be instantiated directly
|
20
|
-
# Use
|
20
|
+
# Use {Connection#service}
|
21
21
|
class Service
|
22
22
|
# The service name.
|
23
23
|
attr_reader :name
|
@@ -28,7 +28,7 @@ module DBus
|
|
28
28
|
|
29
29
|
# Create a new service with a given _name_ on a given _bus_.
|
30
30
|
def initialize(name, bus)
|
31
|
-
@name = name
|
31
|
+
@name = BusName.new(name)
|
32
32
|
@bus = bus
|
33
33
|
@root = Node.new("/")
|
34
34
|
end
|
@@ -148,20 +148,22 @@ module DBus
|
|
148
148
|
|
149
149
|
# Return an XML string representation of the node.
|
150
150
|
# It is shallow, not recursing into subnodes
|
151
|
-
|
151
|
+
# @param node_opath [String]
|
152
|
+
def to_xml(node_opath)
|
152
153
|
xml = '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
153
154
|
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
154
|
-
<node>
|
155
155
|
'
|
156
|
+
xml += "<node name=\"#{node_opath}\">\n"
|
156
157
|
each_pair do |k, _v|
|
157
|
-
xml += "<node name=\"#{k}\"
|
158
|
+
xml += " <node name=\"#{k}\" />\n"
|
158
159
|
end
|
159
160
|
if @object
|
160
161
|
@object.intfs.each_pair do |_k, v|
|
161
|
-
xml +=
|
162
|
+
xml += " <interface name=\"#{v.name}\">\n"
|
162
163
|
v.methods.each_value { |m| xml += m.to_xml }
|
163
164
|
v.signals.each_value { |m| xml += m.to_xml }
|
164
|
-
xml +=
|
165
|
+
v.properties.each_value { |m| xml += m.to_xml }
|
166
|
+
xml += " </interface>\n"
|
165
167
|
end
|
166
168
|
end
|
167
169
|
xml += "</node>"
|
@@ -387,7 +389,7 @@ module DBus
|
|
387
389
|
# introspect in synchronous !
|
388
390
|
data = introspect_data(dest, path)
|
389
391
|
pof = DBus::ProxyObjectFactory.new(data, self, dest, path)
|
390
|
-
|
392
|
+
pof.build
|
391
393
|
else
|
392
394
|
introspect_data(dest, path) do |async_data|
|
393
395
|
yield(DBus::ProxyObjectFactory.new(async_data, self, dest, path).build)
|
@@ -458,6 +460,9 @@ module DBus
|
|
458
460
|
retm = wait_for_message
|
459
461
|
process(retm)
|
460
462
|
end
|
463
|
+
rescue EOFError
|
464
|
+
new_err = DBus::Error.new("Connection dropped after we sent #{m.inspect}")
|
465
|
+
raise new_err
|
461
466
|
end
|
462
467
|
|
463
468
|
# @api private
|
@@ -529,7 +534,8 @@ module DBus
|
|
529
534
|
m.member == "Introspect"
|
530
535
|
reply = Message.new(Message::METHOD_RETURN).reply_to(m)
|
531
536
|
reply.sender = @unique_name
|
532
|
-
|
537
|
+
xml = node.to_xml(m.path)
|
538
|
+
reply.add_param(Type::STRING, xml)
|
533
539
|
@message_queue.push(reply)
|
534
540
|
else
|
535
541
|
obj = node.object
|
@@ -538,7 +544,8 @@ module DBus
|
|
538
544
|
end
|
539
545
|
when DBus::Message::SIGNAL
|
540
546
|
# the signal can match multiple different rules
|
541
|
-
|
547
|
+
# clone to allow new signale handlers to be registered
|
548
|
+
@signal_matchrules.dup.each do |mrs, slot|
|
542
549
|
if DBus::MatchRule.new.from_s(mrs).match(m)
|
543
550
|
slot.call(m)
|
544
551
|
end
|
@@ -562,6 +569,11 @@ module DBus
|
|
562
569
|
# @api private
|
563
570
|
# Emit a signal event for the given _service_, object _obj_, interface
|
564
571
|
# _intf_ and signal _sig_ with arguments _args_.
|
572
|
+
# @param service [Service]
|
573
|
+
# @param obj [DBus::Object]
|
574
|
+
# @param intf [Interface]
|
575
|
+
# @param sig [Signal]
|
576
|
+
# @param args arguments for the signal
|
565
577
|
def emit(service, obj, intf, sig, *args)
|
566
578
|
m = Message.new(DBus::Message::SIGNAL)
|
567
579
|
m.path = obj.path
|
@@ -664,7 +676,7 @@ module DBus
|
|
664
676
|
# (for Unix-socket) unix:path=/tmp/my_funky_bus_socket
|
665
677
|
#
|
666
678
|
# you'll need to take care about authentification then, more info here:
|
667
|
-
#
|
679
|
+
# https://gitlab.com/pangdudu/ruby-dbus/-/blob/master/README.rdoc
|
668
680
|
class RemoteBus < Connection
|
669
681
|
# Get the remote bus.
|
670
682
|
def initialize(socket_name)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# This file is part of the ruby-dbus project
|
2
|
+
# Copyright (C) 2019 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
|
+
# A {::String} that validates at initialization time
|
11
|
+
# @see https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus
|
12
|
+
class BusName < String
|
13
|
+
# @raise Error if not a valid bus name
|
14
|
+
def initialize(s)
|
15
|
+
unless self.class.valid?(s)
|
16
|
+
raise DBus::Error, "Invalid bus name #{s.inspect}"
|
17
|
+
end
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.valid?(s)
|
22
|
+
s.size <= 255 &&
|
23
|
+
(s =~ /\A:[A-Za-z0-9_-]+(\.[A-Za-z0-9_-]+)+\z/ ||
|
24
|
+
s =~ /\A[A-Za-z_-][A-Za-z0-9_-]*(\.[A-Za-z_-][A-Za-z0-9_-]*)+\z/)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# copied from activesupport/core_ext from Rails, MIT license
|
2
|
-
# https://github.com/rails/rails/tree/
|
3
|
-
|
4
|
-
|
5
|
-
require 'dbus/core_ext/array/extract_options'
|
3
|
+
# https://github.com/rails/rails/tree/9794e85351243cac6d4e78adaba634b8e4ecad0a/activesupport/lib/active_support/core_ext
|
4
|
+
|
5
|
+
require_relative "../module/redefine_method"
|
6
6
|
|
7
7
|
class Class
|
8
8
|
# Declare a class-level attribute whose value is inheritable by subclasses.
|
9
9
|
# Subclasses can change their own value and it will not impact parent class.
|
10
10
|
#
|
11
|
+
# ==== Examples
|
12
|
+
#
|
11
13
|
# class Base
|
12
|
-
#
|
14
|
+
# my_class_attribute :setting
|
13
15
|
# end
|
14
16
|
#
|
15
17
|
# class Subclass < Base
|
@@ -22,14 +24,14 @@ class Class
|
|
22
24
|
# Base.setting # => true
|
23
25
|
#
|
24
26
|
# In the above case as long as Subclass does not assign a value to setting
|
25
|
-
# by performing <tt>Subclass.setting = _something_
|
27
|
+
# by performing <tt>Subclass.setting = _something_</tt>, <tt>Subclass.setting</tt>
|
26
28
|
# would read value assigned to parent class. Once Subclass assigns a value then
|
27
29
|
# the value assigned by Subclass would be returned.
|
28
30
|
#
|
29
31
|
# This matches normal Ruby method inheritance: think of writing an attribute
|
30
32
|
# on a subclass as overriding the reader method. However, you need to be aware
|
31
33
|
# when using +class_attribute+ with mutable structures as +Array+ or +Hash+.
|
32
|
-
# In such cases, you don't want to do changes in
|
34
|
+
# In such cases, you don't want to do changes in place. Instead use setters:
|
33
35
|
#
|
34
36
|
# Base.setting = []
|
35
37
|
# Base.setting # => []
|
@@ -59,39 +61,25 @@ class Class
|
|
59
61
|
# object.setting = false
|
60
62
|
# object.setting # => false
|
61
63
|
# Base.setting # => true
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
# object.setting # => NoMethodError
|
66
|
-
# object.setting? # => NoMethodError
|
67
|
-
#
|
68
|
-
# To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
|
69
|
-
#
|
70
|
-
# object.setting = false # => NoMethodError
|
71
|
-
#
|
72
|
-
# To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
|
73
|
-
def class_attribute(*attrs)
|
74
|
-
options = attrs.extract_options!
|
75
|
-
instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
|
76
|
-
instance_writer = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
|
77
|
-
instance_predicate = options.fetch(:instance_predicate, true)
|
64
|
+
def my_class_attribute(*attrs)
|
65
|
+
instance_reader = true
|
66
|
+
instance_writer = true
|
78
67
|
|
79
68
|
attrs.each do |name|
|
69
|
+
singleton_class.silence_redefinition_of_method(name)
|
80
70
|
define_singleton_method(name) { nil }
|
81
|
-
define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
|
82
71
|
|
83
|
-
ivar = "@#{name}"
|
72
|
+
ivar = "@#{name}".to_sym
|
84
73
|
|
74
|
+
singleton_class.silence_redefinition_of_method("#{name}=")
|
85
75
|
define_singleton_method("#{name}=") do |val|
|
86
76
|
singleton_class.class_eval do
|
87
|
-
|
88
|
-
define_method(name) { val }
|
77
|
+
redefine_method(name) { val }
|
89
78
|
end
|
90
79
|
|
91
80
|
if singleton_class?
|
92
81
|
class_eval do
|
93
|
-
|
94
|
-
define_method(name) do
|
82
|
+
redefine_method(name) do
|
95
83
|
if instance_variable_defined? ivar
|
96
84
|
instance_variable_get ivar
|
97
85
|
else
|
@@ -104,26 +92,20 @@ class Class
|
|
104
92
|
end
|
105
93
|
|
106
94
|
if instance_reader
|
107
|
-
|
108
|
-
define_method(name) do
|
95
|
+
redefine_method(name) do
|
109
96
|
if instance_variable_defined?(ivar)
|
110
97
|
instance_variable_get ivar
|
111
98
|
else
|
112
99
|
self.class.public_send name
|
113
100
|
end
|
114
101
|
end
|
115
|
-
define_method("#{name}?") { !!public_send(name) } if instance_predicate
|
116
102
|
end
|
117
103
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
private
|
123
|
-
|
124
|
-
unless respond_to?(:singleton_class?)
|
125
|
-
def singleton_class?
|
126
|
-
ancestors.first != self
|
104
|
+
if instance_writer
|
105
|
+
redefine_method("#{name}=") do |val|
|
106
|
+
instance_variable_set ivar, val
|
107
|
+
end
|
127
108
|
end
|
128
109
|
end
|
110
|
+
end
|
129
111
|
end
|