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