matrix_sdk 2.5.0 → 2.8.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 +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
|