matrix_sdk 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/CHANGELOG.md +11 -0
- data/README.md +2 -0
- data/examples/simple_client.rb +6 -3
- data/lib/matrix_sdk.rb +13 -2
- data/lib/matrix_sdk/api.rb +70 -720
- data/lib/matrix_sdk/application_service.rb +210 -0
- data/lib/matrix_sdk/client.rb +69 -44
- data/lib/matrix_sdk/extensions.rb +22 -10
- data/lib/matrix_sdk/protocols/as.rb +5 -0
- data/lib/matrix_sdk/protocols/cs.rb +799 -0
- data/lib/matrix_sdk/protocols/is.rb +33 -0
- data/lib/matrix_sdk/protocols/ss.rb +12 -0
- data/lib/matrix_sdk/room.rb +15 -38
- data/lib/matrix_sdk/user.rb +6 -4
- data/lib/matrix_sdk/version.rb +1 -1
- data/matrix-sdk.gemspec +4 -3
- metadata +25 -7
@@ -0,0 +1,210 @@
|
|
1
|
+
require 'matrix_sdk'
|
2
|
+
|
3
|
+
module MatrixSdk
|
4
|
+
class ApplicationService
|
5
|
+
include MatrixSdk::Logging
|
6
|
+
attr_reader :api, :port
|
7
|
+
|
8
|
+
def_delegators :@api,
|
9
|
+
:access_token, :access_token=, :device_id, :device_id=, :homeserver, :homeserver=,
|
10
|
+
:validate_certificate, :validate_certificate=
|
11
|
+
|
12
|
+
def initialize(hs_url, as_token:, hs_token:, default_routes: true, **params)
|
13
|
+
logger.warning 'This abstraction is still under HEAVY development, expect errors'
|
14
|
+
|
15
|
+
params = { protocols: %i[AS CS] }.merge(params).merge(access_token: as_token)
|
16
|
+
if hs_url.is_a? Api
|
17
|
+
@api = hs_url
|
18
|
+
params.each do |k, v|
|
19
|
+
api.instance_variable_set("@#{k}", v) if api.instance_variable_defined? "@#{k}"
|
20
|
+
end
|
21
|
+
else
|
22
|
+
@api = Api.new hs_url, params
|
23
|
+
end
|
24
|
+
|
25
|
+
@id = params.fetch(:id, MatrixSdk::Api::USER_AGENT)
|
26
|
+
@port = params.fetch(:port, 8888)
|
27
|
+
@url = params.fetch(:url, URI("http://localhost:#{@port}"))
|
28
|
+
@as_token = as_token
|
29
|
+
@hs_token = hs_token
|
30
|
+
|
31
|
+
@method_map = {}
|
32
|
+
|
33
|
+
if default_routes
|
34
|
+
add_method(:GET, '/_matrix/app/v1/users/', %r{^/_matrix/app/v1/users/(?<user>[^/]+)$}, :do_get_user)
|
35
|
+
add_method(:GET, '/_matrix/app/v1/rooms/', %r{^/_matrix/app/v1/rooms/(?<room>[^/]+)$}, :do_get_room)
|
36
|
+
|
37
|
+
add_method(:GET, '/_matrix/app/v1/thirdparty/protocol/', %r{^/_matrix/app/v1/thirdparty/protocol/(?<protocol>[^/]+)$}, :do_get_3p_protocol_p)
|
38
|
+
add_method(:GET, '/_matrix/app/v1/thirdparty/user/', %r{^/_matrix/app/v1/thirdparty/user/(?<protocol>[^/]+)$}, :do_get_3p_user_p)
|
39
|
+
add_method(:GET, '/_matrix/app/v1/thirdparty/location/', %r{^/_matrix/app/v1/thirdparty/location/(?<protocol>[^/]+)$}, :do_get_3p_location_p)
|
40
|
+
add_method(:GET, '/_matrix/app/v1/thirdparty/user', %r{^/_matrix/app/v1/thirdparty/user$}, :do_get_3p_user)
|
41
|
+
add_method(:GET, '/_matrix/app/v1/thirdparty/location', %r{^/_matrix/app/v1/thirdparty/location$}, :do_get_3p_location)
|
42
|
+
|
43
|
+
add_method(:PUT, '/_matrix/app/v1/transactions/', %r{^/_matrix/app/v1/transactions/(?<txn_id>[^/]+)$}, :do_put_transaction)
|
44
|
+
|
45
|
+
if params.fetch(:legacy_routes, false)
|
46
|
+
add_method(:GET, '/users/', %r{^/users/(?<user>[^/]+)$}, :do_get_user)
|
47
|
+
add_method(:GET, '/rooms/', %r{^/rooms/(?<room>[^/]+)$}, :do_get_room)
|
48
|
+
|
49
|
+
add_method(:GET, '/_matrix/app/unstable/thirdparty/protocol/', %r{^/_matrix/app/unstable/thirdparty/protocol/(?<protocol>[^/]+)$}, :do_get_3p_protocol_p)
|
50
|
+
add_method(:GET, '/_matrix/app/unstable/thirdparty/user/', %r{^/_matrix/app/unstable/thirdparty/user/(?<protocol>[^/]+)$}, :do_get_3p_user_p)
|
51
|
+
add_method(:GET, '/_matrix/app/unstable/thirdparty/location/', %r{^/_matrix/app/unstable/thirdparty/location/(?<protocol>[^/]+)$}, :do_get_3p_location_p)
|
52
|
+
add_method(:GET, '/_matrix/app/unstable/thirdparty/user', %r{^/_matrix/app/unstable/thirdparty/user$}, :do_get_3p_user)
|
53
|
+
add_method(:GET, '/_matrix/app/unstable/thirdparty/location', %r{^/_matrix/app/unstable/thirdparty/location$}, :do_get_3p_location)
|
54
|
+
|
55
|
+
add_method(:PUT, '/transactions/', %r{^/transactions/(?<txn_id>[^/]+)$}, :do_put_transaction)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
start_server
|
60
|
+
end
|
61
|
+
|
62
|
+
def registration
|
63
|
+
{
|
64
|
+
id: @id,
|
65
|
+
url: @url,
|
66
|
+
as_token: @as_token,
|
67
|
+
hs_token: @hs_token,
|
68
|
+
sender_localpart: '',
|
69
|
+
namespaces: {
|
70
|
+
users: [],
|
71
|
+
aliases: [],
|
72
|
+
rooms: []
|
73
|
+
},
|
74
|
+
rate_limited: false,
|
75
|
+
protocols: []
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def port=(port)
|
80
|
+
raise ArgumentError, 'Port must be a number' unless port.is_a? Numeric
|
81
|
+
|
82
|
+
raise NotImplementedError, "Can't change port of a running server" if server.status != :Stop
|
83
|
+
|
84
|
+
@port = port
|
85
|
+
end
|
86
|
+
|
87
|
+
protected
|
88
|
+
|
89
|
+
def add_method(verb, prefix, regex, proc = nil, &block)
|
90
|
+
proc ||= block
|
91
|
+
raise ArgumentError, 'No method specified' if proc.nil?
|
92
|
+
|
93
|
+
method_entry = (@method_map[verb] ||= {})[regex] = {
|
94
|
+
verb: verb,
|
95
|
+
prefix: prefix,
|
96
|
+
proc: proc
|
97
|
+
}
|
98
|
+
return true unless @server
|
99
|
+
|
100
|
+
server.mount_proc(method.prefix) { |req, res| _handle_proc(verb, method_entry, req, res) }
|
101
|
+
end
|
102
|
+
|
103
|
+
def do_get_user(user:, **params)
|
104
|
+
[user, params]
|
105
|
+
raise NotImplementedError
|
106
|
+
end
|
107
|
+
|
108
|
+
def do_get_room(room:, **params)
|
109
|
+
[room, params]
|
110
|
+
raise NotImplementedError
|
111
|
+
end
|
112
|
+
|
113
|
+
def do_get_3p_protocol_p(protocol:, **params)
|
114
|
+
[protocol, params]
|
115
|
+
raise NotImplementedError
|
116
|
+
end
|
117
|
+
|
118
|
+
def do_get_3p_user_p(protocol:, **params)
|
119
|
+
[protocol, params]
|
120
|
+
raise NotImplementedError
|
121
|
+
end
|
122
|
+
|
123
|
+
def do_get_3p_location_p(protocol:, **params)
|
124
|
+
[protocol, params]
|
125
|
+
raise NotImplementedError
|
126
|
+
end
|
127
|
+
|
128
|
+
def do_get_3p_location(**params)
|
129
|
+
[protocol, params]
|
130
|
+
raise NotImplementedError
|
131
|
+
end
|
132
|
+
|
133
|
+
def do_get_3p_user(**params)
|
134
|
+
[protocol, params]
|
135
|
+
raise NotImplementedError
|
136
|
+
end
|
137
|
+
|
138
|
+
def do_put_transaction(txn_id:, **params)
|
139
|
+
[txn_id, params]
|
140
|
+
raise NotImplementedError
|
141
|
+
end
|
142
|
+
|
143
|
+
def start_server
|
144
|
+
server.start
|
145
|
+
|
146
|
+
@method_map.each do |verb, method_entry|
|
147
|
+
# break if verb != method_entry[:verb]
|
148
|
+
|
149
|
+
method = method_entry[:proc]
|
150
|
+
server.mount_proc(method.prefix) { |req, res| _handle_proc(verb, method_entry, req, res) }
|
151
|
+
end
|
152
|
+
|
153
|
+
logger.info "Application Service is now running on port #{port}"
|
154
|
+
end
|
155
|
+
|
156
|
+
def stop_server
|
157
|
+
@server.shutdown if @server
|
158
|
+
@server = nil
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def _handle_proc(verb, method_entry, req, res)
|
164
|
+
logger.debug "Received request for #{verb} #{method_entry}"
|
165
|
+
match = regex.match(req.request_uri.path)
|
166
|
+
match_hash = Hash[match.names.zip(match.captures)].merge(
|
167
|
+
request: req,
|
168
|
+
response: res
|
169
|
+
)
|
170
|
+
|
171
|
+
if method.is_a? Symbol
|
172
|
+
send method, match_hash
|
173
|
+
else
|
174
|
+
method.call match_hash
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def server
|
179
|
+
@server ||= WEBrick::HTTPServer.new(Port: port, ServerSoftware: "#{MatrixSdk::Api::USER_AGENT} (Ruby #{RUBY_VERSION})").tap do |server|
|
180
|
+
server.mount_proc '/', &:handle_request
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def handle_request(request, response)
|
185
|
+
logger.debug "Received request #{request.inspect}"
|
186
|
+
|
187
|
+
req_method = request.request_method.to_s.to_sym
|
188
|
+
req_uri = request.request_uri
|
189
|
+
|
190
|
+
map = @method_map[req_method]
|
191
|
+
raise WEBrick::HTTPStatus[405], { message: 'Unsupported verb' }.to_json if map.nil?
|
192
|
+
|
193
|
+
discovered = map.find { |k, _v| k =~ req_uri.path }
|
194
|
+
raise WEBrick::HTTPStatus[404], { message: 'Unknown request' }.to_json if discovered.nil?
|
195
|
+
|
196
|
+
method = discovered.last
|
197
|
+
match = Regexp.last_match
|
198
|
+
match_hash = Hash[match.names.zip(match.captures)].merge(
|
199
|
+
request: request,
|
200
|
+
response: response
|
201
|
+
)
|
202
|
+
|
203
|
+
if method.is_a? Symbol
|
204
|
+
send method, match_hash
|
205
|
+
else
|
206
|
+
method.call match_hash
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
data/lib/matrix_sdk/client.rb
CHANGED
@@ -4,19 +4,28 @@ require 'forwardable'
|
|
4
4
|
|
5
5
|
module MatrixSdk
|
6
6
|
class Client
|
7
|
+
include MatrixSdk::Logging
|
7
8
|
extend Forwardable
|
8
9
|
|
9
10
|
attr_reader :api
|
10
11
|
attr_accessor :cache, :sync_filter
|
11
12
|
|
12
|
-
events :event, :presence_event, :invite_event, :
|
13
|
+
events :event, :presence_event, :invite_event, :leave_event, :ephemeral_event
|
13
14
|
ignore_inspect :api,
|
14
|
-
:on_event, :on_presence_event, :on_invite_event, :
|
15
|
+
:on_event, :on_presence_event, :on_invite_event, :on_leave_event, :on_ephemeral_event
|
15
16
|
|
16
17
|
def_delegators :@api,
|
17
18
|
:access_token, :access_token=, :device_id, :device_id=, :homeserver, :homeserver=,
|
18
19
|
:validate_certificate, :validate_certificate=
|
19
20
|
|
21
|
+
def self.new_for_domain(domain, **params)
|
22
|
+
api = MatrixSdk::Api.new_for_domain(domain, keep_wellknown: true)
|
23
|
+
return new(api, params) unless api.well_known.key? 'm.identity_server'
|
24
|
+
|
25
|
+
identity_server = MatrixSdk::Api.new(api.well_known['m.identity_server']['base_url'], protocols: %i[IS])
|
26
|
+
new(api, params.merge(identity_server: identity_server))
|
27
|
+
end
|
28
|
+
|
20
29
|
# @param hs_url [String,URI,Api] The URL to the Matrix homeserver, without the /_matrix/ part, or an existing Api instance
|
21
30
|
# @param client_cache [:all,:some,:none] (:all) How much data should be cached in the client
|
22
31
|
# @param params [Hash] Additional parameters on creation
|
@@ -40,10 +49,11 @@ module MatrixSdk
|
|
40
49
|
@rooms = {}
|
41
50
|
@users = {}
|
42
51
|
@cache = client_cache
|
52
|
+
@identity_server = params.fetch(:identity_server, nil)
|
43
53
|
|
44
54
|
@sync_token = nil
|
45
55
|
@sync_thread = nil
|
46
|
-
@sync_filter = { room: { timeline: { limit: params.fetch(:sync_filter_limit, 20) } } }
|
56
|
+
@sync_filter = { room: { timeline: { limit: params.fetch(:sync_filter_limit, 20) }, state: { lazy_load_members: true } } }
|
47
57
|
|
48
58
|
@should_listen = false
|
49
59
|
@next_batch = nil
|
@@ -61,10 +71,6 @@ module MatrixSdk
|
|
61
71
|
@mxid = params[:user_id]
|
62
72
|
end
|
63
73
|
|
64
|
-
def logger
|
65
|
-
@logger ||= Logging.logger[self]
|
66
|
-
end
|
67
|
-
|
68
74
|
def mxid
|
69
75
|
@mxid ||= begin
|
70
76
|
api.whoami?[:user_id] if api && api.access_token
|
@@ -154,8 +160,15 @@ module MatrixSdk
|
|
154
160
|
ensure_room(data.fetch(:room_id, room_id_or_alias))
|
155
161
|
end
|
156
162
|
|
157
|
-
def find_room(room_id_or_alias)
|
158
|
-
|
163
|
+
def find_room(room_id_or_alias, only_canonical: false)
|
164
|
+
room_id_or_alias = MXID.new(room_id_or_alias.to_s) unless room_id_or_alias.is_a? MXID
|
165
|
+
raise ArgumentError, 'Must be a room id or alias' unless %i[room_id room_alias].include? room_id_or_alias.type
|
166
|
+
|
167
|
+
return @rooms.fetch(room_id_or_alias, nil) if room_id_or_alias.room_id?
|
168
|
+
|
169
|
+
return @rooms.values.find { |r| r.canonical_alias == room_id_or_alias.to_s } if only_canonical
|
170
|
+
|
171
|
+
@rooms.values.find { |r| r.aliases.include? room_id_or_alias.to_s }
|
159
172
|
end
|
160
173
|
|
161
174
|
def get_user(user_id)
|
@@ -177,10 +190,6 @@ module MatrixSdk
|
|
177
190
|
raise MatrixUnexpectedResponseError, 'Upload succeeded, but no media URI returned'
|
178
191
|
end
|
179
192
|
|
180
|
-
def listen_for_events(timeout: 30, **arguments)
|
181
|
-
sync(arguments.merge(timeout: timeout))
|
182
|
-
end
|
183
|
-
|
184
193
|
def start_listener_thread(params = {})
|
185
194
|
@should_listen = true
|
186
195
|
thread = Thread.new { listen_forever(params) }
|
@@ -196,19 +205,44 @@ module MatrixSdk
|
|
196
205
|
@sync_thread = nil
|
197
206
|
end
|
198
207
|
|
208
|
+
def sync(skip_store_batch: false, **params)
|
209
|
+
extra_params = {
|
210
|
+
filter: sync_filter,
|
211
|
+
timeout: 30
|
212
|
+
}
|
213
|
+
extra_params[:since] = @next_batch unless @next_batch.nil?
|
214
|
+
extra_params.merge!(params)
|
215
|
+
extra_params[:filter] = extra_params[:filter].to_json unless extra_params[:filter].is_a? String
|
216
|
+
|
217
|
+
attempts = 0
|
218
|
+
data = loop do
|
219
|
+
begin
|
220
|
+
break api.sync extra_params
|
221
|
+
rescue MatrixSdk::MatrixTimeoutError => e
|
222
|
+
raise e if (attempts += 1) >= params.fetch(:allow_sync_retry, 0)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
@next_batch = data[:next_batch] unless skip_store_batch
|
227
|
+
|
228
|
+
handle_sync_response(data)
|
229
|
+
end
|
230
|
+
|
231
|
+
alias listen_for_events sync
|
232
|
+
|
199
233
|
private
|
200
234
|
|
201
235
|
def listen_forever(timeout: 30, bad_sync_timeout: 5, sync_interval: 30, **params)
|
202
|
-
orig_bad_sync_timeout = bad_sync_timeout
|
236
|
+
orig_bad_sync_timeout = bad_sync_timeout + 0
|
203
237
|
while @should_listen
|
204
238
|
begin
|
205
239
|
sync(params.merge(timeout: timeout))
|
206
240
|
|
207
241
|
bad_sync_timeout = orig_bad_sync_timeout
|
208
242
|
sleep(sync_interval) if sync_interval > 0
|
209
|
-
rescue MatrixRequestError =>
|
210
|
-
logger.warn("A #{
|
211
|
-
if
|
243
|
+
rescue MatrixRequestError => e
|
244
|
+
logger.warn("A #{e.class} occurred during sync")
|
245
|
+
if e.httpstatus >= 500
|
212
246
|
logger.warn("Serverside error, retrying in #{bad_sync_timeout} seconds...")
|
213
247
|
sleep params[:bad_sync_timeout]
|
214
248
|
bad_sync_timeout = [bad_sync_timeout * 2, @bad_sync_timeout_limit].min
|
@@ -227,7 +261,11 @@ module MatrixSdk
|
|
227
261
|
|
228
262
|
def ensure_room(room_id)
|
229
263
|
room_id = room_id.to_s unless room_id.is_a? String
|
230
|
-
@rooms.fetch(room_id)
|
264
|
+
@rooms.fetch(room_id) do
|
265
|
+
room = Room.new(self, room_id)
|
266
|
+
@rooms[room_id] = room unless cache == :none
|
267
|
+
room
|
268
|
+
end
|
231
269
|
end
|
232
270
|
|
233
271
|
def handle_state(room_id, state_event)
|
@@ -240,6 +278,8 @@ module MatrixSdk
|
|
240
278
|
room.instance_variable_set '@name', content[:name]
|
241
279
|
when 'm.room.canonical_alias'
|
242
280
|
room.instance_variable_set '@canonical_alias', content[:alias]
|
281
|
+
# Also add as a regular alias
|
282
|
+
room.instance_variable_get('@aliases').concat [content[:alias]]
|
243
283
|
when 'm.room.topic'
|
244
284
|
room.instance_variable_set '@topic', content[:topic]
|
245
285
|
when 'm.room.aliases'
|
@@ -252,63 +292,48 @@ module MatrixSdk
|
|
252
292
|
return unless cache == :all
|
253
293
|
|
254
294
|
if content[:membership] == 'join'
|
255
|
-
room.send
|
295
|
+
room.send(:ensure_member, get_user(state_event[:state_key]).dup.tap do |u|
|
296
|
+
u.instance_variable_set :@display_name, content[:displayname]
|
297
|
+
end)
|
256
298
|
elsif %w[leave kick invite].include? content[:membership]
|
257
299
|
room.members.delete_if { |m| m.id == state_event[:state_key] }
|
258
300
|
end
|
259
301
|
end
|
260
302
|
end
|
261
303
|
|
262
|
-
def sync(skip_store_batch: false, **params)
|
263
|
-
extra_params = {
|
264
|
-
filter: sync_filter.to_json
|
265
|
-
}
|
266
|
-
extra_params[:since] = @next_batch unless @next_batch.nil?
|
267
|
-
|
268
|
-
attempts = 0
|
269
|
-
data = loop do
|
270
|
-
begin
|
271
|
-
break api.sync extra_params.merge(params)
|
272
|
-
rescue MatrixTimeoutError => ex
|
273
|
-
raise ex if (attempts += 1) > params.fetch(:allow_sync_retry, 0)
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
@next_batch = data[:next_batch] unless skip_store_batch
|
278
|
-
|
279
|
-
handle_sync_response(data)
|
280
|
-
end
|
281
|
-
|
282
304
|
def handle_sync_response(data)
|
283
305
|
data[:presence][:events].each do |presence_update|
|
284
306
|
fire_presence_event(MatrixEvent.new(self, presence_update))
|
285
307
|
end
|
286
308
|
|
287
309
|
data[:rooms][:invite].each do |room_id, invite|
|
288
|
-
fire_invite_event(MatrixEvent.new(self, invite), room_id)
|
310
|
+
fire_invite_event(MatrixEvent.new(self, invite), room_id.to_s)
|
289
311
|
end
|
290
312
|
|
291
313
|
data[:rooms][:leave].each do |room_id, left|
|
292
|
-
fire_leave_event(MatrixEvent.new(self, left), room_id)
|
314
|
+
fire_leave_event(MatrixEvent.new(self, left), room_id.to_s)
|
293
315
|
end
|
294
316
|
|
295
317
|
data[:rooms][:join].each do |room_id, join|
|
296
318
|
room = ensure_room(room_id)
|
297
319
|
room.instance_variable_set '@prev_batch', join[:timeline][:prev_batch]
|
320
|
+
room.instance_variable_set :@members_loaded, true unless sync_filter.fetch(:room, {}).fetch(:state, {}).fetch(:lazy_load_members, false)
|
321
|
+
|
298
322
|
join[:state][:events].each do |event|
|
299
|
-
event[:room_id] = room_id
|
323
|
+
event[:room_id] = room_id.to_s
|
300
324
|
handle_state(room_id, event)
|
301
325
|
end
|
302
326
|
|
303
327
|
join[:timeline][:events].each do |event|
|
304
|
-
event[:room_id] = room_id
|
328
|
+
event[:room_id] = room_id.to_s
|
329
|
+
handle_state(room_id, event) unless event[:type] == 'm.room.message'
|
305
330
|
room.send :put_event, event
|
306
331
|
|
307
332
|
fire_event(MatrixEvent.new(self, event), event[:type])
|
308
333
|
end
|
309
334
|
|
310
335
|
join[:ephemeral][:events].each do |event|
|
311
|
-
event[:room_id] = room_id
|
336
|
+
event[:room_id] = room_id.to_s
|
312
337
|
room.send :put_ephemeral_event, event
|
313
338
|
|
314
339
|
fire_ephemeral_event(MatrixEvent.new(self, event), event[:type])
|
@@ -10,6 +10,14 @@ module URI
|
|
10
10
|
@@schemes['MXC'] = MATRIX
|
11
11
|
end
|
12
12
|
|
13
|
+
unless Object.respond_to? :yield_self
|
14
|
+
class Object
|
15
|
+
def yield_self
|
16
|
+
yield(self)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
13
21
|
def events(*symbols)
|
14
22
|
module_name = "#{name}Events"
|
15
23
|
|
@@ -52,15 +60,23 @@ end
|
|
52
60
|
def ignore_inspect(*symbols)
|
53
61
|
class_eval %*
|
54
62
|
def inspect
|
63
|
+
reentrant = caller_locations.any? { |l| l.absolute_path == __FILE__ && l.label == 'inspect' }
|
55
64
|
"\#{to_s[0..-2]} \#{instance_variables
|
56
65
|
.reject { |f| %i[#{symbols.map { |s| "@#{s}" }.join ' '}].include? f }
|
57
|
-
.map { |f| "\#{f}=\#{instance_variable_get(f).inspect}" }.join " " }}>"
|
66
|
+
.map { |f| "\#{f}=\#{reentrant ? instance_variable_get(f) : instance_variable_get(f).inspect}" }.join " " }}>"
|
58
67
|
end
|
59
|
-
*, __FILE__, __LINE__ -
|
68
|
+
*, __FILE__, __LINE__ - 7
|
60
69
|
end
|
61
70
|
|
62
71
|
module MatrixSdk
|
72
|
+
module Logging
|
73
|
+
def logger
|
74
|
+
@logger ||= ::Logging.logger[self]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
63
78
|
class EventHandlerArray < Hash
|
79
|
+
include MatrixSdk::Logging
|
64
80
|
attr_accessor :reraise_exceptions
|
65
81
|
|
66
82
|
def initialize(*args)
|
@@ -82,17 +98,13 @@ module MatrixSdk
|
|
82
98
|
reverse_each do |_k, h|
|
83
99
|
begin
|
84
100
|
h[:block].call(event) if event.matches?(h[:filter], filter)
|
85
|
-
rescue StandardError =>
|
86
|
-
logger.error "#{
|
101
|
+
rescue StandardError => e
|
102
|
+
logger.error "#{e.class.name} occurred when firing event (#{event})\n#{e}"
|
87
103
|
|
88
|
-
raise
|
104
|
+
raise e if @reraise_exceptions
|
89
105
|
end
|
90
106
|
end
|
91
107
|
end
|
92
|
-
|
93
|
-
def logger
|
94
|
-
@logger ||= Logging.logger[self]
|
95
|
-
end
|
96
108
|
end
|
97
109
|
|
98
110
|
class Event
|
@@ -150,7 +162,7 @@ module MatrixSdk
|
|
150
162
|
super
|
151
163
|
end
|
152
164
|
|
153
|
-
def respond_to_missing?(method)
|
165
|
+
def respond_to_missing?(method, *)
|
154
166
|
event.key? method
|
155
167
|
end
|
156
168
|
end
|