matrix_sdk 2.5.0 → 2.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/README.md +17 -2
- data/lib/matrix_sdk/api.rb +56 -17
- data/lib/matrix_sdk/bot/base.rb +847 -0
- data/lib/matrix_sdk/bot/main.rb +79 -0
- data/lib/matrix_sdk/bot.rb +4 -0
- data/lib/matrix_sdk/client.rb +44 -12
- data/lib/matrix_sdk/mxid.rb +2 -0
- data/lib/matrix_sdk/protocols/cs.rb +12 -18
- data/lib/matrix_sdk/protocols/msc.rb +5 -4
- data/lib/matrix_sdk/response.rb +2 -0
- data/lib/matrix_sdk/room.rb +172 -89
- data/lib/matrix_sdk/rooms/space.rb +2 -2
- data/lib/matrix_sdk/user.rb +23 -1
- data/lib/matrix_sdk/util/account_data_cache.rb +91 -0
- data/lib/matrix_sdk/util/extensions.rb +16 -6
- data/lib/matrix_sdk/util/state_event_cache.rb +92 -0
- data/lib/matrix_sdk/util/tinycache.rb +8 -2
- data/lib/matrix_sdk/util/tinycache_adapter.rb +11 -1
- data/lib/matrix_sdk/util/uri.rb +16 -4
- data/lib/matrix_sdk/version.rb +1 -1
- data/lib/matrix_sdk.rb +7 -1
- metadata +8 -3
data/lib/matrix_sdk/room.rb
CHANGED
@@ -31,12 +31,11 @@ module MatrixSdk
|
|
31
31
|
ignore_inspect :client, :events, :prev_batch, :logger, :tinycache_adapter
|
32
32
|
|
33
33
|
# Requires heavy lookups, so they're cached for an hour
|
34
|
-
cached :joined_members,
|
35
|
-
# Only cache unfiltered requests for all members
|
36
|
-
cached :all_members, unless: proc { |args| args.any? }, cache_level: :all, expires_in: 3600
|
34
|
+
cached :joined_members, cache_level: :all, expires_in: 60 * 60
|
37
35
|
|
38
|
-
#
|
39
|
-
cached :
|
36
|
+
# Only cache unfiltered requests for aliases and members
|
37
|
+
cached :aliases, unless: proc { |args| args.any? }, cache_level: :all, expires_in: 60 * 60
|
38
|
+
cached :all_members, unless: proc { |args| args.any? }, cache_level: :all, expires_in: 60 * 60
|
40
39
|
|
41
40
|
alias room_id id
|
42
41
|
alias members joined_members
|
@@ -82,6 +81,12 @@ module MatrixSdk
|
|
82
81
|
|
83
82
|
@prev_batch = nil
|
84
83
|
|
84
|
+
%i[name topic canonical_alias avatar_url].each do |type|
|
85
|
+
room_state.tinycache_adapter.write("m.room.#{type}", { type => data.delete(type) }) if data.key? type
|
86
|
+
end
|
87
|
+
room_state.tinycache_adapter.write('m.room.join_rules', { join_rule: data.delete(:join_rule) }) if data.key? :join_rule
|
88
|
+
room_state.tinycache_adapter.write('m.room.history_visibility', { history_visibility: data.delete(:world_readable) ? :world_readable : nil }) if data.key? :world_readable
|
89
|
+
|
85
90
|
data.each do |k, v|
|
86
91
|
next if %i[client].include? k
|
87
92
|
|
@@ -125,6 +130,12 @@ module MatrixSdk
|
|
125
130
|
ensure_room_handlers[:event]
|
126
131
|
end
|
127
132
|
|
133
|
+
# @!attribute [r] on_account_data
|
134
|
+
# @return [EventHandlerArray] The list of event handlers for account data changes
|
135
|
+
def on_account_data
|
136
|
+
ensure_room_handlers[:account_data]
|
137
|
+
end
|
138
|
+
|
128
139
|
# @!attribute [r] on_state_event
|
129
140
|
# @return [EventHandlerArray] The list of event handlers for only state events
|
130
141
|
def on_state_event
|
@@ -167,7 +178,7 @@ module MatrixSdk
|
|
167
178
|
|
168
179
|
# @return [String, nil] the canonical alias of the room
|
169
180
|
def canonical_alias
|
170
|
-
|
181
|
+
get_state('m.room.canonical_alias')[:alias]
|
171
182
|
rescue MatrixSdk::MatrixNotFoundError
|
172
183
|
nil
|
173
184
|
end
|
@@ -200,17 +211,43 @@ module MatrixSdk
|
|
200
211
|
#
|
201
212
|
# @return [String,nil] The room name - if any
|
202
213
|
def name
|
203
|
-
|
214
|
+
get_state('m.room.name')[:name]
|
204
215
|
rescue MatrixNotFoundError
|
205
216
|
# No room name has been specified
|
206
217
|
nil
|
207
218
|
end
|
208
219
|
|
220
|
+
# Checks if the room is a direct message / 1:1 room
|
221
|
+
#
|
222
|
+
# @param members_only [Boolean] Should directness only care about member count?
|
223
|
+
# @return [Boolean]
|
224
|
+
def dm?(members_only: false)
|
225
|
+
return true if !members_only && client.direct_rooms.any? { |_uid, rooms| rooms.include? id.to_s }
|
226
|
+
|
227
|
+
joined_members.count <= 2
|
228
|
+
end
|
229
|
+
|
230
|
+
# Mark a room as a direct (1:1) message Room
|
231
|
+
def dm=(direct)
|
232
|
+
rooms = client.direct_rooms
|
233
|
+
dirty = false
|
234
|
+
list_for_room = (rooms[id.to_s] ||= [])
|
235
|
+
if direct && !list_for_room.include?(id.to_s)
|
236
|
+
list_for_room << id.to_s
|
237
|
+
dirty = true
|
238
|
+
elsif !direct && list_for_room.include?(id.to_s)
|
239
|
+
list_for_room.delete id.to_s
|
240
|
+
rooms.delete id.to_s if list_for_room.empty?
|
241
|
+
dirty = true
|
242
|
+
end
|
243
|
+
client.account_data['m.direct'] = rooms if dirty
|
244
|
+
end
|
245
|
+
|
209
246
|
# Gets the avatar url of the room - if any
|
210
247
|
#
|
211
248
|
# @return [String,nil] The avatar URL - if any
|
212
249
|
def avatar_url
|
213
|
-
|
250
|
+
get_state('m.room.avatar_url')[:url]
|
214
251
|
rescue MatrixNotFoundError
|
215
252
|
# No avatar has been set
|
216
253
|
nil
|
@@ -220,7 +257,7 @@ module MatrixSdk
|
|
220
257
|
#
|
221
258
|
# @return [String,nil] The topic of the room
|
222
259
|
def topic
|
223
|
-
|
260
|
+
get_state('m.room.topic')[:topic]
|
224
261
|
rescue MatrixNotFoundError
|
225
262
|
# No room name has been specified
|
226
263
|
nil
|
@@ -230,14 +267,14 @@ module MatrixSdk
|
|
230
267
|
#
|
231
268
|
# @return [:can_join,:forbidden] The current guest access right
|
232
269
|
def guest_access
|
233
|
-
|
270
|
+
get_state('m.room.guest_access')[:guest_access]&.to_sym
|
234
271
|
end
|
235
272
|
|
236
273
|
# Gets the join rule for the room
|
237
274
|
#
|
238
275
|
# @return [:public,:knock,:invite,:private] The current join rule
|
239
276
|
def join_rule
|
240
|
-
|
277
|
+
get_state('m.room.join_rules')[:join_rule]&.to_sym
|
241
278
|
end
|
242
279
|
|
243
280
|
# Checks if +guest_access+ is set to +:can_join+
|
@@ -255,11 +292,27 @@ module MatrixSdk
|
|
255
292
|
join_rule == :knock
|
256
293
|
end
|
257
294
|
|
295
|
+
def room_state
|
296
|
+
return MatrixSdk::Util::StateEventCache.new self if client.cache == :none
|
297
|
+
|
298
|
+
@room_state ||= MatrixSdk::Util::StateEventCache.new self
|
299
|
+
end
|
300
|
+
|
301
|
+
# Gets a state object in the room
|
302
|
+
def get_state(type, state_key: nil)
|
303
|
+
room_state[type, state_key]
|
304
|
+
end
|
305
|
+
|
306
|
+
# Sets a state object in the room
|
307
|
+
def set_state(type, data, state_key: nil)
|
308
|
+
room_state[type, state_key] = data
|
309
|
+
end
|
310
|
+
|
258
311
|
# Gets the history visibility of the room
|
259
312
|
#
|
260
313
|
# @return [:invited,:joined,:shared,:world_readable] The current history visibility for the room
|
261
314
|
def history_visibility
|
262
|
-
|
315
|
+
get_state('m.room.history_visibility')[:history_visibility]&.to_sym
|
263
316
|
end
|
264
317
|
|
265
318
|
# Checks if the room history is world readable
|
@@ -272,15 +325,14 @@ module MatrixSdk
|
|
272
325
|
|
273
326
|
# Gets the room aliases
|
274
327
|
#
|
328
|
+
# @param canonical_only [Boolean] Should the list of aliases only contain the canonical ones
|
275
329
|
# @return [Array[String]] The assigned room aliases
|
276
|
-
def aliases
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
.flatten
|
283
|
-
.compact
|
330
|
+
def aliases(canonical_only: true)
|
331
|
+
canonical = get_state('m.room.canonical_alias') rescue {}
|
332
|
+
aliases = ([canonical[:alias]].compact + (canonical[:alt_aliases] || [])).uniq.sort
|
333
|
+
return aliases if canonical_only
|
334
|
+
|
335
|
+
(aliases + client.api.get_room_aliases(id).aliases).uniq.sort
|
284
336
|
end
|
285
337
|
|
286
338
|
#
|
@@ -399,6 +451,31 @@ module MatrixSdk
|
|
399
451
|
client.api.send_content(id, url, name, 'm.audio', extra_information: audio_info)
|
400
452
|
end
|
401
453
|
|
454
|
+
# Sends a customized message to the Room
|
455
|
+
#
|
456
|
+
# @param body [String] The clear-text body of the message
|
457
|
+
# @param content [Hash] The custom content of the message
|
458
|
+
# @param msgtype [String] The type of the message, should be one of the known types (m.text, m.notice, m.emote, etc)
|
459
|
+
def send_custom_message(body, content = {}, msgtype: nil)
|
460
|
+
content.merge!(
|
461
|
+
body: body,
|
462
|
+
msgtype: msgtype || 'm.text'
|
463
|
+
)
|
464
|
+
|
465
|
+
client.api.send_message_event(id, 'm.room.message', content)
|
466
|
+
end
|
467
|
+
|
468
|
+
# Sends a custom timeline event to the Room
|
469
|
+
#
|
470
|
+
# @param type [String,Symbol] The type of the Event.
|
471
|
+
# For custom events, this should be written in reverse DNS format (e.g. com.example.event)
|
472
|
+
# @param content [Hash] The contents of the message, this will be the
|
473
|
+
# :content key of the resulting event object
|
474
|
+
# @see Protocols::CS#send_message_event
|
475
|
+
def send_event(type, content = {})
|
476
|
+
client.api.send_message_event(id, type, content)
|
477
|
+
end
|
478
|
+
|
402
479
|
# Redacts a message from the room
|
403
480
|
#
|
404
481
|
# @param event_id [String] the ID of the event to redact
|
@@ -495,12 +572,18 @@ module MatrixSdk
|
|
495
572
|
true
|
496
573
|
end
|
497
574
|
|
575
|
+
def account_data
|
576
|
+
return MatrixSdk::Util::AccountDataCache.new client, room: self if client.cache == :none
|
577
|
+
|
578
|
+
@account_data ||= MatrixSdk::Util::AccountDataCache.new client, room: self
|
579
|
+
end
|
580
|
+
|
498
581
|
# Retrieves a custom entry from the room-specific account data
|
499
582
|
#
|
500
583
|
# @param type [String] the data type to retrieve
|
501
584
|
# @return [Hash] the data that was stored under the given type
|
502
585
|
def get_account_data(type)
|
503
|
-
|
586
|
+
account_data[type]
|
504
587
|
end
|
505
588
|
|
506
589
|
# Stores a custom entry into the room-specific account data
|
@@ -508,7 +591,7 @@ module MatrixSdk
|
|
508
591
|
# @param type [String] the data type to store
|
509
592
|
# @param account_data [Hash] the data to store
|
510
593
|
def set_account_data(type, account_data)
|
511
|
-
|
594
|
+
self.account_data[type] = account_data
|
512
595
|
true
|
513
596
|
end
|
514
597
|
|
@@ -534,8 +617,7 @@ module MatrixSdk
|
|
534
617
|
#
|
535
618
|
# @return [Response] The content of the m.room.create event
|
536
619
|
def creation_info
|
537
|
-
|
538
|
-
client.api.get_room_creation_info(id)
|
620
|
+
room_state['m.room.create']
|
539
621
|
end
|
540
622
|
|
541
623
|
# Retrieves the type of the room
|
@@ -543,9 +625,6 @@ module MatrixSdk
|
|
543
625
|
# @return ['m.space',String,nil] The type of the room
|
544
626
|
def room_type
|
545
627
|
# Can't change, so a permanent cache is ok
|
546
|
-
return @room_type if @room_type_retrieved || @room_type
|
547
|
-
|
548
|
-
@room_type_retrieved = true
|
549
628
|
@room_type ||= creation_info[:type]
|
550
629
|
end
|
551
630
|
|
@@ -553,6 +632,7 @@ module MatrixSdk
|
|
553
632
|
#
|
554
633
|
# @return [String] The version of the room
|
555
634
|
def room_version
|
635
|
+
# Can't change, so a permanent cache is ok
|
556
636
|
@room_version ||= creation_info[:room_version]
|
557
637
|
end
|
558
638
|
|
@@ -627,8 +707,7 @@ module MatrixSdk
|
|
627
707
|
#
|
628
708
|
# @param name [String] The new name to set
|
629
709
|
def name=(name)
|
630
|
-
|
631
|
-
client.api.set_room_name(id, name)
|
710
|
+
room_state['m.room.name'] = { name: name }
|
632
711
|
name
|
633
712
|
end
|
634
713
|
|
@@ -636,7 +715,7 @@ module MatrixSdk
|
|
636
715
|
#
|
637
716
|
# @return [Boolean] if the name was changed or not
|
638
717
|
def reload_name!
|
639
|
-
|
718
|
+
room_state.expire('m.room.name')
|
640
719
|
end
|
641
720
|
alias refresh_name! reload_name!
|
642
721
|
|
@@ -644,8 +723,7 @@ module MatrixSdk
|
|
644
723
|
#
|
645
724
|
# @param topic [String] The new topic to set
|
646
725
|
def topic=(topic)
|
647
|
-
|
648
|
-
client.api.set_room_topic(id, topic)
|
726
|
+
room_state['m.room.topic'] = { topic: topic }
|
649
727
|
topic
|
650
728
|
end
|
651
729
|
|
@@ -653,7 +731,7 @@ module MatrixSdk
|
|
653
731
|
#
|
654
732
|
# @return [Boolean] if the topic was changed or not
|
655
733
|
def reload_topic!
|
656
|
-
|
734
|
+
room_state.expire('m.room.topic')
|
657
735
|
end
|
658
736
|
alias refresh_topic! reload_topic!
|
659
737
|
|
@@ -672,6 +750,7 @@ module MatrixSdk
|
|
672
750
|
# @note The list of aliases is not sorted, ordering changes will result in
|
673
751
|
# alias list updates.
|
674
752
|
def reload_aliases!
|
753
|
+
room_state.expire('m.room.canonical_alias')
|
675
754
|
clear_aliases_cache
|
676
755
|
end
|
677
756
|
alias refresh_aliases! reload_aliases!
|
@@ -688,8 +767,7 @@ module MatrixSdk
|
|
688
767
|
#
|
689
768
|
# @param join_rule [:invite,:public] The join rule of the room
|
690
769
|
def join_rule=(join_rule)
|
691
|
-
|
692
|
-
tinycache_adapter.write(:join_rule, join_rule)
|
770
|
+
room_state['m.room.join_rules'] = { join_rule: join_rule }
|
693
771
|
join_rule
|
694
772
|
end
|
695
773
|
|
@@ -705,8 +783,7 @@ module MatrixSdk
|
|
705
783
|
#
|
706
784
|
# @param guest_access [:can_join,:forbidden] The new guest access status of the room
|
707
785
|
def guest_access=(guest_access)
|
708
|
-
|
709
|
-
tinycache_adapter.write(:guest_access, guest_access)
|
786
|
+
room_state['m.room.guest_access'] = { guest_access: guest_access }
|
710
787
|
guest_access
|
711
788
|
end
|
712
789
|
|
@@ -717,8 +794,7 @@ module MatrixSdk
|
|
717
794
|
avatar_url = URI(avatar_url) unless avatar_url.is_a? URI
|
718
795
|
raise ArgumentError, 'Must be a valid MXC URL' unless avatar_url.is_a? URI::MXC
|
719
796
|
|
720
|
-
|
721
|
-
tinycache_adapter.write(:avatar_url, avatar_url)
|
797
|
+
room_state['m.room.avatar_url'] = { avatar_url: avatar_url }
|
722
798
|
avatar_url
|
723
799
|
end
|
724
800
|
|
@@ -728,7 +804,7 @@ module MatrixSdk
|
|
728
804
|
# @return [Hash] The current power levels as set for the room
|
729
805
|
# @see Protocols::CS#get_power_levels
|
730
806
|
def power_levels
|
731
|
-
|
807
|
+
get_state('m.room.power_levels')
|
732
808
|
end
|
733
809
|
|
734
810
|
# Gets the power level of a user in the room
|
@@ -740,13 +816,27 @@ module MatrixSdk
|
|
740
816
|
def user_powerlevel(user, use_default: true)
|
741
817
|
user = user.id if user.is_a? User
|
742
818
|
user = MXID.new(user.to_s) unless user.is_a? MXID
|
743
|
-
raise ArgumentError, 'Must provide a valid
|
819
|
+
raise ArgumentError, 'Must provide a valid User or MXID' unless user.user?
|
744
820
|
|
745
821
|
level = power_levels.dig(:users, user.to_s.to_sym)
|
746
|
-
level
|
822
|
+
level ||= power_levels[:users_default] || 0 if use_default
|
747
823
|
level
|
748
824
|
end
|
749
825
|
|
826
|
+
# Checks if a user can send a given event type in the room
|
827
|
+
#
|
828
|
+
# @param user [User,MXID,String] The user to check
|
829
|
+
# @param event [String,Symbol] The event type to check
|
830
|
+
# @param state [Boolean] If the given event is a state event or a message event
|
831
|
+
# @return [Boolean] If the given user is allowed to send an event of the given type
|
832
|
+
def user_can_send?(user, event, state: false)
|
833
|
+
user_pl = user_powerlevel(user)
|
834
|
+
event_pl = power_levels.dig(:events, event.to_s.to_sym)
|
835
|
+
event_pl ||= state ? (power_levels[:state_default] || 50) : (power_levels[:events_default] || 0)
|
836
|
+
|
837
|
+
user_pl >= event_pl
|
838
|
+
end
|
839
|
+
|
750
840
|
# Check if a user is an admin in the room
|
751
841
|
#
|
752
842
|
# @param user [User,MXID,String] The user to check for admin privileges
|
@@ -811,8 +901,9 @@ module MatrixSdk
|
|
811
901
|
def modify_user_power_levels(users = nil, users_default = nil)
|
812
902
|
return false if users.nil? && users_default.nil?
|
813
903
|
|
814
|
-
|
815
|
-
|
904
|
+
room_state.tinycache_adapter.expire 'm.room.power_levels'
|
905
|
+
|
906
|
+
data = power_levels
|
816
907
|
data[:users_default] = users_default unless users_default.nil?
|
817
908
|
|
818
909
|
if users
|
@@ -830,7 +921,7 @@ module MatrixSdk
|
|
830
921
|
end
|
831
922
|
end
|
832
923
|
|
833
|
-
|
924
|
+
room_state['m.room.power_levels'] = data
|
834
925
|
true
|
835
926
|
end
|
836
927
|
|
@@ -842,8 +933,9 @@ module MatrixSdk
|
|
842
933
|
def modify_required_power_levels(events = nil, params = {})
|
843
934
|
return false if events.nil? && (params.nil? || params.empty?)
|
844
935
|
|
845
|
-
|
846
|
-
|
936
|
+
room_state.tinycache_adapter.expire 'm.room.power_levels'
|
937
|
+
|
938
|
+
data = power_levels
|
847
939
|
data.merge!(params)
|
848
940
|
data.delete_if { |_k, v| v.nil? }
|
849
941
|
|
@@ -853,37 +945,21 @@ module MatrixSdk
|
|
853
945
|
data[:events].delete_if { |_k, v| v.nil? }
|
854
946
|
end
|
855
947
|
|
856
|
-
|
948
|
+
room_state['m.room.power_levels'] = data
|
857
949
|
true
|
858
950
|
end
|
859
951
|
|
860
952
|
private
|
861
953
|
|
862
954
|
def ensure_member(member)
|
955
|
+
return unless client.cache == :all
|
956
|
+
|
863
957
|
tinycache_adapter.write(:joined_members, []) unless tinycache_adapter.exist? :joined_members
|
864
958
|
|
865
959
|
members = tinycache_adapter.read(:joined_members) || []
|
866
960
|
members << member unless members.any? { |m| m.id == member.id }
|
867
|
-
end
|
868
961
|
|
869
|
-
|
870
|
-
tinycache_adapter.write(:power_levels, event[:content])
|
871
|
-
end
|
872
|
-
|
873
|
-
def handle_room_name(event)
|
874
|
-
tinycache_adapter.write(:name, event.dig(*%i[content name]))
|
875
|
-
end
|
876
|
-
|
877
|
-
def handle_room_topic(event)
|
878
|
-
tinycache_adapter.write(:topic, event.dig(*%i[content topic]))
|
879
|
-
end
|
880
|
-
|
881
|
-
def handle_room_guest_access(event)
|
882
|
-
tinycache_adapter.write(:guest_access, event.dig(*%i[content guest_access])&.to_sym)
|
883
|
-
end
|
884
|
-
|
885
|
-
def handle_room_join_rules(event)
|
886
|
-
tinycache_adapter.write(:join_rule, event.dig(*%i[content join_rule])&.to_sym)
|
962
|
+
tinycache_adapter.write(:joined_members, members)
|
887
963
|
end
|
888
964
|
|
889
965
|
def handle_room_member(event)
|
@@ -900,20 +976,13 @@ module MatrixSdk
|
|
900
976
|
end
|
901
977
|
|
902
978
|
def handle_room_canonical_alias(event)
|
903
|
-
|
979
|
+
room_state.tinycache_adapter.write('m.room.canonical_alias', event[:content], expires_in: room_state.cache_time)
|
980
|
+
canonical_alias = event.dig(*%i[content alias])
|
904
981
|
|
905
982
|
data = tinycache_adapter.read(:aliases) || []
|
906
983
|
data << canonical_alias
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
def handle_room_aliases(event)
|
911
|
-
tinycache_adapter.write(:aliases, []) unless tinycache_adapter.exist? :aliases
|
912
|
-
|
913
|
-
aliases = tinycache_adapter.read(:aliases) || []
|
914
|
-
aliases.concat(event.dig(*%i[content aliases]))
|
915
|
-
|
916
|
-
tinycache_adapter.write(:aliases, aliases)
|
984
|
+
data += event.dig(*%i[content alt_aliases]) || []
|
985
|
+
tinycache_adapter.write(:aliases, data.uniq.sort)
|
917
986
|
end
|
918
987
|
|
919
988
|
def room_handlers?
|
@@ -922,22 +991,13 @@ module MatrixSdk
|
|
922
991
|
|
923
992
|
def ensure_room_handlers
|
924
993
|
client.instance_variable_get(:@room_handlers)[id] ||= {
|
994
|
+
account_data: MatrixSdk::EventHandlerArray.new,
|
925
995
|
event: MatrixSdk::EventHandlerArray.new,
|
926
996
|
state_event: MatrixSdk::EventHandlerArray.new,
|
927
997
|
ephemeral_event: MatrixSdk::EventHandlerArray.new
|
928
998
|
}
|
929
999
|
end
|
930
1000
|
|
931
|
-
INTERNAL_HANDLERS = {
|
932
|
-
'm.room.aliases' => :handle_room_aliases,
|
933
|
-
'm.room.canonical_alias' => :handle_room_canonical_alias,
|
934
|
-
'm.room.guest_access' => :handle_room_guest_access,
|
935
|
-
'm.room.join_rules' => :handle_room_join_rules,
|
936
|
-
'm.room.member' => :handle_room_member,
|
937
|
-
'm.room.name' => :handle_room_name,
|
938
|
-
'm.room.power_levels' => :handle_power_levels,
|
939
|
-
'm.room.topic' => :handle_room_topic
|
940
|
-
}.freeze
|
941
1001
|
def put_event(event)
|
942
1002
|
ensure_room_handlers[:event].fire(MatrixEvent.new(self, event), event[:type]) if room_handlers?
|
943
1003
|
|
@@ -945,14 +1005,37 @@ module MatrixSdk
|
|
945
1005
|
@events.shift if @events.length > @event_history_limit
|
946
1006
|
end
|
947
1007
|
|
1008
|
+
def put_account_data(event)
|
1009
|
+
if client.cache != :none
|
1010
|
+
adapter = account_data.tinycache_adapter
|
1011
|
+
adapter.write(event[:type], event[:content], expires_in: account_data.cache_time)
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
return unless room_handlers?
|
1015
|
+
|
1016
|
+
ensure_room_handlers[:account_data].fire(MatrixEvent.new(self, event))
|
1017
|
+
end
|
1018
|
+
|
948
1019
|
def put_ephemeral_event(event)
|
949
1020
|
return unless room_handlers?
|
950
1021
|
|
951
1022
|
ensure_room_handlers[:ephemeral_event].fire(MatrixEvent.new(self, event), event[:type])
|
952
1023
|
end
|
953
1024
|
|
1025
|
+
INTERNAL_HANDLERS = {
|
1026
|
+
'm.room.canonical_alias' => :handle_room_canonical_alias,
|
1027
|
+
'm.room.member' => :handle_room_member
|
1028
|
+
}.freeze
|
1029
|
+
|
954
1030
|
def put_state_event(event)
|
955
|
-
|
1031
|
+
if INTERNAL_HANDLERS.key? event[:type]
|
1032
|
+
send(INTERNAL_HANDLERS[event[:type]], event)
|
1033
|
+
elsif client.cache != :none
|
1034
|
+
adapter = room_state.tinycache_adapter
|
1035
|
+
key = event[:type]
|
1036
|
+
key += "|#{event[:state_key]}" unless event[:state_key].nil? || event[:state_key].empty?
|
1037
|
+
adapter.write(key, event[:content], expires_in: room_state.cache_time)
|
1038
|
+
end
|
956
1039
|
|
957
1040
|
return unless room_handlers?
|
958
1041
|
|
@@ -6,12 +6,12 @@ module MatrixSdk::Rooms
|
|
6
6
|
|
7
7
|
def tree(suggested_only: nil, max_rooms: nil)
|
8
8
|
begin
|
9
|
-
data = client.api.request :get, :
|
9
|
+
data = client.api.request :get, :client_r0, "/rooms/#{id}/spaces", query: {
|
10
10
|
suggested_only: suggested_only,
|
11
11
|
max_rooms_per_space: max_rooms
|
12
12
|
}.compact
|
13
13
|
rescue MatrixRequestError
|
14
|
-
data = client.api.request :get, :
|
14
|
+
data = client.api.request :get, :client_unstable, "/org.matrix.msc2946/rooms/#{id}/spaces", query: {
|
15
15
|
suggested_only: suggested_only,
|
16
16
|
max_rooms_per_space: max_rooms
|
17
17
|
}.compact
|
data/lib/matrix_sdk/user.rb
CHANGED
@@ -28,6 +28,12 @@ module MatrixSdk
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
def to_s
|
32
|
+
"#{display_name} (#{id})" if @display_name
|
33
|
+
|
34
|
+
@id.to_s
|
35
|
+
end
|
36
|
+
|
31
37
|
# @return [String] the display name
|
32
38
|
# @see MatrixSdk::Protocols::CS#get_display_name
|
33
39
|
def display_name
|
@@ -68,6 +74,22 @@ module MatrixSdk
|
|
68
74
|
@avatar_url = url
|
69
75
|
end
|
70
76
|
|
77
|
+
# Check if the user is an admin in a given room
|
78
|
+
#
|
79
|
+
# @param room [String,MXID] the room to check
|
80
|
+
# @return [Boolean] If the user is an admin (PL >= 100)
|
81
|
+
def admin?(room)
|
82
|
+
client.ensure_room(room).user_powerlevel(self) >= 100
|
83
|
+
end
|
84
|
+
|
85
|
+
# Check if the user is a moderator in a given room
|
86
|
+
#
|
87
|
+
# @param room [String,MXID] the room to check
|
88
|
+
# @return [Boolean] If the user is an admin (PL >= 50)
|
89
|
+
def moderator?(room)
|
90
|
+
client.ensure_room(room).user_powerlevel(self) >= 50
|
91
|
+
end
|
92
|
+
|
71
93
|
# Get the user's current presence status
|
72
94
|
#
|
73
95
|
# @return [Symbol] One of :online, :offline, :unavailable
|
@@ -132,7 +154,7 @@ module MatrixSdk
|
|
132
154
|
|
133
155
|
# Returns all the current device keys for the user, retrieving them if necessary
|
134
156
|
def device_keys
|
135
|
-
@device_keys ||= client.api.keys_query(device_keys: { id => [] }).yield_self do |resp|
|
157
|
+
@device_keys ||= client.api.keys_query(device_keys: { id => [] }).yield_self do |resp| # rubocop:disable Style/ObjectThen # Keep Ruby 2.5 support a little longer
|
136
158
|
resp.dig(:device_keys, id.to_sym)
|
137
159
|
end
|
138
160
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MatrixSdk::Util
|
4
|
+
class AccountDataCache
|
5
|
+
extend MatrixSdk::Extensions
|
6
|
+
extend MatrixSdk::Util::Tinycache
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
attr_reader :client, :room
|
10
|
+
|
11
|
+
attr_accessor :cache_time
|
12
|
+
|
13
|
+
ignore_inspect :client, :room, :tinycache_adapter
|
14
|
+
|
15
|
+
def initialize(client, room: nil, cache_time: 1 * 60 * 60, **_params)
|
16
|
+
raise ArgumentError, 'Must be given a Client instance' unless client.is_a? MatrixSdk::Client
|
17
|
+
|
18
|
+
@client = client
|
19
|
+
@cache_time = cache_time
|
20
|
+
|
21
|
+
return unless room
|
22
|
+
|
23
|
+
@room = room
|
24
|
+
@room = client.ensure_room room unless @room.is_a? MatrixSdk::Room
|
25
|
+
end
|
26
|
+
|
27
|
+
def reload!
|
28
|
+
tinycache_adapter.clear
|
29
|
+
end
|
30
|
+
|
31
|
+
def keys
|
32
|
+
tinycache_adapter.send(:cache).keys
|
33
|
+
end
|
34
|
+
|
35
|
+
def values
|
36
|
+
keys.map { |key| tinycache_adapter.read(key) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def size
|
40
|
+
keys.count
|
41
|
+
end
|
42
|
+
|
43
|
+
def key?(key)
|
44
|
+
keys.key?(key.to_s)
|
45
|
+
end
|
46
|
+
|
47
|
+
def each(live: false)
|
48
|
+
return to_enum(__method__, live: live) { keys.count } unless block_given?
|
49
|
+
|
50
|
+
keys.each do |key|
|
51
|
+
v = live ? self[key] : tinycache_adapter.read(key)
|
52
|
+
# hash = v.hash
|
53
|
+
yield key, v
|
54
|
+
# self[key] = v if hash != v.hash
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def delete(key)
|
59
|
+
key = key.to_s unless key.is_a? String
|
60
|
+
if room
|
61
|
+
client.api.set_room_account_data(client.mxid, room.id, key, {})
|
62
|
+
else
|
63
|
+
client.api.set_account_data(client.mxid, key, {})
|
64
|
+
end
|
65
|
+
tinycache_adapter.delete(key)
|
66
|
+
end
|
67
|
+
|
68
|
+
def [](key)
|
69
|
+
key = key.to_s unless key.is_a? String
|
70
|
+
tinycache_adapter.fetch(key, expires_in: @cache_time) do
|
71
|
+
if room
|
72
|
+
client.api.get_room_account_data(client.mxid, room.id, key)
|
73
|
+
else
|
74
|
+
client.api.get_account_data(client.mxid, key)
|
75
|
+
end
|
76
|
+
rescue MatrixSdk::MatrixNotFoundError
|
77
|
+
{}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def []=(key, value)
|
82
|
+
key = key.to_s unless key.is_a? String
|
83
|
+
if room
|
84
|
+
client.api.set_room_account_data(client.mxid, room.id, key, value)
|
85
|
+
else
|
86
|
+
client.api.set_account_data(client.mxid, key, value)
|
87
|
+
end
|
88
|
+
tinycache_adapter.write(key, value)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|